Beispiel #1
0
def test_fidelity():
    #test with kets
    up = JzKet(S(1) / 2, S(1) / 2)
    down = JzKet(S(1) / 2, -S(1) / 2)
    updown = (S(1) / sqrt(2)) * up + (S(1) / sqrt(2)) * down

    #check with matrices
    up_dm = represent(up * Dagger(up))
    down_dm = represent(down * Dagger(down))
    updown_dm = represent(updown * Dagger(updown))

    assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
    assert fidelity(up_dm, down_dm) < 1e-3
    assert abs(fidelity(up_dm, updown_dm) - (S(1) / sqrt(2))) < 1e-3
    assert abs(fidelity(updown_dm, down_dm) - (S(1) / sqrt(2))) < 1e-3

    #check with density
    up_dm = Density([up, 1.0])
    down_dm = Density([down, 1.0])
    updown_dm = Density([updown, 1.0])

    assert abs(fidelity(up_dm, up_dm) - 1) < 1e-3
    assert abs(fidelity(up_dm, down_dm)) < 1e-3
    assert abs(fidelity(up_dm, updown_dm) - (S(1) / sqrt(2))) < 1e-3
    assert abs(fidelity(updown_dm, down_dm) - (S(1) / sqrt(2))) < 1e-3

    #check mixed states with density
    updown2 = (sqrt(3) / 2) * up + (S(1) / 2) * down
    d1 = Density([updown, 0.25], [updown2, 0.75])
    d2 = Density([updown, 0.75], [updown2, 0.25])
    assert abs(fidelity(d1, d2) - 0.991) < 1e-3
    assert abs(fidelity(d2, d1) - fidelity(d1, d2)) < 1e-3

    #using qubits/density(pure states)
    state1 = Qubit('0')
    state2 = Qubit('1')
    state3 = (S(1) / sqrt(2)) * state1 + (S(1) / sqrt(2)) * state2
    state4 = (sqrt(S(2) / 3)) * state1 + (S(1) / sqrt(3)) * state2

    state1_dm = Density([state1, 1])
    state2_dm = Density([state2, 1])
    state3_dm = Density([state3, 1])

    assert fidelity(state1_dm, state1_dm) == 1
    assert fidelity(state1_dm, state2_dm) == 0
    assert abs(fidelity(state1_dm, state3_dm) - 1 / sqrt(2)) < 1e-3
    assert abs(fidelity(state3_dm, state2_dm) - 1 / sqrt(2)) < 1e-3

    #using qubits/density(mixed states)
    d1 = Density([state3, 0.70], [state4, 0.30])
    d2 = Density([state3, 0.20], [state4, 0.80])
    assert abs(fidelity(d1, d1) - 1) < 1e-3
    assert abs(fidelity(d1, d2) - 0.996) < 1e-3
    assert abs(fidelity(d1, d2) - fidelity(d2, d1)) < 1e-3

    #TODO: test for invalid arguments
    # non-square matrix
    mat1 = [[0, 0], [0, 0], [0, 0]]

    mat2 = [[0, 0], [0, 0]]
    raises(ValueError, lambda: fidelity(mat1, mat2))

    # unequal dimensions
    mat1 = [[0, 0], [0, 0]]
    mat2 = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    raises(ValueError, lambda: fidelity(mat1, mat2))

    # unsupported data-type
    x, y = 1, 2  #random values that is not a matrix
    raises(ValueError, lambda: fidelity(x, y))
Beispiel #2
0
 def _eval_adjoint(self):
     return OuterProduct(Dagger(self.bra), Dagger(self.ket))
Beispiel #3
0
 elif isinstance(expr, Add):
     result = represent(expr.args[0], **options)
     for args in expr.args[1:]:
         # scipy.sparse doesn't support += so we use plain = here.
         result = result + represent(args, **options)
     return result
 elif isinstance(expr, Pow):
     base, exp = expr.as_base_exp()
     if format == 'numpy' or format == 'scipy.sparse':
         exp = _sympy_to_scalar(exp)
     return represent(base, **options)**exp
 elif isinstance(expr, TensorProduct):
     new_args = [represent(arg, **options) for arg in expr.args]
     return TensorProduct(*new_args)
 elif isinstance(expr, Dagger):
     return Dagger(represent(expr.args[0], **options))
 elif isinstance(expr, Commutator):
     A = represent(expr.args[0], **options)
     B = represent(expr.args[1], **options)
     return A*B - B*A
 elif isinstance(expr, AntiCommutator):
     A = represent(expr.args[0], **options)
     B = represent(expr.args[1], **options)
     return A*B + B*A
 elif isinstance(expr, InnerProduct):
     return represent(Mul(expr.bra,expr.ket), **options)
 elif not (isinstance(expr, Mul) or isinstance(expr, OuterProduct)):
     # For numpy and scipy.sparse, we can only handle numerical prefactors.
     if format == 'numpy' or format == 'scipy.sparse':
         return _sympy_to_scalar(expr)
     return expr
Beispiel #4
0
class BOp(Operator):
    def _represent_default_basis(self, **options):
        return self._represent_AOp(None, **options)

    def _represent_AOp(self, basis, **options):
        return Bmat


k = AKet("a")
b = ABra("a")
A = AOp("A")
B = BOp("B")

