是否有可能在R中求解代数方程?

时间:2015-09-16 03:21:09

标签: r algebra equation-solving

我想找到解决方案:

-x^3+6*x^2+51*x+44=0

但是有R.可能吗?

我找到了Ryacas包,但似乎没有人能够使它工作。

可能听起来微不足道,但我找不到一个简单的方法来做到这一点...

你有其他选择吗?

谢谢你们!

3 个答案:

答案 0 :(得分:7)

您可以使用polynom包:

library(polynom)
p <- polynomial(c(44,51,6,-1))
# 44 + 51*x + 6*x^2 - x^3 
solve(p)
# [1] -4 -1 11

但您只需使用polyroot包中的base函数:

polyroot(c(44,51,6,-1))
# [1] -1+0i -4+0i 11+0i

如果您使用Re保留真实部分:

Re(polyroot(c(44,51,6,-1)))
# [1] -1 -4 11

答案 1 :(得分:6)

这里我们使用矩阵与其特征多项式之间的关系来求解根。

给定多项式a0 + a1*x^1 + a2*x^2 + x^3,定义矩阵:

0   0  -a0
1   0  -a1
0   1  -a2

该矩阵的特征值是多项式的根。

在多项式方程中替换y = -x得出这个

y^3 + 6*y^2 - 51*y + 44=0

并给出了这个例子

> 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

或者,因为我们已将-y替换为x

> eigen(-z)$values
[1] 11 -4 -1

请参阅:http://www-math.mit.edu/~edelman/publications/polynomial_roots.pdf

答案 2 :(得分:3)

我只是偶然发现了这个问题,我不确定Ryacas软件包是否有内在的变化,但它似乎在2020年效果很好,下面是一个有用的入门插图:https://cran.r-project.org/web/packages/Ryacas/vignettes/getting-started.html

在插图之后,当我运行代码时,一切似乎按预期工作:

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)"

您可以像这样计算表达式,为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"

在这里您可以看到x = 0的答案为44,x = 1的答案为100等...

如果您评估了新的简化或分解式版本并进行了评估,那么您最终将获得相同的准确结果:

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"

请注意,$src输出中的公式已更改,但结果相同。

这里也是因素之一: 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"

我在此处概述的内容与在小插图中概述的内容之间的唯一真正区别是实际公式,以及我使用library(glue)而非paste0的事实,这也是一个合理的选择。 / p>