def test_tex_bra_elements(): """Test the tex representation of "atomic" kets""" hs1 = LocalSpace('q1', basis=('g', 'e')) hs2 = LocalSpace('q2', basis=('g', 'e')) alpha, beta = symbols('alpha, beta') bra = Bra(KetSymbol('Psi', hs=hs1)) assert latex(bra) == r'\left\langle \Psi \right\rvert^{(q_{1})}' assert latex(Bra(KetSymbol('Psi', alpha, beta, hs=hs1))) == ( r'\left\langle \Psi\left(\alpha, \beta\right) \right\rvert^{(q_{1})}') assert latex(bra, tex_use_braket=True) == r'\Bra{\Psi}^{(q_{1})}' assert (latex(bra, tex_use_braket=True, show_hs_label='subscript') == r'\Bra{\Psi}_{(q_{1})}') assert (latex(bra, tex_use_braket=True, show_hs_label=False) == r'\Bra{\Psi}') assert (latex(Bra(KetSymbol( 'Psi', hs=1))) == r'\left\langle \Psi \right\rvert^{(1)}') assert (latex(Bra(KetSymbol( 'Psi', hs=(1, 2)))) == r'\left\langle \Psi \right\rvert^{(1 \otimes 2)}') assert (latex(Bra(KetSymbol( 'Psi', hs=hs1 * hs2))) == r'\left\langle \Psi \right\rvert^{(q_{1} \otimes q_{2})}') assert (latex(KetSymbol( 'Psi', hs=1).dag()) == r'\left\langle \Psi \right\rvert^{(1)}') assert latex(Bra(ZeroKet)) == '0' assert latex(Bra(TrivialKet)) == '1' assert (latex(BasisKet( 'e', hs=hs1).adjoint()) == r'\left\langle e \right\rvert^{(q_{1})}') assert (latex(BasisKet( 1, hs=1).adjoint()) == r'\left\langle 1 \right\rvert^{(1)}') assert (latex(CoherentStateKet( 2.0, hs=1).dag()) == r'\left\langle \alpha=2 \right\rvert^{(1)}')
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
def test_tex_symbolic_labels(): """Test tex representation of symbols with symbolic labels""" i = IdxSym('i') j = IdxSym('j') hs0 = LocalSpace(0) hs1 = LocalSpace(1) Psi = IndexedBase('Psi') with configure_printing(tex_use_braket=True): assert latex(BasisKet(FockIndex(2 * i), hs=hs0)) == r'\Ket{2 i}^{(0)}' assert latex(KetSymbol(StrLabel(2 * i), hs=hs0)) == r'\Ket{2 i}^{(0)}' assert (latex(KetSymbol(StrLabel(Psi[i, j]), hs=hs0 * hs1)) == r'\Ket{\Psi_{i j}}^{(0 \otimes 1)}') expr = BasisKet(FockIndex(i), hs=hs0) * BasisKet(FockIndex(j), hs=hs1) assert latex(expr) == r'\Ket{i,j}^{(0 \otimes 1)}' assert (latex(Bra(BasisKet(FockIndex(2 * i), hs=hs0))) == r'\Bra{2 i}^{(0)}') assert (latex(LocalSigma(FockIndex(i), FockIndex(j), hs=hs0)) == r'\Ket{i}\!\Bra{j}^{(0)}') alpha = symbols('alpha') expr = CoherentStateKet(alpha, hs=1).to_fock_representation() assert (latex(expr) == r'e^{- \frac{\alpha \overline{\alpha}}{2}} ' r'\left(\sum_{n \in \mathcal{H}_{1}} ' r'\frac{\alpha^{n}}{\sqrt{n!}} \Ket{n}^{(1)}\right)') assert (latex( expr, conjg_style='star') == r'e^{- \frac{\alpha {\alpha}^*}{2}} ' r'\left(\sum_{n \in \mathcal{H}_{1}} ' r'\frac{\alpha^{n}}{\sqrt{n!}} \Ket{n}^{(1)}\right)') tls = SpinSpace(label='s', spin='1/2', basis=('down', 'up')) Sig = IndexedBase('sigma') n = IdxSym('n') Sig_n = OperatorSymbol(StrLabel(Sig[n]), hs=tls) assert latex(Sig_n, show_hs_label=False) == r'\hat{\sigma}_{n}'
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)'
def test_ascii_symbolic_labels(): """Test ascii representation of symbols with symbolic labels""" i = IdxSym('i') j = IdxSym('j') hs0 = LocalSpace(0) hs1 = LocalSpace(1) Psi = IndexedBase('Psi') assert ascii(BasisKet(FockIndex(2 * i), hs=hs0)) == '|2*i>^(0)' assert ascii(KetSymbol(StrLabel(2 * i), hs=hs0)) == '|2*i>^(0)' assert (ascii(KetSymbol(StrLabel(Psi[i, j]), hs=hs0 * hs1)) == '|Psi_ij>^(0*1)') expr = BasisKet(FockIndex(i), hs=hs0) * BasisKet(FockIndex(j), hs=hs1) assert ascii(expr) == '|i,j>^(0*1)' assert ascii(Bra(BasisKet(FockIndex(2 * i), hs=hs0))) == '<2*i|^(0)' assert (ascii(LocalSigma(FockIndex(i), FockIndex(j), hs=hs0)) == '|i><j|^(0)') expr = CoherentStateKet(symbols('alpha'), hs=1).to_fock_representation() assert (ascii(expr) == 'exp(-alpha*conjugate(alpha)/2) * ' '(Sum_{n in H_1} alpha**n/sqrt(n!) * |n>^(1))') tls = SpinSpace(label='s', spin='1/2', basis=('down', 'up')) Sig = IndexedBase('sigma') n = IdxSym('n') Sig_n = OperatorSymbol(StrLabel(Sig[n]), hs=tls) assert ascii(Sig_n, show_hs_label=False) == 'sigma_n'
def test_ascii_ket_elements(): """Test the ascii representation of "atomic" kets""" hs1 = LocalSpace('q1', basis=('g', 'e')) hs2 = LocalSpace('q2', basis=('g', 'e')) alpha, beta = symbols('alpha, beta') assert ascii(KetSymbol('Psi', hs=hs1)) == '|Psi>^(q1)' psi = KetSymbol('Psi', hs=1) assert ascii(psi) == '|Psi>^(1)' assert ascii(KetSymbol('Psi', alpha, beta, hs=1)) == ('|Psi(alpha, beta)>^(1)') assert ascii(psi, show_hs_label='subscript') == '|Psi>_(1)' assert ascii(psi, show_hs_label=False) == '|Psi>' assert ascii(KetSymbol('Psi', hs=(1, 2))) == '|Psi>^(1*2)' assert ascii(KetSymbol('Psi', hs=hs1 * hs2)) == '|Psi>^(q1*q2)' with pytest.raises(ValueError): KetSymbol(r'\Psi', hs=hs1) assert ascii(KetSymbol('Psi', hs=1)) == '|Psi>^(1)' assert ascii(KetSymbol('Psi', hs=hs1 * hs2)) == '|Psi>^(q1*q2)' assert ascii(ZeroKet) == '0' assert ascii(TrivialKet) == '1' assert ascii(BasisKet('e', hs=hs1)) == '|e>^(q1)' assert ascii(BasisKet(1, hs=1)) == '|1>^(1)' assert ascii(BasisKet(1, hs=hs1)) == '|e>^(q1)' with pytest.raises(ValueError): BasisKet('1', hs=hs1) assert ascii(CoherentStateKet(2.0, hs=1)) == '|alpha=2>^(1)' assert ascii(CoherentStateKet(2.1, hs=1)) == '|alpha=2.1>^(1)'
def bell1_expr(): hs1 = LocalSpace('q_1', basis=('g', 'e')) hs2 = LocalSpace('q_2', basis=('g', 'e')) ket_g1 = BasisKet('g', hs=hs1) ket_e1 = BasisKet('e', hs=hs1) ket_g2 = BasisKet('g', hs=hs2) ket_e2 = BasisKet('e', hs=hs2) return (ket_e1 * ket_g2 - I * ket_g1 * ket_e2) / sqrt(2)
def test_unicode_operator_elements(): """Test the unicode representation of "atomic" operator algebra elements""" hs1 = LocalSpace('q1', dimension=2) hs2 = LocalSpace('q2', dimension=2) alpha, beta = symbols('alpha, beta') assert unicode(OperatorSymbol("A", hs=hs1)) == 'A\u0302^(q\u2081)' # Â^(q₁) assert (unicode(OperatorSymbol('A', hs=1), show_hs_label='subscript') == 'A\u0302\u208d\u2081\u208e' ) # Â₍₁₎ assert (unicode( OperatorSymbol("A", hs=hs1), unicode_op_hats=False, unicode_sub_super=False, ) == 'A^(q_1)') assert (unicode(OperatorSymbol( "A_1", hs=hs1 * hs2)) == 'A\u0302_1^(q\u2081\u2297q\u2082)') # Â_1^(q₁⊗q₂) assert (unicode(OperatorSymbol( "Xi_2", hs=('q1', 'q2'))) == '\u039e\u0302_2^(q\u2081\u2297q\u2082)' ) # Ξ̂_2^(q₁⊗q₂) assert unicode(OperatorSymbol("Xi", alpha, beta, hs=1)) == ('Ξ̂⁽¹⁾(α, β)') assert unicode(IdentityOperator) == "𝟙" assert unicode(ZeroOperator) == "0" assert unicode(Create(hs=1)) == 'a\u0302^(1)\u2020' # â^(1)† assert unicode(Destroy(hs=1)) == 'a\u0302\u207d\xb9\u207e' # â⁽¹⁾ assert unicode(Destroy(hs=1), unicode_sub_super=False) == 'a\u0302^(1)' assert unicode(Destroy(hs=1), unicode_op_hats=False) == 'a\u207d\xb9\u207e' assert (unicode(Destroy(hs=1), unicode_op_hats=False, unicode_sub_super=False) == 'a^(1)') assert (unicode(Squeeze(Rational(1, 2), hs=1)) == 'Squeeze\u207d\xb9\u207e(1/2)') # Squeeze⁽¹⁾(1/2) hs_tls = LocalSpace('1', basis=('g', 'e')) sig_e_g = LocalSigma('e', 'g', hs=hs_tls) assert unicode(sig_e_g) == '|e⟩⟨g|⁽¹⁾' assert unicode(sig_e_g, unicode_sub_super=False) == '|e⟩⟨g|^(1)' assert unicode(sig_e_g, show_hs_label=False) == '|e⟩⟨g|' assert (unicode(sig_e_g, sig_as_ketbra=False) == '\u03c3\u0302_e,g^(1)' ) # σ̂_e,g^(1) sig_e_e = LocalProjector('e', hs=hs_tls) assert unicode(sig_e_e) == '|e⟩⟨e|⁽¹⁾' assert (unicode( sig_e_e, sig_as_ketbra=False) == '\u03a0\u0302\u2091\u207d\xb9\u207e') # Π̂ₑ⁽¹⁾ assert (unicode(BasisKet(0, hs=1) * BasisKet(0, hs=2) * BasisKet(0, hs=3)) == '|0,0,0⟩^(1⊗2⊗3)') assert unicode(BasisKet(0, hs=hs1) * BasisKet(0, hs=hs2)) == '|00⟩^(q₁⊗q₂)'
def test_unicode_spin_arrows(): """Test the representation of spin-1/2 spaces with special labels "down", "up" as arrows""" tls1 = SpinSpace('1', spin='1/2', basis=("down", "up")) tls2 = SpinSpace('2', spin='1/2', basis=("down", "up")) tls3 = SpinSpace('3', spin='1/2', basis=("down", "up")) down1 = BasisKet('down', hs=tls1) up1 = BasisKet('up', hs=tls1) down2 = BasisKet('down', hs=tls2) up3 = BasisKet('up', hs=tls3) assert unicode(down1) == r'|↓⟩⁽¹⁾' assert unicode(up1) == r'|↑⟩⁽¹⁾' ket = down1 * down2 * up3 assert unicode(ket) == r'|↓↓↑⟩^(1⊗2⊗3)' sig = LocalSigma("up", "down", hs=tls1) assert unicode(sig) == r'|↑⟩⟨↓|⁽¹⁾'
def test_unicode_bra_elements(): """Test the unicode representation of "atomic" kets""" hs1 = LocalSpace('q1', basis=('g', 'e')) alpha, beta = symbols('alpha, beta') assert unicode(Bra(KetSymbol('Psi', hs=hs1))) == '⟨Ψ|^(q₁)' assert unicode(Bra(KetSymbol('Psi', hs=1))) == '⟨Ψ|⁽¹⁾' assert unicode(Bra(KetSymbol('Psi', alpha, beta, hs=hs1))) == ('⟨Ψ(α, β)|^(q₁)') assert unicode(Bra(KetSymbol('Psi', hs=(1, 2)))) == '⟨Ψ|^(1⊗2)' assert unicode(Bra(ZeroKet)) == '0' assert unicode(Bra(TrivialKet)) == '1' assert unicode(BasisKet('e', hs=hs1).adjoint()) == '⟨e|^(q₁)' assert unicode(BasisKet(1, hs=1).adjoint()) == '⟨1|⁽¹⁾' assert unicode(CoherentStateKet(2.0, hs=1).dag()) == '⟨α=2|⁽¹⁾' assert unicode(CoherentStateKet(0.5j, hs=1).dag()) == '⟨α=0.5j|⁽¹⁾' assert unicode(CoherentStateKet(I / 2, hs=1).dag()) == '⟨α=ⅈ/2|⁽¹⁾'
def test_coherent_state(): """Test fock representation of coherent state""" alpha = symbols('alpha') hs0 = LocalSpace(0) hs1 = LocalSpace(1, dimension=3) i = IdxSym('i') n = IdxSym('n') psi = CoherentStateKet(alpha, hs=hs0) psi_focksum_3 = psi.to_fock_representation(max_terms=3) assert len(psi_focksum_3.term) == 3 for n_val in (0, 1, 2): assert n_val in psi_focksum_3.term.ranges[0] psi_focksum_inf = psi.to_fock_representation() with pytest.raises(InfiniteSumError): len(psi_focksum_inf.term) for n_val in (0, 1, 2, 3): assert n_val in psi_focksum_inf.term.ranges[0] assert psi_focksum_inf.term.term.free_symbols == set([n, symbols('alpha')]) assert psi_focksum_inf.free_symbols == set([symbols('alpha')]) assert psi_focksum_inf.term.variables == [n] assert psi_focksum_inf.substitute({n: i}).term.variables == [i] assert (psi_focksum_inf.substitute({hs0: hs1}) == CoherentStateKet( alpha, hs=hs1).to_fock_representation()) assert (psi.to_fock_representation(index_symbol='i').substitute( {i: n}) == psi_focksum_inf) assert (psi.to_fock_representation(index_symbol=i).substitute( {i: n}) == psi_focksum_inf) assert psi_focksum_3.doit([IndexedSum ]) == psi_focksum_inf.doit([IndexedSum], max_terms=3) psi_expanded_3 = psi_focksum_3.doit([IndexedSum]) assert psi_expanded_3 == ( sympy.exp(-alpha * alpha.conjugate() / 2) * KetPlus( BasisKet(0, hs=LocalSpace(0)), ScalarTimesKet(alpha, BasisKet(1, hs=LocalSpace(0))), ScalarTimesKet(alpha**2 / sympy.sqrt(2), BasisKet(2, hs=LocalSpace(0))), )) psi = CoherentStateKet(alpha, hs=hs1) assert psi.to_fock_representation().doit( [IndexedSum]) == psi_expanded_3.substitute({hs0: hs1})
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))
def test_tex_ket_elements(): """Test the tex representation of "atomic" kets""" hs1 = LocalSpace('q1', basis=('g', 'e')) hs2 = LocalSpace('q2', basis=('g', 'e')) alpha, beta = symbols('alpha, beta') psi = KetSymbol('Psi', hs=hs1) assert latex(psi) == r'\left\lvert \Psi \right\rangle^{(q_{1})}' assert (latex(KetSymbol('Psi', alpha, beta, hs=1)) == r'\left\lvert \Psi\left(\alpha, \beta\right) \right\rangle^{(1)}') assert latex(psi, tex_use_braket=True) == r'\Ket{\Psi}^{(q_{1})}' assert (latex(psi, tex_use_braket=True, show_hs_label='subscript') == r'\Ket{\Psi}_{(q_{1})}') assert (latex(psi, tex_use_braket=True, show_hs_label=False) == r'\Ket{\Psi}') assert (latex(KetSymbol('Psi', hs=1)) == r'\left\lvert \Psi \right\rangle^{(1)}') assert (latex(KetSymbol( 'Psi', hs=(1, 2))) == r'\left\lvert \Psi \right\rangle^{(1 \otimes 2)}') assert (latex(KetSymbol( 'Psi', hs=hs1 * hs2)) == r'\left\lvert \Psi \right\rangle^{(q_{1} \otimes q_{2})}') assert (latex(KetSymbol('Psi', hs=1)) == r'\left\lvert \Psi \right\rangle^{(1)}') assert latex(ZeroKet) == '0' assert latex(TrivialKet) == '1' assert (latex(BasisKet( 'e', hs=hs1)) == r'\left\lvert e \right\rangle^{(q_{1})}') hs_tls = LocalSpace('1', basis=('excited', 'ground')) assert (latex(BasisKet( 'excited', hs=hs_tls)) == r'\left\lvert \text{excited} \right\rangle^{(1)}') assert latex(BasisKet(1, hs=1)) == r'\left\lvert 1 \right\rangle^{(1)}' spin = SpinSpace('s', spin=(3, 2)) assert (latex(SpinBasisKet( -3, 2, hs=spin)) == r'\left\lvert -3/2 \right\rangle^{(s)}') assert (latex(SpinBasisKet( 1, 2, hs=spin)) == r'\left\lvert +1/2 \right\rangle^{(s)}') assert (latex(SpinBasisKet(-3, 2, hs=spin), tex_frac_for_spin_labels=True) == r'\left\lvert -\frac{3}{2} \right\rangle^{(s)}') assert (latex(SpinBasisKet(1, 2, hs=spin), tex_frac_for_spin_labels=True) == r'\left\lvert +\frac{1}{2} \right\rangle^{(s)}') assert (latex(CoherentStateKet( 2.0, hs=1)) == r'\left\lvert \alpha=2 \right\rangle^{(1)}')
def test_tex_spin_arrows(): """Test the representation of spin-1/2 spaces with special labels "down", "up" as arrows""" tls1 = SpinSpace('1', spin='1/2', basis=("down", "up")) tls2 = SpinSpace('2', spin='1/2', basis=("down", "up")) tls3 = SpinSpace('3', spin='1/2', basis=("down", "up")) down1 = BasisKet('down', hs=tls1) up1 = BasisKet('up', hs=tls1) down2 = BasisKet('down', hs=tls2) up3 = BasisKet('up', hs=tls3) assert latex(down1) == r'\left\lvert \downarrow \right\rangle^{(1)}' assert latex(up1) == r'\left\lvert \uparrow \right\rangle^{(1)}' ket = down1 * down2 * up3 assert ( latex(ket) == r'\left\lvert \downarrow\downarrow\uparrow \right\rangle' r'^{(1 \otimes 2 \otimes 3)}') sig = LocalSigma("up", "down", hs=tls1) assert (latex(sig) == r'\left\lvert \uparrow \middle\rangle\!' r'\middle\langle \downarrow \right\rvert^{(1)}')
def test_ascii_operator_elements(): """Test the ascii representation of "atomic" operator algebra elements""" hs1 = LocalSpace('q1', dimension=2) hs2 = LocalSpace('q2', dimension=2) alpha, beta = symbols('alpha, beta') assert ascii(OperatorSymbol("A", hs=hs1)) == 'A^(q1)' A_1 = OperatorSymbol("A_1", hs=1) assert ascii(A_1, show_hs_label='subscript') == 'A_1,(1)' assert ascii(OperatorSymbol("A", hs=hs1), show_hs_label=False) == 'A' assert ascii(OperatorSymbol("A_1", hs=hs1 * hs2)) == 'A_1^(q1*q2)' assert ascii(OperatorSymbol("Xi_2", hs=('q1', 'q2'))) == 'Xi_2^(q1*q2)' assert ascii(OperatorSymbol("Xi_full", hs=1)) == 'Xi_full^(1)' assert ascii(OperatorSymbol("Xi", alpha, beta, hs=1)) == ('Xi^(1)(alpha, beta)') with pytest.raises(ValueError): OperatorSymbol(r'\Xi^2', hs='a') assert ascii(IdentityOperator) == "1" assert ascii(ZeroOperator) == "0" assert ascii(Create(hs=1)) == "a^(1)H" assert ascii(Create(hs=1), show_hs_label=False) == "a^H" assert ascii(Create(hs=1), show_hs_label='subscript') == "a_(1)^H" assert ascii(Destroy(hs=1)) == "a^(1)" fock1 = LocalSpace(1, local_identifiers={ 'Create': 'b', 'Destroy': 'b', 'Phase': 'Ph' }) spin1 = SpinSpace(1, spin=1, local_identifiers={ 'Jz': 'Z', 'Jplus': 'Jp', 'Jminus': 'Jm' }) assert ascii(Create(hs=fock1)) == "b^(1)H" assert ascii(Destroy(hs=fock1)) == "b^(1)" assert ascii(Jz(hs=SpinSpace(1, spin=1))) == "J_z^(1)" assert ascii(Jz(hs=spin1)) == "Z^(1)" assert ascii(Jplus(hs=spin1)) == "Jp^(1)" assert ascii(Jminus(hs=spin1)) == "Jm^(1)" assert ascii(Phase(0.5, hs=1)) == 'Phase^(1)(0.5)' assert ascii(Phase(0.5, hs=fock1)) == 'Ph^(1)(0.5)' assert ascii(Displace(0.5, hs=1)) == 'D^(1)(0.5)' assert ascii(Squeeze(0.5, hs=1)) == 'Squeeze^(1)(0.5)' hs_tls = LocalSpace('1', basis=('g', 'e')) sig_e_g = LocalSigma('e', 'g', hs=hs_tls) assert ascii(sig_e_g) == '|e><g|^(1)' assert ascii(sig_e_g, sig_as_ketbra=False) == 'sigma_e,g^(1)' sig_e_e = LocalProjector('e', hs=hs_tls) assert ascii(sig_e_e, sig_as_ketbra=False) == 'Pi_e^(1)' assert (ascii(BasisKet(0, hs=1) * BasisKet(0, hs=2) * BasisKet(0, hs=3)) == '|0,0,0>^(1*2*3)') assert ascii(BasisKet(0, hs=hs1) * BasisKet(0, hs=hs2)) == '|00>^(q1*q2)' assert (ascii( BasisKet(0, hs=LocalSpace(0, dimension=20)) * BasisKet(0, hs=LocalSpace(1, dimension=20))) == '|0,0>^(0*1)')
def test_unicode_ket_elements(): """Test the unicode representation of "atomic" kets""" hs1 = LocalSpace('q1', basis=('g', 'e')) hs2 = LocalSpace('q2', basis=('g', 'e')) alpha, beta = symbols('alpha, beta') psi_hs1 = KetSymbol('Psi', hs=hs1) assert unicode(psi_hs1) == '|Ψ⟩^(q₁)' assert unicode(psi_hs1, unicode_sub_super=False) == '|Ψ⟩^(q_1)' assert unicode(KetSymbol('Psi', hs=1)) == '|Ψ⟩⁽¹⁾' assert unicode(KetSymbol('Psi', alpha, beta, hs=1)) == '|Ψ(α, β)⟩⁽¹⁾' assert unicode(KetSymbol('Psi', hs=(1, 2))) == '|Ψ⟩^(1⊗2)' assert unicode(KetSymbol('Psi', hs=hs1 * hs2)) == '|Ψ⟩^(q₁⊗q₂)' assert unicode(ZeroKet) == '0' assert unicode(TrivialKet) == '1' assert unicode(BasisKet('e', hs=hs1)) == '|e⟩^(q₁)' assert unicode(BasisKet(1, hs=1)) == '|1⟩⁽¹⁾' assert unicode(CoherentStateKet(2, hs=1)) == '|α=2⟩⁽¹⁾' assert unicode(CoherentStateKet(2.0, hs=1)) == '|α=2⟩⁽¹⁾' unicode.printer.cache = {} assert unicode(CoherentStateKet(2.0, hs=1)) == '|α=2⟩⁽¹⁾' assert unicode(CoherentStateKet(2.1, hs=1)) == '|α=2.1⟩⁽¹⁾'
def test_ascii_bra_elements(): """Test the ascii representation of "atomic" kets""" hs1 = LocalSpace('q1', basis=('g', 'e')) hs2 = LocalSpace('q2', basis=('g', 'e')) bra = Bra(KetSymbol('Psi', hs=1)) alpha, beta = symbols('alpha, beta') assert ascii(Bra(KetSymbol('Psi', hs=hs1))) == '<Psi|^(q1)' assert ascii(bra) == '<Psi|^(1)' assert ascii(bra, show_hs_label=False) == '<Psi|' assert ascii(bra, show_hs_label='subscript') == '<Psi|_(1)' assert ascii(Bra(KetSymbol('Psi', alpha, beta, hs=hs1))) == ('<Psi(alpha, beta)|^(q1)') assert ascii(Bra(KetSymbol('Psi', hs=(1, 2)))) == '<Psi|^(1*2)' assert ascii(Bra(KetSymbol('Psi', hs=hs1 * hs2))) == '<Psi|^(q1*q2)' assert ascii(KetSymbol('Psi', hs=1).dag()) == '<Psi|^(1)' assert ascii(Bra(ZeroKet)) == '0' assert ascii(Bra(TrivialKet)) == '1' assert ascii(BasisKet('e', hs=hs1).adjoint()) == '<e|^(q1)' assert ascii(BasisKet(1, hs=1).adjoint()) == '<1|^(1)' assert ascii(CoherentStateKet(2.0, hs=1).dag()) == '<alpha=2|^(1)' assert ascii(CoherentStateKet(2.1, hs=1).dag()) == '<alpha=2.1|^(1)' assert ascii(CoherentStateKet(0.5j, hs=1).dag()) == '<alpha=0.5j|^(1)'
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
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
def test_ket_tree(): """Test tree representation of a state algebra expression""" hs1 = LocalSpace('q_1', basis=('g', 'e')) hs2 = LocalSpace('q_2', basis=('g', 'e')) ket_g1 = BasisKet('g', hs=hs1) ket_e1 = BasisKet('e', hs=hs1) ket_g2 = BasisKet('g', hs=hs2) ket_e2 = BasisKet('e', hs=hs2) gamma = symbols('gamma', positive=True) phase = exp(-I * gamma) bell1 = (ket_e1 * ket_g2 - phase * ket_g1 * ket_e2) / sqrt(2) bell2 = (ket_e1 * ket_e2 - ket_g1 * ket_g2) / sqrt(2) tree = tree_str(KetBra.create(bell1, bell2)) assert (tree == dedent(r''' . ScalarTimesOperator(1/2, ...) ├─ ScalarValue(1/2) └─ KetBra(..., ...) ├─ KetPlus(|eg⟩^(q₁⊗q₂), ...) │ ├─ TensorKet(|e⟩^(q₁), |g⟩^(q₂)) │ │ ├─ BasisKet(e, hs=ℌ_q₁) │ │ └─ BasisKet(g, hs=ℌ_q₂) │ └─ ScalarTimesKet(-exp(-ⅈ γ), |ge⟩^(q₁⊗q₂)) │ ├─ ScalarValue(-exp(-ⅈ γ)) │ └─ TensorKet(|g⟩^(q₁), |e⟩^(q₂)) │ ├─ BasisKet(g, hs=ℌ_q₁) │ └─ BasisKet(e, hs=ℌ_q₂) └─ KetPlus(|ee⟩^(q₁⊗q₂), -|gg⟩^(q₁⊗q₂)) ├─ TensorKet(|e⟩^(q₁), |e⟩^(q₂)) │ ├─ BasisKet(e, hs=ℌ_q₁) │ └─ BasisKet(e, hs=ℌ_q₂) └─ ScalarTimesKet(-1, |gg⟩^(q₁⊗q₂)) ├─ ScalarValue(-1) └─ TensorKet(|g⟩^(q₁), |g⟩^(q₂)) ├─ BasisKet(g, hs=ℌ_q₁) └─ BasisKet(g, hs=ℌ_q₂) ''').strip())
def test_unicode_symbolic_labels(): """Test unicode representation of symbols with symbolic labels""" i = IdxSym('i') j = IdxSym('j') hs0 = LocalSpace(0) hs1 = LocalSpace(1) Psi = IndexedBase('Psi') assert unicode(BasisKet(FockIndex(2 * i), hs=hs0)) == '|2 i⟩⁽⁰⁾' assert unicode(KetSymbol(StrLabel(2 * i), hs=hs0)) == '|2 i⟩⁽⁰⁾' assert (unicode(KetSymbol(StrLabel(Psi[i, j]), hs=hs0 * hs1)) == '|Ψ_ij⟩^(0⊗1)') expr = BasisKet(FockIndex(i), hs=hs0) * BasisKet(FockIndex(j), hs=hs1) assert unicode(expr) == '|i,j⟩^(0⊗1)' assert unicode(Bra(BasisKet(FockIndex(2 * i), hs=hs0))) == '⟨2 i|⁽⁰⁾' assert (unicode(LocalSigma(FockIndex(i), FockIndex(j), hs=hs0)) == '|i⟩⟨j|⁽⁰⁾') expr = CoherentStateKet(symbols('alpha'), hs=1).to_fock_representation() assert unicode(expr) == 'exp(-α α ⃰/2) (∑_{n ∈ ℌ₁} αⁿ/√n! |n⟩⁽¹⁾)' tls = SpinSpace(label='s', spin='1/2', basis=('down', 'up')) Sig = IndexedBase('sigma') n = IdxSym('n') Sig_n = OperatorSymbol(StrLabel(Sig[n]), hs=tls) assert unicode(Sig_n, show_hs_label=False) == 'σ̂ₙ'
def test_cached_srepr(bell1_expr): """Test that we can get simplified expressions by passing a cache, and that the cache is updated appropriately while printing""" hs1 = LocalSpace('q_1', basis=('g', 'e')) hs2 = LocalSpace('q_2', basis=('g', 'e')) ket_g1 = BasisKet('g', hs=hs1) cache = {hs1: 'hs1', hs2: 'hs2', 1 / sqrt(2): '1/sqrt(2)', -I: '-I'} res = srepr(bell1_expr, cache=cache) expected = ( "ScalarTimesKet(1/sqrt(2), KetPlus(TensorKet(BasisKet('e', hs=hs1), " "BasisKet('g', hs=hs2)), ScalarTimesKet(-I, " "TensorKet(BasisKet('g', hs=hs1), BasisKet('e', hs=hs2)))))") assert res == expected assert ket_g1 in cache assert cache[ket_g1] == "BasisKet('g', hs=hs1)" cache = {hs1: 'hs1', hs2: 'hs2', 1 / sqrt(2): '1/sqrt(2)', -I: '-I'} # note that we *must* use a different cache res = srepr(bell1_expr, cache=cache, indented=True) expected = dedent(r''' ScalarTimesKet( 1/sqrt(2), KetPlus( TensorKet( BasisKet( 'e', hs=hs1), BasisKet( 'g', hs=hs2)), ScalarTimesKet( -I, TensorKet( BasisKet( 'g', hs=hs1), BasisKet( 'e', hs=hs2)))))''').strip() assert res == expected assert ket_g1 in cache assert cache[ket_g1] == "BasisKet(\n 'g',\n hs=hs1)"
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
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
def state_exprs(): """Prepare a list of state algebra expressions""" hs1 = LocalSpace('q1', basis=('g', 'e')) hs2 = LocalSpace('q2', basis=('g', 'e')) ket_g1 = BasisKet('g', hs=hs1) ket_e1 = BasisKet('e', hs=hs1) ket_g2 = BasisKet('g', hs=hs2) ket_e2 = BasisKet('e', hs=hs2) psi1 = KetSymbol("Psi_1", hs=hs1) psi1_l = KetSymbol("Psi_1", hs=hs1) psi2 = KetSymbol("Psi_2", hs=hs1) psi2 = KetSymbol("Psi_2", hs=hs1) psi3 = KetSymbol("Psi_3", hs=hs1) phi = KetSymbol("Phi", hs=hs2) phi_l = KetSymbol("Phi", hs=hs2) A = OperatorSymbol("A_0", hs=hs1) gamma = symbols('gamma') phase = exp(-I * gamma) bell1 = (ket_e1 * ket_g2 - I * ket_g1 * ket_e2) / sqrt(2) bell2 = (ket_e1 * ket_e2 - ket_g1 * ket_g2) / sqrt(2) bra_psi1 = KetSymbol("Psi_1", hs=hs1).dag() bra_psi1_l = KetSymbol("Psi_1", hs=hs1).dag() bra_psi2 = KetSymbol("Psi_2", hs=hs1).dag() bra_psi2 = KetSymbol("Psi_2", hs=hs1).dag() bra_phi_l = KetSymbol("Phi", hs=hs2).dag() return [ KetSymbol('Psi', hs=hs1), KetSymbol('Psi', hs=1), KetSymbol('Psi', hs=(1, 2)), KetSymbol('Psi', symbols('alpha'), symbols('beta'), hs=(1, 2)), KetSymbol('Psi', hs=1), ZeroKet, TrivialKet, BasisKet('e', hs=hs1), BasisKet('excited', hs=LocalSpace(1, basis=('ground', 'excited'))), BasisKet(1, hs=1), CoherentStateKet(2.0, hs=1), CoherentStateKet(2.0, hs=1).to_fock_representation(), Bra(KetSymbol('Psi', hs=hs1)), Bra(KetSymbol('Psi', hs=1)), Bra(KetSymbol('Psi', hs=(1, 2))), Bra(KetSymbol('Psi', hs=hs1 * hs2)), KetSymbol('Psi', hs=1).dag(), Bra(ZeroKet), Bra(TrivialKet), BasisKet('e', hs=hs1).adjoint(), BasisKet(1, hs=1).adjoint(), CoherentStateKet(2.0, hs=1).dag(), psi1 + psi2, psi1 - psi2 + psi3, psi1 * phi, psi1_l * phi_l, phase * psi1, A * psi1, BraKet(psi1, psi2), ket_e1.dag() * ket_e1, ket_g1.dag() * ket_e1, KetBra(psi1, psi2), bell1, BraKet.create(bell1, bell2), KetBra.create(bell1, bell2), (psi1 + psi2).dag(), bra_psi1 + bra_psi2, bra_psi1_l * bra_phi_l, Bra(phase * psi1), (A * psi1).dag(), ]
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
def test_unicode_ket_operations(): """Test the unicode representation of ket operations""" hs1 = LocalSpace('q_1', basis=('g', 'e')) hs2 = LocalSpace('q_2', basis=('g', 'e')) ket_g1 = BasisKet('g', hs=hs1) ket_e1 = BasisKet('e', hs=hs1) ket_g2 = BasisKet('g', hs=hs2) ket_e2 = BasisKet('e', hs=hs2) psi1 = KetSymbol("Psi_1", hs=hs1) psi2 = KetSymbol("Psi_2", hs=hs1) phi = KetSymbol("Phi", hs=hs2) A = OperatorSymbol("A_0", hs=hs1) gamma = symbols('gamma', positive=True) alpha = symbols('alpha') beta = symbols('beta') phase = exp(-I * gamma) i = IdxSym('i') assert unicode(psi1 + psi2) == '|Ψ₁⟩^(q₁) + |Ψ₂⟩^(q₁)' assert unicode(psi1 * phi) == '|Ψ₁⟩^(q₁) ⊗ |Φ⟩^(q₂)' assert unicode(phase * psi1) == 'exp(-ⅈ γ) |Ψ₁⟩^(q₁)' assert unicode((alpha + 1) * KetSymbol('Psi', hs=0)) == '(α + 1) |Ψ⟩⁽⁰⁾' assert (unicode( A * psi1) == 'A\u0302_0^(q\u2081) |\u03a8\u2081\u27e9^(q\u2081)') # Â_0^(q₁) |Ψ₁⟩^(q₁) assert unicode(BraKet(psi1, psi2)) == '⟨Ψ₁|Ψ₂⟩^(q₁)' expr = BraKet(KetSymbol('Psi_1', alpha, hs=hs1), KetSymbol('Psi_2', beta, hs=hs1)) assert unicode(expr) == '⟨Ψ₁(α)|Ψ₂(β)⟩^(q₁)' assert unicode(ket_e1.dag() * ket_e1) == '1' assert unicode(ket_g1.dag() * ket_e1) == '0' assert unicode(KetBra(psi1, psi2)) == '|Ψ₁⟩⟨Ψ₂|^(q₁)' expr = KetBra(KetSymbol('Psi_1', alpha, hs=hs1), KetSymbol('Psi_2', beta, hs=hs1)) assert unicode(expr) == '|Ψ₁(α)⟩⟨Ψ₂(β)|^(q₁)' bell1 = (ket_e1 * ket_g2 - I * ket_g1 * ket_e2) / sqrt(2) bell2 = (ket_e1 * ket_e2 - ket_g1 * ket_g2) / sqrt(2) assert unicode(bell1) == '1/√2 (|eg⟩^(q₁⊗q₂) - ⅈ |ge⟩^(q₁⊗q₂))' assert (unicode(BraKet.create( bell1, bell2)) == r'1/2 (⟨eg|^(q₁⊗q₂) + ⅈ ⟨ge|^(q₁⊗q₂)) (|ee⟩^(q₁⊗q₂) - ' r'|gg⟩^(q₁⊗q₂))') assert (unicode(KetBra.create( bell1, bell2)) == r'1/2 (|eg⟩^(q₁⊗q₂) - ⅈ |ge⟩^(q₁⊗q₂))(⟨ee|^(q₁⊗q₂) - ' r'⟨gg|^(q₁⊗q₂))') assert (unicode( KetBra.create(bell1, bell2), show_hs_label=False) == r'1/2 (|eg⟩ - ⅈ |ge⟩)(⟨ee| - ⟨gg|)') expr = KetBra(KetSymbol('Psi', hs=0), BasisKet(FockIndex(i), hs=0)) assert unicode(expr) == "|Ψ⟩⟨i|⁽⁰⁾" expr = KetBra(BasisKet(FockIndex(i), hs=0), KetSymbol('Psi', hs=0)) assert unicode(expr) == "|i⟩⟨Ψ|⁽⁰⁾" expr = BraKet(KetSymbol('Psi', hs=0), BasisKet(FockIndex(i), hs=0)) assert unicode(expr) == "⟨Ψ|i⟩⁽⁰⁾" expr = BraKet(BasisKet(FockIndex(i), hs=0), KetSymbol('Psi', hs=0)) assert unicode(expr) == "⟨i|Ψ⟩⁽⁰⁾"
def test_tex_ket_operations(): """Test the tex representation of ket operations""" hs1 = LocalSpace('q_1', basis=('g', 'e')) hs2 = LocalSpace('q_2', basis=('g', 'e')) ket_g1 = BasisKet('g', hs=hs1) ket_e1 = BasisKet('e', hs=hs1) ket_g2 = BasisKet('g', hs=hs2) ket_e2 = BasisKet('e', hs=hs2) psi1 = KetSymbol("Psi_1", hs=hs1) psi2 = KetSymbol("Psi_2", hs=hs1) psi2 = KetSymbol("Psi_2", hs=hs1) psi3 = KetSymbol("Psi_3", hs=hs1) phi = KetSymbol("Phi", hs=hs2) A = OperatorSymbol("A_0", hs=hs1) gamma = symbols('gamma', positive=True) alpha = symbols('alpha') beta = symbols('beta') phase = exp(-I * gamma) i = IdxSym('i') assert (latex(psi1 + psi2) == r'\left\lvert \Psi_{1} \right\rangle^{(q_{1})} + ' r'\left\lvert \Psi_{2} \right\rangle^{(q_{1})}') assert (latex(psi1 - psi2 + psi3) == r'\left\lvert \Psi_{1} \right\rangle^{(q_{1})} - ' r'\left\lvert \Psi_{2} \right\rangle^{(q_{1})} + ' r'\left\lvert \Psi_{3} \right\rangle^{(q_{1})}') assert (latex( psi1 * phi) == r'\left\lvert \Psi_{1} \right\rangle^{(q_{1})} \otimes ' r'\left\lvert \Phi \right\rangle^{(q_{2})}') assert (latex(phase * psi1) == r'e^{- i \gamma} \left\lvert \Psi_{1} \right\rangle^{(q_{1})}') assert (latex((alpha + 1) * KetSymbol('Psi', hs=0)) == r'\left(\alpha + 1\right) \left\lvert \Psi \right\rangle^{(0)}') assert (latex( A * psi1 ) == r'\hat{A}_{0}^{(q_{1})} \left\lvert \Psi_{1} \right\rangle^{(q_{1})}') braket = BraKet(psi1, psi2) assert ( latex(braket, show_hs_label='subscript') == r'\left\langle \Psi_{1} \middle\vert \Psi_{2} \right\rangle_{(q_{1})}') assert (latex(braket, show_hs_label=False) == r'\left\langle \Psi_{1} \middle\vert \Psi_{2} \right\rangle') expr = BraKet(KetSymbol('Psi_1', alpha, hs=hs1), KetSymbol('Psi_2', beta, hs=hs1)) assert (latex(expr) == r'\left\langle \Psi_{1}\left(\alpha\right) \middle\vert ' r'\Psi_{2}\left(\beta\right) \right\rangle^{(q_{1})}') assert (latex( ket_e1 * ket_e2) == r'\left\lvert ee \right\rangle^{(q_{1} \otimes q_{2})}') assert latex(ket_e1.dag() * ket_e1) == r'1' assert latex(ket_g1.dag() * ket_e1) == r'0' ketbra = KetBra(psi1, psi2) assert (latex(ketbra) == r'\left\lvert \Psi_{1} \middle\rangle\!' r'\middle\langle \Psi_{2} \right\rvert^{(q_{1})}') assert (latex( ketbra, show_hs_label='subscript') == r'\left\lvert \Psi_{1} \middle\rangle\!' r'\middle\langle \Psi_{2} \right\rvert_{(q_{1})}') assert (latex( ketbra, show_hs_label=False) == r'\left\lvert \Psi_{1} \middle\rangle\!' r'\middle\langle \Psi_{2} \right\rvert') expr = KetBra(KetSymbol('Psi_1', alpha, hs=hs1), KetSymbol('Psi_2', beta, hs=hs1)) assert ( latex(expr) == r'\left\lvert \Psi_{1}\left(\alpha\right) \middle\rangle\!' r'\middle\langle \Psi_{2}\left(\beta\right) \right\rvert^{(q_{1})}') bell1 = (ket_e1 * ket_g2 - I * ket_g1 * ket_e2) / sqrt(2) bell2 = (ket_e1 * ket_e2 - ket_g1 * ket_g2) / sqrt(2) assert (latex(bell1) == r'\frac{1}{\sqrt{2}} \left(\left\lvert eg \right\rangle^{(q_{1} ' r'\otimes q_{2})} - i \left\lvert ge \right\rangle' r'^{(q_{1} \otimes q_{2})}\right)') assert (latex(bell2) == r'\frac{1}{\sqrt{2}} \left(\left\lvert ee \right\rangle^{(q_{1} ' r'\otimes q_{2})} - \left\lvert gg \right\rangle' r'^{(q_{1} \otimes q_{2})}\right)') assert (latex(bell2, show_hs_label=False) == r'\frac{1}{\sqrt{2}} \left(\left\lvert ee \right\rangle - ' r'\left\lvert gg \right\rangle\right)') assert BraKet.create(bell1, bell2).expand() == 0 assert (latex(BraKet.create( bell1, bell2)) == r'\frac{1}{2} \left(\left\langle eg \right\rvert' r'^{(q_{1} \otimes q_{2})} + i \left\langle ge \right\rvert' r'^{(q_{1} \otimes q_{2})}\right) ' r'\left(\left\lvert ee \right\rangle^{(q_{1} \otimes q_{2})} ' r'- \left\lvert gg \right\rangle^{(q_{1} \otimes q_{2})}\right)') assert ( latex(KetBra.create( bell1, bell2)) == r'\frac{1}{2} \left(\left\lvert eg \right\rangle' r'^{(q_{1} \otimes q_{2})} - i \left\lvert ge \right\rangle' r'^{(q_{1} \otimes q_{2})}\right)\left(\left\langle ee \right\rvert' r'^{(q_{1} \otimes q_{2})} - \left\langle gg \right\rvert' r'^{(q_{1} \otimes q_{2})}\right)') with configure_printing(tex_use_braket=True): expr = KetBra(KetSymbol('Psi', hs=0), BasisKet(FockIndex(i), hs=0)) assert latex(expr) == r'\Ket{\Psi}\!\Bra{i}^{(0)}' expr = KetBra(BasisKet(FockIndex(i), hs=0), KetSymbol('Psi', hs=0)) assert latex(expr) == r'\Ket{i}\!\Bra{\Psi}^{(0)}' expr = BraKet(KetSymbol('Psi', hs=0), BasisKet(FockIndex(i), hs=0)) assert latex(expr) == r'\Braket{\Psi | i}^(0)' expr = BraKet(BasisKet(FockIndex(i), hs=0), KetSymbol('Psi', hs=0)) assert latex(expr) == r'\Braket{i | \Psi}^(0)'
def test_ascii_ket_operations(): """Test the ascii representation of ket operations""" hs1 = LocalSpace('q_1', basis=('g', 'e')) hs2 = LocalSpace('q_2', basis=('g', 'e')) ket_g1 = BasisKet('g', hs=hs1) ket_e1 = BasisKet('e', hs=hs1) ket_g2 = BasisKet('g', hs=hs2) ket_e2 = BasisKet('e', hs=hs2) psi1 = KetSymbol("Psi_1", hs=hs1) psi2 = KetSymbol("Psi_2", hs=hs1) psi2 = KetSymbol("Psi_2", hs=hs1) psi3 = KetSymbol("Psi_3", hs=hs1) phi = KetSymbol("Phi", hs=hs2) A = OperatorSymbol("A_0", hs=hs1) gamma = symbols('gamma', positive=True) alpha = symbols('alpha') beta = symbols('beta') phase = exp(-I * gamma) i = IdxSym('i') assert ascii(psi1 + psi2) == '|Psi_1>^(q_1) + |Psi_2>^(q_1)' assert (ascii(psi1 - psi2 + psi3) == '|Psi_1>^(q_1) - |Psi_2>^(q_1) + |Psi_3>^(q_1)') with pytest.raises(UnequalSpaces): psi1 + phi with pytest.raises(AttributeError): (psi1 * phi).label assert ascii(psi1 * phi) == '|Psi_1>^(q_1) * |Phi>^(q_2)' with pytest.raises(OverlappingSpaces): psi1 * psi2 assert ascii(phase * psi1) == 'exp(-I*gamma) * |Psi_1>^(q_1)' assert (ascii( (alpha + 1) * KetSymbol('Psi', hs=0)) == '(alpha + 1) * |Psi>^(0)') assert ascii(A * psi1) == 'A_0^(q_1) |Psi_1>^(q_1)' with pytest.raises(SpaceTooLargeError): A * phi assert ascii(BraKet(psi1, psi2)) == '<Psi_1|Psi_2>^(q_1)' expr = BraKet(KetSymbol('Psi_1', alpha, hs=hs1), KetSymbol('Psi_2', beta, hs=hs1)) assert ascii(expr) == '<Psi_1(alpha)|Psi_2(beta)>^(q_1)' assert ascii(psi1.dag() * psi2) == '<Psi_1|Psi_2>^(q_1)' assert ascii(ket_e1.dag() * ket_e1) == '1' assert ascii(ket_g1.dag() * ket_e1) == '0' assert ascii(KetBra(psi1, psi2)) == '|Psi_1><Psi_2|^(q_1)' expr = KetBra(KetSymbol('Psi_1', alpha, hs=hs1), KetSymbol('Psi_2', beta, hs=hs1)) assert ascii(expr) == '|Psi_1(alpha)><Psi_2(beta)|^(q_1)' bell1 = (ket_e1 * ket_g2 - I * ket_g1 * ket_e2) / sqrt(2) bell2 = (ket_e1 * ket_e2 - ket_g1 * ket_g2) / sqrt(2) assert ascii(bell1) == '1/sqrt(2) * (|eg>^(q_1*q_2) - I * |ge>^(q_1*q_2))' assert ascii(bell2) == '1/sqrt(2) * (|ee>^(q_1*q_2) - |gg>^(q_1*q_2))' expr = BraKet.create(bell1, bell2) expected = ( r'1/2 * (<eg|^(q_1*q_2) + I * <ge|^(q_1*q_2)) * (|ee>^(q_1*q_2) ' r'- |gg>^(q_1*q_2))') assert ascii(expr) == expected assert (ascii(KetBra.create(bell1, bell2)) == '1/2 * (|eg>^(q_1*q_2) - I * |ge>^(q_1*q_2))(<ee|^(q_1*q_2) ' '- <gg|^(q_1*q_2))') expr = KetBra(KetSymbol('Psi', hs=0), BasisKet(FockIndex(i), hs=0)) assert ascii(expr) == "|Psi><i|^(0)" expr = KetBra(BasisKet(FockIndex(i), hs=0), KetSymbol('Psi', hs=0)) assert ascii(expr) == "|i><Psi|^(0)" expr = BraKet(KetSymbol('Psi', hs=0), BasisKet(FockIndex(i), hs=0)) assert ascii(expr) == "<Psi|i>^(0)" expr = BraKet(BasisKet(FockIndex(i), hs=0), KetSymbol('Psi', hs=0)) assert ascii(expr) == "<i|Psi>^(0)"
{}, ScalarTimesOperator(gamma, OpA), ), # 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