用sympy.physics.quantum

时间:2017-02-23 18:10:07

标签: python sympy states orthogonal

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

如何设置&#39; Dead&#39;并且&#39; Alive&#39;作为正交状态,因此 d.doit()给出:

sqrt(2)/2

(我只能这样做:

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

但我确信有更好的方法)

5 个答案:

答案 0 :(得分:2)

您的问题是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类和一个实现2个方法的新Ket类来解决您的问题 - 一个用于评估每个内部产品(使用命名约定)上文)。

为了完整性,您可能还希望为正交状态实现其他Ket,并确保dual_class在每种情况下都返回正确的类。

答案 1 :(得分: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

答案 2 :(得分:0)

也许expression.xreplace()正是您要找的?根据{{​​3}},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)

(警告:尚未测试......)

这至少为您提供了在一个地方定义所有所需替换的选项,并且&#34;重用&#34;他们喜欢的地方。

答案 3 :(得分:0)

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

希尔伯特空间是否可以做同样的事情?

答案 4 :(得分:0)

正如Peter在回答中指出的那样,您需要自己实现一个新的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