_tests = [
    # Bra
    (b, Dagger(Avec)),
    (Dagger(b), Avec),
    # Ket
    (k, Avec),
    (Dagger(k), Dagger(Avec)),
    # Operator
    (A, Amat),
    (Dagger(A), Dagger(Amat)),
    # OuterProduct
    (OuterProduct(k, b), Avec * Avec.H),
    # TensorProduct
    (TensorProduct(A, B), matrix_tensor_product(Amat, Bmat)),
    # Pow
    (A ** 2, Amat ** 2),
    # Add/Mul
    (A * B + 2 * A, Amat * Bmat + 2 * Amat),
Beispiel #5
0
represent(q11)

# ### 任意の状態

# In[20]:

a, b = sympy.symbols('alpha, beta')
psi = a * q0 + b * q1
psi

# エルミート共役を取って内積を計算してみます。

# In[21]:

from sympy.physics.quantum.qapply import qapply
qapply(Dagger(psi) * psi)

# ## 量子ゲート
# まずは1量子ビットに対する演算子からです。
# 基本的には恒等演算子($I$)、パウリ演算子($X$,$Y$,$Z$)、重ね合わせ状態を作成するアダマール演算子($H$)、位相演算子($ST$,$T$)になります。実際にsympy上でどう定義されているのか見た方がわかりやすいです。

# In[22]:

from sympy.physics.quantum.gate import I, X, Y, Z, H, S, T

# In[23]:

print(type(I))
print(X)
print(Y)
print(Z)
Beispiel #6
0
 def _eval_adjoint(self):
     return TensorProduct(*[Dagger(i) for i in self.args])
Beispiel #7
0
def test_bfs_identity_search_xfail():
    s = PhaseGate(0)
    t = TGate(0)
    gate_list = [Dagger(s), t]
    id_set = {GateIdentity(Dagger(s), t, t)}
    assert bfs_identity_search(gate_list, 1, max_depth=3) == id_set
def test_eval_trace():
    # This test includes tests with dependencies between TensorProducts
    #and density operators. Since, the test is more to test the behavior of
    #TensorProducts it remains here

    A, B, C, D, E, F = symbols('A B C D E F', commutative=False)

    # Density with simple tensor products as args
    t = TensorProduct(A, B)
    d = Density([t, 1.0])
    tr = Tr(d)
    assert tr.doit() == 1.0 * Tr(A * Dagger(A)) * Tr(B * Dagger(B))

    ## partial trace with simple tensor products as args
    t = TensorProduct(A, B, C)
    d = Density([t, 1.0])
    tr = Tr(d, [1])
    assert tr.doit() == 1.0 * A * Dagger(A) * Tr(B * Dagger(B)) * C * Dagger(C)

    tr = Tr(d, [0, 2])
    assert tr.doit() == 1.0 * Tr(A * Dagger(A)) * B * Dagger(B) * Tr(
        C * Dagger(C))

    # Density with multiple Tensorproducts as states
    t2 = TensorProduct(A, B)
    t3 = TensorProduct(C, D)

    d = Density([t2, 0.5], [t3, 0.5])
    t = Tr(d)
    assert t.doit() == (0.5 * Tr(A * Dagger(A)) * Tr(B * Dagger(B)) +
                        0.5 * Tr(C * Dagger(C)) * Tr(D * Dagger(D)))

    t = Tr(d, [0])
    assert t.doit() == (0.5 * Tr(A * Dagger(A)) * B * Dagger(B) +
                        0.5 * Tr(C * Dagger(C)) * D * Dagger(D))

    #Density with mixed states
    d = Density([t2 + t3, 1.0])
    t = Tr(d)
    assert t.doit() == (1.0 * Tr(A * Dagger(A)) * Tr(B * Dagger(B)) +
                        1.0 * Tr(A * Dagger(C)) * Tr(B * Dagger(D)) +
                        1.0 * Tr(C * Dagger(A)) * Tr(D * Dagger(B)) +
                        1.0 * Tr(C * Dagger(C)) * Tr(D * Dagger(D)))

    t = Tr(d, [1])
    assert t.doit() == (1.0 * A * Dagger(A) * Tr(B * Dagger(B)) +
                        1.0 * A * Dagger(C) * Tr(B * Dagger(D)) +
                        1.0 * C * Dagger(A) * Tr(D * Dagger(B)) +
                        1.0 * C * Dagger(C) * Tr(D * Dagger(D)))
Beispiel #9
0
def test_operator_dagger():
    A = Operator('A')
    B = Operator('B')
    assert Dagger(A * B) == Dagger(B) * Dagger(A)
    assert Dagger(A + B) == Dagger(A) + Dagger(B)
    assert Dagger(A**2) == Dagger(A)**2
Beispiel #10
0
def fermionic_constraints(a):
    """Return  a set of constraints that define fermionic ladder operators.

    :param a: The non-Hermitian variables.
    :type a: list of :class:`sympy.physics.quantum.operator.Operator`.
    :returns: tuple of dict of substitutions and list of equalities and
              inequalities.
    """
    n_vars = len(a)
    monomial_substitutions = {}
    equalities = []
    inequalities = []
    for i in range(n_vars):
        for j in range(i + 1, n_vars):
            # {a_i,a_jT} = 0 for i\neq j
            # monomial_substitutions[Dagger(a[j]) * a[i]] = - a[i] *
            # Dagger(a[j])
            equalities.append(Dagger(a[j]) * a[i] + a[i] * Dagger(a[j]))
            # monomial_substitutions[a[j] * Dagger(a[i])] = - Dagger(a[i]) *
            # a[j]
            equalities.append(a[j] * Dagger(a[i]) + Dagger(a[i]) * a[j])
            # {a_i, a_j} = 0
            # monomial_substitutions[a[j] * a[i]] = - a[i] * a[j]
            equalities.append(a[j] * a[i] + a[i] * a[j])
            # {a_iT, a_jT} = 0
            # monomial_substitutions[Dagger(a[j]) * Dagger(a[i])] = -
            # Dagger(a[i]) * Dagger(a[j])
            equalities.append(
                Dagger(a[j]) * Dagger(a[i]) + Dagger(a[i]) * Dagger(a[j]))

    # {a_i,a_iT} = 1
    for i in range(n_vars):
        # monomial_substitutions[a[i] ** 2] = 0
        equalities.append(a[i]**2)
        # monomial_substitutions[Dagger(a[i]) ** 2] = 0
        equalities.append(Dagger(a[i])**2)
        equalities.append(a[i] * Dagger(a[i]) + Dagger(a[i]) * a[i] - 1.0)

    for i in range(n_vars):
        inequalities.append(Dagger(a[i]) * a[i])
        inequalities.append(1 - Dagger(a[i]) * a[i])
    return monomial_substitutions, equalities, inequalities
Beispiel #11
0
def test_printing():
    psi = Ket('psi')
    ip = Dagger(psi) * psi
    assert pretty(ip, use_unicode=True) == u'\u27e8\u03c8\u2758\u03c8\u27e9'
    assert latex(ip) == r"\left\langle \psi \right. {\left|\psi\right\rangle }"
 def _eval_conjugate(self):
     return InnerProduct(Dagger(self.ket), Dagger(self.bra))
Beispiel #13
0
def test_eval_adjoint():
    f = Foo()
    d = Dagger(f)
    assert d == I
Beispiel #14
0
def test_matrix():
    x = symbols('x')
    m = Matrix([[I, x * I], [2, 4]])
    assert Dagger(m) == m.H
Beispiel #15
0
def test_printing():
    psi = Ket('psi')
    assert pretty(psi, use_unicode=True) == u'\u2758\u03c8\u27e9'
    assert pretty(Dagger(psi), use_unicode=True) == u'\u27e8\u03c8\u2758'
    assert latex(psi) == r"{\left|\psi\right\rangle }"
    assert latex(Dagger(psi)) == r"{\left\langle \psi\right|}"
Beispiel #16
0
def test_tensor_product_dagger():
    assert Dagger(TensorProduct(I*A, B)) == \
        -I*TensorProduct(Dagger(A), Dagger(B))
    assert Dagger(TensorProduct(mat1, mat2)) == \
        TensorProduct(Dagger(mat1), Dagger(mat2))
def test_commutator_dagger():
    comm = Comm(A * B, C)
    assert Dagger(comm).expand(commutator=True) ==\
        - Comm(Dagger(B),Dagger(C))*Dagger(A) -\
        Dagger(B)*Comm(Dagger(A),Dagger(C))
Beispiel #18
0
 def _represent(self, **options):
     """A default represent that uses the Ket's version."""
     from sympy.physics.quantum.dagger import Dagger
     return Dagger(self.dual._represent(**options))
Beispiel #19
0
DeltaT = N * deltaT

# %%
T = diag(*Range(N))

# %%
T

# %%
F = DFT(N)

# %%
F.as_explicit()

# %%
Dagger(F).as_explicit()

# %%
Omega = (Dagger(F) @ T @ F).as_explicit()

# %%
Omega

# %%
T @ Omega - Omega @ T

# %% [markdown]
# Zero-valued diagonal, as argued in Weyl, H. (1950), "The theory of groups and quantum mechanics".
#
# The commutator is not a constant.
Beispiel #20
0
def qapply(e, **options):
    """Apply operators to states in a quantum expression.

    Parameters
    ==========

    e : Expr
        The expression containing operators and states. This expression tree
        will be walked to find operators acting on states symbolically.
    options : dict
        A dict of key/value pairs that determine how the operator actions
        are carried out.

        The following options are valid:

        * ``dagger``: try to apply Dagger operators to the left
          (default: False).
        * ``ip_doit``: call ``.doit()`` in inner products when they are
          encountered (default: True).

    Returns
    =======

    e : Expr
        The original expression, but with the operators applied to states.
    """
    from sympy.physics.quantum.density import Density

    dagger = options.get('dagger', False)

    if e == 0:
        return S.Zero

    # This may be a bit aggressive but ensures that everything gets expanded
    # to its simplest form before trying to apply operators. This includes
    # things like (A+B+C)*|a> and A*(|a>+|b>) and all Commutators and
    # TensorProducts. The only problem with this is that if we can't apply
    # all the Operators, we have just expanded everything.
    # TODO: don't expand the scalars in front of each Mul.
    e = e.expand(commutator=True, tensorproduct=True)

    # If we just have a raw ket, return it.
    if isinstance(e, KetBase):
        return e

    # We have an Add(a, b, c, ...) and compute
    # Add(qapply(a), qapply(b), ...)
    elif isinstance(e, Add):
        result = 0
        for arg in e.args:
            result += qapply(arg, **options)
        return result

    # For a Density operator call qapply on its state
    elif isinstance(e, Density):
        new_args = [(qapply(state, **options), prob) for (state,
                     prob) in e.args]
        return Density(*new_args)

    # For a raw TensorProduct, call qapply on its args.
    elif isinstance(e, TensorProduct):
        return TensorProduct(*[qapply(t, **options) for t in e.args])

    # For a Pow, call qapply on its base.
    elif isinstance(e, Pow):
        return qapply(e.base, **options)**e.exp

    # We have a Mul where there might be actual operators to apply to kets.
    elif isinstance(e, Mul):
        result = qapply_Mul(e, **options)
        if result == e and dagger:
            return Dagger(qapply_Mul(Dagger(e), **options))
        else:
            return result

    # In all other cases (State, Operator, Pow, Commutator, InnerProduct,
    # OuterProduct) we won't ever have operators to apply to kets.
    else:
        return e
Beispiel #21
0
 def _eval_dagger(self):
     return InnerProduct(Dagger(self.ket), Dagger(self.bra))
Beispiel #22
0
def represent(expr, **options):
    """Represent the quantum expression in the given basis.

    In quantum mechanics abstract states and operators can be represented in
    various basis sets. Under this operation the follow transforms happen:

    * Ket -> column vector or function
    * Bra -> row vector of function
    * Operator -> matrix or differential operator

    This function is the top-level interface for this action.

    This function walks the sympy expression tree looking for ``QExpr``
    instances that have a ``_represent`` method. This method is then called
    and the object is replaced by the representation returned by this method.
    By default, the ``_represent`` method will dispatch to other methods
    that handle the representation logic for a particular basis set. The
    naming convention for these methods is the following::

        def _represent_FooBasis(self, e, basis, **options)

    This function will have the logic for representing instances of its class
    in the basis set having a class named ``FooBasis``.

    Parameters
    ==========
    expr  : Expr
        The expression to represent.
    basis : Operator, basis set
        An object that contains the information about the basis set. If an
        operator is used, the basis is assumed to be the orthonormal
        eigenvectors of that operator. In general though, the basis argument
        can be any object that contains the basis set information.
    options : dict
        Key/value pairs of options that are passed to the underlying method
        that does finds the representation. These options can be used to
        control how the representation is done. For example, this is where
        the size of the basis set would be set.

    Returns
    =======
    e : Expr
        The sympy expression of the represented quantum expression.

    Examples
    ========

    Here we subclass ``Operator`` and ``Ket`` to create the z-spin operator
    and its spin 1/2 up eigenstate. By definining the ``_represent_SzOp``
    method, the ket can be represented in the z-spin basis.

        >>> from sympy.physics.quantum import Operator, represent, Ket
        >>> from sympy import Matrix

        >>> class SzUpKet(Ket):
        ...     def _represent_SzOp(self, basis, **options):
        ...         return Matrix([1,0])
        ...
        >>> class SzOp(Operator):
        ...     pass
        ...
        >>> sz = SzOp('Sz')
        >>> up = SzUpKet('up')
        >>> represent(up, basis=sz)
        [1]
        [0]
    """
    format = options.get('format', 'sympy')
    if isinstance(expr, QExpr):
        return expr._represent(**options)
    elif isinstance(expr, Add):
        result = represent(expr.args[0], **options)
        for args in expr.args[1:]:
            # scipy.sparse doesn't support += so we use plain = here.
            result = result + represent(args, **options)
        return result
    elif isinstance(expr, Pow):
        exp = expr.exp
        if format == 'numpy' or format == 'scipy.sparse':
            exp = _sympy_to_scalar(exp)
        return represent(expr.base, **options)**exp
    elif isinstance(expr, TensorProduct):
        new_args = [represent(arg, **options) for arg in expr.args]
        return TensorProduct(*new_args)
    elif isinstance(expr, Dagger):
        return Dagger(represent(expr.args[0], **options))
    elif isinstance(expr, Commutator):
        A = represent(expr.args[0], **options)
        B = represent(expr.args[1], **options)
        return A * B - B * A
    elif isinstance(expr, AntiCommutator):
        A = represent(expr.args[0], **options)
        B = represent(expr.args[1], **options)
        return A * B + B * A
    elif isinstance(expr, InnerProduct):
        return represent(Mul(expr.bra, expr.ket), **options)
    elif not isinstance(expr, Mul):
        # For numpy and scipy.sparse, we can only handle numerical prefactors.
        if format == 'numpy' or format == 'scipy.sparse':
            return _sympy_to_scalar(expr)
        return expr

    if not isinstance(expr, Mul):
        raise TypeError('Mul expected, got: %r' % expr)

    result = represent(expr.args[-1], **options)
    for arg in reversed(expr.args[:-1]):
        result = represent(arg, **options) * result
    # All three matrix formats create 1 by 1 matrices when inner products of
    # vectors are taken. In these cases, we simply return a scalar.
    result = flatten_scalar(result)
    return result
Beispiel #23
0
def test_innerproduct_dagger():
    k = Ket('k')
    b = Bra('b')
    ip = b*k
    assert Dagger(ip) == Dagger(k)*Dagger(b)
Beispiel #24
0
 def _eval_adjoint(self):
     return AntiCommutator(Dagger(self.args[0]), Dagger(self.args[1]))
Beispiel #25
0
def test_doit():
    f = FooKet('foo')
    b = BarBra('bar')
    assert InnerProduct(b, f).doit() == I
    assert InnerProduct(Dagger(f), Dagger(b)).doit() == -I
    assert InnerProduct(Dagger(f), f).doit() == Integer(1)
Beispiel #26
0
def represent(expr, **options):
    """Represent the quantum expression in the given basis.

    In quantum mechanics abstract states and operators can be represented in
    various basis sets. Under this operation the follow transforms happen:

    * Ket -> column vector or function
    * Bra -> row vector of function
    * Operator -> matrix or differential operator

    This function is the top-level interface for this action.

    This function walks the SymPy expression tree looking for ``QExpr``
    instances that have a ``_represent`` method. This method is then called
    and the object is replaced by the representation returned by this method.
    By default, the ``_represent`` method will dispatch to other methods
    that handle the representation logic for a particular basis set. The
    naming convention for these methods is the following::

        def _represent_FooBasis(self, e, basis, **options)

    This function will have the logic for representing instances of its class
    in the basis set having a class named ``FooBasis``.

    Parameters
    ==========

    expr  : Expr
        The expression to represent.
    basis : Operator, basis set
        An object that contains the information about the basis set. If an
        operator is used, the basis is assumed to be the orthonormal
        eigenvectors of that operator. In general though, the basis argument
        can be any object that contains the basis set information.
    options : dict
        Key/value pairs of options that are passed to the underlying method
        that finds the representation. These options can be used to
        control how the representation is done. For example, this is where
        the size of the basis set would be set.

    Returns
    =======

    e : Expr
        The SymPy expression of the represented quantum expression.

    Examples
    ========

    Here we subclass ``Operator`` and ``Ket`` to create the z-spin operator
    and its spin 1/2 up eigenstate. By defining the ``_represent_SzOp``
    method, the ket can be represented in the z-spin basis.

    >>> from sympy.physics.quantum import Operator, represent, Ket
    >>> from sympy import Matrix

    >>> class SzUpKet(Ket):
    ...     def _represent_SzOp(self, basis, **options):
    ...         return Matrix([1,0])
    ...
    >>> class SzOp(Operator):
    ...     pass
    ...
    >>> sz = SzOp('Sz')
    >>> up = SzUpKet('up')
    >>> represent(up, basis=sz)
    Matrix([
    [1],
    [0]])

    Here we see an example of representations in a continuous
    basis. We see that the result of representing various combinations
    of cartesian position operators and kets give us continuous
    expressions involving DiracDelta functions.

    >>> from sympy.physics.quantum.cartesian import XOp, XKet, XBra
    >>> X = XOp()
    >>> x = XKet()
    >>> y = XBra('y')
    >>> represent(X*x)
    x*DiracDelta(x - x_2)
    >>> represent(X*x*y)
    x*DiracDelta(x - x_3)*DiracDelta(x_1 - y)

    """

    format = options.get('format', 'sympy')
    if format == 'numpy':
        import numpy as np
    if isinstance(expr, QExpr) and not isinstance(expr, OuterProduct):
        options['replace_none'] = False
        temp_basis = get_basis(expr, **options)
        if temp_basis is not None:
            options['basis'] = temp_basis
        try:
            return expr._represent(**options)
        except NotImplementedError as strerr:
            #If no _represent_FOO method exists, map to the
            #appropriate basis state and try
            #the other methods of representation
            options['replace_none'] = True

            if isinstance(expr, (KetBase, BraBase)):
                try:
                    return rep_innerproduct(expr, **options)
                except NotImplementedError:
                    raise NotImplementedError(strerr)
            elif isinstance(expr, Operator):
                try:
                    return rep_expectation(expr, **options)
                except NotImplementedError:
                    raise NotImplementedError(strerr)
            else:
                raise NotImplementedError(strerr)
    elif isinstance(expr, Add):
        result = represent(expr.args[0], **options)
        for args in expr.args[1:]:
            # scipy.sparse doesn't support += so we use plain = here.
            result = result + represent(args, **options)
        return result
    elif isinstance(expr, Pow):
        base, exp = expr.as_base_exp()
        if format in ('numpy', 'scipy.sparse'):
            exp = _sympy_to_scalar(exp)
        base = represent(base, **options)
        # scipy.sparse doesn't support negative exponents
        # and warns when inverting a matrix in csr format.
        if format == 'scipy.sparse' and exp < 0:
            from scipy.sparse.linalg import inv
            exp = - exp
            base = inv(base.tocsc()).tocsr()
        if format == 'numpy':
            return np.linalg.matrix_power(base, exp)
        return base ** exp
    elif isinstance(expr, TensorProduct):
        new_args = [represent(arg, **options) for arg in expr.args]
        return TensorProduct(*new_args)
    elif isinstance(expr, Dagger):
        return Dagger(represent(expr.args[0], **options))
    elif isinstance(expr, Commutator):
        A = expr.args[0]
        B = expr.args[1]
        return represent(Mul(A, B) - Mul(B, A), **options)
    elif isinstance(expr, AntiCommutator):
        A = expr.args[0]
        B = expr.args[1]
        return represent(Mul(A, B) + Mul(B, A), **options)
    elif isinstance(expr, InnerProduct):
        return represent(Mul(expr.bra, expr.ket), **options)
    elif not isinstance(expr, (Mul, OuterProduct)):
        # For numpy and scipy.sparse, we can only handle numerical prefactors.
        if format in ('numpy', 'scipy.sparse'):
            return _sympy_to_scalar(expr)
        return expr

    if not isinstance(expr, (Mul, OuterProduct)):
        raise TypeError('Mul expected, got: %r' % expr)

    if "index" in options:
        options["index"] += 1
    else:
        options["index"] = 1

    if "unities" not in options:
        options["unities"] = []

    result = represent(expr.args[-1], **options)
    last_arg = expr.args[-1]

    for arg in reversed(expr.args[:-1]):
        if isinstance(last_arg, Operator):
            options["index"] += 1
            options["unities"].append(options["index"])
        elif isinstance(last_arg, BraBase) and isinstance(arg, KetBase):
            options["index"] += 1
        elif isinstance(last_arg, KetBase) and isinstance(arg, Operator):
            options["unities"].append(options["index"])
        elif isinstance(last_arg, KetBase) and isinstance(arg, BraBase):
            options["unities"].append(options["index"])

        next_arg = represent(arg, **options)
        if format == 'numpy' and isinstance(next_arg, np.ndarray):
            # Must use np.matmult to "matrix multiply" two np.ndarray
            result = np.matmul(next_arg, result)
        else:
            result = next_arg*result
        last_arg = arg

    # All three matrix formats create 1 by 1 matrices when inner products of
    # vectors are taken. In these cases, we simply return a scalar.
    result = flatten_scalar(result)

    result = integrate_result(expr, result, **options)

    return result
Beispiel #27
0
 def _eval_dagger(self):
     return Commutator(Dagger(self.args[1]), Dagger(self.args[0]))
Beispiel #28
0
def test_doit():

    x, y = symbols('x y')
    A, B, C, D, E, F = symbols('A B C D E F', commutative=False)
    d = Density([XKet(), 0.5], [PxKet(), 0.5])
    assert (0.5 * (PxKet() * Dagger(PxKet())) + 0.5 *
            (XKet() * Dagger(XKet()))) == d.doit()

    # check for kets with expr in them
    d_with_sym = Density([XKet(x * y), 0.5], [PxKet(x * y), 0.5])
    assert (0.5 * (PxKet(x * y) * Dagger(PxKet(x * y))) + 0.5 *
            (XKet(x * y) * Dagger(XKet(x * y)))) == d_with_sym.doit()

    d = Density([(A + B) * C, 1.0])
    assert d.doit() == (1.0 * A * C * Dagger(C) * Dagger(A) +
                        1.0 * A * C * Dagger(C) * Dagger(B) +
                        1.0 * B * C * Dagger(C) * Dagger(A) +
                        1.0 * B * C * Dagger(C) * Dagger(B))

    #  With TensorProducts as args

    # Density with simple tensor products as args
    t = TensorProduct(A, B, C)
    d = Density([t, 1.0])
    assert d.doit() == 1.0 * TensorProduct(A * Dagger(A), B * Dagger(B),
                                           C * Dagger(C))

    # Density with multiple Tensorproducts as states
    t2 = TensorProduct(A, B)
    t3 = TensorProduct(C, D)

    d = Density([t2, 0.5], [t3, 0.5])
    assert d.doit() == (0.5 * TensorProduct(A * Dagger(A), B * Dagger(B)) +
                        0.5 * TensorProduct(C * Dagger(C), D * Dagger(D)))

    #Density with mixed states
    d = Density([t2 + t3, 1.0])
    assert d.doit() == (1.0 * TensorProduct(A * Dagger(A), B * Dagger(B)) +
                        1.0 * TensorProduct(A * Dagger(C), B * Dagger(D)) +
                        1.0 * TensorProduct(C * Dagger(A), D * Dagger(B)) +
                        1.0 * TensorProduct(C * Dagger(C), D * Dagger(D)))

    #Density operators with spin states
    tp1 = TensorProduct(JzKet(1, 1), JzKet(1, -1))
    d = Density([tp1, 1])

    # full trace
    t = Tr(d)
    assert t.doit() == 1

    #Partial trace on density operators with spin states
    t = Tr(d, [0])
    assert t.doit() == JzKet(1, -1) * Dagger(JzKet(1, -1))
    t = Tr(d, [1])
    assert t.doit() == JzKet(1, 1) * Dagger(JzKet(1, 1))

    # with another spin state
    tp2 = TensorProduct(JzKet(S(1) / 2, S(1) / 2), JzKet(S(1) / 2, -S(1) / 2))
    d = Density([tp2, 1])

    #full trace
    t = Tr(d)
    assert t.doit() == 1

    #Partial trace on density operators with spin states
    t = Tr(d, [0])
    assert t.doit() == JzKet(S(1) / 2, -S(1) / 2) * Dagger(
        JzKet(S(1) / 2, -S(1) / 2))
    t = Tr(d, [1])
    assert t.doit() == JzKet(S(1) / 2,
                             S(1) / 2) * Dagger(JzKet(S(1) / 2,
                                                      S(1) / 2))
Beispiel #29
0
def test_big_expr():
    f = Function('f')
    x = symbols('x')
    e1 = Dagger(AntiCommutator(Operator('A') + Operator('B'), Pow(DifferentialOperator(Derivative(f(x), x), f(x)), 3))*TensorProduct(Jz**2, Operator('A') + Operator('B')))*(JzBra(1, 0) + JzBra(1, 1))*(JzKet(0, 0) + JzKet(1, -1))
    e2 = Commutator(Jz**2, Operator('A') + Operator('B'))*AntiCommutator(Dagger(Operator('C')*Operator('D')), Operator('E').inv()**2)*Dagger(Commutator(Jz, J2))
    e3 = Wigner3j(1, 2, 3, 4, 5, 6)*TensorProduct(Commutator(Operator('A') + Dagger(Operator('B')), Operator('C') + Operator('D')), Jz - J2)*Dagger(OuterProduct(Dagger(JzBra(1, 1)), JzBra(1, 0)))*TensorProduct(JzKetCoupled(1, 1, (1, 1)) + JzKetCoupled(1, 0, (1, 1)), JzKetCoupled(1, -1, (1, 1)))
    e4 = (ComplexSpace(1)*ComplexSpace(2) + FockSpace()**2)*(L2(Interval(
        0, oo)) + HilbertSpace())
    assert str(e1) == '(Jz**2)x(Dagger(A) + Dagger(B))*{Dagger(DifferentialOperator(Derivative(f(x), x),f(x)))**3,Dagger(A) + Dagger(B)}*(<1,0| + <1,1|)*(|0,0> + |1,-1>)'
    ascii_str = \
"""\
                 /                                      3        \\                                 \n\
                 |/                                   +\\         |                                 \n\
    2  / +    +\\ <|                    /d            \\ |   +    +>                                 \n\
/J \\ x \\A  + B /*||DifferentialOperator|--(f(x)),f(x)| | ,A  + B |*(<1,0| + <1,1|)*(|0,0> + |1,-1>)\n\
\\ z/             \\\\                    \\dx           / /         /                                 \
"""
    ucode_str = \
u("""\
                 ⎧                                      3        ⎫                                 \n\
                 ⎪⎛                                   †⎞         ⎪                                 \n\
    2  ⎛ †    †⎞ ⎨⎜                    ⎛d            ⎞ ⎟   †    †⎬                                 \n\
⎛J ⎞ ⨂ ⎝A  + B ⎠⋅⎪⎜DifferentialOperator⎜──(f(x)),f(x)⎟ ⎟ ,A  + B ⎪⋅(⟨1,0❘ + ⟨1,1❘)⋅(❘0,0⟩ + ❘1,-1⟩)\n\
⎝ z⎠             ⎩⎝                    ⎝dx           ⎠ ⎠         ⎭                                 \
""")
    assert pretty(e1) == ascii_str
    assert upretty(e1) == ucode_str
    assert latex(e1) == \
        r'{J_z^{2}}\otimes \left({A^{\dagger} + B^{\dagger}}\right) \left\{\left(DifferentialOperator\left(\frac{d}{d x} f{\left (x \right )},f{\left (x \right )}\right)^{\dagger}\right)^{3},A^{\dagger} + B^{\dagger}\right\} \left({\left\langle 1,0\right|} + {\left\langle 1,1\right|}\right) \left({\left|0,0\right\rangle } + {\left|1,-1\right\rangle }\right)'
    sT(e1, "Mul(TensorProduct(Pow(JzOp(Symbol('J')), Integer(2)), Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), AntiCommutator(Pow(Dagger(DifferentialOperator(Derivative(Function('f')(Symbol('x')), Symbol('x')),Function('f')(Symbol('x')))), Integer(3)),Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), Add(JzBra(Integer(1),Integer(0)), JzBra(Integer(1),Integer(1))), Add(JzKet(Integer(0),Integer(0)), JzKet(Integer(1),Integer(-1))))")
    assert str(e2) == '[Jz**2,A + B]*{E**(-2),Dagger(D)*Dagger(C)}*[J2,Jz]'
    ascii_str = \
"""\
[    2      ] / -2  +  +\\ [ 2   ]\n\
[/J \\ ,A + B]*<E  ,D *C >*[J ,J ]\n\
[\\ z/       ] \\         / [    z]\
"""
    ucode_str = \
u("""\
⎡    2      ⎤ ⎧ -2  †  †⎫ ⎡ 2   ⎤\n\
⎢⎛J ⎞ ,A + B⎥⋅⎨E  ,D ⋅C ⎬⋅⎢J ,J ⎥\n\
⎣⎝ z⎠       ⎦ ⎩         ⎭ ⎣    z⎦\
""")
    assert pretty(e2) == ascii_str
    assert upretty(e2) == ucode_str
    assert latex(e2) == \
        r'\left[J_z^{2},A + B\right] \left\{E^{-2},D^{\dagger} C^{\dagger}\right\} \left[J^2,J_z\right]'
    sT(e2, "Mul(Commutator(Pow(JzOp(Symbol('J')), Integer(2)),Add(Operator(Symbol('A')), Operator(Symbol('B')))), AntiCommutator(Pow(Operator(Symbol('E')), Integer(-2)),Mul(Dagger(Operator(Symbol('D'))), Dagger(Operator(Symbol('C'))))), Commutator(J2Op(Symbol('J')),JzOp(Symbol('J'))))")
    assert str(e3) == \
        "Wigner3j(1, 2, 3, 4, 5, 6)*[Dagger(B) + A,C + D]x(-J2 + Jz)*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x|1,-1,j1=1,j2=1>"
    ascii_str = \
"""\
          [ +          ]  /   2     \\                                                                 \n\
/1  3  5\\*[B  + A,C + D]x |- J  + J |*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x |1,-1,j1=1,j2=1>\n\
|       |                 \\        z/                                                                 \n\
\\2  4  6/                                                                                             \
"""
    ucode_str = \
u("""\
          ⎡ †          ⎤  ⎛   2     ⎞                                                                 \n\
⎛1  3  5⎞⋅⎣B  + A,C + D⎦⨂ ⎜- J  + J ⎟⋅❘1,0⟩⟨1,1❘⋅(❘1,0,j₁=1,j₂=1⟩ + ❘1,1,j₁=1,j₂=1⟩)⨂ ❘1,-1,j₁=1,j₂=1⟩\n\
⎜       ⎟                 ⎝        z⎠                                                                 \n\
⎝2  4  6⎠                                                                                             \
""")
    assert pretty(e3) == ascii_str
    assert upretty(e3) == ucode_str
    assert latex(e3) == \
        r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right) {\left[B^{\dagger} + A,C + D\right]}\otimes \left({- J^2 + J_z}\right) {\left|1,0\right\rangle }{\left\langle 1,1\right|} \left({{\left|1,0,j_{1}=1,j_{2}=1\right\rangle } + {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }}\right)\otimes {{\left|1,-1,j_{1}=1,j_{2}=1\right\rangle }}'
    sT(e3, "Mul(Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6)), TensorProduct(Commutator(Add(Dagger(Operator(Symbol('B'))), Operator(Symbol('A'))),Add(Operator(Symbol('C')), Operator(Symbol('D')))), Add(Mul(Integer(-1), J2Op(Symbol('J'))), JzOp(Symbol('J')))), OuterProduct(JzKet(Integer(1),Integer(0)),JzBra(Integer(1),Integer(1))), TensorProduct(Add(JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))), JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))), JzKetCoupled(Integer(1),Integer(-1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))))")
    assert str(e4) == '(C(1)*C(2)+F**2)*(L2(Interval(0, oo))+H)'
    ascii_str = \
