Major update of Ryacas (R Interface to the Yacas Computer Algebra System)

We (Søren Højsgaard and I) are preparing a new major release of Ryacas (GitHub). It will have a new interface to yacas that is thinner, cleaner and more robust. It relies on yacas’s RForm() function rather than an OpenMath XML interface.

It also means that the API has changed in Ryacas: new functions are introduced and old ones deprecated. Before showing the new API, let us first mention that a legacy version of Ryacas is available at GitHub. We call it Ryacas0.

Below, we will show you how to use the new version. Please give it a try yourself and let us know of your experiences (e.g. on GitHub, Twitter, or by sending me an email).

First, install the development version of Ryacas (if needed):

if (packageVersion("Ryacas") < "0.9") {
  devtools::install_github("mikldk/ryacas")
}

Now, let us load the new version:

library(Ryacas)
packageVersion("Ryacas")
## [1] '0.9.0.9111'

The general idea is that there are two Ryacas functions that call yacas:

  • yac_str(): returns result as string
  • yac_expr(): returns result as an R expression

Brief example

Let us demontrate it by expanding and factoring a polynomial:

# Returning string
yac_str("Expand((x + 1)*(x - 4))")
## [1] "x^2-3*x-4"
yac_str("Factor(x^2 - 3*x - 4)")
## [1] "(x-4)*(x+1)"
# Returning expression
yac_expr("Expand((x + 1)*(x - 4))")
## expression(x^2 - 3 * x - 4)
yac_expr("Factor(x^2 - 3*x - 4)")
## expression((x - 4) * (x + 1))
eval(yac_expr("Factor(x^2 - 3*x - 4)"), list(x = 2))
## [1] -6

Some of the features of Ryacas and yacas are shown in the README and in the “Getting started” vignette.

A few central concepts are shown below (simplifying and \(\LaTeX\) representation):

poly <- "(x + 1/3)*(x - 4)"
cmd <- paste0("Expand(", poly, ")")
cmd
## [1] "Expand((x + 1/3)*(x - 4))"
yac_str(cmd)
## [1] "x^2+((-11)*x)/3-4/3"
# Easier calling functions with y_fn:
cmd <- y_fn(poly, "Expand")
cmd
## [1] "Expand((x + 1/3)*(x - 4))"
yac_str(cmd)
## [1] "x^2+((-11)*x)/3-4/3"
# ... and magrittr's pipe:
poly %>% y_fn("Expand") %>% yac_str()
## [1] "x^2+((-11)*x)/3-4/3"
poly %>% y_fn("Expand") %>% y_fn("Simplify") %>% yac_str()
## [1] "(3*x^2-11*x-4)/3"
poly %>% y_fn("Expand") %>% y_fn("Simplify") %>% y_fn("TeXForm") %>% yac_str()
## [1] "\\frac{3 x ^{2} - 11 x - 4}{3} "

And we can differentiate (and simplify):

poly %>% y_fn("D(x)") %>% yac_str()
## [1] "x+1/3+x-4"
poly %>% y_fn("D(x)") %>% y_fn("Simplify") %>% yac_str()
## [1] "(6*x-11)/3"

Symbolic linear algebra

Let us demonstrate an example using symbolic linear algebra:

# Construct character matrix
Amat <- matrix("0", nrow = 3, ncol = 3)
Amat[1, 1] <- "a"
Amat[1, 3] <- "b"
Amat[2, 3] <- "c"
Amat[3, 1] <- "d"
Amat[3, 2] <- "e"
Amat
##      [,1] [,2] [,3]
## [1,] "a"  "0"  "b" 
## [2,] "0"  "0"  "c" 
## [3,] "d"  "e"  "0"
# Convert to yacas matrix (list of lists; a yacas vector is a list)
A <- as_y(Amat)
A
## [1] "{{a, 0, b}, {0, 0, c}, {d, e, 0}}"
# Prettier print
y_print(A)
## {{a, 0, b},
##  {0, 0, c},
##  {d, e, 0}}
# Find inverse:
At <- A %>% y_fn("Inverse") %>% yac_str()
# Print it for console
y_print(At)
## {{          1/a,      (-b/a)/c,             0},
##  {     (-d/a)/e, (b*d)/(c*a*e),           1/e},
##  {            0,           1/c,             0}}
# LaTeX
At %>% y_fn("TeXForm") %>% yac_str()
## [1] "\\left( \\begin{array}{ccc} \\frac{1}{a}  & \\frac{ - \\frac{b}{a} }{c}  & 0 \\\\ \\frac{ - \\frac{d}{a} }{e}  & \\frac{b d}{c a e}  & \\frac{1}{e}  \\\\ 0 & \\frac{1}{c}  & 0 \\end{array} \\right) "

