如何正确找到多项式根?

NKN*_*NKN 7 matlab polynomials

考虑一个多项式,例如:

p = [1 -9 27 -27];
Run Code Online (Sandbox Code Playgroud)

显然真正的根是3:

polyval(p,3)

0
Run Code Online (Sandbox Code Playgroud)

使用该roots功能时

q = roots([1 -9 27 -27]);
Run Code Online (Sandbox Code Playgroud)

format short:

q =

   3.0000 + 0.0000i
   3.0000 + 0.0000i
   3.0000 - 0.0000i
Run Code Online (Sandbox Code Playgroud)

并检查根是否真实:

bsxfun(@eq,ones(size(q)),isreal(q))

0
0
0
Run Code Online (Sandbox Code Playgroud)

format long我得到的更糟糕的是:

roots([1 -9 27 -27])

ans =

  3.000019414068325 + 0.000000000000000i
  2.999990292965843 + 0.000016813349886i
  2.999990292965843 - 0.000016813349886i
Run Code Online (Sandbox Code Playgroud)

如何正确计算多项式的根?

Lui*_*ndo 6

您可能需要象征性地工作.你需要符号数学工具箱.

  1. 将多项式定义为符号函数.您可以(a)使用poly2sym从其系数生成符号多项式.或者(b)更好的是,使用字符串直接定义符号函数.这样就可以避免将系数表示为可能导致的精度损失double.

  2. 使用solve,象征性地解决代数方程.

带选项(a)的代码:

p = [1 -9 27 -27];
ps = poly2sym(p);
rs = solve(ps);
Run Code Online (Sandbox Code Playgroud)

带选项(b)的代码:

ps = sym('x^3-9*x^2+27*x-27');
rs = solve(ps);
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,结果都是象征性的:

>> rs
rs =
 3
 3
 3
Run Code Online (Sandbox Code Playgroud)

您可能希望使用转换为数值

r = double(rs);
Run Code Online (Sandbox Code Playgroud)

在你的例子中,这给出了

>> format long
>> r
r =
     3
     3
     3
Run Code Online (Sandbox Code Playgroud)

  • 我认为不需要使用`poly2sym`.这很好用:`roots(sym([1 -9 27 -27]))`.`roots`函数似乎没有为符号类型重载,而是它调用的底层函数.在Symbolic Math工具箱中还有[`root`](http://www.mathworks.com/help/symbolic/root.html),可以用来代替更通用的`solve`. (3认同)
  • 我认为`round`功能更快,但在准确性和效率之间存在折衷. (2认同)

Sar*_*ama 5

这是由于浮点不准确.看看这篇文章的细节: 浮点数学是否破碎?

你可以做的一件事是将答案/舍入到一些小数位,如下所示:

q = round(roots([1 -9 27 -27]), 4) % rounding off to 4 decimal places
Run Code Online (Sandbox Code Playgroud)