Преобразуйте симпати поли с мнимыми способностями в mpmath mpc

У меня есть симпатичный поли, который выглядит так:

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. Предполагая, что мои mpc и sympy type имеют одинаковую точность (например, 100 dps), есть ли потеря точности при использовании этого преобразования из a в d?
  2. Есть ли лучший способ конвертировать?

В стороне: sympy, кажется, относится ко мне просто как к символу здесь. Как мне получить упрощение, чтобы упростить этот полином?

Редактировать: я также заметил, что следующие работы вместо a выше:

a = val.args[0]

2 ответа

Решение

Строки и выражения

Коренная причина проблемы видна в 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() Поли, чтобы получить выражение от этого.

Преобразование в mpmath и потерю точности

есть ли потеря точности при использовании этого преобразования из a в 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**3 оценивает -I Вам не нужно ничего делать, чтобы это произошло.
  • Строковое представление высокоточного десятичного числа используется для создания такого типа с плавающей точкой в ​​SymPy. Вот S обозначает sympify, Можно также быть более прямым и использовать Float('1.1111111111111111111111111')
  • Прямое преобразование комплексного числа SymPy в комплексное число mpmath предпочтительнее, чем расщепление в вещественное / сложное и рекомбинирование.

Заключение

Большинство из вышеперечисленных просто говорит о проблеме XY. Ваше выражение со мной было не таким, как вы думаете, поэтому вы пытались делать странные вещи, в которых не было необходимости, и мой ответ - в основном пустая трата времени.

Я добавляю здесь свой собственный ответ, так как ответ 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) исправило исключения. Я не проверял, какое из этих обновлений действительно решило проблему.

Другие вопросы по тегам