Sympy:如何使用第二个量化模块获得简化的换向器?
Sympy: How to get simplified commutators using the second quantization module?
所以我想利用 [b,bd]=1 的事实,其中 [] 是换向器,使用 sympy 获得一些更复杂表达式的换向器,而不是手动完成,但是我得到包含换向器但未替换为 1 的巨大表达式,这是代码
from sympy import *
from sympy.physics.secondquant import *
comm1=simplify(Commutator(B(0),Bd(0)).doit())
comm1
这种情况下的输出是 1 ,它对应于 [b,bd]=1 的情况,但是如果我输入更复杂的表达式,例如
w1,w2,g=symbols('w1 w1 g')
H=w1*B(0)*Bd(0)+w2*B(1)*Bd(1)+g*Bd(0)*B(1)+conjugate(g)*Bd(1)*B(0)
comm2=simplify(Commutator(H,B(0)))
print(simplify(comm2))
我明白了
-g*(AnnihilateBoson(0)*CreateBoson(0)*AnnihilateBoson(1) - CreateBoson(0)*AnnihilateBoson(1)*AnnihilateBoson(0)) - w1*(AnnihilateBoson(0)*AnnihilateBoson(1)*CreateBoson(1) - AnnihilateBoson(1)*CreateBoson(1)*AnnihilateBoson(0)) + w1*(AnnihilateBoson(0)*CreateBoson(0)*AnnihilateBoson(0) - AnnihilateBoson(0)**2*CreateBoson(0)) - conjugate(g)*(AnnihilateBoson(0)*CreateBoson(1)*AnnihilateBoson(0) - CreateBoson(1)*AnnihilateBoson(0)**2)
如果 [b,bd]=1 被替换,这显然会简化很多,有人知道怎么做吗?或者谁能告诉我另一个能够做到这一点的工具?
关键技巧始终是使用换向关系将 'a' 或 'a^\dagger' 向左移动,直到你不能再这样做为止。
我没有一个好的 Sympy 答案,但既然你问过其他工具,这里有一个关于你如何在 Cadabra (https://cadabra.science) 中做到这一点的无耻插件(尽管它使用 Sympy 做各种事情)不是这个特定的计算)。首先设置两组 creation/annihilation 运算符使用:
{a_{0}, ad_{0}}::NonCommuting;
{a_{1}, ad_{1}}::NonCommuting;
{a_{0}, ad_{0}, a_{1}, ad_{1}}::SortOrder.
他们会打印得更好
\bar{#}::Accent;
ad_{n?}::LaTeXForm("a^\dagger",n?,"").
你的哈密顿量:
H:= w_{1} a_{0} ad_{0} + w_{2} a_{1} ad_{1} + g ad_{0} a_{1} + \bar{g} ad_{1} a_{1};
您要计算的换向器:
ex:= @(H) a_{0} - a_{0} @(H);
只是扩展这个(没有使用 [a,ad]=1 换向器进行简化)
distribute(ex);
sort_product(ex);
第二行将具有不同下标的运算符相互移动,但保持具有相同下标的运算符的顺序。应用换向器直到表达式不再改变:
converge(ex):
substitute(ex, $a_{n?} ad_{n?} = ad_{n?} a_{n?} + 1$)
distribute(ex)
;
最后给'-a_0 w_1 - a_1 g'.
所以我想利用 [b,bd]=1 的事实,其中 [] 是换向器,使用 sympy 获得一些更复杂表达式的换向器,而不是手动完成,但是我得到包含换向器但未替换为 1 的巨大表达式,这是代码
from sympy import *
from sympy.physics.secondquant import *
comm1=simplify(Commutator(B(0),Bd(0)).doit())
comm1
这种情况下的输出是 1 ,它对应于 [b,bd]=1 的情况,但是如果我输入更复杂的表达式,例如
w1,w2,g=symbols('w1 w1 g')
H=w1*B(0)*Bd(0)+w2*B(1)*Bd(1)+g*Bd(0)*B(1)+conjugate(g)*Bd(1)*B(0)
comm2=simplify(Commutator(H,B(0)))
print(simplify(comm2))
我明白了
-g*(AnnihilateBoson(0)*CreateBoson(0)*AnnihilateBoson(1) - CreateBoson(0)*AnnihilateBoson(1)*AnnihilateBoson(0)) - w1*(AnnihilateBoson(0)*AnnihilateBoson(1)*CreateBoson(1) - AnnihilateBoson(1)*CreateBoson(1)*AnnihilateBoson(0)) + w1*(AnnihilateBoson(0)*CreateBoson(0)*AnnihilateBoson(0) - AnnihilateBoson(0)**2*CreateBoson(0)) - conjugate(g)*(AnnihilateBoson(0)*CreateBoson(1)*AnnihilateBoson(0) - CreateBoson(1)*AnnihilateBoson(0)**2)
如果 [b,bd]=1 被替换,这显然会简化很多,有人知道怎么做吗?或者谁能告诉我另一个能够做到这一点的工具?
关键技巧始终是使用换向关系将 'a' 或 'a^\dagger' 向左移动,直到你不能再这样做为止。
我没有一个好的 Sympy 答案,但既然你问过其他工具,这里有一个关于你如何在 Cadabra (https://cadabra.science) 中做到这一点的无耻插件(尽管它使用 Sympy 做各种事情)不是这个特定的计算)。首先设置两组 creation/annihilation 运算符使用:
{a_{0}, ad_{0}}::NonCommuting;
{a_{1}, ad_{1}}::NonCommuting;
{a_{0}, ad_{0}, a_{1}, ad_{1}}::SortOrder.
他们会打印得更好
\bar{#}::Accent;
ad_{n?}::LaTeXForm("a^\dagger",n?,"").
你的哈密顿量:
H:= w_{1} a_{0} ad_{0} + w_{2} a_{1} ad_{1} + g ad_{0} a_{1} + \bar{g} ad_{1} a_{1};
您要计算的换向器:
ex:= @(H) a_{0} - a_{0} @(H);
只是扩展这个(没有使用 [a,ad]=1 换向器进行简化)
distribute(ex);
sort_product(ex);
第二行将具有不同下标的运算符相互移动,但保持具有相同下标的运算符的顺序。应用换向器直到表达式不再改变:
converge(ex):
substitute(ex, $a_{n?} ad_{n?} = ad_{n?} a_{n?} + 1$)
distribute(ex)
;
最后给'-a_0 w_1 - a_1 g'.