RStudio as a symbolic computing platform

RStudio combined with knitr provides a very practical platform for literate (mathematical) programming. However, lately I have become interested in enhancing this toolset with symbolic math. I'm adding some theoretical explanations to my probability tutorial and kept switching back and forth between RStudio and another application to check the resuls of some algebra. That got me thinking how it would be handy if I could do symbolic computing directly in RStudio. As it turns out, using the Ryacas interface to the yacas computer algebra language solves that problem.

Yacas is an entire mathematical computing platform in its own right, but the Ryacas library provides a direct interface to R, so that yacas functions can be mixed in with the R language. Since Yacas also has functions to print its output in LaTeX, we can easily incorporate symbolic computing into our literate programming with knitr and RStudio.

This little tutorial is something I wrote to show how to get started.

Firstly, install the Ryacas package with the RStudio Tools... packages menu. Next, I need to load the Ryacas library before any code that makes use of it in the rest of my document.

library(Ryacas)

Now, the simplest way to perform yacas commands is to pass the entire command to the yacas interpreter, using the yacas() function. Here's a simple example that simplifies the expression \(\LARGE \frac{x^2 -1}{x-1}\).

yacas("Simplify((x^2-1)/(x-1))")
## [1] "Starting Yacas!"
## expression(x + 1)

The Ryacas interface returns yacas results as R expressions. There is a handy tutorial vignette linked to the Ryacas package help that explains more on how to work with yacas functions in R. And of course, yacas itself also needs some studying.

Next, let's define a shorthand formula for passing a string to yacas and returning LaTeX formatted output.

yx <- function(s) {
    s <- as.character(yacas(TeXForm(s), retclass = "unquote"))
    return(paste("$\\LARGE", substr(s, 2, nchar(s))))
}

Now, let's try that function with inline R code in knitr. I'll try for simplification of the expresssion \(\LARGE \frac{\frac{2}{b}}{c}\). When I pass that to yacas as an inline function in RStudio/knitr, like this yx("(2/b)/c"), I get the following result: \(\LARGE \frac{2}{b c} \).

Next, let's use the same function, but now in a knitr code chunk. I've set the chunk option results="asis" to make sure the LaTex formatted result from yacas is passed directly to output by knitr. That also means using the cat function to print the output, which avoids the bracketed line numbers that R usually prints.

cat(yx("(2/b)/c"))

\(\LARGE \frac{2}{b c} \)

The yx() function provides a convenient shorthand for solving algebraic equations and showing the results in LaTex. However, I may wish to display longer formulas in the LaTex display form (i.e. centered on a separate line). For that, let's create an additional function.

YX <- function(s) {
    s <- as.character(yacas(TeXForm(s), retclass = "unquote"))
    return(paste("$$\\LARGE ", substr(s, 2, nchar(s)), "$", sep = ""))
}

Now, let's use that function to obtain a display formula. We'll try to solve \(\LARGE \frac{1}{2}b h = 1\) for \(\LARGE h\). We plug the formula into yacas as follows: YX("Solve((1/2)*b*h==1,h"). It should then show the following:

\[\LARGE \left( h = \frac{2}{b} \right) \]

Just a few functions, and of course the addition of Yacas, and I've now got a literate programming environment for both symbolic and numeric computing.