为什么 Sympy 会切断系数较小的多项式项?
Why does Sympy cut off polynomial terms with small coefficients?
我正在尝试使用 sympy.Poly()
将包含具有不同程度的符号变量 z_s
的项的表达式转换为 python 中的多项式,以便我可以使用 sympy.Poly()
提取系数.coeffs()
.
我的表达式是一个具有独立符号变量的高阶多项式z_s。出于某种原因,当我使用 sympy.Poly() 将表达式转换为多项式时,它似乎切断了系数较小的项。下面是我的函数,我包括了我将其重新定义为符号多项式的行:
f = -1.29096669270427e-61*z_s**33 + 6.24438995041203e-59*z_s**32 - 6.41125090009095e-57*z_s**31 - 8.30852813320818e-55*z_s**30 + 5.84175807723288e-53*z_s**29 + 1.88577332997761e-50*z_s**28 + 9.46504910106607e-49*z_s**27 - 2.28903644846359e-46*z_s**26 - 4.63321594171589e-44*z_s**25 - 1.78254194888339e-42*z_s**24 + 6.43406800910469e-40*z_s**23 + 1.20425521347205e-37*z_s**22 + 3.4116753522246e-36*z_s**21 - 1.92084369416715e-33*z_s**20 - 3.04107684362554e-31*z_s**19 + 2.89289551256439e-30*z_s**18 + 6.38382842182985e-27*z_s**17 + 5.46438700248253e-25*z_s**16 - 8.50501280745176e-23*z_s**15 - 1.6344595302306e-20*z_s**14 + 1.07764488797684e-18*z_s**13 + 3.47026242660686e-16*z_s**12 - 2.93966702403133e-14*z_s**11 - 5.25394006214533e-12*z_s**10 + 1.21642330162702e-9*z_s**9 - 1.16577645027166e-7*z_s**8 + 6.82117624588787e-6*z_s**7 - 0.000267513120031891*z_s**6 + 0.00723589681411793*z_s**5 - 0.134846078975788*z_s**4 + 1.69035817278476*z_s**3 - 13.5277365002646*z_s**2 + 62.3459673862853*z_s - 76.5029927727737
sympy.Poly(f,z_s)
这个returns:
Poly(-2.93966702403133e-14*z_s**11 - 5.25394006214533e-12*z_s**10 + 1.21642330162702e-9*z_s**9 - 1.16577645027166e-7*z_s**8 + 6.82117624588787e-6*z_s**7 - 0.000267513120031891*z_s**6 + 0.00723589681411793*z_s**5 - 0.134846078975788*z_s**4 + 1.69035817278476*z_s**3 - 13.5277365002646*z_s**2 + 62.3459673862853*z_s - 76.5029927727737, z_s, domain='RR')
如你所见,前几项被去掉了
起初我以为它会切断我的高阶项,因为高阶多项式有一些内置的截止点,但我在任何文档中都找不到这种情况。然后我发现被截断的项似乎是因为系数值低而被截断(我假设 sympy 或 python 认为该项可以忽略不计,因为它的系数非常接近于零)。您可以在我的函数中看到第一项的系数约为 -1.3e-61
。我用一个简单的例子测试了这个理论,这个例子有一个 2 项多项式,次数为 1,有一个 "small" 项截止:
h = 10e-27*z_s + 1
sympy.Poly(h,z_s)
(编辑:+ 1
应该在 h
函数中,我只是修复它以便它正确读取。这不会改变输出。)
这个returns:
Poly(1.0, z_s, domain='RR')
如您所见,包含系数 10e-27
的项已从多项式中删除,仅保留常数 (1.0
)。
我在多个论坛或 SymPy 文档中找不到任何关于此的信息(除非我错过了)。然而,我确实发现人们正在尝试做与我正在尝试做的完全相反的事情(参见 here,例如):他们试图切断系数较小的项,而我正在尝试防止 python 切断这些条款。
有没有办法告诉 python/sympy 我不想将那些小系数设置为零?
或者,为了绕过这个问题,是否有另一种方法可以在不使用 sympy.Poly()
和 .coeffs()
的情况下按顺序从我的原始函数中提取系数?
我不知道为什么 sympy 在构造实数多项式时会截断小系数,但它不会在有理数上这样做。因此,作为一种解决方法,您可以构造一个包含 domain='QQ'
的多项式,提取系数,然后再转换回浮点数。
使用多项式的示例:
import sympy
z_s = symbols('z_s')
f = -1.29096669270427e-61*z_s**33 + 6.24438995041203e-59*z_s**32 - 6.41125090009095e-57*z_s**31 - 8.30852813320818e-55*z_s**30 + 5.84175807723288e-53*z_s**29 + 1.88577332997761e-50*z_s**28 + 9.46504910106607e-49*z_s**27 - 2.28903644846359e-46*z_s**26 - 4.63321594171589e-44*z_s**25 - 1.78254194888339e-42*z_s**24 + 6.43406800910469e-40*z_s**23 + 1.20425521347205e-37*z_s**22 + 3.4116753522246e-36*z_s**21 - 1.92084369416715e-33*z_s**20 - 3.04107684362554e-31*z_s**19 + 2.89289551256439e-30*z_s**18 + 6.38382842182985e-27*z_s**17 + 5.46438700248253e-25*z_s**16 - 8.50501280745176e-23*z_s**15 - 1.6344595302306e-20*z_s**14 + 1.07764488797684e-18*z_s**13 + 3.47026242660686e-16*z_s**12 - 2.93966702403133e-14*z_s**11 - 5.25394006214533e-12*z_s**10 + 1.21642330162702e-9*z_s**9 - 1.16577645027166e-7*z_s**8 + 6.82117624588787e-6*z_s**7 - 0.000267513120031891*z_s**6 + 0.00723589681411793*z_s**5 - 0.134846078975788*z_s**4 + 1.69035817278476*z_s**3 - 13.5277365002646*z_s**2 + 62.3459673862853*z_s - 76.5029927727737
[sympy.N(c) for c in sympy.poly(f,z_s,domain='QQ').coeffs()]
returns
[-1.29096669270427e-61, 6.24438995041203e-59, -6.41125090009095e-57, -8.30852813320818e-55, 5.84175807723288e-53, 1.88577332997761e-50, 9.46504910106607e-49, -2.28903644846359e-46, -4.63321594171589e-44, -1.78254194888339e-42, 6.43406800910469e-40, 1.20425521347205e-37, 3.41167535222460e-36, -1.92084369416715e-33, -3.04107684362554e-31, 2.89289551256439e-30, 6.38382842182985e-27, 5.46438700248253e-25, -8.50501280745176e-23, -1.63445953023060e-20, 1.07764488797684e-18, 3.47026242660686e-16, -2.93966702403133e-14, -5.25394006214533e-12, 1.21642330162702e-9, -1.16577645027166e-7, 6.82117624588787e-6, -0.000267513120031891, 0.00723589681411793, -0.134846078975788, 1.69035817278476, -13.5277365002646, 62.3459673862853, -76.5029927727737]
我正在尝试使用 sympy.Poly()
将包含具有不同程度的符号变量 z_s
的项的表达式转换为 python 中的多项式,以便我可以使用 sympy.Poly()
提取系数.coeffs()
.
我的表达式是一个具有独立符号变量的高阶多项式z_s。出于某种原因,当我使用 sympy.Poly() 将表达式转换为多项式时,它似乎切断了系数较小的项。下面是我的函数,我包括了我将其重新定义为符号多项式的行:
f = -1.29096669270427e-61*z_s**33 + 6.24438995041203e-59*z_s**32 - 6.41125090009095e-57*z_s**31 - 8.30852813320818e-55*z_s**30 + 5.84175807723288e-53*z_s**29 + 1.88577332997761e-50*z_s**28 + 9.46504910106607e-49*z_s**27 - 2.28903644846359e-46*z_s**26 - 4.63321594171589e-44*z_s**25 - 1.78254194888339e-42*z_s**24 + 6.43406800910469e-40*z_s**23 + 1.20425521347205e-37*z_s**22 + 3.4116753522246e-36*z_s**21 - 1.92084369416715e-33*z_s**20 - 3.04107684362554e-31*z_s**19 + 2.89289551256439e-30*z_s**18 + 6.38382842182985e-27*z_s**17 + 5.46438700248253e-25*z_s**16 - 8.50501280745176e-23*z_s**15 - 1.6344595302306e-20*z_s**14 + 1.07764488797684e-18*z_s**13 + 3.47026242660686e-16*z_s**12 - 2.93966702403133e-14*z_s**11 - 5.25394006214533e-12*z_s**10 + 1.21642330162702e-9*z_s**9 - 1.16577645027166e-7*z_s**8 + 6.82117624588787e-6*z_s**7 - 0.000267513120031891*z_s**6 + 0.00723589681411793*z_s**5 - 0.134846078975788*z_s**4 + 1.69035817278476*z_s**3 - 13.5277365002646*z_s**2 + 62.3459673862853*z_s - 76.5029927727737
sympy.Poly(f,z_s)
这个returns:
Poly(-2.93966702403133e-14*z_s**11 - 5.25394006214533e-12*z_s**10 + 1.21642330162702e-9*z_s**9 - 1.16577645027166e-7*z_s**8 + 6.82117624588787e-6*z_s**7 - 0.000267513120031891*z_s**6 + 0.00723589681411793*z_s**5 - 0.134846078975788*z_s**4 + 1.69035817278476*z_s**3 - 13.5277365002646*z_s**2 + 62.3459673862853*z_s - 76.5029927727737, z_s, domain='RR')
如你所见,前几项被去掉了
起初我以为它会切断我的高阶项,因为高阶多项式有一些内置的截止点,但我在任何文档中都找不到这种情况。然后我发现被截断的项似乎是因为系数值低而被截断(我假设 sympy 或 python 认为该项可以忽略不计,因为它的系数非常接近于零)。您可以在我的函数中看到第一项的系数约为 -1.3e-61
。我用一个简单的例子测试了这个理论,这个例子有一个 2 项多项式,次数为 1,有一个 "small" 项截止:
h = 10e-27*z_s + 1
sympy.Poly(h,z_s)
(编辑:+ 1
应该在 h
函数中,我只是修复它以便它正确读取。这不会改变输出。)
这个returns:
Poly(1.0, z_s, domain='RR')
如您所见,包含系数 10e-27
的项已从多项式中删除,仅保留常数 (1.0
)。
我在多个论坛或 SymPy 文档中找不到任何关于此的信息(除非我错过了)。然而,我确实发现人们正在尝试做与我正在尝试做的完全相反的事情(参见 here,例如):他们试图切断系数较小的项,而我正在尝试防止 python 切断这些条款。
有没有办法告诉 python/sympy 我不想将那些小系数设置为零?
或者,为了绕过这个问题,是否有另一种方法可以在不使用 sympy.Poly()
和 .coeffs()
的情况下按顺序从我的原始函数中提取系数?
我不知道为什么 sympy 在构造实数多项式时会截断小系数,但它不会在有理数上这样做。因此,作为一种解决方法,您可以构造一个包含 domain='QQ'
的多项式,提取系数,然后再转换回浮点数。
使用多项式的示例:
import sympy
z_s = symbols('z_s')
f = -1.29096669270427e-61*z_s**33 + 6.24438995041203e-59*z_s**32 - 6.41125090009095e-57*z_s**31 - 8.30852813320818e-55*z_s**30 + 5.84175807723288e-53*z_s**29 + 1.88577332997761e-50*z_s**28 + 9.46504910106607e-49*z_s**27 - 2.28903644846359e-46*z_s**26 - 4.63321594171589e-44*z_s**25 - 1.78254194888339e-42*z_s**24 + 6.43406800910469e-40*z_s**23 + 1.20425521347205e-37*z_s**22 + 3.4116753522246e-36*z_s**21 - 1.92084369416715e-33*z_s**20 - 3.04107684362554e-31*z_s**19 + 2.89289551256439e-30*z_s**18 + 6.38382842182985e-27*z_s**17 + 5.46438700248253e-25*z_s**16 - 8.50501280745176e-23*z_s**15 - 1.6344595302306e-20*z_s**14 + 1.07764488797684e-18*z_s**13 + 3.47026242660686e-16*z_s**12 - 2.93966702403133e-14*z_s**11 - 5.25394006214533e-12*z_s**10 + 1.21642330162702e-9*z_s**9 - 1.16577645027166e-7*z_s**8 + 6.82117624588787e-6*z_s**7 - 0.000267513120031891*z_s**6 + 0.00723589681411793*z_s**5 - 0.134846078975788*z_s**4 + 1.69035817278476*z_s**3 - 13.5277365002646*z_s**2 + 62.3459673862853*z_s - 76.5029927727737
[sympy.N(c) for c in sympy.poly(f,z_s,domain='QQ').coeffs()]
returns
[-1.29096669270427e-61, 6.24438995041203e-59, -6.41125090009095e-57, -8.30852813320818e-55, 5.84175807723288e-53, 1.88577332997761e-50, 9.46504910106607e-49, -2.28903644846359e-46, -4.63321594171589e-44, -1.78254194888339e-42, 6.43406800910469e-40, 1.20425521347205e-37, 3.41167535222460e-36, -1.92084369416715e-33, -3.04107684362554e-31, 2.89289551256439e-30, 6.38382842182985e-27, 5.46438700248253e-25, -8.50501280745176e-23, -1.63445953023060e-20, 1.07764488797684e-18, 3.47026242660686e-16, -2.93966702403133e-14, -5.25394006214533e-12, 1.21642330162702e-9, -1.16577645027166e-7, 6.82117624588787e-6, -0.000267513120031891, 0.00723589681411793, -0.134846078975788, 1.69035817278476, -13.5277365002646, 62.3459673862853, -76.5029927727737]