упростить комплексное выражение с питоном для вещественной и мнимой частей - PullRequest
0 голосов
/ 07 мая 2018

Выражение Exp (it) - Exp (6it) / 2 + i Exp (-14it) / 3, для t переход к 2 * pi предназначено для построения кривой Мистерии, как объяснено в http://www.johndcook.com/blog/2015/06/03/mystery-curve/ есть список питонов, чтобы построить эту кривую. Я хочу построить эту формулу, используя процедурный язык, как любой основной язык. Итак, я предоставил эту формулу Вольфраму Альфе следующим образом:
Упростить Exp (это) - Exp (6it) / 2 + i Exp (-14it) / 3
и они выводят результат как:

1/3 sin (14 т) + cos (t) -1/2 cos (6 т) + i (sin (t) -1/2 sin (6 т) +1/3 cos (14 т) )

так что на базовом языке я использовал это упрощение так:
x = Cos (t) - Cos (k * t) / 2 + Sin (14 * t) / 3
y = Cos (14 * t) / 3 + Sin (t) - Sin (k * t) / 2

Результат точно такой же, как и в коде Python Numpy, указанном на указанной странице.
Мой вопрос, как получить настоящие и воображаемые части от NumPy, как мы получаем от альфа-сайта Wolfram?
Это говорит нам о том, что действительная часть - это Cos (t) - Cos (k * t) / 2 + Sin (14 * t) / 3, а часть изображения - Cos (14 * t) / 3 + Sin (t) - грех (к * т) / 2. или что-то в этом роде.

1 Ответ

0 голосов
/ 07 мая 2018
In [37]: def f(t):
    ...:     return np.exp(1j*t) - np.exp(6j*t)/2 + 1j*np.exp(-14j*t)/3

In [39]: t = np.linspace(0,2*np.pi, 10)
In [40]: t
Out[40]: 
array([0.        , 0.6981317 , 1.3962634 , 2.0943951 , 2.7925268 ,
       3.4906585 , 4.1887902 , 4.88692191, 5.58505361, 6.28318531])
In [41]: f(t)
Out[41]: 
array([ 0.5       +0.33333333j,  0.90203773+0.76256944j,
        0.63791071+0.8071432j , -1.28867513+0.69935874j,
       -0.36142337+0.83291557j, -1.01796187-0.71715012j,
       -0.71132487-1.03269207j,  0.20938564-0.2964469j ,
        1.13005116-1.38903119j,  0.5       +0.33333333j])

Результатом этого вычисления является массив со сложным dtype. То есть элементы массива являются комплексными числами.

В основном это потому, что np.exp функция возвращает комплексное значение, если дан мнимый аргумент:

In [44]: np.exp(1j*1)
Out[44]: (0.5403023058681398+0.8414709848078965j)

Легко выбрать только части real или imag этих комплексных чисел с атрибутом np.real() или real:

In [42]: f(t).real
Out[42]: 
array([ 0.5       ,  0.90203773,  0.63791071, -1.28867513, -0.36142337,
       -1.01796187, -0.71132487,  0.20938564,  1.13005116,  0.5       ])
In [43]: f(t).imag
Out[43]: 
array([ 0.33333333,  0.76256944,  0.8071432 ,  0.69935874,  0.83291557,
       -0.71715012, -1.03269207, -0.2964469 , -1.38903119,  0.33333333])

Out[44] можно воспроизвести с помощью:

In [46]: np.cos(1) + 1j*np.sin(1)
Out[46]: (0.5403023058681398+0.8414709848078965j)

Документы для np.exp предполагают, что это расширение используется внутренне,

Для сложных аргументов x = a + ib мы можем написать e ^ x = e ^ a e ^ {ib}. Первый член, e ^ a, уже известен (это реальный аргумент, описанный выше). Второе слагаемое, e ^ {ib}, является \ cos b + i \ sin b, функцией с величиной 1 и периодической фазой.

Но numpy не имеет никакого механизма для выполнения символического (алгебраического) вычисления. Он работает напрямую с комплексными числами, а не с алгебраическими выражениями.


С sympy, пакетом математических символов Python:

In [1]: import sympy

In [3]: fn = sympy.sympify('exp(1j*re(x)) -exp(6j*re(x))/2 + 1j*exp(-14j*re(x))/3')
   ...: 
In [4]: fn
Out[4]: -exp(6*I*re(x))/2 + exp(I*re(x)) + I*exp(-14*I*re(x))/3
In [5]: fn.as_real_imag()
Out[5]: 
(sin(14*re(x))/3 + cos(re(x)) - cos(6*re(x))/2,
 sin(re(x)) - sin(6*re(x))/2 + cos(14*re(x))/3)

Мне пришлось использовать re(x), чтобы ограничить переменную x реальностью. В противном случае это расширило бы выражение до

exp(14*im(x))*sin(14*re(x))/3 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...