예제 #1
0
def test_sum_instantiator():
    """Test use of Sum instantiator."""
    i = IdxSym('i')
    j = IdxSym('j')
    ket_i = BasisKet(FockIndex(i), hs=0)
    ket_j = BasisKet(FockIndex(j), hs=0)
    A_i = OperatorSymbol(StrLabel(IndexedBase('A')[i]), hs=0)
    hs0 = LocalSpace('0')

    sum = Sum(i)(ket_i)
    ful = KetIndexedSum(ket_i, ranges=IndexOverFockSpace(i, hs=hs0))
    assert sum == ful
    assert sum == Sum(i, hs0)(ket_i)
    assert sum == Sum(i, hs=hs0)(ket_i)

    sum = Sum(i, 1, 10)(ket_i)
    ful = KetIndexedSum(ket_i, ranges=IndexOverRange(i, 1, 10))
    assert sum == ful
    assert sum == Sum(i, 1, 10, 1)(ket_i)
    assert sum == Sum(i, 1, to=10, step=1)(ket_i)
    assert sum == Sum(i, 1, 10, step=1)(ket_i)

    sum = Sum(i, (1, 2, 3))(ket_i)
    ful = KetIndexedSum(ket_i, ranges=IndexOverList(i, (1, 2, 3)))
    assert sum == KetIndexedSum(ket_i, ranges=IndexOverList(i, (1, 2, 3)))
    assert sum == Sum(i, [1, 2, 3])(ket_i)

    sum = Sum(i)(Sum(j)(ket_i * ket_j.dag()))
    ful = OperatorIndexedSum(
        ket_i * ket_j.dag(),
        ranges=(IndexOverFockSpace(i, hs0), IndexOverFockSpace(j, hs0)),
    )
    assert sum == ful
예제 #2
0
def test_qubit_state_bra():
    """Test  sum_i alpha_i <i| for TLS"""
    i = IdxSym('i')
    alpha = IndexedBase('alpha')
    alpha_i = alpha[i]
    hs_tls = LocalSpace('tls', basis=('g', 'e'))

    term = alpha_i * BasisKet(FockIndex(i), hs=hs_tls).dag()

    expr = KetIndexedSum.create(term, ranges=IndexOverFockSpace(i, hs=hs_tls))

    assert IndexOverFockSpace(i, hs=hs_tls) in expr.ket.kwargs['ranges']

    assert ascii(expr) == "Sum_{i in H_tls} alpha_i * <i|^(tls)"

    assert expr.ket.term.free_symbols == set([i, symbols('alpha'), alpha_i])
    assert expr.free_symbols == set([symbols('alpha'), alpha_i])
    assert expr.ket.variables == [i]
    assert expr.space == hs_tls
    assert len(expr.ket.args) == 1
    assert len(expr.ket.operands) == 1
    assert len(expr.ket.kwargs) == 1
    assert expr.ket.args[0] == term.ket
    assert expr.ket.term == term.ket
    assert len(expr.kwargs) == 0
    expr_expand = Bra.create(expr.ket.doit().substitute({
        alpha[0]: alpha['g'],
        alpha[1]: alpha['e']
    }))
    assert expr_expand == (alpha['g'] * BasisKet('g', hs=hs_tls).dag() +
                           alpha['e'] * BasisKet('e', hs=hs_tls).dag())
    assert ascii(expr_expand) == 'alpha_e * <e|^(tls) + alpha_g * <g|^(tls)'
