diff --git a/R/blanks.R b/R/blanks.R deleted file mode 100644 index 246c6fc..0000000 --- a/R/blanks.R +++ /dev/null @@ -1,14 +0,0 @@ -#' @title Blanks -#' @description Create character vector of blanks -#' @details This function emulates the behavior of a homonimous function from Matlab -#' @param n length of vector -#' @return Vector of n blanks -#' @author Waldir Leoncio -#' @export -blanks <- function(n) { - if (n < 0) { - warning("Negative n passed. Treating as n = 0") - n <- 0 - } - paste(rep(" ", n), collapse = "") -} diff --git a/R/cell.R b/R/cell.R deleted file mode 100644 index 7febb6b..0000000 --- a/R/cell.R +++ /dev/null @@ -1,36 +0,0 @@ -#' @title Cell array -#' @description Creates an array of zeros -#' @param n a the first dimension (or both, if sz is not passed) -#' @param sz the second dimension (or 1st and 2nd, if not passed) -#' @param expandable if TRUE, output is a list (so it can take different -#' lengths) -#' @param ... Other dimensions -#' @return An array of zeroes with the dimensions passed on call -cell <- function(n, sz = c(n, n), expandable = FALSE, ...) { - - # Uglyly figuring out if the third arg is an extra dim --- # - - sz3 <- vector() - if (!is.logical(expandable)) { - sz3 <- expandable - expandable <- FALSE - } - args <- c(as.list(environment()), list(...)) - exp <- args$expandable - extra_dims <- c(sz3, args[names(args) == ""]) - - # Creating output vector --------------------------------- # - - if (exp) { - return(vector("list", length = n)) - } - if (length(sz) == 1 & length(extra_dims) == 0) { - return(array(0, dim = c(n, sz))) - } else if (length(extra_dims) > 0) { - return(array(0, dim = c(n, sz, extra_dims))) - } else if (length(sz) == 2) { - return(array(0, dim = sz)) - } else { - return(array(0, dim = c(n, sz, ...))) - } -} diff --git a/R/colon.R b/R/colon.R deleted file mode 100644 index c4c78d2..0000000 --- a/R/colon.R +++ /dev/null @@ -1,12 +0,0 @@ -#' @title Vector creation -#' @description Simulates the function `colon()` and its equivalent `:` operator from Matlab, which have a similar but not quite equivalent behavior when compared to `seq()` and `:` in R. -#' @param a initial number -#' @param b final number -#' @export -colon <- function(a, b) { - if (a <= b) { - return(a:b) - } else { - return(vector(mode = "numeric")) - } -} diff --git a/R/find.R b/R/find.R deleted file mode 100644 index 4c7e42f..0000000 --- a/R/find.R +++ /dev/null @@ -1,15 +0,0 @@ -#' @title Find indices and values of nonzero elements -#' @description Emulates behavior of `find` -#' @param x object or logic operation on an object -#' @param sort sort output? -find <- function(x, sort = TRUE) { - if (is.logical(x)) { - out <- which(x) - } else { - out <- which(x > 0) - } - if (sort) { - out <- sort(out) - } - return(out) -} diff --git a/R/fix.R b/R/fix.R deleted file mode 100644 index 988b6e4..0000000 --- a/R/fix.R +++ /dev/null @@ -1,5 +0,0 @@ -#' @title Round toward zero -#' @description Rounds each element of input to the nearest integer towards zero. Basically the same as trunc() -#' @param X input element -#' @author Waldir Leoncio -fix <- function(X) trunc(X) diff --git a/R/inputdlg.R b/R/inputdlg.R deleted file mode 100644 index cf59589..0000000 --- a/R/inputdlg.R +++ /dev/null @@ -1,18 +0,0 @@ -#' @title Gather user input -#' @description Replicates the functionality of the homonymous function in Matlab (sans dialog box) -#' @param prompt Text field with user instructions -#' @param dims number of dimensions in the answwers -#' @param definput default value of the input -#' @export -inputdlg <- function(prompt, dims = 1, definput = NULL) { - if (!is.null(definput)) { - prompt <- append(prompt, paste0(" (default: ", definput, ")")) - } - input_chr <- readline(paste0(prompt, ": ")) - if (input_chr == "") input_chr <- definput - input_chr_or_num <- tryCatch( - as.numeric(input_chr), - warning = function(w) input_chr - ) - return(input_chr_or_num) -} diff --git a/R/isempty.R b/R/isempty.R deleted file mode 100644 index e1ef187..0000000 --- a/R/isempty.R +++ /dev/null @@ -1,13 +0,0 @@ -#' @title Is Array Empty? -#' @description Determine whether array is empty. An empty array, table, or timetable has at least one dimension with length 0, such as 0-by-0 or 0-by-5. -#' @details Emulates the behavior of the `isempty` function on Matlab -#' @param x array -#' -isempty <- function(x) { - if (class(x)[1] %in% c("array", "matrix")) { - dim_mat_x <- dim(x) - } else { - dim_mat_x <- dim(matrix(x)) - } - return(any(dim_mat_x == 0) | is.null(dim_mat_x)) -} diff --git a/R/isfield.R b/R/isfield.R deleted file mode 100644 index 2120b85..0000000 --- a/R/isfield.R +++ /dev/null @@ -1,10 +0,0 @@ -#' @title Checks if a list contains a field -#' @description This function tries to replicate the behavior of the `isfield` -#' function in Matlab -#' @param x list -#' @param field name of field -#' @references https://se.mathworks.com/help/matlab/ref/isfield.html -#' @export -isfield <- function(x, field) { - sapply(field, function(f) f %in% names(x)) -} diff --git a/R/isspace.R b/R/isspace.R deleted file mode 100644 index c00b5f0..0000000 --- a/R/isspace.R +++ /dev/null @@ -1,11 +0,0 @@ -#' @title Determine space characters -#' @description Determine which characters are space characters -#' @param A a character array or a string scalar -#' @return a vector TF such that the elements of TF are logical 1 (true) where corresponding characters in A are space characters, and logical 0 (false) elsewhere -#' @note Recognized whitespace characters are ` ` and `\\t`. -#' @author Waldir Leoncio -isspace <- function(A) { - A_split <- unlist(strsplit(A, "")) - TF <- A_split %in% c(" ", "\t") - return(as.numeric(TF)) -} diff --git a/R/matlab2r.R b/R/matlab2r.R deleted file mode 100644 index 8e1db09..0000000 --- a/R/matlab2r.R +++ /dev/null @@ -1,158 +0,0 @@ -#' @title Convert Matlab function to R -#' @description Performs basic syntax conversion from Matlab to R -#' @param filename name of the file -#' @param output can be "asis", "clean", "save" or "diff" -#' @param improve_formatting if `TRUE` (default), makes minor changes -#' to conform to best-practice formatting conventions -#' @param change_assignment if `TRUE` (default), uses `<-` as the assignment operator -#' @param append if `FALSE` (default), overwrites file; otherwise, append -#' output to input -#' @return text converted to R, printed to screen or replacing input file -#' @author Waldir Leoncio -#' @importFrom utils write.table -#' @export -#' @note This function is intended to expedite the process of converting a -#' Matlab function to R by making common replacements. It does not have the -#' immediate goal of outputting a ready-to-use function. In other words, -#' after using this function you should go back to it and make minor changes. -#' -#' It is also advised to do a dry-run with `output = "clean"` and only switching -#' to `output = "save"` when you are confident that no important code will be -#' lost (for shorter functions, a careful visual inspection should suffice). -matlab2r <- function(filename, output = "diff", improve_formatting = TRUE, change_assignment = TRUE, - append = FALSE) { - # TODO: this function is too long! Split into subfunctions - # (say, by rule and/or section) - # ======================================================== # - # Verification # - # ======================================================== # - if (!file.exists(filename)) stop("File not found") - - # ======================================================== # - # Reading file into R # - # ======================================================== # - txt <- readLines(filename) - original <- txt - - # ======================================================== # - # Replacing text # - # ======================================================== # - - # Uncommenting ------------------------------------------- # - txt <- gsub("^#\\s?(.+)", "\\1", txt) - - # Output variable ---------------------------------------- # - out <- gsub( - pattern = "\\t*function ((\\S|\\,\\s)+)\\s?=\\s?(\\w+)\\((.+)\\)", - replacement = "\\1", - x = txt[1] - ) # TODO: improve by detecting listed outputs - if (substring(out, 1, 1) == "[") { - out <- strsplit(out, "(\\,|\\[|\\]|\\s)")[[1]] - out <- out[which(out != "")] - out <- sapply(seq_along(out), function(x) paste(out[x], "=", out[x])) - out <- paste0("list(", paste(out, collapse = ", "), ")") - } - - # Function header ---------------------------------------- # - txt <- gsub( - pattern = "\\t*function (.+)\\s*=\\s*(.+)\\((.+)\\)", - replacement = "\\2 <- function(\\3) {", - x = txt - ) - txt <- gsub( - pattern = "function (.+)\\((.+)\\)", - replacement = "\\1 <- function(\\2) {", - x = txt - ) - - # Function body ------------------------------------------ # - txt <- gsub("(.+)\\.\\.\\.", "\\1", txt) - txt <- gsub(";", "", txt) - - # Loops and if-statements - txt <- gsub("for (.+)=(.+)", "for (\\1 in \\2) {", txt) - txt <- gsub("end$", "}", txt) - txt <- gsub("if (.+)", "if (\\1) {", txt) # FIXME: paste comments after { - txt <- gsub("else$", "} else {", txt) - txt <- gsub("elseif", "} else if", txt) - txt <- gsub("while (.+)", "while \\1 {", txt) - - # MATLAB-equivalent functions in R - txt <- gsub("gamma_ln", "log_gamma", txt) - txt <- gsub("nchoosek", "choose", txt) - txt <- gsub("isempty", "is.null", txt) - # txt <- gsub("(.+)\\'", "t(\\1)", txt) - - # Subsets ------------------------------------------------ # - ass_op <- ifelse(change_assignment, "<-", "=") - txt <- gsub( - pattern = "([^\\(]+)\\(([^\\(]+)\\)=(.+)", - replacement = paste0("\\1[\\2] ", ass_op, "\\3"), - x = txt - ) - txt <- gsub("\\(:\\)", "[, ]", txt) - txt <- gsub("(.+)(\\[|\\():,end(\\]|\\()", "\\1[, ncol()]", txt) - - # Formatting --------------------------------------------- # - if (improve_formatting) { - txt <- gsub("(.),(\\S)", "\\1, \\2", txt) - # Math operators - txt <- gsub("(\\S)\\+(\\S)", "\\1 + \\2", txt) - txt <- gsub("(\\S)\\-(\\S)", "\\1 - \\2", txt) - txt <- gsub("(\\S)\\*(\\S)", "\\1 * \\2", txt) - txt <- gsub("(\\S)\\/(\\S)", "\\1 / \\2", txt) - # Logic operators - txt <- gsub("~", "!", txt) - txt <- gsub("(\\S)>=(\\S)", "\\1 >= \\2", txt) - txt <- gsub("(\\S)<=(\\S)", "\\1 <= \\2", txt) - txt <- gsub("(\\S)==(\\S)", "\\1 == \\2", txt) - # Assignment - txt <- gsub( - pattern = "(\\w)(\\s?)=(\\s?)(\\w)", - replacement = paste0("\\1 ", ass_op, " \\4"), - x = txt - ) - # txt <- gsub( - # pattern = "(\\s+(.|\\_|\\[|\\])+)(\\s?)=(\\s?)(.+)", - # replacement = paste0("\\1 ", ass_op, "\\5"), - # x = txt - # ) - txt <- gsub("%(\\s?)(\\w)", "# \\2", txt) - } - - # Adding output and end-of-file brace -------------------- # - txt <- append(txt, paste0("\treturn(", out, ")\n}")) - - # Returning converted code ------------------------------- # - if (output == "asis") { - return(txt) - } else if (output == "clean") { - return(cat(txt, sep = "\n")) - } else if (output == "save") { - return( - write.table( - x = txt, - file = filename, - quote = FALSE, - row.names = FALSE, - col.names = FALSE, - append = append - ) - ) - } else if (output == "diff") { - diff_text <- vector(mode = "character", length = (2 * length(original) + 1)) - for (i in seq_along(txt)) { - new_i <- (2 * i) + i - 2 - diff_text[new_i] <- paste( - "-----------------------", "line", i, "-----------------------" - ) - diff_text[new_i + 1] <- original[i] - diff_text[new_i + 2] <- txt[i] - } - message("Displaying line number, original content and modified content") - return(cat(diff_text, sep = "\n")) - } else { - stop("Invalid output argument") - } -} diff --git a/R/min_max_MATLAB.R b/R/min_max_MATLAB.R deleted file mode 100644 index 2d93a15..0000000 --- a/R/min_max_MATLAB.R +++ /dev/null @@ -1,33 +0,0 @@ -#' @title Minimum (MATLAB version) -#' @description Finds the minimum value for each column of a matrix, potentially returning the indices instead -#' @param X matrix -#' @param indices return indices? -#' @return Either a list or a vector -#' @author Waldir Leoncio -min_MATLAB <- function(X, indices = TRUE) { - if (!is(X, "matrix")) X <- as.matrix(X) - mins <- apply(X, 2, min) - idx <- sapply(seq_len(ncol(X)), function(x) match(mins[x], X[, x])) - if (indices) { - return(list(mins = mins, idx = idx)) - } else { - return(mins) - } -} - -#' @title Maximum (MATLAB version) -#' @description Finds the minimum value for each column of a matrix, potentially returning the indices instead -#' @param X matrix -#' @param indices return indices? -#' @return Either a list or a vector -#' @author Waldir Leoncio -max_MATLAB <- function(X, indices = TRUE) { - if (!is(X, "matrix")) X <- as.matrix(X) - maxs <- apply(X, 2, max) - idx <- sapply(seq_len(ncol(X)), function(x) match(maxs[x], X[, x])) - if (indices) { - return(list(maxs = maxs, idx = idx)) - } else { - return(maxs) - } -} diff --git a/R/nargin.R b/R/nargin.R deleted file mode 100644 index 0d48ab2..0000000 --- a/R/nargin.R +++ /dev/null @@ -1,10 +0,0 @@ -#' @title Number of function input arguments -#' @description Returns the number of arguments passed to the parent function -#' @return An integer -#' @author Waldir Leoncio -#' @note This function only makes sense inside another function -#' @references https://stackoverflow.com/q/64422780/1169233 -nargin <- function() { - if (sys.nframe() < 2) stop("must be called from inside a function") - length(as.list(sys.call(-1))) - 1 -} diff --git a/R/questdlg.R b/R/questdlg.R deleted file mode 100644 index 01a5beb..0000000 --- a/R/questdlg.R +++ /dev/null @@ -1,39 +0,0 @@ -#' @title Prompt for multiple-choice -#' @param quest Question -#' @param dlgtitle Title of question -#' @param btn Vector of alternatives -#' @param defbtn Scalar with the name of the default option -#' @param accepted_ans Vector containing accepted answers -#' @description This function aims to loosely mimic the behavior of the -#' questdlg function on Matlab -#' @export -questdlg <- function(quest, - dlgtitle = "", - btn = c("y", "n"), - defbtn = "n", - accepted_ans = c("y", "yes", "n", "no")) { - message(dlgtitle) - # ========================================================================== - # Replacing the default option with a capitalized version on btn - # ========================================================================== - btn[match(tolower(defbtn), tolower(btn))] <- toupper(defbtn) - # ========================================================================== - # Creating prompt - # ========================================================================== - option_char <- paste0(" [", paste(btn, collapse = ", "), "]") - answer <- readline(paste0(quest, option_char, ": ")) - # ========================================================================== - # Processing answer - # ========================================================================== - answer <- tolower(answer) - if (!(answer %in% tolower(c(btn, accepted_ans)))) { - if (answer != "") { - warning( - "'", answer, "' is not a valid alternative. Defaulting to ", - defbtn - ) - } - answer <- defbtn - } - return(answer) -} diff --git a/R/rand.R b/R/rand.R deleted file mode 100644 index 394447c..0000000 --- a/R/rand.R +++ /dev/null @@ -1,10 +0,0 @@ -#' @title Generate matrix with U(0, 1) trials -#' @description Imitates the behavior of `rand()` on Matlab -#' @param r number of rows of output matrix -#' @param c number of columns of output matrix -#' @return \eqn{r \times c} matrix with random trials from a standard uniform distribution. -#' @importFrom stats runif -#' @export -rand <- function(r = 1, c = 1) { - matrix(runif(r * c), r, c) -} diff --git a/R/repmat.R b/R/repmat.R deleted file mode 100644 index 87ee5f9..0000000 --- a/R/repmat.R +++ /dev/null @@ -1,38 +0,0 @@ -#' @title Repeat matrix -#' @description Repeats a matrix over n columns and rows -#' @details This function was created to replicate the behavior of a homonymous -#' function on Matlab -#' @param mx matrix -#' @param n either a scalar with the number of replications in both rows and -#' columns or a <= 3-length vector with individual repetitions. -#' @return matrix replicated over `ncol(mx) * n` columns and `nrow(mx) * n` rows -#' @note The Matlab implementation of this function accepts `n` with length > 2. -#' -#' It should also be noted that a concatenated vector in R, e.g. `c(5, 2)`, becomes a column vector when coerced to matrix, even though it may look like a row vector at first glance. This is important to keep in mind when considering the expected output of this function. Vectors in R make sense to be seen as column vectors, given R's Statistics-oriented paradigm where variables are usually disposed as columns in a dataset. -#' @export -repmat <- function(mx, n) { - # Validation - if (length(n) > 3) warning("Extra dimensions of n ignored") - if (!is(mx, "matrix")) mx <- t(as.matrix(mx)) - if (length(n) == 1) n <- rep(n, 2) - if (any(n == 0)) { - n_zero <- which(n == 0) - out_dim <- dim(mx) - out_dim[n_zero] <- 0 - return(array(dim = out_dim)) - } - - # Replicating cols - out <- mx_col <- matrix(rep(mx, n[2]), nrow(mx)) - - # Replicating rows - if (n[1] > 1) { - for (i in seq(n[1] - 1)) out <- rbind(out, mx_col) - } - - # Replicating 3rd dimension - if (!is.na(n[3]) & n[3] > 1) out <- array(out, c(dim(out), n[3])) - - # Output - return(unname(as.array(out))) -} diff --git a/R/reshape.R b/R/reshape.R deleted file mode 100644 index cb78c59..0000000 --- a/R/reshape.R +++ /dev/null @@ -1,24 +0,0 @@ -#' @title Reshape array -#' @description Reshapes a matrix according to a certain number of dimensions -#' @param A input matrix -#' @param sz vector containing the dimensions of the output vector -#' @details This function replicates the functionality of the `reshape()` -#' function on Matlab. This function is basically a fancy wrapper for the -#' `array()` function in R, but is useful because it saves the user translation -#' time. Moreover, it introduces validation code that alter the behavior of -#' `array()` and makes it more similar to `replicate()`. -#' @note The Matlab function also accepts as input the dismemberment of sz as -#' scalars. -reshape <- function(A, sz) { - # Validation - if (prod(sz) != prod(dim(A))) { - stop("To RESHAPE the number of elements must not change.") - } - if (length(sz) == 1) { - stop("Size vector must have at least two elements.") - } - - # Reshaping A - A <- array(A, sz) - return(A) -} diff --git a/R/setdiff_MATLAB.R b/R/setdiff_MATLAB.R deleted file mode 100644 index 2d00f8f..0000000 --- a/R/setdiff_MATLAB.R +++ /dev/null @@ -1,25 +0,0 @@ -#' @title Set differences of two arrays -#' @description Loosely replicates the behavior of the homonym Matlab function -#' @param A first array -#' @param B second array -#' @param legacy if `TRUE`, preserves the behavior of the setdiff function from MATLAB R2012b and prior releases. (currently not supported) -#' @author Waldir Leoncio -setdiff_MATLAB <- function(A, B, legacy = FALSE) { - if (legacy) message("legacy=TRUE not supported. Ignoring.") - if (is(A, "numeric") & is(B, "numeric")) { - values <- sort(unique(A[is.na(match(A, B))])) - } else if (is(A, "data.frame") & is(B, "data.frame")) { - C <- A - exclude_rows <- vector() - for (r1 in seq_len(nrow(A))) { - for (r2 in seq_len(nrow(B))) { - if (all(A[r1, ] == B[r2, ])) { - exclude_rows <- append(exclude_rows, r1) - } - } - } - values <- C[-exclude_rows, ] - } - # TODO: add support for indices (if necessary) - return(values) -} diff --git a/R/size.R b/R/size.R deleted file mode 100644 index 0192a1c..0000000 --- a/R/size.R +++ /dev/null @@ -1,38 +0,0 @@ -#' @title Size of an object -#' @description This functions tries to replicate the behavior of the base function "size" in Matlab -#' @param x object to be evaluated -#' @param d dimension of object to be evaluated -#' @note On MATLAB, size(1, 100) returns 1. As a matter of fact, if the user -#' calls for a dimension which x doesn't have `size()` always returns 1. R's -#' default behavior is more reasonable in those cases (i.e., returning NA), -#' but since the point of this function is to replicate MATLAB behaviors -#' (bugs and questionable behaviors included), this function also does this. -#' @export -size <- function(x, d) { - # Determining the number of dimensions - if (all(is.na(x))) { - if (missing(d)) { - return(c(0, 0)) - } else { - return(ifelse(d <= 2, 0, 1)) - } - } - if (length(x) == 1) { - # x is surely a scalar - return(1) - } else { - # x is a vector, a matrix or an array - n_dim <- ifelse(is.null(dim(x)), 1, length(dim(x))) - if (missing(d)) { - if (n_dim == 1) { - out <- c(1, length(x)) - } else { - out <- dim(x) - } - } else { - out <- ifelse(n_dim == 1, c(1, length(x))[d], dim(x)[d]) - if (is.na(out)) out <- 1 # for MATLAB compatibility - } - return(out) - } -} diff --git a/R/sortrows.R b/R/sortrows.R deleted file mode 100644 index c17fc2a..0000000 --- a/R/sortrows.R +++ /dev/null @@ -1,15 +0,0 @@ -#' @title Sort rows of matrix or table -#' @description Emulates the behavior of the `sortrows` function on Matlab -#' @param A matrix -#' @param column ordering column -sortrows <- function(A, column = 1) { - if (length(column) == 1) { - new_row_order <- order(A[, column]) - } else if (length(column) == 2) { - new_row_order <- order(A[, column[1]], A[, column[2]]) - } else { - stop("Not yet implemented for 2+ tie-breakers") - } - A_reordered <- A[new_row_order, ] - return(A_reordered) -} diff --git a/R/squeeze.R b/R/squeeze.R deleted file mode 100644 index fc8e654..0000000 --- a/R/squeeze.R +++ /dev/null @@ -1,15 +0,0 @@ -#' @title Squeeze -#' @description Remove dimensions of length 1 -#' @details This function implements the behavior of the homonimous function on -#' Matlab. `B = squeeze(A)` returns an array with the same elements as the -#' input array A, but with dimensions of length 1 removed. For example, if A is -#' a 3-by-1-by-1-by-2 array, then squeeze(A) returns a 3-by-2 matrix. If A is a -#' row vector, column vector, scalar, or an array with no dimensions of length -#' 1, then squeeze returns the input A. -#' @note This is basically a wrapper of drop() with a minor adjustment to adapt -#' the output to what happens on Matlab -#' @param A input or array matrix -#' @return An array with the same elements as the input array, but with -#' dimensions of length 1 removed. -#' @author Waldir Leoncio -squeeze <- function(A) as.matrix(drop(A)) diff --git a/R/strcmp.R b/R/strcmp.R deleted file mode 100644 index 4522dd3..0000000 --- a/R/strcmp.R +++ /dev/null @@ -1,28 +0,0 @@ -#' @title Compare two character elements -#' @description Logical test if two character elements are identical -#' @param s1 first character element (string, vector or matrix) -#' @param s2 second character element (string, vector or matrix) -#' @return a logical element of the same type as the input -#' @export -strcmp <- function(s1, s2) { - if (length(s1) == 1 & length(s2) == 1) { - # Both are scalars, comparison is straightforward - return(identical(s1, s2)) - } else if (length(s1) == 1 & length(s2) > 1) { - # s1 is a scalar and s2 is a vector or a matrix - checks <- sapply(s2, function(s) s1 %in% s) - if (is(s2, "matrix")) checks <- matrix(checks, nrow(s2)) - } else if (length(s1) > 1 & length(s2) == 1) { - # s1 is a vector/matrix, s2 is a scalar - checks <- sapply(s1, function(s) s2 %in% s) - if (is(s1, "matrix")) checks <- matrix(checks, nrow(s1)) - } else { - # s1 and s2 are vectors/matrices - if (identical(dim(s1), dim(s2))) { - checks <- as.matrix(s1 == s2) - } else { - stop("Inputs must be the same size or either one can be a scalar.") - } - } - return(checks) -} diff --git a/R/times.R b/R/times.R deleted file mode 100644 index 7c58fee..0000000 --- a/R/times.R +++ /dev/null @@ -1,51 +0,0 @@ -#' @title Element-wise matrix multiplication -#' @description Emulates the `times()` and `.*` operators from Matlab. -#' @details This function basically handles elements of different length better than the `*` operator in R, at least as far as behavior from a Matlab user is expecting. -#' @param a first factor of the multiplication -#' @param b second factor of the multiplication -#' @export -#' @returns matrix with dimensions equal to the larger of the two factors -times <- function(a, b) { - # Converting everything to matrix because Matlab looooooves the matrix - a <- as.matrix(a) - b <- as.matrix(b) - - dominant_mx <- NULL - if (!all(dim(a) == dim(b))) { - if (all(dim(a) >= dim(b))) { - dominant_mx <- a - dominated_mx <- b - } else if (all(dim(b) >= dim(a))) { - dominant_mx <- b - dominated_mx <- a - } else { - dominant_mx <- "neither" - dominant_dim <- c(max(nrow(b), nrow(a)), max(ncol(b), ncol(a))) - } - } - - if (is.null(dominant_mx)) { - out <- a * b - } else if (dominant_mx[1] == "neither") { - a <- repmat( - mx = a, - n = c(dominant_dim[1] - nrow(a) + 1, dominant_dim[2] - ncol(a) + 1) - ) - b <- repmat( - mx = b, - n = c(dominant_dim[1] - nrow(b) + 1, dominant_dim[2] - ncol(b) + 1) - ) - out <- a * b - } else { - # Expanding dominated matrix - dominated_mx <- repmat( - mx = dominated_mx, - n = c( - nrow(dominant_mx) - nrow(dominated_mx) + 1, - ncol(dominant_mx) - ncol(dominated_mx) + 1 - ) - ) - out <- dominant_mx * dominated_mx - } - return(out) -} diff --git a/R/uigetfile.R b/R/uigetfile.R deleted file mode 100644 index bfcb72c..0000000 --- a/R/uigetfile.R +++ /dev/null @@ -1,31 +0,0 @@ -#' @title Select a file for loading -#' @description Loosely mimics the functionality of the `uigetfile` function on -#' Matlab. -#' @references https://se.mathworks.com/help/matlab/ref/uigetfile.html -#' @param filter Filter listed files -#' @param title Pre-prompt message -#' @export -uigetfile <- function(filter = "", title = "") { - # ========================================================================== - # Pre-prompt message - # ========================================================================== - message(title) - # ========================================================================== - # Reading file path and name - # ========================================================================== - filepath <- readline( - paste0("Enter file path (leave empty for ", getwd(), "): ") - ) - if (filepath == "") filepath <- getwd() - # ========================================================================== - # Presenting possible files - # ========================================================================== - message("Files present on that directory:") - print(list.files(path = filepath, pattern = filter, ignore.case = TRUE)) - filename <- file.choose() - # ========================================================================== - # Organizing output - # ========================================================================== - out <- list(name = filename, path = filepath) - return(out) -} diff --git a/R/uiputfile.R b/R/uiputfile.R deleted file mode 100644 index 7a0ba92..0000000 --- a/R/uiputfile.R +++ /dev/null @@ -1,21 +0,0 @@ -#' @title Save file -#' @param filter accepted file extension -#' @param title Title -#' @description This function intends to loosely mimic the behaviour of the -#' homonymous Matlab function. -#' @export -uiputfile <- function(filter = ".rda", title = "Save file") { - # ========================================================================== - # Processing input - # ========================================================================== - message(title) - filename <- readline(paste0("File name (end with ", filter, "): ")) - filepath <- readline(paste0("File path (leave empty for ", getwd(), "): ")) - if (filename == "") filename <- 0 - if (filepath == "") filepath <- getwd() - # ========================================================================== - # Processing output - # ========================================================================== - out <- list(name = filename, path = filepath) - return(out) -} diff --git a/R/zeros_ones.R b/R/zeros_ones.R deleted file mode 100644 index 4ac8d63..0000000 --- a/R/zeros_ones.R +++ /dev/null @@ -1,50 +0,0 @@ -#' @title Matrix of zeros or ones -#' @description Generates a square or rectangular matrix of zeros or ones -#' @param n scalar or 2D vector -#' @param x value to fill matrix with -#' @return n-by-n matrix filled with `x` -#' @details This is a wrapper function to replicate the behavior of the -#' `zeros()` and the `ones()` functions on Matlab -#' @note Actually works for any `x`, but there's no need to bother imposing -#' validation controls here. -zeros_or_ones <- function(n, x) { - # Expanding n to length 2 if necessary - if (length(n) == 1) n <- c(n, n) - - # Returning a matrix or an array - if (length(n) == 2) { - return(matrix(x, n[1], n[2])) - } else { - return(array(x, dim = n)) - } -} - -#' @title Matrix of zeros -#' @description wrapper of `zeros_or_ones()` that replicates the behavior of -#' the `zeros()` function on Matlab -#' @param n1 number of rows -#' @param n2 number of columns -#' @param ... extra dimensions -zeros <- function(n1, n2 = n1, ...) { - if (length(n1) == 1) { - n <- c(n1, n2, ...) - } else { - n <- n1 - } - return(zeros_or_ones(n, 0)) -} - -#' @title Matrix of ones -#' @description wrapper of `zeros_or_ones()` that replicates the behavior of -#' the `ones()` function on Matlab -#' @param n1 number of rows -#' @param n2 number of columns -#' @param ... extra dimensions -ones <- function(n1, n2 = n1, ...) { - if (length(n1) == 1) { - n <- c(n1, n2, ...) - } else { - n <- n1 - } - return(zeros_or_ones(n, 1)) -} diff --git a/tests/testthat/test-convertedBaseFunctions.R b/tests/testthat/test-convertedBaseFunctions.R deleted file mode 100644 index d2a0a44..0000000 --- a/tests/testthat/test-convertedBaseFunctions.R +++ /dev/null @@ -1,245 +0,0 @@ -context("Basic Matlab functions") - -test_that("rand works properly", { - expect_equal(dim(rand()), c(1, 1)) - expect_equal(dim(rand(1, 2)), c(1, 2)) - expect_equal(dim(rand(3, 2)), c(3, 2)) -}) - -test_that("repmat works properly", { - mx0 <- c(1:4) # when converted to matrix, results in a column vector - mx1 <- matrix(5:8) - mx2 <- matrix(0:-3, 2) - expect_error(repmat(mx0)) - expect_equal(repmat(mx0, 1), t(as.matrix(mx0))) - expect_equal( - object = repmat(mx0, 2), - expected = unname(cbind(rbind(mx0, mx0), rbind(mx0, mx0))) - ) - expect_equal( - object = repmat(mx1, 2), - expected = unname(cbind(rbind(mx1, mx1), rbind(mx1, mx1))) - ) - expect_equal( - object = repmat(mx2, c(2, 3)), - expected = cbind(rbind(mx2, mx2), rbind(mx2, mx2), rbind(mx2, mx2)) - ) - expect_equal( - object = repmat(mx2, c(4, 1)), - expected = rbind(mx2, mx2, mx2, mx2) - ) - expect_equal( - object = repmat(mx2, c(1, 1, 2)), - expected = array(mx2, c(2, 2, 2)) - ) - expect_equal(repmat(1:2, 3), matrix(rep(1:2, 9), 3, 6, byrow = TRUE)) - expect_equal(repmat(10, c(3, 2)), matrix(10, 3, 2)) -}) - -test_that("zeros and ones work as expected", { - expect_equal(zeros(1), matrix(0, 1)) - expect_equal(zeros(2), matrix(0, 2, 2)) - expect_equal(zeros(2, 1), matrix(0, 2, 1)) - expect_equal(zeros(1, 10), matrix(0, 1, 10)) - expect_equal(zeros(3, 2, 4), array(0, c(3, 2, 4))) - expect_equal(ones(8), matrix(1, 8, 8)) - expect_equal(ones(5, 2), matrix(1, 5, 2)) - expect_equal(ones(2, 100), matrix(1, 2, 100)) - expect_equal(ones(3, 2, 4, 2), array(1, c(3, 2, 4, 2))) -}) - -test_that("times works as expected", { - expect_equal(times(9, 6), as.matrix(54)) - expect_equal(times(9, c(.8, 9)), as.matrix(c(7.2, 81))) - expect_equal(times(c(.8, 9), 5), as.matrix(c(4, 45))) - expect_equal(times(matrix(1:4, 2), 5), matrix(c(5, 10, 15, 20), 2)) - expect_equal(times(5, matrix(1:4, 2)), matrix(c(5, 10, 15, 20), 2)) - expect_equal(times(matrix(1:4, 2), c(10, 3)), matrix(c(10, 6, 30, 12), 2)) - expect_equal( - object = times(matrix(1:4, 2), matrix(c(10, 3), 1)), - expected = matrix(c(10, 20, 9, 12), 2) - ) - expect_equal(times(c(10, 3), matrix(1:4, 2)), matrix(c(10, 6, 30, 12), 2)) - expect_equal( - object = times(matrix(c(10, -5, 3, 9), 2), matrix(1:4, 2)), - expected = matrix(c(10, -10, 9, 36), 2) - ) - expect_equal( - object = times(matrix(c(-1.6, 5), 1), c(8, 1)), - expected = matrix(c(-12.8, -1.6, 40, 5), 2) - ) -}) - -test_that("colon works as expected (hee hee)", { - expect_equal(colon(1, 4), 1:4) - expect_length(colon(4, 1), 0) -}) - -test_that("size works as on MATLAB", { - sk <- 10 - vk <- 1:4 - mx <- matrix(1:6, 2) - ra <- array(1:24, c(2, 3, 4)) - expect_equal(size(sk), 1) - expect_equal(size(vk), c(1, 4)) - expect_equal(size(mx), c(2, 3)) - expect_equal(size(ra), c(2, 3, 4)) - expect_equal(size(sk, 199), 1) - expect_equal(size(vk, 199), 1) - expect_equal(size(mx, 199), 1) - expect_equal(size(ra, 199), 1) - expect_equal(size(vk, 2), 4) - expect_equal(size(mx, 2), 3) - expect_equal(size(ra, 2), 3) - expect_equal(size(ra, 3), 4) -}) - -test_that("reshape reshapes properly", { - mx <- matrix(1:4, 2) - ra <- array(1:12, c(2, 3, 2)) - expect_equal(reshape(mx, c(1, 4)), matrix(1:4, 1)) - expect_equal(reshape(mx, c(2, 2)), mx) - expect_equal(reshape(mx, c(1, 1, 4)), array(mx, c(1, 1, 4))) - expect_error(reshape(mx, c(1, 2, 3))) - expect_error(reshape(ra, c(1, 2, 3))) - expect_equal(reshape(ra, c(3, 2, 2)), array(ra, c(3, 2, 2))) -}) - -test_that("isfield works as on Matlab", { - S <- list() - S$x <- rnorm(100) - S$y <- sin(S$x) - S$title <- "y = sin(x)" - expect_true(isfield(S, "title")) - expect_equivalent( - object = isfield(S, c("x", "y", "z", "title", "error")), - expected = c(TRUE, TRUE, FALSE, TRUE, FALSE) - ) -}) - -test_that("strcmp works as expected", { - yes <- "Yes" - no <- "No" - ja <- "Yes" - expect_false(strcmp(yes, no)) - expect_true(strcmp(yes, ja)) - s1 <- "upon" - s2 <- matrix(c("Once", "upon", "a", "time"), 2, byrow = TRUE) - s3 <- c("Once", "upon", "a", "time") - s4 <- matrix(c("A", "bc", "def", "G"), 2, byrow = TRUE) - s5 <- matrix(c("B", "c", "def", "G"), 2, byrow = TRUE) - expect_equal(strcmp(s1, s2), matrix(c(FALSE, FALSE, TRUE, FALSE), 2)) - expect_equivalent(strcmp(s1, s3), c(FALSE, TRUE, FALSE, FALSE)) - expect_error(strcmp(s2, s3)) - expect_equal(strcmp(s4, s5), matrix(c(FALSE, TRUE, FALSE, TRUE), 2)) -}) - -test_that("isempty works as expected", { - A <- array(dim = c(0, 2, 2)) - B <- matrix(rep(NA, 4), 2) - C <- matrix(rep(0, 4), 2) - cat1 <- as.factor(c(NA, NA)) - cat2 <- factor() - str1 <- matrix(rep("", 3)) - expect_true(isempty(A)) - expect_false(isempty(B)) - expect_false(isempty(C)) - expect_false(isempty(cat1)) - expect_true(isempty(cat2)) - expect_false(isempty(str1)) -}) - -test_that("find works as expected", { - X <- matrix(c(1, 0, 2, 0, 1, 1, 0, 0, 4), 3, byrow = TRUE) - Y <- seq(1, 19, 2) - expect_equal(find(X), c(1, 5, 7, 8, 9)) - expect_equal(find(!X), c(2, 3, 4, 6)) - expect_equal(find(Y == 13), 7) -}) - -test_that("sortrows works as expected", { - mx <- matrix(c(3, 2, 2, 1, 1, 10, 0, pi), 4) - expect_equal(sortrows(mx), matrix(c(1, 2, 2, 3, pi, 10, 0, 1), 4)) - expect_equal(sortrows(mx, 2), matrix(c(2, 3, 1, 2, 0, 1, pi, 10), 4)) - expect_equal(sortrows(mx, 1:2), mx[order(mx[, 1], mx[, 2]), ]) -}) - -test_that("cell works as expected", { - expect_equivalent(cell(0), array(0, dim = c(0, 0))) - expect_equivalent(cell(1), array(0, dim = c(1, 1))) - expect_equivalent(cell(2), array(0, dim = c(2, 2))) - expect_equivalent(cell(3, 4), array(0, dim = c(3, 4))) - expect_equivalent(cell(5, 7, 6), array(0, dim = c(5, 7, 6))) -}) - -test_that("blanks works as expected", { - expect_warning(blanks(-1)) - expect_equal(suppressWarnings(blanks(-1)), "") - expect_equal(blanks(0), "") - expect_equal(blanks(1), " ") - expect_equal(blanks(10), " ") -}) - -test_that("squeeze works as expected", { - A <- array(dim = c(2, 1, 2)) - A[, , 1] <- c(1, 2) - A[, , 2] <- c(3, 4) - expect_equal(squeeze(A), matrix(1:4, 2)) - A <- array(0, dim = c(1, 1, 3)) - A[, , 1:3] <- 1:3 - expect_equal(squeeze(A), matrix(1:3, 3)) -}) - -test_that("fix works as expected", { - X <- matrix(c(-1.9, -3.4, 1.6, 2.5, -4.5, 4.5), 3, byrow = TRUE) - Y <- matrix(c(-1, -3, 1, 2, -4, 4), 3, byrow = TRUE) - expect_identical(fix(X), Y) -}) - -test_that("isspace works as expected", { - chr <- "123 Main St." - X <- "\t a b\tcde f" - expect_identical(isspace(chr), c(0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0)) - expect_identical(isspace(X), c(1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0)) -}) - -test_that("nargin works correctly", { - addme <- function(a, b) { - if (nargin() == 2) { - c <- a + b - } else if (nargin() == 1) { - c <- a + a - } else { - c <- 0 - } - return(c) - } - expect_equal(addme(13, 42), 55) - expect_equal(addme(13), 26) - expect_equal(addme(), 0) -}) - -test_that("setdiff works as expected", { - A <- c(3, 6, 2, 1, 5, 1, 1) - B <- c(2, 4, 6) - C <- c(1, 3, 5) - expect_equal(setdiff_MATLAB(A, B), C) - A <- data.frame( - Var1 = 1:5, - Var2 = LETTERS[1:5], - Var3 = c(FALSE, TRUE, FALSE, TRUE, FALSE) - ) - B <- data.frame( - Var1 = seq(1, 9, by = 2), - Var2 = LETTERS[seq(1, 9, by = 2)], - Var3 = rep(FALSE, 5) - ) - C <- data.frame( - Var1 = c(2, 4), - Var2 = c("B", "D"), - Var3 = c(TRUE, TRUE) - ) - row.names(C) <- c(2L, 4L) - expect_equal(setdiff_MATLAB(A, B), C) # TODO: implement for data frames - # TODO: add more examples from https://se.mathworks.com/help/matlab/ref/double.setdiff.html;jsessionid=0d8d42582d4d299b8224403899f1 -})