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 ...