# The high-level (symbol) interface In Ryacas: R Interface to the 'Yacas' Computer Algebra System

knitr::opts_chunk\$set(echo = TRUE)

library(Ryacas)


A short summary of often-used yacas commands are found in the section "yacas reference" in the "Getting started" vignette. A short summary of Ryacas's high-level functions are found in the section "Ryacas high-level reference" at the end of this document.

# Introduction

• A yacas command, e.g. x, 2*a or something similar
• An R matrix or vector.

Here, we keep it simple.

x <- ysym("x")
2*x^2 - 5
c(-2, 5)*x
c(2*x, -x^3)
as_r(c(-2, 5)*x) # or yac_expr(c(-2, 5)*x)


Then consider an R matrix and vector:

A <- outer(0:3, 1:4, "-") + diag(2:5)
a <- 1:4
A
a


They are now considered yacas-enabled:

B <- ysym(A)
B
as_r(B)
b <- ysym(a)
b
as_r(b)


Notice how they are printed using yacas's syntax.

We can apply yacas functions using y_fn():

y_fn(B, "Transpose")
y_fn(B, "Inverse")
y_fn(B, "Trace")


Standard R commands are available (see the section "Ryacas high-level reference" at the end of this document):

A %*% a
B %*% b
t(A)
t(B)
exp(B)
as_r(exp(B))
A[, 2:3]
B[, 2:3]
A[upper.tri(A)] <- 1
B[upper.tri(B)] <- 1
A
B
2*A - A
2*B - B
A %*% solve(A)
B %*% solve(B)
solve(A %*% t(A))
solve(B %*% t(B))
solve(A, a)
solve(B, b)


We can also assign a yacas variable, but remember that this may be difficult to distinguish:

yac_str("W") # Get variable W if exists, or else just a symbol
yac_str("Variables()") # ...or list variables
B
yac_assign(B, "W") # assign B in R to W in yacas
yac_str("W") # Get variable W if exists, or else just a symbol
yac_str("Variables()") # ...or list variables
yac_silent("Clear(W)")
yac_str("Variables()") # List variables
yac_str("W") # Get variable W if exists, or else just a symbol


# Simplify and output to TeX

• simplify()
• tex()

To demonstrate these and some additional benefit, we exploit yacas's symbolic availabilities.

D <- diag(4) %>% ysym()
D
D <- D/2
D
D[2:3, 1] <- "d"
D[3, 4] <- "2*d + 2"
D
D %>% solve()
D %>% solve() %>% simplify()
D %>% solve() %>% simplify() %>% tex()


[ r D %>% solve() %>% simplify() %>% tex() ]

yacas has a Simplify() function. This is made available via a simplify() function that also includes a time-out that prevents yacas in making the R session hang, but it requires that the unix package is available. The default timeout value used when unix is available is 2 seconds.

# Derivatives

We illustrate using the example in https://mikl.dk/post/2019-pizza-frozen-yogurt-goebner/:

L <- ysym("x^2 * (y/4) - a*(3*x + 3*y/2 - 45)")
L


We can consider one variable only:

deriv(L, "x")
Hessian(L, "x")


Or multiple variables:

deriv(L, c("x", "y", "a"))
H <- Hessian(L, c("x", "y", "a"))
H
as_r(H)
eval(as_r(H), list(x = 2, y = 2, a = 2))


The Jacobian is taken on a vector function denoted by many functions:

L2 <- ysym(c("x^2 * (y/4) - a*(3*x + 3*y/2 - 45)",
"x^3 + 4*a^2")) # just some function
L2
Jacobian(L2, "x")
Jacobian(L2, c("x", "y", "a"))


# Solving equations

Say we want to find roots of a polynomial. We use the generic solve(a, b, ...) function.

Note the conventions are as follows:

