Sympy: Как получить упрощенные коммутаторы с помощью модуля второго квантования?

Поэтому я хочу использовать тот факт, что [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 было заменено. Кто-нибудь знает, как это сделать? Или может кто-нибудь указать мне на другой инструмент, способный это сделать?

1 ответ

Ключевой трюк состоит в том, чтобы всегда использовать коммутационное отношение для перемещения "a" или "a^\dagger" влево до тех пор, пока вы больше не сможете этого сделать.

У меня нет хорошего ответа Sympy, но, поскольку вы спросили о других инструментах, вот бесстыдный плагин о том, как вы это делаете в Cadabra ( https://cadabra.science/) (который использует Sympy для разных вещей, но не в этом конкретном вычисление). Сначала настройте два набора операторов создания / уничтожения, используя:

{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'.

Другие вопросы по тегам