예제 #3
0
def test_ketbra_indexed_sum():
    """Test ketbra product of sums"""
    i = IdxSym('i')
    hs = LocalSpace(1, dimension=5)
    alpha = IndexedBase('alpha')

    psi = KetSymbol('Psi', hs=hs)

    psi1 = KetIndexedSum(
        alpha[1, i] * BasisKet(FockIndex(i), hs=hs),
        ranges=IndexOverFockSpace(i, hs),
    )

    psi2 = KetIndexedSum(
        alpha[2, i] * BasisKet(FockIndex(i), hs=hs),
        ranges=IndexOverFockSpace(i, hs),
    )

    expr = psi1 * psi2.dag()
    assert expr.space == hs
    expected = OperatorIndexedSum(
        alpha[2, i.prime].conjugate() * alpha[1, i] *
        KetBra.create(BasisKet(FockIndex(i), hs=hs),
                      BasisKet(FockIndex(i.prime), hs=hs)),
        ranges=(IndexOverFockSpace(i, hs), IndexOverFockSpace(i.prime, hs)),
    )
    assert expr == expected
    assert KetBra.create(psi1, psi2) == expr

    expr = psi * psi2.dag()
    assert expr.space == hs
    expected = OperatorIndexedSum(
        alpha[2, i].conjugate() *
        KetBra.create(psi, BasisKet(FockIndex(i), hs=hs)),
        ranges=IndexOverFockSpace(i, hs),
    )
    assert expr == expected
    assert KetBra.create(psi, psi2) == expr

    expr = psi1 * psi.dag()
    assert expr.space == hs
    expected = OperatorIndexedSum(
        alpha[1, i] * KetBra.create(BasisKet(FockIndex(i), hs=hs), psi),
        ranges=IndexOverFockSpace(i, hs),
    )
    assert expr == expected
    assert KetBra.create(psi1, psi) == expr
예제 #4
0
def test_ket_indexed_sum_simplify_scalar():
    """Test calling the simplify_scalar method of an KetIndexedSum."""
    # This tests originates from some broken behavior when IndexedSum received
    # `ranges` as a positional argument instead of a keyword argument.
    a, b, ϕ = symbols('a, b, phi')
    factor = (a + b) * sympy.exp(I * ϕ)
    factor_expand = factor.expand()
    hs = LocalSpace(0)
    n = symbols('n', cls=IdxSym)
    psi_n = hs.basis_state(FockIndex(n))
    expr = KetIndexedSum(factor * psi_n,
                         ranges=(IndexOverFockSpace(n, hs=hs), ))
    expr_expand = expr.simplify_scalar(sympy.expand)
    expected = factor_expand * KetIndexedSum(
        psi_n, ranges=(IndexOverFockSpace(n, hs=hs), ))
    assert expr_expand != expected.term  # happened when ranges was an argument
    assert expr_expand == expected
예제 #5
0
def test_create_on_fock_expansion():
    """Test ``Create * sum_i alpha_i |i> = sqrt(i+1) * alpha_i * |i+1>``"""
    i = IdxSym('i')
    alpha = IndexedBase('alpha')
    hs = LocalSpace('0', dimension=3)

    expr = Create(hs=hs) * KetIndexedSum(
        alpha[i] * BasisKet(FockIndex(i), hs=hs),
        ranges=IndexOverFockSpace(i, hs),
    )

    assert expr == KetIndexedSum(
        sympy.sqrt(i + 1) * alpha[i] * BasisKet(FockIndex(i + 1), hs=hs),
        ranges=IndexOverFockSpace(i, hs),
    )

    assert expr.doit() == (alpha[0] * BasisKet(1, hs=hs) +
                           sympy.sqrt(2) * alpha[1] * BasisKet(2, hs=hs))
예제 #6
0
def test_braket_indexed_sum():
    """Test braket product of sums"""
    i = IdxSym('i')
    hs = LocalSpace(1, dimension=5)
    alpha = IndexedBase('alpha')

    psi = KetSymbol('Psi', hs=hs)

    psi1 = KetIndexedSum(
        alpha[1, i] * BasisKet(FockIndex(i), hs=hs),
        ranges=IndexOverFockSpace(i, hs),
    )

    psi2 = KetIndexedSum(
        alpha[2, i] * BasisKet(FockIndex(i), hs=hs),
        ranges=IndexOverFockSpace(i, hs),
    )

    expr = Bra.create(psi1) * psi2
    assert expr.space == TrivialSpace
    assert expr == ScalarIndexedSum.create(
        alpha[1, i].conjugate() * alpha[2, i],
        ranges=(IndexOverFockSpace(i, hs), ),
    )
    assert BraKet.create(psi1, psi2) == expr

    expr = psi.dag() * psi2
    assert expr == ScalarIndexedSum(
        alpha[2, i] * BraKet(psi, BasisKet(FockIndex(i), hs=hs)),
        ranges=IndexOverFockSpace(i, hs),
    )
    assert BraKet.create(psi, psi2) == expr

    expr = psi1.dag() * psi
    assert expr == ScalarIndexedSum(
        alpha[1, i].conjugate() * BraKet(BasisKet(FockIndex(i), hs=hs), psi),
        ranges=IndexOverFockSpace(i, hs),
    )
    assert BraKet.create(psi1, psi) == expr
