如何正确找到多项式根?

时间:2016-09-01 02:46:53

标签: matlab polynomials

考虑多项式,例如:

p = [1 -9 27 -27];

显然真正的根是3:

polyval(p,3)

0

使用roots功能时

q = roots([1 -9 27 -27]);

format short

q =

   3.0000 + 0.0000i
   3.0000 + 0.0000i
   3.0000 - 0.0000i

并检查根是否真实:

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

0
0
0

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

roots([1 -9 27 -27])

ans =

  3.000019414068325 + 0.000000000000000i
  2.999990292965843 + 0.000016813349886i
  2.999990292965843 - 0.000016813349886i

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

3 个答案:

答案 0 :(得分:6)

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

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

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

  3. 带选项(a)的代码:

    p = [1 -9 27 -27];
    ps = poly2sym(p);
    rs = solve(ps);
    

    带选项(b)的代码:

    ps = sym('x^3-9*x^2+27*x-27');
    rs = solve(ps);
    

    在任何一种情况下,结果都是符号:

    >> rs
    rs =
     3
     3
     3
    

    您可能希望使用

    转换为数字值
    r = double(rs);
    

    在你的例子中,这给出了

    >> format long
    >> r
    r =
         3
         3
         3
    

答案 1 :(得分:5)

这是由于浮点不准确造成的。有关详细信息,请查看此帖子: Is floating point math broken?

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

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

答案 2 :(得分:0)

这非常特定于多项式。通常,您必须期望多重m的根具有相对浮点误差大小mu^(1/m),其中mu=1e-15是机器精度。在这种情况下,多重性为m=3,因此误差范围为10^(-5)。这正是结果中错误的大小。

这里发生的清晰整数系数是matlab使用的方法的结果,它计算伴随矩阵的特征值,特征值算法将整数矩阵转换为适当的浮点矩阵,其中有相应的舍入误差。算法的第一步。

其他算法对多重性和近似根的相关聚类进行经验测试,因此能够纠正此错误。在这种情况下,您可以通过将每个根替换为3个根的平均值来实现此目的。

在数学上,你有一些多项式

p(x)=(x-a)^m*q(x)

根目录x=a的多重性m。由于浮点运算,求解器有效地“看到”多项式

p(x)+e(x)

其中e(x)的系数的大小是pmu系数的大小。靠近根a,这个被扰动的多项式可以有效地替换为

(x-a)^m*q(a)+e(a) = 0  <==>  (x-a)^m = -e(a)/q(a)

以便解决方案形成一个以a为中心的m形正多边形或星形,半径为|e(a)/q(a)|^(1/m),该区域应位于|a|*mu^(1/m)区域内。