matconv v0.2.0 Released
A new version of “matconv” has been released and can be found here. In this update of my Matlab to R converter, I added function converters to take matLab function calls and turn them into R calls. This can be manipulated for your own project and a base dictionary largely converted from this reference text can be found at ‘inst/extData/HiebelerDict.txt’. The following is the vignette for function calls that uses some of the dictionary lines in this file to illustrate all the different syntax and flags that can be used.
You cab define a map from using a character vector or a ascii file with the dictionaries. They take on the form “matlab function : Rfunction, arguments”. The arguments are given as a comma separated list. For verbatim translation, plain numbers are used and can be used as follows:
|linspace:seq, 2, 1||thing = linspace(first, second)||thing <- seq(second, first)|
The dictionary is turned into converting functions that are returned as a list of functions using the function “makeMaps”. These are named with the matLab function so the right converter is chosen using name subsetting. You can also do literal strings and strings that have references to the arguments using a percent sign as shown below:
|linspace:seq, 1, 2, len = %3||thing = linspace(1, 2, 3)||thing <- seq(1, 2, len = 3)|
|binornd:rbinom, 1L, 1, 2||hjkl = binornd(2.3, 1.5)||hjkl <- rbinom(1, 2.3, 1.5)|
|erf: , 2 * pnorm(%1 * sqrt(2)) - 1||asdf = erf(2)||asdf <- (2 * pnorm(2 * sqrt(2)) - 1)|
In the second example, R has an extra argument of number of outputs wanted which for the matlab function is always 1. To do this a literal numeral is used by append it with an “L”.
In the third example, there isn’t a good translation for the “erf” function but it can be done using the mathematical formula. This can be done by just leaving the R function blank and using a literal string.
MatLab has a lot of functions that change dramatically with different inputs. This can be done using flags on the name of the matLab function. Instead of returning a list of one function in the map it returns multiple functions for conversion. The decision making to use one function over the other is given as another function depending on the inputs in “map$flags$DictSwitch”. So the calls that are used are used are grabbing the matLab arguments and throwing them into “dictSwitch” to figure out the index of the function to use. The rest of the flags can be found using that index as well as the function to convert the matLab line. The switching flags that can be used are as follows:
- number of arguments (–if 2)
- an argument is equal to a particular value (–if 2 == 2L)
- number of outputs requested (–length(out) == 2)
- if none of the other conditions were met (–finally)
|rand--if 1 == 1L:runif, 2||thing = rand(1, 5)||thing <- runif(5)|
|rand--if 2 == 1L:runif, 1||thing = rand(5, 1)||thing <- runif(5)|
|rand--if finally:matrix, runif(%1 * %2), %1)||thing = rand(5, 5)||thing <- matrix(runif(5 * 5), 5))|
R doesn’t have a native way have more than one output from a function like matlab but we can simulate it using a list out and then assign the variables in other calls. For user made functions the solution was to return a list of the variables and this is the unpacking in another environment. This can be done with the flag on the output, “–out args”. here args is a space separated list with the args of that R gives in the list output.
|lu: , expand(lu(Matrix::Matrix(%1))) --out L U P||[myL myU myP] = lu(badMatrix)||lout <- (expand(lu(Matrix); myL <- lout$L; myU <- lout$U; myP <- lout$P|
Function switchers and multiple outputs or any other flag can be used together as everything is indexed at the same level. I can imagine more flags can be added to deal with matrix algebra more directly. This will evolve once the data structures are converted in a later version.
rmarkdown files for this post can be found at: https://github.com/sidjai.github.io/_drafts/matconv020.rmd