예제 #7
0
def test_tls_norm():
    """Test that calculating the norm of a TLS state results in 1"""
    hs = LocalSpace('tls', dimension=2)
    i = IdxSym('i')

    ket_i = BasisKet(FockIndex(i), hs=hs)
    nrm = BraKet.create(ket_i, ket_i)
    assert nrm == 1

    psi = KetIndexedSum((1 / sympy.sqrt(2)) * ket_i,
                        ranges=IndexOverFockSpace(i, hs))
    nrm = BraKet.create(psi, psi)
    assert nrm == 1
예제 #8
0
def test_tensor_indexed_sum():
    """Test tensor product of sums"""
    i = IdxSym('i')
    hs1 = LocalSpace(1)
    hs2 = LocalSpace(2)
    alpha = IndexedBase('alpha')

    psi1 = KetIndexedSum(
        alpha[1, i] * BasisKet(FockIndex(i), hs=hs1),
        ranges=IndexOverFockSpace(i, hs1),
    )

    psi2 = KetIndexedSum(
        alpha[2, i] * BasisKet(FockIndex(i), hs=hs2),
        ranges=IndexOverFockSpace(i, hs2),
    )

    expr = psi1 * psi2
    assert expr.space == hs1 * hs2
    rhs = KetIndexedSum(
        alpha[1, i] * alpha[2, i.prime] *
        (BasisKet(FockIndex(i), hs=hs1) *
         BasisKet(FockIndex(i.prime), hs=hs2)),
        ranges=(IndexOverFockSpace(i, hs1), IndexOverFockSpace(i.prime, hs2)),
    )
    assert expr == rhs
    psi0 = KetSymbol('Psi', hs=0)
    psi3 = KetSymbol('Psi', hs=3)
    expr2 = psi0 * psi1 * psi2 * psi3
    rhs = KetIndexedSum(
        alpha[1, i] * alpha[2, i.prime] *
        (psi0 * BasisKet(FockIndex(i), hs=hs1) *
         BasisKet(FockIndex(i.prime), hs=hs2) * psi3),
        ranges=(IndexOverFockSpace(i, hs1), IndexOverFockSpace(i.prime, hs2)),
    )
    assert expr2 == rhs
    assert TensorKet.create(psi0, psi1, psi2, psi3) == expr2
예제 #9
0
def test_two_hs_symbol_sum():
    """Test sum_{ij} a_{ij} Psi_{ij}"""
    i = IdxSym('i')
    j = IdxSym('j')
    a = IndexedBase('a')
    hs1 = LocalSpace('1', dimension=3)
    hs2 = LocalSpace('2', dimension=3)
    hs = hs1 * hs2
    Psi = IndexedBase('Psi')
    a_ij = a[i, j]
    Psi_ij = Psi[i, j]
    KetPsi_ij = KetSymbol(StrLabel(Psi_ij), hs=hs)
    term = a_ij * KetPsi_ij

    expr1 = KetIndexedSum(
        term,
        ranges=(IndexOverFockSpace(i, hs=hs1), IndexOverFockSpace(j, hs=hs2)),
    )

    expr2 = KetIndexedSum(term,
                          ranges=(IndexOverRange(i, 0,
                                                 2), IndexOverRange(j, 0, 2)))

    assert expr1.term.free_symbols == set(
        [i, j, symbols('a'), symbols('Psi'), a_ij, Psi_ij])
    assert expr1.free_symbols == set(
        [symbols('a'), symbols('Psi'), a_ij, Psi_ij])
    assert expr1.variables == [i, j]

    assert (
        ascii(expr1) == 'Sum_{i in H_1} Sum_{j in H_2} a_ij * |Psi_ij>^(1*2)')
    assert unicode(expr1) == '∑_{i ∈ ℌ₁} ∑_{j ∈ ℌ₂} a_ij |Ψ_ij⟩^(1⊗2)'
    assert (latex(expr1) ==
            r'\sum_{i \in \mathcal{H}_{1}} \sum_{j \in \mathcal{H}_{2}} '
            r'a_{i j} \left\lvert \Psi_{i j} \right\rangle^{(1 \otimes 2)}')

    assert ascii(expr2) == 'Sum_{i,j=0}^{2} a_ij * |Psi_ij>^(1*2)'
    assert unicode(expr2) == '∑_{i,j=0}^{2} a_ij |Ψ_ij⟩^(1⊗2)'
    assert (latex(expr2) == r'\sum_{i,j=0}^{2} a_{i j} '
            r'\left\lvert \Psi_{i j} \right\rangle^{(1 \otimes 2)}')

    assert expr1.doit() == expr2.doit()
    assert expr1.doit() == KetPlus(
        a[0, 0] * KetSymbol('Psi_00', hs=hs),
        a[0, 1] * KetSymbol('Psi_01', hs=hs),
        a[0, 2] * KetSymbol('Psi_02', hs=hs),
        a[1, 0] * KetSymbol('Psi_10', hs=hs),
        a[1, 1] * KetSymbol('Psi_11', hs=hs),
        a[1, 2] * KetSymbol('Psi_12', hs=hs),
        a[2, 0] * KetSymbol('Psi_20', hs=hs),
        a[2, 1] * KetSymbol('Psi_21', hs=hs),
        a[2, 2] * KetSymbol('Psi_22', hs=hs),
    )
