符号复数表达式简化
symbolic complex expression simplification
虽然我的问题与具体问题有关,但我想用更笼统的术语来处理它。
我想简化通过使用 sympy 包乘以符号矩阵获得的分数复数表达式。
我得到的是一个带有实参数和许多复指数项(相位项)的分数,如 exp(-jd)、exp(-2jd) 和 exp(-4j*d ).我得到了正确的结果,但是当我尝试计算 ||**2,这是一个实数表达式时,sympy.simplify() 无法管理相位项,我得到了一个巨大的表达式,我必须减少用手。
我的测试程序是 T、M、M_inv、F 和 T,2x2 符号矩阵是:
import simply as sym
Mf = T @ M_inv @ F @ T
Mf = sym.simplify(Mf)
eig = Mf.eigenvals()
for key,value in eig.items():
val = key
eig_cc = np.conj(val)
final = sym.simplify(val*eig_cc)
我想知道是否存在改进计算的特定工具。
经过快速研究,我在 post 中发现了两种可能性:
a.trigsimp() 对于 expr.rewrite(cos).expand().as_real_imag()
expr.rewrite(cos).simplify().trigsimp()
虽然第一个为更简单的表达式提供了正确的结果(不是我试图解决的那个),但其中 none 对我有效。
第二个问题,eig 输出有一个字典形状,所以取值我使用了 for 循环。
for key,value in eig.items():
val = key
是否有更好、更快的方法来达到相同的结果?
我使用的代码是:
import numpy as np
import sympy as sym
from sympy import *
t = sym.Symbol('t', real=True)
r = sym.Symbol('r', real=True)
u = sym.Symbol('u', real=True)
d = sym.Symbol('d', real=True)
a = sym.Symbol('a', real=True)
I = np.identity(2)
T = sym.Matrix ([[t,0],[0,t]])
R = sym.Matrix ([[r,0],[0,r]])
F = sym.Matrix ([[sym.sqrt(u)*sym.exp(-1j*d),0],[0,sym.sqrt(u)*sym.exp(-1j*d)]])
sym.init_printing()
M = (I - F @ R @ F @ R)
M_inv = M.inv()
Mf = T @ M_inv @ F @ T
Mf = sym.simplify(Mf)
eig = Mf.eigenvals()
for key,value in eig.items():
val = key
eig_cc = np.conj(val)
expr = finale = sym.simplify(val*eig_cc)
"""
Test1
"""
result = [a.trigsimp() for a in expr.rewrite(sin).expand().as_real_imag()]
"""
Test2
"""
result1 = expr.rewrite(sin).simplify().trigsimp()
提前致谢
几点:
除非您确切地知道自己在做什么,否则不要像这样混淆 numpy 和 sympy。这里根本不需要使用 numpy,所以使用例如sym.eye(2)
和 sym.conjugate(val)
除非有充分的理由,否则不要使用浮点数 - 使用 sym.I
而不是 1j
。使用 numpy 可能会引入浮点数,所以除非你知道自己在做什么,否则不要这样做。
虽然 eigenvals
returns 在这种情况下是一个字典,但你只关心字典的值,所以你可以只做 list(M.eigenvals())
.
虽然您将所有符号声明为真实的,但您使用的 sqrt(u)
只有在 u
为正时才是真实的。除非您打算 sqrt(u)
可能是虚构的,否则 u
应该声明为正值。
通过上述更改,您的代码如下所示:
import sympy as sym
from sympy import *
t = sym.Symbol('t', real=True)
r = sym.Symbol('r', real=True)
u = sym.Symbol('u', positive=True)
d = sym.Symbol('d', real=True)
a = sym.Symbol('a', real=True)
I = sym.eye(2)
T = sym.Matrix ([[t,0],[0,t]])
R = sym.Matrix ([[r,0],[0,r]])
F = sym.Matrix ([[sym.sqrt(u)*sym.exp(-sym.I*d),0],[0,sym.sqrt(u)*sym.exp(-sym.I*d)]])
sym.init_printing()
M = (I - F @ R @ F @ R)
M_inv = M.inv()
Mf = T @ M_inv @ F @ T
Mf = sym.simplify(Mf)
[eig] = Mf.eigenvals()
expr = eig * sym.conjugate(eig)
现在最终的表达式 expr
是这样的:
In [8]: expr
Out[8]:
4
t ⋅u
────────────────────────────────
⎛ 2 -2⋅ⅈ⋅d⎞ ⎛ 2 2⋅ⅈ⋅d⎞
⎝r ⋅u - ℯ ⎠⋅⎝r ⋅u - ℯ ⎠
In [9]: expr.expand()
Out[9]:
4
t ⋅u
──────────────────────────────────────
4 2 2 2⋅ⅈ⋅d 2 -2⋅ⅈ⋅d
r ⋅u - r ⋅u⋅ℯ - r ⋅u⋅ℯ + 1
In [10]: expr.expand().rewrite(sin)
Out[10]:
4
t ⋅u
────────────────────────────────────────────────────────────────────────
4 2 2 2
r ⋅u - r ⋅u⋅(-ⅈ⋅sin(2⋅d) + cos(2⋅d)) - r ⋅u⋅(ⅈ⋅sin(2⋅d) + cos(2⋅d)) + 1
In [11]: expr.expand().rewrite(sin).expand()
Out[11]:
4
t ⋅u
───────────────────────────
4 2 2
r ⋅u - 2⋅r ⋅u⋅cos(2⋅d) + 1
我想最后的结果就是你想要的。
虽然我的问题与具体问题有关,但我想用更笼统的术语来处理它。 我想简化通过使用 sympy 包乘以符号矩阵获得的分数复数表达式。 我得到的是一个带有实参数和许多复指数项(相位项)的分数,如 exp(-jd)、exp(-2jd) 和 exp(-4j*d ).我得到了正确的结果,但是当我尝试计算 ||**2,这是一个实数表达式时,sympy.simplify() 无法管理相位项,我得到了一个巨大的表达式,我必须减少用手。 我的测试程序是 T、M、M_inv、F 和 T,2x2 符号矩阵是:
import simply as sym
Mf = T @ M_inv @ F @ T
Mf = sym.simplify(Mf)
eig = Mf.eigenvals()
for key,value in eig.items():
val = key
eig_cc = np.conj(val)
final = sym.simplify(val*eig_cc)
我想知道是否存在改进计算的特定工具。
经过快速研究,我在 post 中发现了两种可能性:
a.trigsimp() 对于 expr.rewrite(cos).expand().as_real_imag()
expr.rewrite(cos).simplify().trigsimp()
虽然第一个为更简单的表达式提供了正确的结果(不是我试图解决的那个),但其中 none 对我有效。
第二个问题,eig 输出有一个字典形状,所以取值我使用了 for 循环。
for key,value in eig.items():
val = key
是否有更好、更快的方法来达到相同的结果?
我使用的代码是:
import numpy as np
import sympy as sym
from sympy import *
t = sym.Symbol('t', real=True)
r = sym.Symbol('r', real=True)
u = sym.Symbol('u', real=True)
d = sym.Symbol('d', real=True)
a = sym.Symbol('a', real=True)
I = np.identity(2)
T = sym.Matrix ([[t,0],[0,t]])
R = sym.Matrix ([[r,0],[0,r]])
F = sym.Matrix ([[sym.sqrt(u)*sym.exp(-1j*d),0],[0,sym.sqrt(u)*sym.exp(-1j*d)]])
sym.init_printing()
M = (I - F @ R @ F @ R)
M_inv = M.inv()
Mf = T @ M_inv @ F @ T
Mf = sym.simplify(Mf)
eig = Mf.eigenvals()
for key,value in eig.items():
val = key
eig_cc = np.conj(val)
expr = finale = sym.simplify(val*eig_cc)
"""
Test1
"""
result = [a.trigsimp() for a in expr.rewrite(sin).expand().as_real_imag()]
"""
Test2
"""
result1 = expr.rewrite(sin).simplify().trigsimp()
提前致谢
几点:
除非您确切地知道自己在做什么,否则不要像这样混淆 numpy 和 sympy。这里根本不需要使用 numpy,所以使用例如
sym.eye(2)
和sym.conjugate(val)
除非有充分的理由,否则不要使用浮点数 - 使用
sym.I
而不是1j
。使用 numpy 可能会引入浮点数,所以除非你知道自己在做什么,否则不要这样做。虽然
eigenvals
returns 在这种情况下是一个字典,但你只关心字典的值,所以你可以只做list(M.eigenvals())
.虽然您将所有符号声明为真实的,但您使用的
sqrt(u)
只有在u
为正时才是真实的。除非您打算sqrt(u)
可能是虚构的,否则u
应该声明为正值。
通过上述更改,您的代码如下所示:
import sympy as sym
from sympy import *
t = sym.Symbol('t', real=True)
r = sym.Symbol('r', real=True)
u = sym.Symbol('u', positive=True)
d = sym.Symbol('d', real=True)
a = sym.Symbol('a', real=True)
I = sym.eye(2)
T = sym.Matrix ([[t,0],[0,t]])
R = sym.Matrix ([[r,0],[0,r]])
F = sym.Matrix ([[sym.sqrt(u)*sym.exp(-sym.I*d),0],[0,sym.sqrt(u)*sym.exp(-sym.I*d)]])
sym.init_printing()
M = (I - F @ R @ F @ R)
M_inv = M.inv()
Mf = T @ M_inv @ F @ T
Mf = sym.simplify(Mf)
[eig] = Mf.eigenvals()
expr = eig * sym.conjugate(eig)
现在最终的表达式 expr
是这样的:
In [8]: expr
Out[8]:
4
t ⋅u
────────────────────────────────
⎛ 2 -2⋅ⅈ⋅d⎞ ⎛ 2 2⋅ⅈ⋅d⎞
⎝r ⋅u - ℯ ⎠⋅⎝r ⋅u - ℯ ⎠
In [9]: expr.expand()
Out[9]:
4
t ⋅u
──────────────────────────────────────
4 2 2 2⋅ⅈ⋅d 2 -2⋅ⅈ⋅d
r ⋅u - r ⋅u⋅ℯ - r ⋅u⋅ℯ + 1
In [10]: expr.expand().rewrite(sin)
Out[10]:
4
t ⋅u
────────────────────────────────────────────────────────────────────────
4 2 2 2
r ⋅u - r ⋅u⋅(-ⅈ⋅sin(2⋅d) + cos(2⋅d)) - r ⋅u⋅(ⅈ⋅sin(2⋅d) + cos(2⋅d)) + 1
In [11]: expr.expand().rewrite(sin).expand()
Out[11]:
4
t ⋅u
───────────────────────────
4 2 2
r ⋅u - 2⋅r ⋅u⋅cos(2⋅d) + 1
我想最后的结果就是你想要的。