Home > Software engineering >  Treat a literal variable as a constant with Ryacas (or an alternative)
Treat a literal variable as a constant with Ryacas (or an alternative)

Time:05-22

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?

CodePudding user response:

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.

CodePudding user response:

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
  • Related