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)

两个问题。

  1. a假设我的 mpc 和 sympy 类型具有相同的精度(例如 100 dps),使用这种从to的转换是否存在精度损失d
  2. 有没有更好的转换方法?

旁白: sympy 似乎在这里把我当作一个符号来对待。我如何获得同情来简化这个多项式?

编辑:我还注意到以下内容代替了a上述内容:

a = val.args[0]
4

2 回答 2

1

字符串和表达式

问题的根本原因在于val.subs('I', 1.0j)——您似乎将字符串作为参数传递给 SymPy 函数。这有一些有效的用途(例如创建高精度浮点数),但是当涉及到符号时,使用字符串会造成混淆。字符串 'I' 被隐式转换为 SymPy 表达式Symbol('I'),这与 SymPy 表达式不同I。所以答案

我如何获得同情来简化这个多项式?

是重新审视创建该多项式的过程,并修复它。如果您确实需要从字符串创建它,请使用locals参数:

>>> S('3.3*I**2 + 2*I', locals={'I': I})
-3.3 + 2*I

多项式和表达式

如果不需要 Poly 结构,则使用as_expr()Poly 的方法从中获取表达式。

转换为 mpmath 和精度损失

使用这种从 a 到 d 的转换是否存在精度损失?

是的,拆分为实数和虚数,然后重新组合会导致精度损失。mpc如果您知道它是复数,则直接将 SymPy 对象传递给。或者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评估 fo -I,您无需为它发生任何事情。
  • 高精度十进制的字符串表示用于在 SymPy 中创建这样的浮点数。这里S代表sympify. 也可以更直接的使用Float('1.1111111111111111111111111')
  • 将 SymPy 复数直接转换为 mpmath 复数比拆分为实数/复数并重新组合更可取。

结论

以上大部分内容只是在谈论 XY 问题。你和我的表情不是你想象的那样,所以你试图做一些不需要的奇怪事情,而我的回答大多是浪费时间。

于 2018-03-10T19:10:20.710 回答
0

我在这里添加了我自己的答案,因为 FTP 的答案虽然相关且非常有帮助,但并没有(直接)解决我的问题(从问题 tbh 中并不清楚)。当我在他的示例中运行代码时,我得到以下信息:

>>> 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) 修复了异常。我没有测试这些升级中的哪一个实际上解决了这个问题。

于 2018-03-10T21:26:18.340 回答