"""\
// 1    2\\    x2\\   / 2    \\\n\
\\\\C  x C / + F  / x \\L  + H/\
"""
    ucode_str = \
u("""\
⎛⎛ 1    2⎞    ⨂2⎞   ⎛ 2    ⎞\n\
⎝⎝C  ⨂ C ⎠ ⊕ F  ⎠ ⨂ ⎝L  ⊕ H⎠\
""")
    assert pretty(e4) == ascii_str
    assert upretty(e4) == ucode_str
    assert latex(e4) == \
        r'\left(\left(\mathcal{C}^{1}\otimes \mathcal{C}^{2}\right)\oplus {\mathcal{F}}^{\otimes 2}\right)\otimes \left({\mathcal{L}^2}\left( \left[0, \infty\right) \right)\oplus \mathcal{H}\right)'
    sT(e4, "TensorProductHilbertSpace((DirectSumHilbertSpace(TensorProductHilbertSpace(ComplexSpace(Integer(1)),ComplexSpace(Integer(2))),TensorPowerHilbertSpace(FockSpace(),Integer(2)))),(DirectSumHilbertSpace(L2(Interval(Integer(0), oo, S.false, S.true)),HilbertSpace())))")
Beispiel #30
0
 def test_fast_substitute(self):
     f = generate_operators('f', 2)
     substitutions = {}
     substitutions[Dagger(f[0])*f[0]] = -f[0]*Dagger(f[0])
     monomial = Dagger(f[0])*f[0]
     lhs = Dagger(f[0])*f[0]
     rhs = -f[0]*Dagger(f[0])
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])*f[0]**2
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])**2*f[0]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])**2*f[0]
     lhs = Dagger(f[0])**2
     rhs = -f[0]*Dagger(f[0])
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     g = generate_operators('g', 2)
     monomial = 2*g[0]**3*g[1]*Dagger(f[0])**2*f[0]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = S.One
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = 5
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial)
     monomial = 2*g[0]**3*g[1]*Dagger(f[0])**2*f[0] + f[1]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = f[1]*Dagger(f[0])**2*f[0]
     lhs = f[1]
     rhs = 1.0 + f[0]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     expand(monomial.subs(lhs, rhs)))
     monomial = f[1]**2*Dagger(f[0])**2*f[0]
     result = fast_substitute(fast_substitute(monomial, lhs, rhs), lhs, rhs)
     self.assertTrue(result == expand(monomial.subs(lhs, rhs)))
