Treat a literal variable as a constant with Ryacas (or an alternative)

Viewed 41

With Ryacas, one has:

> yac_str("Simplify(2*x^2*4 + x^2*5)")
[1] "13*x^2"

Now, instead of 4 and 5, I would like to give two letters treated as constants. That is, Ryacas does:

> yac_str("Simplify(2*x^2*a + x^2*b)")
[1] "2*x^2*a+x^2*b"

but I would like that it treats x as an unknown variable and a and b as constants, i.e. I would like to get the result:

(2*a+b)*x^2

I spent one hour to try with no luck. Is it possible? Otherwise, with another package?

2 Answers

I found the way with caracas.

library(caracas)

def_sym(x, y, z, a, b)

as.character(sympy_func(x^2 + a*x^2 + 2*y + b*y + x*z + a*x*z, "Poly", domain = "RR[a,b]"))
# "Poly((1.0*a + 1.0)*x^2 + (1.0*a + 1.0)*x*z + (1.0*b + 2.0)*y, x, y, z, domain='RR[a,b]')"

You can also work with rational numbers:

poly <- 
  sympy_func(x^2 + a*x^2 + 2/3*y + b*y + x*z + a*x*z, "Poly", domain = "QQ[a,b]")
as.character(poly)
# "Poly((a + 1)*x^2 + (a + 1)*x*z + (b + 2/3)*y, x, y, z, domain='QQ[a,b]')"

To get the coefficient of a term, e.g. xz (i.e. x^1y^0z^1):

sympy <- get_sympy()
sympy$Poly$nth(poly$pyobj, 1, 0, 1)
# a + 1

This seems to be just how yacas wants to simplify that expression. SymPy does it the way you want though, and it has an R wrapper called caracas

library(caracas)

a <- as_sym("a")
b <- as_sym("b")
x <- as_sym("x")

caracas::simplify(2*x^2*a+x^2*b)
#> [caracas]:  2        
#>            x *(2*a + b)

I don't like the way it prints x^2, but you can't have everything.

Related