예제 #10
0
def test_scalar_indexed_sum(braket):
    """Test instantiation and behavior of a ScalarIndexedSum"""
    i = IdxSym('i')
    ip = i.prime
    ipp = ip.prime
    alpha = IndexedBase('alpha')
    a = symbols('a')
    hs = LocalSpace(0)
    ket_sum = KetIndexedSum(
        alpha[1, i] * BasisKet(FockIndex(i), hs=hs),
        ranges=(IndexOverRange(i, 1, 2), ),
    )
    bra = KetSymbol('Psi', hs=hs).dag()
    expr = bra * ket_sum
    half = sympify(1) / 2
    assert isinstance(expr, ScalarIndexedSum)
    assert isinstance(expr.term, ScalarTimes)
    assert expr.term == bra * ket_sum.term
    assert expr.ranges == ket_sum.ranges
    assert expr.doit() == (alpha[1, 1] * bra * BasisKet(1, hs=hs) +
                           alpha[1, 2] * bra * BasisKet(2, hs=hs))

    expr = ScalarIndexedSum.create(i, ranges=(IndexOverRange(i, 1, 2), ))
    assert expr == ScalarIndexedSum(i, ranges=(IndexOverRange(i, 1, 2), ))
    assert isinstance(expr.doit(), ScalarValue)
    assert expr.doit() == 3

    assert expr.real == expr
    assert expr.imag == Zero
    assert expr.conjugate() == expr

    assert 3 * expr == expr * 3 == Sum(i, 1, 2)(3 * i)
    assert a * expr == expr * a == Sum(i, 1, 2)(a * i)
    assert braket * expr == ScalarTimes(braket, Sum(i, 1, 2)(i))
    assert expr * braket == ScalarTimes(braket, Sum(i, 1, 2)(i))
    assert (2 * i) * expr == 2 * expr * i
    assert (2 * i) * expr == Sum(i, 1, 2)(2 * i * i.prime)

    assert expr * expr == ScalarIndexedSum(
        ScalarValue(i * ip),
        ranges=(IndexOverRange(i, 1, 2), IndexOverRange(ip, 1, 2)),
    )

    sum3 = expr**3
    assert sum3 == ScalarIndexedSum(
        ScalarValue(i * ip * ipp),
        ranges=(
            IndexOverRange(i, 1, 2),
            IndexOverRange(ip, 1, 2),
            IndexOverRange(ipp, 1, 2),
        ),
    )

    assert expr**0 is One
    assert expr**1 is expr
    assert (expr**alpha).exp == alpha
    assert expr**-1 == 1 / expr
    assert (1 / expr).exp == -1
    assert (expr**-alpha).exp == -alpha

    sqrt_sum = sqrt(expr)
    assert sqrt_sum == ScalarPower(expr, ScalarValue(half))

    expr = ScalarIndexedSum.create(I * i, ranges=(IndexOverRange(i, 1, 2), ))
    assert expr.real == Zero
    assert expr.imag == ScalarIndexedSum.create(i,
                                                ranges=(IndexOverRange(
                                                    i, 1, 2), ))
    assert expr.conjugate() == -expr
