首页 > 解决方案 > 将 python numpy 复杂表达式简化为实部和虚部

问题描述

表达式 Exp(it) – Exp(6it)/2 + i Exp(-14it)/3 ,对于 t 去 2*pi 是用于绘制神秘曲线,如http://www.johndcook.com/blog中所述/2015/06/03/mystery-curve/ 有一个 python numpy 列表来绘制这条曲线。我想使用像任何基本语言一样的程序语言来绘制这个公式。所以我向 Wolfram Alpha 提供了这个公式,如下所示:
化简 Exp(it) – Exp(6it)/2 + i Exp(-14it)/3
,他们将结果输出为:

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

所以在基本语言中,我使用了这样的简化:
x = Cos(t) - Cos(k* t)/2 + Sin(14* t)/3
y = Cos(14* t)/3 + Sin( t)- Sin(k* t)/2

结果与引用页面中列出的 python numpy 代码完全相同。
我的问题是,如何像从 wolfram alpha 站点获得它一样从 numpy 获得真实和图像部分?
所以它告诉我们实部是 Cos(t) - Cos(k* t)/2 + Sin(14* t)/3,而图像部分是 Cos(14* t)/3 + Sin(t) - Sin(k* t)/2。或类似的东西。

标签: numpy

解决方案


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)

使用or属性很容易选择这些复数的一部分real或部分:imagnp.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^ae^{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 ...

推荐阅读