• Linear system of equations (works as R's solve() as demonstrated above):
• When a is a matrix and b not provided, this finds the inverse of a.
• When a is a matrix and a vector b is provided, the linear system of equations is solved.
• Else:
• solve(a, b): find roots of a for variable b, i.e. yacas Solve(a == 0, b)
• solve(a, b, v): find solutions to a == b for variable v, i.e. yacas Solve(a == b, v)
xs <- ysym("x")
poly <- xs^2 - xs - 6
poly
zeroes <- solve(poly, "x") # Solve(x^2 - x - 6 == 0, x)
zeroes
tex(zeroes)
zeroes %>% y_rmvars()


We can also find values of x where the polynomial equals another constant. If we were working with strings via the low-level interface it would be easy via paste(), but as we are working with ysym()'s we use the solve() function directly:

solve(poly, 3, "x") # Solve(x^2 - x - 6 == 3, x)
solve(poly, 3, "x") %>% tex()


[ r solve(poly, 3, "x") %>% tex() ]

## Solving a system of equations

x <- ysym("x")
y <- ysym("y")
lhs <- c(3*x*y - y, x)
rhs <- c(-5*x, y+4)


\begin{align} r tex(lhs[[1]]) &= r tex(rhs[[1]]) \ r tex(lhs[[2]]) &= r tex(rhs[[2]]) \end{align}

sol <- solve(lhs, rhs, c("x", "y"))
sol
sol_vals <- lapply(seq_len(nrow(sol)), function(sol_no) {
y_rmvars(sol[sol_no, ])
})
sol_vals
sol_envir <- lapply(sol_vals, function(l) {
list(x = as_r(l[1]), y = as_r(l[2]))
})
sol_envir
do.call(rbind, lapply(seq_along(sol_envir), function(sol_no) {
sol_val <- sol_envir[[sol_no]]
data.frame(sol_no = sol_no,
eq_no = seq_along(sol_val),
lhs = eval(as_r(lhs), sol_val),
rhs = eval(as_r(rhs), sol_val))
}))


# Ryacas high-level reference

Principle:

• ysym(x) converts x to a yac_symbol that automatically runs yacas when needed. x can both be a text string with yacas commands or an R vector/matrix.
• as_r(x): Is used to convert the yac_symbol back to an R representation.
• y_fn(x, fn, ...): Apply a yacas function fn to the yac_symbol x, i.e. fn(x, ...); note that this is evaluated immediately when x is a yac_symbol as opposed to when x is a string

Reference:

The following functions work with yac_symbols.

• ysym(): Create yac_symbol
• ysym_make(): Make a vector of yac_symbols
• ysym_ls(): List declared yac_symbols
• yac_*() functions (see the "Getting started" vignette)
• yac_str(): Return yacas string
• yac_expr(): Return R expression
• yac_silent(): Do something silently
• yac_assign(): Assign a variable
• Other
• simplify(x, timeout = 2): Try yacas's Simplify() function. When the unix package is available, the timeout (in seconds), stops trying after that amount of time to avoid making the R process hang.
• tex(): Convert
• y_fn(x, fn, ...): Apply a yacas function fn to the yac_symbol x, i.e. fn(x, ...)
• y_rmvars(x): Remove variable names in x
• Derivatives:
• deriv(expr, vars): takes derivative of yac_symbol expr with respect to vars
• Jacobian(expr, vars): finds Jacobian of yac_symbol expr (usually a vector of expressions) with respect to vars
• Hessian(expr, vars): finds Hessian matrix of yac_symbol expr with respect to vars
• Other
• lim()
• Standard R that has been implemented for yac_symbols:
• print()
• c()
• dim()
• cbind()
• rbind()
• [ getter
• [<- setter
• [[ getter
• %*% matrix/vector multiplication
• diag() getter
• diag<-() setter
• upper.tri() getter
• lower.tri() getter
• t()
• solve() (see above and in help page)
• integrate()
• sum()
• prod()
• Ops: +, -, *, /, ^
• Math functions: sin(), cos(), tan(), asin(), acos(), atan(), asinh(), acosh(), atanh(), exp(), log(), sqrt()

## Try the Ryacas package in your browser

Any scripts or data that you put into this service are public.

Ryacas documentation built on Jan. 17, 2023, 1:11 a.m.