3

人们会期望并希望,如果您要求Mathematica找到多项式的根,它应该给出相同(近似)的答案,无论您是象征性地执行此操作,然后找到这些确切答案的数值近似值,还是您是否以数字方式执行此操作。这是一个示例,它(在Mathematica 7OS X 上运行)严重失败:

poly = -112 + 1/q^28 + 1/q^26 - 1/q^24 - 6/q^22 - 14/q^20 - 25/q^18 -
  38/q^16 - 52/q^14 - 67/q^12 - 81/q^10 - 93/q^8 - 102/q^6 - 108/
  q^4 - 111/q^2 - 111 q^2 - 108 q^4 - 102 q^6 - 93 q^8 - 81 q^10 -
  67 q^12 - 52 q^14 - 38 q^16 - 25 q^18 - 14 q^20 - 6 q^22 - q^24 +
  q^26 + q^28;

Total[q^4 /. NSolve[poly == 0, q]] - Total[q^4 /. N[Solve[poly == 0, q]]]

(注意:这实际上是一个 Laurent 多项式,如果你乘以一个很大的幂,q问题就消失了。)

这里的最后一行只是证明找到的解决方案非常不同;事实上,这是我们试图在我们正在研究的问题中计算的数量。

如果您仔细查看 和 的输出NSolve[poly == 0, q]N[Solve[poly == 0, q]您会发现 NSolve 只给出54根而不是预期的56. 这并不是说它只是错过了重复的根或任何东西;它缺少两个最大的量级根(大约+/- 1.59

这是 Mathematica 中的错误吗?有没有人解释为什么会这样?

4

1 回答 1

7

不幸的是,您的期望是没有根据的。

正如您所说,Solve[]给出了一个精确的解决方案并N[]引入了一个小错误,但只有一次,当您评估它时。NSolve[]另一方面,从一开始就使用数值近似值,因此会累积显着的舍入误差。

您还受到计算默认精度的限制,这可能导致数值方法完全失败,例如,缺少根(请参阅威尔金森多项式)。NSolve[]您可以通过告诉使用更高的精度来抵消这种情况,如下所示:

In[1]  := Total[q^4 /. NSolve[poly == 0, q, WorkingPrecision -> 50]] - 
          Total[q^4 /. N[Solve[poly == 0, q]]]
Out[1] := 0. - 3.66374*10^-15 I

在使用数值方法时,记住错误总是很重要的。由于这对于从求解长多项式到对角化大矩阵再到奇怪函数的积分等各种数值分析问题都是正确的,因此没有一种正确的方法,因此需要告诉 Mathematica,例如提高 WorkingPrecision ,或应用不同的数值技术。

于 2010-10-19T06:52:26.003 回答