Beispiel #31
0
    com(U10, U01), com(U00, U11))
f4 = 1 / sqrt(2) * acom(com(U01, U00), com(U11, U10))
f5 = 1 / 2 * acom(com(U11, U10), com(U11, U00)) + 1 / 2 * acom(
    com(U11, U10), com(U01, U10))
f6 = com(U11, U10)**2

sumf = f1 + f2 + f3 + f4 + f5 + f6
print("Fin du calcul de sumf : ", time.time() - start)

combU = U01 * U00 * U01 * U00 - U00 * U01 * U01 * U00 - U01 * U00 * U00 * U01 + U00 * U01 * U00 * U01 + U11 * U00 * U01 * U00 - U10 * U01 * U01 * U00 - U11 * U00 * U00 * U01 + U10 * U01 * U00 * U01 + U01 * U10 * U01 * U00 - U00 * U11 * U01 * U00 - U01 * U10 * U00 * U01 + U00 * U11 * U00 * U01 + U11 * U10 * U01 * U00 - U10 * U11 * U01 * U00 - U11 * U10 * U00 * U01 + U10 * U11 * U00 * U01 + U01 * U00 * U11 * U00 - U00 * U01 * U11 * U00 - U01 * U00 * U10 * U01 + U00 * U01 * U10 * U01 + U11 * U00 * U11 * U00 - U10 * U01 * U11 * U00 - U11 * U00 * U10 * U01 + U10 * U01 * U10 * U01 + U01 * U10 * U11 * U00 - U00 * U11 * U11 * U00 - U01 * U10 * U10 * U01 + U00 * U11 * U10 * U01 + U11 * U10 * U11 * U00 - U10 * U11 * U11 * U00 - U11 * U10 * U10 * U01 + U10 * U11 * U10 * U01 + U01 * U00 * U01 * U10 - U00 * U01 * U01 * U10 - U01 * U00 * U00 * U11 + U00 * U01 * U00 * U11 + U11 * U00 * U01 * U10 - U10 * U01 * U01 * U10 - U11 * U00 * U00 * U11 + U10 * U01 * U00 * U11 + U01 * U10 * U01 * U10 - U00 * U11 * U01 * U10 - U01 * U10 * U00 * U11 + U00 * U11 * U00 * U11 + U11 * U10 * U01 * U10 - U10 * U11 * U01 * U10 - U11 * U10 * U00 * U11 + U10 * U11 * U00 * U11 + U01 * U00 * U11 * U10 - U00 * U01 * U11 * U10 - U01 * U00 * U10 * U11 + U00 * U01 * U10 * U11 + U11 * U00 * U11 * U10 - U10 * U01 * U11 * U10 - U11 * U00 * U10 * U11 + U10 * U01 * U10 * U11 + U01 * U10 * U11 * U10 - U00 * U11 * U11 * U10 - U01 * U10 * U10 * U11 + U00 * U11 * U10 * U11 + U11 * U10 * U11 * U10 - U10 * U11 * U11 * U10 - U11 * U10 * U10 * U11 + U10 * U11 * U10 * U11
print("Fin du calcul de combU : ", time.time() - start)

psi1 = 1 / 2 * combU * psi0
print("Fin du calcul de psi0 : ", time.time() - start)

norm = Dagger(psi1) * psi1
print("Fin du calcul de norm : ", time.time() - start)

mel = Dagger(sumf * psi0) * (sumf * psi0)
print("Fin du calcul de mel : ", time.time() - start)

A = mel / norm

print("Fin du calcul de proba : ", time.time() - start)

print(A)

# INTEGRATION ---------------------------------

# A = cos(t12)*sin(t12)*cos(t13)*sin(t13)*cos(t23)*sin(t23)^3*cos(t14)*sin(t14)*cos(t24)*sin(t24)*cos(t34)*sin(t34)^5