15

在 sympy 中,我定义了两个 kets 和一个相应的胸罩,当我将胸罩应用于 kets 时......

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)

但是我如何让刹车自动评估呢?为什么InnerProduct相同刹车的结果不是 1,而具有不同标签的刹车的结果不是 0?

4

5 回答 5

3

您的问题是InnerProduct不知道如何评估这些值,因此留下了未简化的表达式。查看源代码,我看到它试图调用,它说明_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在每种情况下都返回正确的类。

于 2017-04-13T00:27:46.127 回答
1

正如彼得在他的回答中指出的那样,您需要自己实现一个新的 Bra and Ket 类。这是您可以使用的正交状态的一个很好的通用实现。

示例用法:

>>> OrthogonalBra(n)*OrthogonalKet(n)
1
>>> OrthogonalBra(n)*OrthogonalKet(n+1)
0
>>> OrthogonalBra(n)*OrthogonalKet(m)
<n|m>

执行:

class OrthogonalKet(Ket):

    @classmethod
    def dual_class(self):
        return OrthogonalBra

    def _eval_innerproduct(self, bra, **hints):

        if len(self.args) != len(bra.args):
            raise ValueError('Cannot multiply a ket that has a different number of labels.')

        for i in range(len(self.args)):
            diff = self.args[i] - bra.args[i]
            diff.simplify()

            if diff.is_nonzero:
                return 0

            if not diff.is_zero:
                return None

        return 1


class OrthogonalBra(Bra):

    @classmethod
    def dual_class(self):
        return OrthogonalKet

于 2019-12-30T19:44:44.883 回答
0

福克空间的答案:

>>> 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

在希尔伯特空间中是否可能发生同样的事情?

于 2017-04-12T07:49:25.147 回答
0

也许expression.xreplace()是你正在寻找的?根据这本书,该xreplace函数可以采用一个字典,其中 sympy-symbols 或表达式是可散列的键。这仍然会像这样笨重:

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)

(注意:尚未测试...)

这至少使您可以选择在一个地方定义所有所需的替换,并在您喜欢的任何地方“重用”它们。

于 2017-04-11T09:00:59.053 回答
0

这并不是您要寻找的,但您可以使用它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
于 2017-04-06T19:58:33.050 回答