如何解决符号复杂表达式简化
虽然我的问题与特定问题有关,但我想用更一般的术语来解决它。 我想简化通过使用 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)
我想知道是否存在改进计算的特定工具。
经过快速研究,我在帖子中发现了两种可能性:
Exponential to trigonometric conversion in SymPy while simplifying - a stubborn expression
-
a.trigsimp() for a in expr.rewrite(cos).expand().as_real_imag()
-
expr.rewrite(cos).simplify().trigsimp()
虽然第一个为更简单的表达式提供了正确的结果(不是我想要解决的那个),但在我的情况下它们都不起作用。
第二个问题,eig 输出有一个 dict 形状,所以为了取值,我使用了 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,r]])
F = sym.Matrix ([[sym.sqrt(u)*sym.exp(-1j*d),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
返回一个 dict,但您只关心 dict 的值,因此您可以只执行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,r]])
F = sym.Matrix ([[sym.sqrt(u)*sym.exp(-sym.I*d),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
我想最终的结果就是你想要的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。