Is it possible to solve an algebraic equation in R?
You can use polynom
package:
library(polynom)
p <- polynomial(c(44,51,6,-1))
# 44 + 51*x + 6*x^2 - x^3
solve(p)
# [1] -4 -1 11
But you simply can use the function polyroot
from base
package:
polyroot(c(44,51,6,-1))
# [1] -1+0i -4+0i 11+0i
If you keep the real part with Re
:
Re(polyroot(c(44,51,6,-1)))
# [1] -1 -4 11
Here we solve for the roots using the relationship between a matrix and its characteristic polynomial.
Given the polynomial a0 + a1*x^1 + a2*x^2 + x^3
, define the matrix:
0 0 -a0
1 0 -a1
0 1 -a2
The eigenvalues of this matrix are the roots of the polynomial.
Substituting y = -x
in your polynomial equation gives this
y^3 + 6*y^2 - 51*y + 44=0
And gives this example
> z <- matrix(c(0,1,0,0,0,1,-44,51,-6),3,3)
> z
[,1] [,2] [,3]
[1,] 0 0 -44
[2,] 1 0 51
[3,] 0 1 -6
> eigen(z)
$values
[1] -11 4 1
$vectors
[,1] [,2] [,3]
[1,] 0.6172134 0.73827166 0.98733164
[2,] -0.7715167 -0.67115606 -0.15707549
[3,] 0.1543033 -0.06711561 -0.02243936
Or, since we've substituted -y
for x
:
> eigen(-z)$values
[1] 11 -4 -1
See: http://www-math.mit.edu/~edelman/publications/polynomial_roots.pdf
I just stumbled upon this question and I am not sure if anything inherently changed around the Ryacas package, but it seems to work great in 2020, here is a helpful vignette to get started: https://cran.r-project.org/web/packages/Ryacas/vignettes/getting-started.html
Following the vignette, things seem to work as expected when I run the code:
library(Ryacas)
# initialize equation:
eq <- "-x^3+6*x^2+51*x+44"
# simplify the equation:
library(glue)
yac_str(glue("Simplify({eq})"))
[1] "6*x^2-x^3+51*x+44"
# factor:
yac_str(glue("Factor({eq})"))
[1] "(-1)*(x-11)*(x+4)*(x+1)"
You can evaluate the expression like this, plugging in whatever values for x:
# evaluate
evaluate(eq,list(x=c(0,1,10,100,-100)))
[[1]]
$src
[1] "-x^3+6*x^2+51*x+44"
attr(,"class")
[1] "source"
[[2]]
[1] "[1] 44 100 154 -934856 1054944\n"
Here you can see the results where x=0 produced an answer of 44, x=1 produced an answer of 100, etc...
If you evaluated the new simplified or factored versions and evaluated those, you would of course end up with the same exact results:
evaluate(yac_str(glue("Simplify({eq})")),list(x=c(0,1,10,100,-100)))
[[1]]
$src
[1] "6*x^2-x^3+51*x+44"
attr(,"class")
[1] "source"
[[2]]
[1] "[1] 44 100 154 -934856 1054944\n"
Notice the formula changed in the $src
output, but we get the same results.
Here's the factored one too:
evaluate(yac_str(glue("Factor({eq})")),list(x=c(0,1,10,100,-100)))
[[1]]
$src
[1] "(-1)*(x-11)*(x+4)*(x+1)"
attr(,"class")
[1] "source"
[[2]]
[1] "[1] 44 100 154 -934856 1054944\n"
The only real difference between what I outlined here and what's outlined in the vignette is the actual formula, and the fact that I used library(glue)
instead of paste0
, which is also a fair option.