def test_eq_substitute(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') eq1 = eq0.apply('substitute', {E0: 0}).reset() eq2 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0)) assert eq1 == eq2
def test_indexed_hs_not_disjoint(): i, j = symbols('i, j', cls=IdxSym) hs_i = LocalSpace(StrLabel(i)) hs_j = LocalSpace(StrLabel(j)) assert not hs_i.isdisjoint(hs_i) assert not hs_i.isdisjoint(hs_j) expr = Create(hs=hs_j) * Destroy(hs=hs_i) assert expr.args == (Create(hs=hs_j), Destroy(hs=hs_i))
def test_eq_sub_const(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') eq = eq0 - E0 assert eq.lhs == H_0 - E0 assert eq.rhs == ω * Create(hs=0) * Destroy(hs=0) assert eq._tag is None
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_apply_mtd(): H_0 = OperatorSymbol('H_0', hs=0) H = OperatorSymbol('H', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') eq = eq0.apply('substitute', {H_0: H, E0: 0}).tag('new') assert eq.lhs == H assert eq.rhs == ω * Create(hs=0) * Destroy(hs=0) assert eq._tag == 'new'
def test_eq_sub_eq(): ω, E0 = sympy.symbols('omega, E_0') H_0 = OperatorSymbol('H_0', hs=0) H_1 = OperatorSymbol('H_1', hs=0) mu = OperatorSymbol('mu', hs=0) eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') eq1 = Eq(H_1, mu + E0, tag='1') eq = eq0 - eq1 assert eq.lhs == H_0 - H_1 assert eq.rhs == ω * Create(hs=0) * Destroy(hs=0) - mu assert eq._tag is None
def operator_exprs(): """Prepare a list of operator algebra expressions""" hs1 = LocalSpace('q1', dimension=2) hs2 = LocalSpace('q2', dimension=2) A = OperatorSymbol("A", hs=hs1) B = OperatorSymbol("B", hs=hs1) C = OperatorSymbol("C", hs=hs2) a, b = symbols('a, b') A_ab = OperatorSymbol("A", a, b, hs=0) gamma = symbols('gamma') return [ OperatorSymbol("A", hs=hs1), OperatorSymbol("A_1", hs=hs1 * hs2), OperatorSymbol("A_1", symbols('alpha'), symbols('beta'), hs=hs1 * hs2), A_ab.diff(a, n=2).diff(b), A_ab.diff(a, n=2).diff(b).evaluate_at({a: 0}), OperatorSymbol("Xi_2", hs=(r'q1', 'q2')), OperatorSymbol("Xi_full", hs=1), IdentityOperator, ZeroOperator, Create(hs=1), Create(hs=LocalSpace(1, local_identifiers={'Create': 'b'})), Destroy(hs=1), Destroy(hs=LocalSpace(1, local_identifiers={'Destroy': 'b'})), Jz(hs=SpinSpace(1, spin=1)), Jz(hs=SpinSpace(1, spin=1, local_identifiers={'Jz': 'Z'})), Jplus(hs=SpinSpace(1, spin=1, local_identifiers={'Jplus': 'Jp'})), Jminus(hs=SpinSpace(1, spin=1, local_identifiers={'Jminus': 'Jm'})), Phase(0.5, hs=1), Phase(0.5, hs=LocalSpace(1, local_identifiers={'PhaseCC': 'Ph'})), Displace(0.5, hs=1), Squeeze(0.5, hs=1), LocalSigma('e', 'g', hs=LocalSpace(1, basis=('g', 'e'))), LocalSigma('e', 'e', hs=LocalSpace(1, basis=('g', 'e'))), A + B, A * B, A * C, 2 * A, 2j * A, (1 + 2j) * A, gamma**2 * A, -(gamma**2) / 2 * A, tr(A * C, over_space=hs2), Adjoint(A), Adjoint(A + B), PseudoInverse(A), NullSpaceProjector(A), A - B, 2 * A - sqrt(gamma) * (B + C), Commutator(A, B), ]
def test_ascii_equation(): """Test printing of the Eq class""" eq_1 = Eq(lhs=OperatorSymbol('H', hs=0), rhs=Create(hs=0) * Destroy(hs=0)) # fmt: off eq = (eq_1.apply_to_lhs(lambda expr: expr + 1).apply_to_rhs( lambda expr: expr + 1).apply_to_rhs(lambda expr: expr**2).tag( 3).transform(lambda eq: eq + 1).tag(4).apply_to_rhs('expand'). apply_to_lhs(lambda expr: expr**2).tag(5).apply( 'expand').apply_to_lhs(lambda expr: expr**2).tag(6).apply_to_lhs( 'expand').apply_to_rhs(lambda expr: expr + 1)) # fmt: on assert ascii(eq_1) == 'H^(0) = a^(0)H * a^(0)' assert ascii(eq_1.tag(1).reset()) == 'H^(0) = a^(0)H * a^(0) (1)' assert ascii(eq, show_hs_label=False).strip() == (r''' H = a^H * a 1 + H = a^H * a = 1 + a^H * a = (1 + a^H * a) * (1 + a^H * a) (3) 2 + H = 1 + (1 + a^H * a) * (1 + a^H * a) (4) = 2 + a^H * a^H * a * a + 3 * a^H * a (2 + H) * (2 + H) = 2 + a^H * a^H * a * a + 3 * a^H * a (5) 4 + 4 * H + H * H = 2 + a^H * a^H * a * a + 3 * a^H * a (4 + 4 * H + H * H) * (4 + 4 * H + H * H) = 2 + a^H * a^H * a * a + 3 * a^H * a (6) 16 + 32 * H + H * H * H * H + 8 * H * H * H + 24 * H * H = 2 + a^H * a^H * a * a + 3 * a^H * a = 3 + a^H * a^H * a * a + 3 * a^H * a '''.strip())
def test_unicode_equation(): """Test printing of the Eq class""" eq_1 = Eq(lhs=OperatorSymbol('H', hs=0), rhs=Create(hs=0) * Destroy(hs=0)) # fmt: off eq = (eq_1.apply_to_lhs(lambda expr: expr + 1).apply_to_rhs( lambda expr: expr + 1).apply_to_rhs(lambda expr: expr**2).tag( 3).transform(lambda eq: eq + 1).tag(4).apply_to_rhs('expand'). apply_to_lhs(lambda expr: expr**2).tag(5).apply( 'expand').apply_to_lhs(lambda expr: expr**2).tag(6).apply_to_lhs( 'expand').apply_to_rhs(lambda expr: expr + 1)) # fmt: on assert unicode(eq_1) == 'Ĥ⁽⁰⁾ = â^(0)† â⁽⁰⁾' assert unicode(eq_1.tag(1)) == 'Ĥ⁽⁰⁾ = â^(0)† â⁽⁰⁾ (1)' unicode_lines = unicode(eq, show_hs_label=False).split("\n") expected = [ ' Ĥ = â^† â', ' 𝟙 + Ĥ = â^† â', ' = 𝟙 + â^† â', ' = (𝟙 + â^† â) (𝟙 + â^† â) (3)', ' 2 + Ĥ = 𝟙 + (𝟙 + â^† â) (𝟙 + â^† â) (4)', ' = 2 + â^† â^† â â + 3 â^† â', ' (2 + Ĥ) (2 + Ĥ) = 2 + â^† â^† â â + 3 â^† â (5)', ' 4 + 4 Ĥ + Ĥ Ĥ = 2 + â^† â^† â â + 3 â^† â', ' (4 + 4 Ĥ + Ĥ Ĥ) (4 + 4 Ĥ + Ĥ Ĥ) = 2 + â^† â^† â â + 3 â^† â (6)', '16 + 32 Ĥ + Ĥ Ĥ Ĥ Ĥ + 8 Ĥ Ĥ Ĥ + 24 Ĥ Ĥ = 2 + â^† â^† â â + 3 â^† â', ' = 3 + â^† â^† â â + 3 â^† â', ] for i, line in enumerate(unicode_lines): assert line == expected[i] eq = Eq(OperatorSymbol('H', hs=0), 0, eq_sym_str='→') assert unicode(eq, show_hs_label=False) == 'Ĥ → 0'
def test_eq_copy(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') eq = eq0.copy() assert eq == eq0 assert eq is not eq0
def test_repr_latex(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') Eq.latex_renderer = staticmethod(latex) eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') repr1 = eq0._repr_latex_() repr2 = latex(eq0) assert repr1 == repr2
def test_apply_to_lhs(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') eq = eq0.apply_to_lhs(lambda expr: expr + E0).tag('new') assert eq.lhs == H_0 + E0 assert eq.rhs == eq0.rhs assert eq._tag == 'new'
def test_eq_mult_const(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') eq = 2 * eq0 assert eq == eq0 * 2 assert eq.lhs == 2 * eq0.lhs assert eq.rhs == 2 * eq0.rhs assert eq._tag is None
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_quantum_symbols_with_indexedhs(): """Test the free_symbols method for objects that have a Hilbert space with a sybmolic label, for the example of an OperatorSymbol""" i, j = symbols('i, j', cls=IdxSym) hs_i = LocalSpace(StrLabel(i)) hs_j = LocalSpace(StrLabel(j)) A = OperatorSymbol("A", hs=hs_i * hs_j) assert A.free_symbols == {i, j} expr = Create(hs=hs_i) * Destroy(hs=hs_i) assert expr.free_symbols == { i, }
def test_unchanged_apply(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') assert eq0.apply(lambda s: s.expand()).reset() == eq0 assert eq0.apply(lambda s: s.expand()) == eq0 assert eq0.apply(lambda s: s.expand())._lhs is None assert eq0.apply('expand').reset() == eq0 assert eq0.apply('expand') == eq0 assert eq0.apply('expand')._lhs is None
def test_unicode_operator_operations(): """Test the unicode representation of operator algebra operations""" hs1 = LocalSpace('q_1', dimension=2) hs2 = LocalSpace('q_2', dimension=2) A = OperatorSymbol("A", hs=hs1) B = OperatorSymbol("B", hs=hs1) C = OperatorSymbol("C", hs=hs2) psi = KetSymbol('Psi', hs=hs1) gamma = symbols('gamma', positive=True) assert unicode(A + B) == 'A\u0302^(q\u2081) + B\u0302^(q\u2081)' # Â^(q₁) + B̂^(q₁) assert unicode(A * B) == 'A\u0302^(q\u2081) B\u0302^(q\u2081)' # Â^(q₁) B̂^(q₁) assert unicode(A * C) == 'A\u0302^(q\u2081) C\u0302^(q\u2082)' # Â^(q₁) Ĉ^(q₂) assert unicode(2 * A) == '2 A\u0302^(q\u2081)' # 2 Â^(q₁) assert unicode(2j * A) == '2j A\u0302^(q\u2081)' # 2j Â^(q₁) assert unicode((1 + 2j) * A) == '(1+2j) A\u0302^(q\u2081)' # (1+2j) Â^(q₁) assert unicode(gamma**2 * A) == '\u03b3\xb2 A\u0302^(q\u2081)' # γ² Â^(q₁) assert unicode(-(gamma**2) / 2 * A) == '-\u03b3\xb2/2 A\u0302^(q\u2081)' # -γ²/2 Â^(q₁) assert (unicode(tr( A * C, over_space=hs2)) == 'tr_(q\u2082)[C\u0302^(q\u2082)] A\u0302^(q\u2081)' ) # tr_(q₂)[Ĉ^(q₂)] Â^(q₁) assert unicode(Adjoint(A)) == 'A\u0302^(q\u2081)\u2020' # Â^(q₁)† assert unicode(Adjoint(Create(hs=1))) == 'a\u0302\u207d\xb9\u207e' # â⁽¹⁾ assert unicode(PseudoInverse(A)) == '(A\u0302^(q\u2081))^+' # (Â^(q₁))^+ assert unicode(NullSpaceProjector(A)) == 'P\u0302_Ker(A\u0302^(q\u2081))' # P̂_Ker(Â^(q₁)) assert unicode(A - B) == 'A\u0302^(q\u2081) - B\u0302^(q\u2081)' # Â^(q₁) - B̂^(q₁) assert unicode(2 * A - sqrt(gamma) * (B + C)) in [ '2 A\u0302^(q\u2081) - \u221a\u03b3 (B\u0302^(q\u2081) ' '+ C\u0302^(q\u2082))', '2 A\u0302^(q\u2081) - sqrt(\u03b3) (B\u0302^(q\u2081) ' '+ C\u0302^(q\u2082))', ] # 2 Â^(q₁) - √γ (B̂^(q₁) + Ĉ^(q₂)) assert (unicode(Commutator(A, B)) == '[A\u0302^(q\u2081), B\u0302^(q\u2081)]') # [Â^(q₁), B̂^(q₁)] expr = (Commutator(A, B) * psi).dag() assert unicode(expr, show_hs_label=False) == r'⟨Ψ| [Â, B̂]^†'
def test_tex_operator_operations(): """Test the tex representation of operator algebra operations""" hs1 = LocalSpace('q_1', dimension=2) hs2 = LocalSpace('q_2', dimension=2) A = OperatorSymbol("A", hs=hs1) B = OperatorSymbol("B", hs=hs1) C = OperatorSymbol("C", hs=hs2) psi = KetSymbol('Psi', hs=hs1) gamma = symbols('gamma', positive=True) assert latex(A.dag()) == r'\hat{A}^{(q_{1})\dagger}' assert latex(A + B) == r'\hat{A}^{(q_{1})} + \hat{B}^{(q_{1})}' assert latex(A * B) == r'\hat{A}^{(q_{1})} \hat{B}^{(q_{1})}' assert latex(A * C) == r'\hat{A}^{(q_{1})} \hat{C}^{(q_{2})}' assert latex(2 * A) == r'2 \hat{A}^{(q_{1})}' assert latex(2j * A) == r'2i \hat{A}^{(q_{1})}' assert latex((1 + 2j) * A) == r'(1+2i) \hat{A}^{(q_{1})}' assert latex(gamma**2 * A) == r'\gamma^{2} \hat{A}^{(q_{1})}' assert (latex(-(gamma**2) / 2 * A) == r'- \frac{\gamma^{2}}{2} \hat{A}^{(q_{1})}') assert (latex(tr( A * C, over_space=hs2)) == r'{\rm tr}_{q_{2}}\left[\hat{C}^{(q_{2})}\right] ' r'\hat{A}^{(q_{1})}') assert latex(Adjoint(A)) == r'\hat{A}^{(q_{1})\dagger}' assert (latex(Adjoint( A**2)) == r'\left(\hat{A}^{(q_{1})} \hat{A}^{(q_{1})}\right)^\dagger') assert (latex( Adjoint(A)**2) == r'\hat{A}^{(q_{1})\dagger} \hat{A}^{(q_{1})\dagger}') assert latex(Adjoint(Create(hs=1))) == r'\hat{a}^{(1)}' assert (latex(Adjoint(A + B)) == r'\left(\hat{A}^{(q_{1})} + \hat{B}^{(q_{1})}\right)^\dagger') assert latex(PseudoInverse(A)) == r'\left(\hat{A}^{(q_{1})}\right)^+' assert (latex( PseudoInverse(A)**2 ) == r'\left(\hat{A}^{(q_{1})}\right)^+ \left(\hat{A}^{(q_{1})}\right)^+') assert (latex(NullSpaceProjector(A)) == r'\hat{P}_{Ker}\left(\hat{A}^{(q_{1})}\right)') assert latex(A - B) == r'\hat{A}^{(q_{1})} - \hat{B}^{(q_{1})}' assert (latex(A - B + C) == r'\hat{A}^{(q_{1})} - \hat{B}^{(q_{1})} + \hat{C}^{(q_{2})}') assert (latex(2 * A - sqrt(gamma) * (B + C)) == r'2 \hat{A}^{(q_{1})} - \sqrt{\gamma} \left(\hat{B}^{(q_{1})} + ' r'\hat{C}^{(q_{2})}\right)') assert (latex(Commutator( A, B)) == r'\left[\hat{A}^{(q_{1})}, \hat{B}^{(q_{1})}\right]') expr = (Commutator(A, B) * psi).dag() assert (latex(expr, show_hs_label=False) == r'\left\langle \Psi \right\rvert \left[\hat{A}, ' r'\hat{B}\right]^{\dagger}')
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_ascii_operator_operations(): """Test the ascii representation of operator algebra operations""" hs1 = LocalSpace('q_1', dimension=2) hs2 = LocalSpace('q_2', dimension=2) A = OperatorSymbol("A", hs=hs1) B = OperatorSymbol("B", hs=hs1) C = OperatorSymbol("C", hs=hs2) D = OperatorSymbol("D", hs=hs1) psi = KetSymbol('Psi', hs=hs1) gamma = symbols('gamma', positive=True) assert ascii(A + B) == 'A^(q_1) + B^(q_1)' assert ascii(A * B) == 'A^(q_1) * B^(q_1)' assert ascii(A * C) == 'A^(q_1) * C^(q_2)' assert ascii(A * (B + D)) == 'A^(q_1) * (B^(q_1) + D^(q_1))' assert ascii(A * (B - D)) == 'A^(q_1) * (B^(q_1) - D^(q_1))' assert (ascii( (A + B) * (-2 * B - D)) == '(A^(q_1) + B^(q_1)) * (-D^(q_1) - 2 * B^(q_1))') assert ascii(OperatorTimes(A, -B)) == 'A^(q_1) * (-B^(q_1))' assert ascii(OperatorTimes(A, -B), show_hs_label=False) == 'A * (-B)' assert ascii(2 * A) == '2 * A^(q_1)' assert ascii(2j * A) == '2j * A^(q_1)' assert ascii((1 + 2j) * A) == '(1+2j) * A^(q_1)' assert ascii(gamma**2 * A) == 'gamma**2 * A^(q_1)' assert ascii(-(gamma**2) / 2 * A) == '-gamma**2/2 * A^(q_1)' assert ascii(tr(A * C, over_space=hs2)) == 'tr_(q_2)[C^(q_2)] * A^(q_1)' expr = A + OperatorPlusMinusCC(B * D) assert ascii(expr, show_hs_label=False) == 'A + (B * D + c.c.)' expr = A + OperatorPlusMinusCC(B + D) assert ascii(expr, show_hs_label=False) == 'A + (B + D + c.c.)' expr = A * OperatorPlusMinusCC(B * D) assert ascii(expr, show_hs_label=False) == 'A * (B * D + c.c.)' assert ascii(Adjoint(A)) == 'A^(q_1)H' assert ascii(Adjoint(Create(hs=1))) == 'a^(1)' assert ascii(Adjoint(A + B)) == '(A^(q_1) + B^(q_1))^H' assert ascii(PseudoInverse(A)) == '(A^(q_1))^+' assert ascii(NullSpaceProjector(A)) == 'P_Ker(A^(q_1))' assert ascii(A - B) == 'A^(q_1) - B^(q_1)' assert ascii(A - B + C) == 'A^(q_1) - B^(q_1) + C^(q_2)' expr = 2 * A - sqrt(gamma) * (B + C) assert ascii(expr) == '2 * A^(q_1) - sqrt(gamma) * (B^(q_1) + C^(q_2))' assert ascii(Commutator(A, B)) == r'[A^(q_1), B^(q_1)]' expr = (Commutator(A, B) * psi).dag() assert ascii(expr, show_hs_label=False) == r'<Psi| [A, B]^H'
def test_tex_equation(): """Test printing of the Eq class""" eq_1 = Eq(lhs=OperatorSymbol('H', hs=0), rhs=Create(hs=0) * Destroy(hs=0)) # fmt: off eq = (eq_1.apply_to_lhs(lambda expr: expr + 1).apply_to_rhs( lambda expr: expr + 1).apply_to_rhs(lambda expr: expr**2).tag( 3).transform(lambda eq: eq + 1).tag(4).apply_to_rhs('expand'). apply_to_lhs(lambda expr: expr**2).tag(5).apply( 'expand').apply_to_lhs(lambda expr: expr**2).tag(6).apply_to_lhs( 'expand').apply_to_rhs(lambda expr: expr + 1)) # fmt: on assert latex(eq_1).split("\n") == [ r'\begin{equation}', r' \hat{H}^{(0)} = \hat{a}^{(0)\dagger} \hat{a}^{(0)}', r'\end{equation}', '', ] assert latex(eq_1.tag(1).reset()).split("\n") == [ r'\begin{equation}', r' \hat{H}^{(0)} = \hat{a}^{(0)\dagger} \hat{a}^{(0)}', r'\tag{1}\end{equation}', '', ] tex_lines = latex(eq, show_hs_label=False, tex_op_macro=r'\Op{{{name}}}').split("\n") expected = [ r'\begin{align}', r' \Op{H} &= \Op{a}^{\dagger} \Op{a}\\', r' \mathbb{1} + \Op{H} &= \Op{a}^{\dagger} \Op{a}\\', r' &= \mathbb{1} + \Op{a}^{\dagger} \Op{a}\\', r' &= \left(\mathbb{1} + \Op{a}^{\dagger} \Op{a}\right) \left(\mathbb{1} + \Op{a}^{\dagger} \Op{a}\right)\tag{3}\\', r' 2 + \Op{H} &= \mathbb{1} + \left(\mathbb{1} + \Op{a}^{\dagger} \Op{a}\right) \left(\mathbb{1} + \Op{a}^{\dagger} \Op{a}\right)\tag{4}\\', r' &= 2 + \Op{a}^{\dagger} \Op{a}^{\dagger} \Op{a} \Op{a} + 3 \Op{a}^{\dagger} \Op{a}\\', r' \left(2 + \Op{H}\right) \left(2 + \Op{H}\right) &= 2 + \Op{a}^{\dagger} \Op{a}^{\dagger} \Op{a} \Op{a} + 3 \Op{a}^{\dagger} \Op{a}\tag{5}\\', r' 4 + 4 \Op{H} + \Op{H} \Op{H} &= 2 + \Op{a}^{\dagger} \Op{a}^{\dagger} \Op{a} \Op{a} + 3 \Op{a}^{\dagger} \Op{a}\\', r' \left(4 + 4 \Op{H} + \Op{H} \Op{H}\right) \left(4 + 4 \Op{H} + \Op{H} \Op{H}\right) &= 2 + \Op{a}^{\dagger} \Op{a}^{\dagger} \Op{a} \Op{a} + 3 \Op{a}^{\dagger} \Op{a}\tag{6}\\', r' 16 + 32 \Op{H} + \Op{H} \Op{H} \Op{H} \Op{H} + 8 \Op{H} \Op{H} \Op{H} + 24 \Op{H} \Op{H} &= 2 + \Op{a}^{\dagger} \Op{a}^{\dagger} \Op{a} \Op{a} + 3 \Op{a}^{\dagger} \Op{a}\\', r' &= 3 + \Op{a}^{\dagger} \Op{a}^{\dagger} \Op{a} \Op{a} + 3 \Op{a}^{\dagger} \Op{a}', r'\end{align}', r'', ] for i, line in enumerate(tex_lines): assert line == expected[i]
def test_eq_repr(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') assert repr(eq0) == "%s = %s (0)" % (repr(eq0.lhs), repr(eq0.rhs))
def test_no_sympify(): H_0 = OperatorSymbol('H_0', hs=0) ω, E0 = sympy.symbols('omega, E_0') eq0 = Eq(H_0, ω * Create(hs=0) * Destroy(hs=0) + E0, tag='0') with pytest.raises(SympifyError): sympy.sympify(eq0)
def test_tex_operator_elements(): """Test the tex representation of "atomic" operator algebra elements""" hs1 = LocalSpace('q1', dimension=2) hs2 = LocalSpace('q2', dimension=2) alpha, beta = symbols('alpha, beta') fock1 = LocalSpace(1, local_identifiers={ 'Create': 'b', 'Destroy': 'b', 'Phase': 'Phi' }) spin1 = SpinSpace(1, spin=1, local_identifiers={ 'Jz': 'Z', 'Jplus': 'Jp', 'Jminus': 'Jm' }) assert latex(OperatorSymbol("A", hs=hs1)) == r'\hat{A}^{(q_{1})}' assert (latex(OperatorSymbol( "A_1", hs=hs1 * hs2)) == r'\hat{A}_{1}^{(q_{1} \otimes q_{2})}') assert (latex(OperatorSymbol( "Xi_2", hs=(r'q1', 'q2'))) == r'\hat{\Xi}_{2}^{(q_{1} \otimes q_{2})}') assert (latex(OperatorSymbol("Xi_full", hs=1)) == r'\hat{\Xi}_{\text{full}}^{(1)}') assert latex( OperatorSymbol("Xi", alpha, beta, hs=1)) == (r'\hat{\Xi}^{(1)}\left(\alpha, \beta\right)') assert latex(IdentityOperator) == r'\mathbb{1}' assert latex(IdentityOperator, tex_identity_sym='I') == 'I' assert latex(ZeroOperator) == r'\mathbb{0}' assert latex(Create(hs=1)) == r'\hat{a}^{(1)\dagger}' assert latex(Create(hs=fock1)) == r'\hat{b}^{(1)\dagger}' assert latex(Destroy(hs=1)) == r'\hat{a}^{(1)}' assert latex(Destroy(hs=fock1)) == r'\hat{b}^{(1)}' assert latex(Jz(hs=SpinSpace(1, spin=1))) == r'\hat{J}_{z}^{(1)}' assert latex(Jz(hs=spin1)) == r'\hat{Z}^{(1)}' assert latex(Jplus(hs=SpinSpace(1, spin=1))) == r'\hat{J}_{+}^{(1)}' assert latex(Jplus(hs=spin1)) == r'\text{Jp}^{(1)}' assert latex(Jminus(hs=SpinSpace(1, spin=1))) == r'\hat{J}_{-}^{(1)}' assert latex(Jminus(hs=spin1)) == r'\text{Jm}^{(1)}' assert (latex(Phase(Rational( 1, 2), hs=1)) == r'\text{Phase}^{(1)}\left(\frac{1}{2}\right)') assert latex(Phase(0.5, hs=1)) == r'\text{Phase}^{(1)}\left(0.5\right)' assert latex(Phase(0.5, hs=fock1)) == r'\hat{\Phi}^{(1)}\left(0.5\right)' assert latex(Displace(0.5, hs=1)) == r'\hat{D}^{(1)}\left(0.5\right)' assert latex(Squeeze(0.5, hs=1)) == r'\text{Squeeze}^{(1)}\left(0.5\right)' hs_tls = LocalSpace('1', basis=('g', 'e')) sig_e_g = LocalSigma('e', 'g', hs=hs_tls) assert latex(sig_e_g, sig_as_ketbra=False) == r'\hat{\sigma}_{e,g}^{(1)}' assert ( latex(sig_e_g) == r'\left\lvert e \middle\rangle\!\middle\langle g \right\rvert^{(1)}') hs_tls = LocalSpace('1', basis=('excited', 'ground')) sig_excited_ground = LocalSigma('excited', 'ground', hs=hs_tls) assert (latex(sig_excited_ground, sig_as_ketbra=False) == r'\hat{\sigma}_{\text{excited},\text{ground}}^{(1)}') assert (latex(sig_excited_ground) == r'\left\lvert \text{excited} \middle\rangle\!' r'\middle\langle \text{ground} \right\rvert^{(1)}') hs_tls = LocalSpace('1', basis=('mu', 'nu')) sig_mu_nu = LocalSigma('mu', 'nu', hs=hs_tls) assert (latex(sig_mu_nu) == r'\left\lvert \mu \middle\rangle\!' r'\middle\langle \nu \right\rvert^{(1)}') hs_tls = LocalSpace('1', basis=('excited', 'ground')) sig_excited_excited = LocalProjector('excited', hs=hs_tls) assert (latex(sig_excited_excited, sig_as_ketbra=False) == r'\hat{\Pi}_{\text{excited}}^{(1)}') hs_tls = LocalSpace('1', basis=('g', 'e')) sig_e_e = LocalProjector('e', hs=hs_tls) assert latex(sig_e_e, sig_as_ketbra=False) == r'\hat{\Pi}_{e}^{(1)}'