将具有虚幂的 sympy poly 转换为 mpmath mpc
Convert a sympy poly with imaginary powers to an mpmath mpc
我有一个 sympy poly,看起来像:
Poly(0.764635937801645*I**4 + 7.14650839258644*I**3 - 0.667712176660315*I**2 - 2.81663805543677*I - 0.623299856233272, I, domain='RR')
我正在使用以下代码转换为 mpc:
a = val.subs('I',1.0j)
b = sy.re(a)
c = sy.im(a)
d = mpmath.mpc(b,c)
两个问题。
- 假设我的 mpc 和 sympy 类型具有相同的精度(例如 100 dps)使用从
a
到 d
的这种转换是否有精度损失?
- 有没有更好的转换方式?
旁白:sympy 在这里似乎把 I 当作一个符号。我如何获得 sympy 来化简这个多项式?
编辑:我还注意到以下内容代替了上面的 a
:
a = val.args[0]
字符串和表达式
问题的根本原因见 val.subs('I', 1.0j)
——您似乎将字符串作为参数传递给 SymPy 函数。这有一些有效的用途(例如创建 high-precision 浮点数),但是当涉及符号时,使用字符串很容易造成混淆。字符串 'I' 隐式转换为 SymPy 表达式 Symbol('I')
,这与 SymPy 表达式 I
不同。所以
的答案
How do I get sympy to simplify this polynomial?
是重新审视那个多项式的创建过程,并修复它。如果你真的需要从一个字符串创建它,然后使用 locals
参数:
>>> S('3.3*I**2 + 2*I', locals={'I': I})
-3.3 + 2*I
多项式和表达式
如果不需要Poly结构,使用Poly的方法as_expr()
从中获取表达式。
转换为 mpmath 和精度损失
is there a precision loss using this conversion from a to d?
是的,分裂成实部和虚部然后重新组合会导致精度损失。如果您知道它是一个复数,请将 SymPy 对象直接传递给 mpc
。或者 mpmathify
如果你想让 mpmath 决定它应该有什么类型。一个例子:
>>> val = S('1.111111111111111111111111111111111111111111111111')*I**3 - 2
>>> val
-2 - 1.111111111111111111111111111111111111111111111111*I
>>> import mpmath
>>> mpmath.mp.dps = 40
>>> mpmath.mpc(val)
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111111')
>>> mpmath.mpmathify(val)
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111111')
>>> mpmath.mpc(re(val), im(val))
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111114')
观察:
- 当 I 是实虚数单位时,
I**3
的计算结果为 -I
,您无需执行任何操作即可实现。
- high-precision 十进制的字符串表示用于在 SymPy 中创建这样的浮点数。这里
S
代表 sympify
。也可以更直接一点,用Float('1.1111111111111111111111111')
- 将 SymPy 复数直接转换为 mpmath 复数优于拆分 real/complex 并重新组合。
结论
以上大部分内容只是在讨论 XY 问题。你对我的表情不是你想的那样,所以你试图做一些不需要的奇怪事情,而我的回答大多是浪费时间。
我在这里添加我自己的答案,因为 FTP 的答案虽然相关且非常有帮助,但没有(直接)解决我的问题(从问题中看不太清楚) .当我 运行 他的示例中的代码时,我得到以下内容:
>>> from sympy import *
>>> import mpmath
>>> val = S('1.111111111111111111111111111111111111111111111111')*I**3 - 2
>>> val
-2 - 1.111111111111111111111111111111111111111111111111*I
>>> mpmath.mp.dps = 40
>>> mpmath.mpc(val)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 373, in __new__
real = cls.context.mpf(real)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 77, in __new__
v._mpf_ = mpf_pos(cls.mpf_convert_arg(val, prec, rounding), prec, rounding)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 96, in mpf_convert_arg
raise TypeError("cannot create mpf from " + repr(x))
TypeError: cannot create mpf from -2 - 1.111111111111111111111111111111111111111111111111*I
>>> mpmath.mpmathify(val)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 662, in convert
return ctx._convert_fallback(x, strings)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp.py", line 614, in _convert_fallback
raise TypeError("cannot create mpf from " + repr(x))
TypeError: cannot create mpf from -2 - 1.111111111111111111111111111111111111111111111111*I
>>> mpmath.mpc(re(val), im(val))
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111114')
>>> mpmath.mpmathify(val)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 662, in convert
return ctx._convert_fallback(x, strings)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp.py", line 614, in _convert_fallback
raise TypeError("cannot create mpf from " + repr(x))
TypeError: cannot create mpf from -2 - 1.111111111111111111111111111111111111111111111111*I
更新我的 sympy (1.0->1.1.1) 和 mpmath (0.19->1.0.0) 修复了异常。我没有测试这些升级中的哪一个真正解决了问题。
我有一个 sympy poly,看起来像:
Poly(0.764635937801645*I**4 + 7.14650839258644*I**3 - 0.667712176660315*I**2 - 2.81663805543677*I - 0.623299856233272, I, domain='RR')
我正在使用以下代码转换为 mpc:
a = val.subs('I',1.0j)
b = sy.re(a)
c = sy.im(a)
d = mpmath.mpc(b,c)
两个问题。
- 假设我的 mpc 和 sympy 类型具有相同的精度(例如 100 dps)使用从
a
到d
的这种转换是否有精度损失? - 有没有更好的转换方式?
旁白:sympy 在这里似乎把 I 当作一个符号。我如何获得 sympy 来化简这个多项式?
编辑:我还注意到以下内容代替了上面的 a
:
a = val.args[0]
字符串和表达式
问题的根本原因见 val.subs('I', 1.0j)
——您似乎将字符串作为参数传递给 SymPy 函数。这有一些有效的用途(例如创建 high-precision 浮点数),但是当涉及符号时,使用字符串很容易造成混淆。字符串 'I' 隐式转换为 SymPy 表达式 Symbol('I')
,这与 SymPy 表达式 I
不同。所以
How do I get sympy to simplify this polynomial?
是重新审视那个多项式的创建过程,并修复它。如果你真的需要从一个字符串创建它,然后使用 locals
参数:
>>> S('3.3*I**2 + 2*I', locals={'I': I})
-3.3 + 2*I
多项式和表达式
如果不需要Poly结构,使用Poly的方法as_expr()
从中获取表达式。
转换为 mpmath 和精度损失
is there a precision loss using this conversion from a to d?
是的,分裂成实部和虚部然后重新组合会导致精度损失。如果您知道它是一个复数,请将 SymPy 对象直接传递给 mpc
。或者 mpmathify
如果你想让 mpmath 决定它应该有什么类型。一个例子:
>>> val = S('1.111111111111111111111111111111111111111111111111')*I**3 - 2
>>> val
-2 - 1.111111111111111111111111111111111111111111111111*I
>>> import mpmath
>>> mpmath.mp.dps = 40
>>> mpmath.mpc(val)
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111111')
>>> mpmath.mpmathify(val)
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111111')
>>> mpmath.mpc(re(val), im(val))
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111114')
观察:
- 当 I 是实虚数单位时,
I**3
的计算结果为-I
,您无需执行任何操作即可实现。 - high-precision 十进制的字符串表示用于在 SymPy 中创建这样的浮点数。这里
S
代表sympify
。也可以更直接一点,用Float('1.1111111111111111111111111')
- 将 SymPy 复数直接转换为 mpmath 复数优于拆分 real/complex 并重新组合。
结论
以上大部分内容只是在讨论 XY 问题。你对我的表情不是你想的那样,所以你试图做一些不需要的奇怪事情,而我的回答大多是浪费时间。
我在这里添加我自己的答案,因为 FTP 的答案虽然相关且非常有帮助,但没有(直接)解决我的问题(从问题中看不太清楚) .当我 运行 他的示例中的代码时,我得到以下内容:
>>> from sympy import *
>>> import mpmath
>>> val = S('1.111111111111111111111111111111111111111111111111')*I**3 - 2
>>> val
-2 - 1.111111111111111111111111111111111111111111111111*I
>>> mpmath.mp.dps = 40
>>> mpmath.mpc(val)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 373, in __new__
real = cls.context.mpf(real)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 77, in __new__
v._mpf_ = mpf_pos(cls.mpf_convert_arg(val, prec, rounding), prec, rounding)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 96, in mpf_convert_arg
raise TypeError("cannot create mpf from " + repr(x))
TypeError: cannot create mpf from -2 - 1.111111111111111111111111111111111111111111111111*I
>>> mpmath.mpmathify(val)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 662, in convert
return ctx._convert_fallback(x, strings)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp.py", line 614, in _convert_fallback
raise TypeError("cannot create mpf from " + repr(x))
TypeError: cannot create mpf from -2 - 1.111111111111111111111111111111111111111111111111*I
>>> mpmath.mpc(re(val), im(val))
mpc(real='-2.0', imag='-1.111111111111111111111111111111111111111114')
>>> mpmath.mpmathify(val)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\mpmath\ctx_mp_python.py", line 662, in convert
return ctx._convert_fallback(x, strings)
File "C:\Python27\lib\site-packages\mpmath\ctx_mp.py", line 614, in _convert_fallback
raise TypeError("cannot create mpf from " + repr(x))
TypeError: cannot create mpf from -2 - 1.111111111111111111111111111111111111111111111111*I
更新我的 sympy (1.0->1.1.1) 和 mpmath (0.19->1.0.0) 修复了异常。我没有测试这些升级中的哪一个真正解决了问题。