求助:利用函数Series对多项式进行展开时出现问题
mathematica吧
全部回复
仅看楼主
level 7
Cauchy⚡ 楼主
一个很简单的问题. 我在计算中遇到一个关于x的高阶多项式y(含参数a),想要知道y在x=1处的值. 通常来说,我可以直接利用代入法Simplify[y /. {x -> 1}]来计算,但是因为具体问题的需求,我同样尝试了级数展开的方法:Simplify[SeriesCoefficient[y, {x, 1, 0}]]. 因为展开是在x=1处进行的,所以展开的零次项系数应该刚好是y在x=1处的值. 问题就在于,这两种方法得到的结果并不一样,如下:
y=7.270601199813882` a x + 5.562204926209233` a x^2 +
0.3333333333333333` (-32.650577651299955` a -
96.08397908604489` a^3) x^3 +
0.25` (-150.51602339950887` a - 248.87296852530474` a^3) x^4 +
0.2` (919.2006210076765` a + 317.5784638111923` a^3) x^5 +
0.16666666666666666` (-2555.422230693953` a +
4911.964985680276` a^3) x^6 +
0.14285714285714285` (4355.448458005178` a -
18824.775322728674` a^3) x^7 +
0.125` (-4696.079924274361` a + 27571.
18014307068
4` a^3) x^8 +
0.1111111111111111` (3096.6034868890056` a -
31824.812557004327` a^3) x^9 +
0.1` (-1122.8625212148754` a + 456913.9577956844` a^3) x^10 +
0.09090909090909091` (167.88370027990607` a -
3.466803246508558`*^6 a^3) x^11 +
1.2193882300396613`*^6 a^3 x^12 - 3.358922413660531`*^6 a^3 x^13 +
8.3142308074833015`*^6 a^3 x^14 - 2.4645478208932977`*^7 a^3 x^15 +
8.91979591539081`*^7 a^3 x^16 - 3.
15035541681
9327`*^8 a^3 x^17 +
9.5931
18484047457
`*^8 a^3 x^18 - 2.4584310607763934`*^9 a^3 x^19 +
5.330746667547112`*^9 a^3 x^20 - 9.871017330633518`*^9 a^3 x^21 +
1.5717281275620092`*^10 a^3 x^22 - 2.
15972926373
7713`*^10 a^3 x^23 +
2.5624876784219444`*^10 a^3 x^24 - 2.619586130465564`*^10 a^3 x^25 +
2.2967299060876034`*^10 a^3 x^26 -
1.7147698841840883`*^10 a^3 x^27 +
1.0794206588450806`*^10 a^3 x^28 - 5.65
13214838211
13`*^9 a^3 x^29 +
2.4
15218557492
412`*^9 a^3 x^30 - 8.205998295382454`*^8 a^3 x^31 +
2.
13130615298
1354`*^8 a^3 x^32 - 3.973049207193784`*^7 a^3 x^33 +
4.731791485442125`*^6 a^3 x^34 - 270388.0848824072` a^3 x^35;
SeriesCoefficient[y, {x, 1, 0}] // Simplify
y /. {x -> 1} // Simplify
SeriesCoefficient[y, {x, 1, 0}] - y /. {x -> 1} // Simplify
y的代码实在太花了,还请大家体谅一下. 程序的输出结果是:
Out[29]= 4.49658 a - 7.07043 a^3
Out[30]= 4.49658 a - 7.07042 a^3
Out[31]= 1.13687*10^-13 a - 0.0000253148 a^3
可以明显看见两种方法的结果有差别. 我尝试了只截取y的前面十几次方的低阶项进行计算,发现两种方法仍然会得到不一样的结果. 虽说结果相差不大,但是毕竟达不到计算精度的要求. 这两种方法结果的不同难道纯粹是因为不同计算方法产生了不同的计算误差吗?还是说代入法原本就是正确的,而级数展开法会产生较大的误差?
这个问题困扰我很长时间了,查了不少资料也没找到原因,在此向各位求教.
2019年12月06日 07点12分 1
吧务
level 12
就是浮点数运算的舍入误差问题,举个简单例子
In[96]:= ans1 = Factor[x^10000 - 1] /. x -> 1.002;
ans2 = x^10000 - 1 /. x -> 1.002;
ans1 - ans2
Out[98]= 0.0000614524
要解释原因大概就是由于浮点数运算并不精确,同一表达式的不同形式在运算时可能产生不同的舍入误差
2019年12月06日 10点12分 2
Mathematica的默认WorkingPrecision是16位,看上去还挺精确的,我还真么没想到实际计算中会产生这么大的舍入误差。请问有什么办法可以减小这种误差呢?直接提高计算精度可行吗?
2019年12月06日 11点12分
@Cauchy⚡ “Mathematica的默认WorkingPrecision是16位”不对。首先严格来说,计算时使用的精度是由你的输入的精度推定的,此外还和你使用的函数有关;其次,即便只考虑你想表达的那种意思,这个“默认”精度也是MachinePrecision,它的数值值相当于16位,但是……(转下条
2019年12月07日 11点12分
@Cauchy⚡ 突然有点不想写了,总之你观察下{N[1002/1000, N@MachinePrecision], N[1002/1000, MachinePrecision]}。更多内容可参考百度知道的提问《Mathematica实数保留n位有效数字和保留n位小数的最简单的方法分别是什么? 》,链接不贴了,怕吞。
2019年12月07日 11点12分
吧务
level 12
可以,比如你直接加一行
y = SetPrecision[y, 30];
就能把误差降到1e-19以下
不过说实话,这种“误差”在数值计算中十分常见,而且大多数情况下没什么影响。如果是想进行严格的推导证明,建议计算中不要出现任何浮点数,改用纯符号计算
y = Rationalize[y, 1*^-30]
2019年12月06日 14点12分 4
好的,非常感谢!
2019年12月07日 11点12分
对了,我提供的y最多到小数点后16位,Mathematica是如何通过SetPrecision给出更多的有效数字的呢?
2019年12月07日 11点12分
吧务
level 12
回复 手握一滴水😇 :
机器存储浮点数用的是二进制,你提供的y最多到小数点后16位,在电脑中存储的实际是一个“转化成十进制后截止到小数点后十六位都与你给定的y相等的二进制数”,或者更确切地说,是“这个精度能表示的有限个浮点数中与你给的y最接近的数”。这个数自然有更多的有效数字
这么说可能有点不好理解,建议参考贴吧右侧链接中关于浮点数的部分看看(https://www.iteye.com/blog/justjavac-1724438),然后运行以下代码看看结果
Precision[0.1]
SetPrecision[0.1, 50]
Precision[0.11111111111111111111]
SetPrecision[0.11111111111111111111, 50]
2019年12月08日 11点12分 5
1