【问题标题】:Why does sympy think that a function of only real variables is complex?为什么 sympy 认为只有实变量的函数很复杂?
【发布时间】:2015-11-25 18:21:29
【问题描述】:

我一直在努力为我简化这个复杂的代数表达式:

其中 Delta、Gamma、t 和 hbar 是实数。我用来生成这个表达式的代码是:

from __future__ import division
from pylab import *
from sympy import *

def main():
    d, g, t = symbols("Delta Gamma t", real=True)
    hbar = symbols("hbar", positive=True, real=True)
    dg = sqrt(d**2 + g**2)
    S = simplify(Matrix([[(dg - g) / d, -(g + dg)/d], [1, 1]]))
    D = simplify(Matrix([[exp(I * t * dg / hbar), 0], [0, exp(-I * t * dg / hbar)]]))
    Sinverse = simplify(Matrix([[d / (2*dg), (g / dg + 1)/2], [-d / (2 * dg), 1/2 - g / (2*dg)]]))
    U = simplify(S * D * Sinverse)
    initial = Matrix([[1], [0]])
    later = simplify(U * initial)
    P1 = simplify(abs(later[0])**2)
    preview(P1)

if __name__=="__main__":
    main()

由于我不明白的原因,sympy 拒绝承认相位的大小为 1(即我们可以消除绝对值符号内表达式最右侧的乘法指数)。如果我们有一个非常简单的绝对值符号指数,我测试了 sympy 是否会简化这种情况。好像没有:

>>> from pylab import *
>>> from sympy import *
>>> t = symbols("t", real=True)
>>> z = exp(t*I)
>>> abs(z).simplify()
Abs(exp(I*t))

针对这个问题我尝试了两种补救措施,但都没有奏效:


(1) 将绝对值符号的平方替换为参数乘以参数的复共轭。当我将main() 函数的末尾更改为:

    ...
    P1 = simplify(later[0] * later[0].conjugate())
    preview(P1)

我得到了更丑陋的表达:

这确实解决了上述虚构的场景:

>>> from pylab import *
>>> from sympy import *
>>> t = symbols("t", real=True)
>>> z = exp(t*I)
>>> abs(z).simplify()
Abs(exp(I*t))
>>> z * z.conjugate()
1

(2) 用关键字complex=True展开量级,然后化简。这种方法也解决了虚构的场景:

>>> from pylab import *
>>> from sympy import *
>>> t = symbols("t", real=True)
>>> z = exp(t*I)
>>> abs(z).simplify()
Abs(exp(I*t))
>>> abs(z).expand(complex=True).simplify()
1

但是,对于我的实际表达,它可笑地失败了。当我调整我的 main() 函数以使用此方法时:

    ...
    P1 = (abs(later[0])**2).expand(complex=True).simplify()
    preview(P1)

程序崩溃。当我取下.simplify() 并将preview 更改为print 时,我得到了613.8 kB 的文本输出!查看输出文件的第一页和最后一页,它实际上似乎是一个非常巨大的表达式(即,我不认为这是一些愚蠢的长错误消息或类似的东西)。难怪当我试图简化它时程序崩溃了:)


我不知道第二种方法出了什么问题,但是看看第一种方法的输出,sympy 似乎没有意识到实变量平方和的平方根也是实数。我应该怎么做才能解决这个问题?我需要将一些参数传递给某个函数来告诉它 Gamma 和 Delta 的平方和的平方根是实数吗?
任何帮助将不胜感激!

【问题讨论】:

  • 你用的是什么版本的sympy?
  • @thisch 版本 0.7.4.1,根据pip list | grep sympy 命令。

标签: python sympy


【解决方案1】:

看起来 SymPy 的开发版本(即将发布为 1.0)可以做这种简化:

In [1]: t = Symbol('t', real=True)

In [2]: abs(exp(-t*I))
Out[2]: 1

对于你的例子,我得到了

In [13]: P1
Out[13]:
                                                            2
 │                                                _________│
 │                                               ╱  2    2 │
 │                                       2⋅ⅈ⋅t⋅╲╱  Δ  + Γ  │
 │       _________   ⎛       _________⎞  ──────────────────│
 │      ╱  2    2    ⎜      ╱  2    2 ⎟          h̅        │
-│Γ + ╲╱  Δ  + Γ   - ⎝Γ - ╲╱  Δ  + Γ  ⎠⋅ℯ                  │
──────────────────────────────────────────────────────────────
                            2      2
                         4⋅Δ  + 4⋅Γ

但是我检查了最新的稳定版本(0.7.6.1)并没有这样做,所以你要么需要等待 1.0 要么使用git version

【讨论】:

  • 刚刚遇到这个答案并想说 --- 感谢您的回答,也感谢您的答案和代码的许可许可!我也在没有 SA 的情况下获得许可,当我看到其他人也这样做时,我感到很受鼓舞。快乐的黑客攻击!
猜你喜欢
  • 1970-01-01
  • 2013-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多