考虑一个多项式,例如:
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
如何正确计算多项式的根?
发布于 2016-08-31 21:13:39
这是由于浮点不准确。查看这篇文章以获得详细信息:Is floating point math broken?
你可以做的一件事就是把答案舍入小数点后的几位,如下所示:
q = round(roots([1 -9 27 -27]), 4) % rounding off to 4 decimal places
发布于 2016-09-01 01:59:10
你可能得象征性地工作。你需要符号数学工具箱。
poly2sym
从其系数生成符号多项式。或者(b)更好的是,直接使用字符串定义符号函数。这样,您就避免了将系数表示为double
可能导致的准确性损失。solve
,它象征性地解决代数方程。带有选项(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
发布于 2016-09-09 07:00:54
这是非常特定于你的多项式。通常,您必须期望多重性的根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)
系数具有一个大小,即p
乘以mu
系数的大小。在根a
附近,这个受扰动的多项式可以被有效地替换为
(x-a)^m*q(a)+e(a) = 0 <==> (x-a)^m = -e(a)/q(a)
使得解形成一个m点正多边形或以a
为中心的恒星,其半径为|e(a)/q(a)|^(1/m)
,应该在|a|*mu^(1/m)
区域内。
https://stackoverflow.com/questions/39261924
复制