Упростить квантовое выражение с помощью sympy.physics.quantum

С python sympy:

from sympy import sqrt
from sympy.physics.quantum import Bra,Ket,qapply
superpos = (Ket('Dead')+Ket('Alive'))/sqrt(2)
d = qapply(Bra('Dead')*superpos)

Он дает:

sqrt(2)*<Dead|Alive>/2 + sqrt(2)*<Dead|Dead>/2

Как установить "Dead" и "Alive" в качестве ортогональных состояний, так что d.doit() дает:

sqrt(2)/2

(Я мог только сделать:

d.subs(Bra('Dead')*Ket('Dead'),1).subs(Bra('Dead')*Ket('Alive'),0)

но я уверен, что есть лучший способ)

Ответ 1

Ваша проблема в том, что InnerProduct не знает, как оценить эти значения, и поэтому оставляет вместо этого несимметричное выражение. Глядя на source, я вижу, что он пытается вызвать _eval_innerproduct() в Ket, который говорит об этом.

def _eval_innerproduct(self, bra, **hints):
    """Evaluate the inner product betweeen this ket and a bra.

    This is called to compute <bra|ket>, where the ket is ``self``.

    This method will dispatch to sub-methods having the format::

        ``def _eval_innerproduct_BraClass(self, **hints):``

    Subclasses should define these methods (one for each BraClass) to
    teach the ket how to take inner products with bras.
    """

Следовательно, вы должны решить свою проблему, создав 2 новых класса Bra и новый класс Ket, который реализует 2 метода - один для оценки каждого из внутренних продуктов (с использованием соглашения об именах, указанного выше).

Для полноты вы, вероятно, также хотите реализовать другой Ket для вашего ортогонального состояния и убедиться, что dual_class возвращает правильный класс в каждом случае.

Ответ 2

Это не совсем то, что вы ищете, но вы можете использовать Qubit для создания ортогональных состояний.

from sympy import sqrt
from sympy.physics.quantum import Dagger, qapply
from sympy.physics.quantum.qubit import Qubit

dead = Qubit(0)
alive = Qubit(1)

Создайте Ket(0) и Ket(1). Чтобы сделать бюстгальтер, вы можете использовать функцию Dagger.

print(Dagger(dead) * dead)
<0|0>

При применении к вашей проблеме:

superpos = (dead + alive) / sqrt(2)
d = qapply(Dagger(dead) * superpos)

print(d)
sqrt(2)/2

Ответ 3

Может быть, expression.xreplace() - это то, что вы ищете? Согласно этой книге, функция xreplace может принимать словарь, где символьные символы или выражения являются хешируемыми ключами. Это все равно будет неуклюже:

from sympy import sqrt
from sympy.physics.quantum import Bra,Ket,qapply
superpos = (Ket('Dead')+Ket('Alive'))/sqrt(2)
d = qapply(Bra('Dead')*superpos)

mySubs = {Bra('Dead')*Ket('Dead'): 1,  Bra('Dead')*Ket('Alive'): 0} ##plus other bindings
d.xreplace(mySubs)

(осторожно: еще не проверил это...)

Это по крайней мере дает вам возможность определить все нужные замены в одном месте и "повторно использовать" их там, где вам нравится.

Ответ 4

Ответ в пространстве Fock:

>>> from sympy import sqrt
>>> from sympy.physics.quantum import Dagger,qapply
>>> from sympy.physics.quantum.boson import BosonFockKet
>>> ket_Dead = BosonFockKet(0)
>>> ket_Alive = BosonFockKet(1)
>>> superpos = (ket_Dead+ket_Alive)/sqrt(2)
>>> bra_Dead = Dagger(ket_Dead)
>>> qapply(bra_Dead*superpos).doit()
sqrt(2)/2

То же самое возможно в гильбертовом пространстве?