예제 #11
0
    ),
    # State Algebra
    # ...
    (
        KetIndexedSum,
        'R001',
        (KetSymbol(StrLabel(i), hs=0) - KetSymbol(StrLabel(i), hs=0), ),
        dict(ranges=(IndexOverFockSpace(i, hs=LocalSpace(0)), )),
        ZeroKet,
    ),
    (
        KetIndexedSum,
        'R002',
        (symbols('a') * BasisKet(FockIndex(i), hs=0), ),
        dict(ranges=(IndexOverRange(i, 0, 1), )),
        symbols('a') * KetIndexedSum(BasisKet(FockIndex(i), hs=0),
                                     ranges=(IndexOverRange(i, 0, 1), )),
    ),
]


@pytest.mark.parametrize("cls, rule, args, kwargs, expected", TESTS)
def test_rule(cls, rule, args, kwargs, expected, caplog):
    """Check that for the given `cls` and `rule` name (which must be a key in
    ``cls._rules`` or ``cls._binary_rules``), if we instantiate
    ``cls(*args, **kwargs)``, `rule` is applied and we obtain the `expected`
    result.

    In order to review the log of how all test expressions are created, call
    ``py.test`` as::

        py.test -s --log-cli-level DEBUG ./tests/algebra/test_rules.py
예제 #12
0
def test_qubit_state():
    """Test  sum_i alpha_i |i> for TLS"""
    i = IdxSym('i')
    alpha = IndexedBase('alpha')
    alpha_i = alpha[i]
    hs_tls = LocalSpace('tls', basis=('g', 'e'))

    term = alpha_i * BasisKet(FockIndex(i), hs=hs_tls)

    expr1 = KetIndexedSum.create(term, ranges=IndexOverFockSpace(i, hs=hs_tls))

    expr2 = KetIndexedSum.create(term, ranges=IndexOverList(i, [0, 1]))

    expr3 = KetIndexedSum.create(term,
                                 ranges=IndexOverRange(i, start_from=0, to=1))

    assert IndexOverFockSpace(i, hs=hs_tls) in expr1.kwargs['ranges']

    assert ascii(expr1) == "Sum_{i in H_tls} alpha_i * |i>^(tls)"
    assert unicode(expr1) == "∑_{i ∈ ℌ_tls} α_i |i⟩⁽ᵗˡˢ⁾"
    assert (
        srepr(expr1) ==
        "KetIndexedSum(ScalarTimesKet(ScalarValue(Indexed(IndexedBase(Symbol('alpha')), IdxSym('i', integer=True))), BasisKet(FockIndex(IdxSym('i', integer=True)), hs=LocalSpace('tls', basis=('g', 'e')))), ranges=(IndexOverFockSpace(IdxSym('i', integer=True), LocalSpace('tls', basis=('g', 'e'))),))"
    )
    with configure_printing(tex_use_braket=True):
        assert (latex(expr1) ==
                r'\sum_{i \in \mathcal{H}_{tls}} \alpha_{i} \Ket{i}^{(tls)}')

    assert ascii(expr2) == 'Sum_{i in {0,1}} alpha_i * |i>^(tls)'
    assert unicode(expr2) == '∑_{i ∈ {0,1}} α_i |i⟩⁽ᵗˡˢ⁾'
    assert (
        srepr(expr2) ==
        "KetIndexedSum(ScalarTimesKet(ScalarValue(Indexed(IndexedBase(Symbol('alpha')), IdxSym('i', integer=True))), BasisKet(FockIndex(IdxSym('i', integer=True)), hs=LocalSpace('tls', basis=('g', 'e')))), ranges=(IndexOverList(IdxSym('i', integer=True), (0, 1)),))"
    )
    with configure_printing(tex_use_braket=True):
        assert (
            latex(expr2) == r'\sum_{i \in \{0,1\}} \alpha_{i} \Ket{i}^{(tls)}')

    assert ascii(expr3) == 'Sum_{i=0}^{1} alpha_i * |i>^(tls)'
    assert unicode(expr3) == '∑_{i=0}^{1} α_i |i⟩⁽ᵗˡˢ⁾'
    assert (
        srepr(expr3) ==
        "KetIndexedSum(ScalarTimesKet(ScalarValue(Indexed(IndexedBase(Symbol('alpha')), IdxSym('i', integer=True))), BasisKet(FockIndex(IdxSym('i', integer=True)), hs=LocalSpace('tls', basis=('g', 'e')))), ranges=(IndexOverRange(IdxSym('i', integer=True), 0, 1),))"
    )
    with configure_printing(tex_use_braket=True):
        assert latex(expr3) == r'\sum_{i=0}^{1} \alpha_{i} \Ket{i}^{(tls)}'

    for expr in (expr1, expr2, expr3):
        assert expr.term.free_symbols == set([i, symbols('alpha'), alpha_i])
        assert expr.term.bound_symbols == set()
        assert expr.free_symbols == set([symbols('alpha'), alpha_i])
        assert expr.variables == [i]
        assert expr.bound_symbols == set([i])
        assert len(expr) == len(expr.ranges[0]) == 2
        assert 0 in expr.ranges[0]
        assert 1 in expr.ranges[0]
        assert expr.space == hs_tls
        assert len(expr.args) == 1
        assert len(expr.kwargs) == 1
        assert len(expr.operands) == 1
        assert expr.args[0] == term
        assert expr.term == term
        expr_expand = expr.doit().substitute({
            alpha[0]: alpha['g'],
            alpha[1]: alpha['e']
        })
        assert expr_expand == (alpha['g'] * BasisKet('g', hs=hs_tls) +
                               alpha['e'] * BasisKet('e', hs=hs_tls))
        assert (
            ascii(expr_expand) == 'alpha_e * |e>^(tls) + alpha_g * |g>^(tls)')

    with pytest.raises(TypeError) as exc_info:
        KetIndexedSum.create(alpha_i * BasisKet(i, hs=hs_tls),
                             IndexOverFockSpace(i, hs=hs_tls))
    assert "label_or_index must be an instance of" in str(exc_info.value)
예제 #13
0
 def sum(term, *index_symbols):
     return KetIndexedSum(
         term, ranges=[IndexOverRange(i, 0, 2) for i in index_symbols])
예제 #14
0
def test_partial_expansion():
    """Test partially executing the sum (only for a subset of summation
    indices)"""
    i = IdxSym('i')
    j = IdxSym('j')
    k = IdxSym('k')
    hs = LocalSpace('0', dimension=2)
    Psi = IndexedBase('Psi')

    def r(index_symbol):
        return IndexOverFockSpace(index_symbol, hs=hs)

    psi_ijk = KetSymbol(StrLabel(Psi[i, j, k]), hs=hs)

    def psi(i_val, j_val, k_val):
        return psi_ijk.substitute({i: i_val, j: j_val, k: k_val})

    expr = KetIndexedSum(psi_ijk, ranges=(r(i), r(j), r(k)))

    expr_expanded = expr.doit(indices=[i])
    assert expr_expanded == KetIndexedSum(psi(0, j, k) + psi(1, j, k),
                                          ranges=(r(j), r(k)))

    expr_expanded = expr.doit(indices=[j])
    assert expr_expanded == KetIndexedSum(psi(i, 0, k) + psi(i, 1, k),
                                          ranges=(r(i), r(k)))

    assert expr.doit(indices=[j]) == expr.doit(indices=['j'])

    expr_expanded = expr.doit(indices=[i, j])
    assert expr_expanded == KetIndexedSum(psi(0, 0, k) + psi(1, 0, k) +
                                          psi(0, 1, k) + psi(1, 1, k),
                                          ranges=r(k))

    assert expr.doit(indices=[i, j]) == expr.doit(indices=[j, i])

    assert expr.doit(indices=[i, j, k]) == expr.doit()

    with pytest.raises(ValueError):
        expr.doit(indices=[i], max_terms=10)