It can be incorporated into e.g. Rmarkdown: \[ \left( \begin{array}{ccc} \frac{1}{a} & \frac{ - \frac{b}{a} }{c} & 0 \\ \frac{ - \frac{d}{a} }{e} & \frac{b d}{c a e} & \frac{1}{e} \\ 0 & \frac{1}{c} & 0 \end{array} \right) \]

It can also be evaluated numerically using some values:

vals <- list(a = 2, b = 3, c = 1, d = 2, e = 5)
Atmat_eval <- eval(At %>% yac_expr(), vals)
Atmat_eval
##      [,1] [,2] [,3]
## [1,]  0.5 -1.5  0.0
## [2,] -0.2  0.6  0.2
## [3,]  0.0  1.0  0.0
Amat_eval <- eval(A %>% yac_expr(), vals)
Amat_eval
##      [,1] [,2] [,3]
## [1,]    2    0    3
## [2,]    0    0    1
## [3,]    2    5    0
Amat_eval %*% Atmat_eval
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1

Ryacas reference

Principle:

  • yac_*(x) functions evaluate/run yacas command x; the result varies depending on which of the functions used
  • y_*(x) various utility functions (not involving calls to yacas)

Reference:

  • Evaluate yacas expressions
    • yac(x, rettype = c("str", "expr", "silent")): Evaluate yacas command x (a string) and get result determined by rettype (default "str").
    • yac_expr(x): Evaluate yacas command x (a string) and get result as an R expression.
    • yac_silent(x): Evaluate yacas command x (a string) silently; useful for creating yacas variables.
    • yac_solve_expr(x): Evaluate yacas command x (a string starting with ‘Solve’) and reducing var == from the yacas result, and get result as an R expression.
    • yac_solve_str(x): Same as yac_solve_expr(), but get result as as string/character.
    • yac_str(x): Same as yac_expr(), but get result as string/character.
  • Helper functions
    • as_y(x): Convert R character matrix x to a yacas representation
    • as_r(x): Convert a yacas representation x to a R character matrix
    • y_fn(x, fn): Helper function to prepare a call for yacas, e.g. y_fn("x^2 - 1", "Factor") is gives "Factor(x^2 - 1)"
    • y_print(x): Pretty print yacas strings, e.g. a yacas matrix
  • Lower level functions
    • yac_core(x): Evaluate yacas command x (a string) and get both result and side effects; used in the implementation of yac_expr(), yac_silent(), and yac_str()

yacas reference

Below are some yacas functions. A more elaborate reference is available at https://yacas.readthedocs.io/:

  • General
    • Expand(x): Expand an expression
    • Factor(x): Factorise an expression
    • Simplify(x): Simplify an expression
    • Solve(expr, var) solve an equation (refer to the Ryacas functions yac_solve_expr() and yac_solve_str())
    • Variables(): List yacas variables
  • Calculus:
    • D(x) expr: Take the derivative of expr with respect to x
    • HessianMatrix(function, var): Create the Hessian matrix
    • JacobianMatrix(function, var): Create the Jacobian matrix
    • Limit(n, a) f(n): Limit of f(n) for n going towards a (e.g. Infinity or 0)
    • Sum(k, a, b, f(k)): Sum of f(k) for k from a to b.
  • Output
    • TeXForm(x): Get a \(\LaTeX\) representation of an expression
    • PrettyForm(x): Print a prettier ASCII representation of an expression
  • Linear algebra
    • Inverse(A): Inverse of a matrix
    • Transpose(A): Transpose of a matrix
    • A * B: Matrix multiplication (and not as R’s %*%)
Avatar
Mikkel Meyer Andersen
Assoc. Professor of Applied Statistics

My research interests include applied statistics and computational statistics.