Update Aug 27, 2019: Minor change in how equations are solved (from version 0.9.0.9122).
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] '1.1.0'
The general idea is that there are two Ryacas functions that call yacas:
yac_str(): returns result as stringyac_expr(): returns result as anRexpression
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/runyacascommandx; the result varies depending on which of the functions usedy_*(x)various utility functions (not involving calls toyacas)
Reference:
- Evaluate
yacasexpressionsyac(x, rettype = c("str", "expr", "silent")): Evaluateyacascommandx(a string) and get result determined byrettype(default"str").yac_expr(x): Evaluateyacascommandx(a string) and get result as anRexpression.yac_silent(x): Evaluateyacascommandx(a string) silently; useful for creatingyacasvariables.yac_str(x): Same asyac_expr(), but get result as string/character.
- Helper functions
as_y(x): ConvertRcharacter matrixxto ayacasrepresentationas_r(x): Convert ayacasrepresentationxto aRcharacter matrixy_fn(x, fn): Helper function to prepare a call foryacas, e.g.y_fn("x^2 - 1", "Factor")is gives"Factor(x^2 - 1)"y_rmvars(x): Removes variables such that{x == 2}instead gets{2}; remember to callyacaswith e.g.yac_str()oryac_expr()y_print(x): Pretty print yacas strings, e.g. a yacas matrix
- Lower level functions
yac_core(x): Evaluateyacascommandx(a string) and get both result and side effects; used in the implementation ofyac_expr(),yac_silent(), andyac_str()
yacas reference
Below are some yacas functions. A more elaborate reference is available at https://yacas.readthedocs.io/:
- General
Expand(x): Expand an expressionFactor(x): Factorise an expressionSimplify(x): Simplify an expressionSolve(expr, var)solve an equation (refer to theRyacasfunctiony_rmvars())Variables(): Listyacasvariables
- Calculus:
D(x) expr: Take the derivative ofexprwith respect toxHessianMatrix(function, var): Create the Hessian matrixJacobianMatrix(function, var): Create the Jacobian matrixLimit(n, a) f(n): Limit off(n)forngoing towardsa(e.g.Infinityor0)Sum(k, a, b, f(k)): Sum off(k)forkfromatob.
- Output
TeXForm(x): Get a \(\LaTeX\) representation of an expressionPrettyForm(x): Print a prettier ASCII representation of an expression
- Linear algebra
Inverse(A): Inverse of a matrixTranspose(A): Transpose of a matrixA * B: Matrix multiplication (and not asR’s%*%)