def test_nonlocal_sum(): H = LocalSpace(hs_name(), dimension=5) a = Create(hs=H).adjoint() H2 = LocalSpace(hs_name(), basis=("e", "g", "h")) sigma = LocalSigma('g', 'e', hs=H2) assert convert_to_qutip(a + sigma)**2 == convert_to_qutip( (a + sigma) * (a + sigma))
def disjunct_commutative_test_data(): A1 = OperatorSymbol("A", hs=1) B1 = OperatorSymbol("B", hs=1) C1 = OperatorSymbol("C", hs=1) A2 = OperatorSymbol("A", hs=2) B2 = OperatorSymbol("B", hs=2) A3 = OperatorSymbol("A", hs=3) B4 = OperatorSymbol("B", hs=4) tr_A1 = tr(A1, over_space=1) tr_A2 = tr(A2, over_space=2) A1_m = OperatorSymbol("A", hs=LocalSpace(1, order_index=2)) B1_m = OperatorSymbol("B", hs=LocalSpace(1, order_index=2)) B2_m = OperatorSymbol("B", hs=LocalSpace(2, order_index=1)) ket_0 = BasisKet(0, hs=1) ket_1 = BasisKet(1, hs=1) ketbra = KetBra(ket_0, ket_1) braket = BraKet(ket_1, ket_1) # fmt: off return [ ([B2, B1, A1], [B1, A1, B2]), ([B2_m, B1_m, A1_m], [B2_m, B1_m, A1_m]), ([B1_m, A1_m, B2_m], [B2_m, B1_m, A1_m]), ([B1, A2, C1, tr_A2], [tr_A2, B1, C1, A2]), ([A1, B1 + B2], [A1, B1 + B2]), ([B1 + B2, A1], [B1 + B2, A1]), ([A3 + B4, A1 + A2], [A1 + A2, A3 + B4]), ([A1 + A2, A3 + B4], [A1 + A2, A3 + B4]), ([B4 + A3, A2 + A1], [A1 + A2, A3 + B4]), ([tr_A2, tr_A1], [tr_A1, tr_A2]), ([A2, ketbra, A1], [ketbra, A1, A2]), ([A2, braket, A1], [braket, A1, A2]), ]
def test_substitute_sub_expr(H_JC): """Test that we can replace non-atomic sub-expressions""" hil_a = LocalSpace('A') hil_b = LocalSpace('B') omega_a, omega_b, g = symbols('omega_a, omega_b, g') a = Destroy(hs=hil_a) a_dag = a.dag() b = Destroy(hs=hil_b) b_dag = b.dag() n_op_a = OperatorSymbol('n', hs=hil_a) n_op_b = OperatorSymbol('n', hs=hil_b) x_op = OperatorSymbol('x', hs=H_JC.space) mapping = { a_dag * a: n_op_a, b_dag * b: n_op_b, (a_dag * b + b_dag * a): x_op + x_op.dag(), } H2_expected = (omega_a * n_op_a + omega_b * n_op_b + 2 * g * (x_op + x_op.dag())) H2 = H_JC.substitute(mapping) assert H2 == H2_expected H2 = substitute(H_JC, mapping) assert H2 == H2_expected
def testHilbertSpace(self): h1 = LocalSpace("h1") h2 = LocalSpace("h2") a = SuperOperatorSymbol("a", hs=h1) b = SuperOperatorSymbol("b", hs=h2) assert a.space == h1 assert (a * b).space == h1 * h2
def test_symbol(): expN = OperatorSymbol("expN", hs=1) hs1 = LocalSpace("sym1", dimension=10) hs2 = LocalSpace("sym2", dimension=5) N = Create(hs=hs1) * Destroy(hs=hs1) M = Create(hs=hs2) * Destroy(hs=hs2) converter1 = {expN: convert_to_qutip(N).expm()} expNq = convert_to_qutip(expN, mapping=converter1) assert (np.linalg.norm(expNq.data.toarray() - (convert_to_qutip(N).expm().data.toarray())) < 1e-8) expNMq = convert_to_qutip(expN * M, mapping=converter1) assert (np.linalg.norm(expNMq.data.toarray() - (qutip.tensor( convert_to_qutip(N).expm(), convert_to_qutip(M)).data.toarray())) < 1e-8) converter2 = {expN: lambda expr: convert_to_qutip(N).expm()} expNq = convert_to_qutip(expN, mapping=converter2) assert (np.linalg.norm(expNq.data.toarray() - (convert_to_qutip(N).expm().data.toarray())) < 1e-8) expNMq = convert_to_qutip(expN * M, mapping=converter1) assert (np.linalg.norm(expNMq.data.toarray() - (qutip.tensor( convert_to_qutip(N).expm(), convert_to_qutip(M)).data.toarray())) < 1e-8)
def test_tensor_product(): H = LocalSpace(hs_name(), dimension=5) a = Create(hs=H).adjoint() H2 = LocalSpace(hs_name(), basis=("e", "g", "h")) sigma = LocalSigma('g', 'e', hs=H2) assert convert_to_qutip(sigma * a) == qutip.tensor(convert_to_qutip(a), convert_to_qutip(sigma))
def test_finditer(): h1 = LocalSpace("h1") a = OperatorSymbol("a", hs=h1) b = OperatorSymbol("b", hs=h1) c = OperatorSymbol("c", hs=h1) h1_custom = LocalSpace("h1", local_identifiers={'Create': 'c'}) c_local = Create(hs=h1_custom) expr = 2 * (a * b * c - b * c * a + a * b) pat = wc('sym', head=OperatorSymbol) for m in pat.finditer(expr): assert 'sym' in m matches = list(pat.finditer(expr)) assert len(matches) == 8 op_symbols = [m['sym'] for m in matches] assert set(op_symbols) == {a, b, c} op = wc(head=Operator) three_factors = pattern(OperatorTimes, op, op, op).findall(expr) assert three_factors == [a * b * c, b * c * a] assert len(list(pattern(LocalOperator).finditer(expr))) == 0 assert ( len( list( pattern(LocalOperator).finditer(expr.substitute({c: c_local})) ) ) == 2 )
def test_substitute_str(H_JC): """Test that we can substitute e.g. label strings""" H2 = H_JC.substitute({'A': '1', 'B': '2'}) hs_mapping = { LocalSpace('A'): LocalSpace('1'), LocalSpace('B'): LocalSpace('2'), } assert H2 == H_JC.substitute(hs_mapping)
def test_instantiate_with_basis(): """Test that a local space can be instantiated with an explicit basis""" hs1 = LocalSpace('1', basis=(0, 1)) assert hs1.dimension == 2 assert hs1.basis_labels == ('0', '1') hs1 = LocalSpace('1', basis=['g', 'e']) assert hs1.dimension == 2 assert hs1.basis_labels == ('g', 'e')
def testAdditionToSuperOperator(self): h1 = LocalSpace("h1") h2 = LocalSpace("h2") a = SuperOperatorSymbol("a", hs=h1) b = SuperOperatorSymbol("b", hs=h2) assert a + b == b + a assert a + b == SuperOperatorPlus(a, b) assert (a + b).space == h1 * h2
def test_commutator_hs(): """Test that commutator is in the correct Hilbert space""" hs1 = LocalSpace("1") hs2 = LocalSpace("2") A = OperatorSymbol('A', hs=hs1) B = OperatorSymbol('B', hs=hs2) C = OperatorSymbol('C', hs=hs2) assert Commutator.create(B, C).space == hs2 assert Commutator.create(B, A + C).space == hs1 * hs2
def test_custom_localspace_identifier_hash(): """Test hashes for expressions with different local_identifiers for their Hilbert spaces have different hashes""" hs1 = LocalSpace(1) hs1_custom = LocalSpace(1, local_identifiers={'Destroy': 'b'}) assert hash(hs1) != hash(hs1_custom) a = Destroy(hs=hs1) b = Destroy(hs=hs1_custom) assert hash(a) != hash(b)
def test_product_space_order(): H1 = LocalSpace(1) H2 = LocalSpace('2') assert H1 * H2 == H2 * H1 assert (H1 * H2).operands == (H1, H2) H1 = LocalSpace(1) H2 = LocalSpace('2', order_index=2) H3 = LocalSpace(3, order_index=1) assert (H1 * H2 * H3).operands == (H3, H2, H1)
def test_dimension(): h1 = LocalSpace("h1", dimension=10) h2 = LocalSpace("h2", dimension=20) h3 = LocalSpace("h3") h4 = LocalSpace("h4", dimension=100) assert (h1 * h2).dimension == h1.dimension * h2.dimension with pytest.raises(BasisNotSetError): h3.dimension assert h4.dimension == 100
def test_hilbertspace_free_symbols(): """Test that Hilbert spaces with an indexed name return the index symbol in free_symbols""" i, j = symbols('i, j', cls=IdxSym) assert LocalSpace(1).free_symbols == set() hs_i = LocalSpace(StrLabel(i)) hs_j = LocalSpace(StrLabel(j)) assert hs_i.free_symbols == {i} assert hs_j.free_symbols == {j} assert (hs_i * hs_j).free_symbols == {i, j}
def testZeroOne(self): h1 = LocalSpace("h1") h2 = LocalSpace("h2") a = OperatorSymbol("a", hs=h1) B = SuperOperatorSymbol("B", hs=h2) z = ZeroSuperOperator one = IdentitySuperOperator assert one * a == a assert z * a == ZeroOperator
def test_op_product_space(): """Test that a product of operators has the correct Hilbert space""" a = Destroy(hs=1) b = Destroy(hs=2) p = a * b assert p.space == ProductSpace(LocalSpace(1), LocalSpace(2)) assert not p.space.has_basis hs1 = LocalSpace(1, dimension=3) a = a.substitute({LocalSpace(1): hs1}) p = a * b assert p.space == ProductSpace(hs1, LocalSpace(2)) assert not p.space.has_basis hs2 = LocalSpace(2, dimension=2) b = b.substitute({LocalSpace(2): hs2}) p = a * b ps = ProductSpace(hs1, hs2) assert p.space == ps assert p.space.dimension == 6 assert p.space.basis_labels == ('0,0', '0,1', '1,0', '1,1', '2,0', '2,1') hs1_2 = LocalSpace(1, basis=('g', 'e')) hs2_2 = LocalSpace(2, basis=('g', 'e')) p = p.substitute({hs1: hs1_2, hs2: hs2_2}) assert p.space.dimension == 4 assert p.space.basis_labels == ('g,g', 'g,e', 'e,g', 'e,e') b = b.substitute({hs2: hs1}) p = a * b assert p.space == hs1 assert p.space.dimension == 3 assert p.space.basis_labels == ('0', '1', '2')
def test_disjunct_hs(): """Test that commutator of objects in disjunt Hilbert spaces is zero""" hs1 = LocalSpace("1") hs2 = LocalSpace("2") alpha, beta = symbols('alpha, beta') A = OperatorSymbol('A', hs=hs1) B = OperatorSymbol('B', hs=hs2) assert Commutator.create(A, B) == ZeroOperator assert Commutator.create(alpha, beta) == ZeroOperator assert Commutator.create(alpha, B) == ZeroOperator assert Commutator.create(A, beta) == ZeroOperator
def H_JC(): hil_a = LocalSpace('A') hil_b = LocalSpace('B') a = Destroy(hs=hil_a) a_dag = a.dag() b = Destroy(hs=hil_b) b_dag = b.dag() omega_a, omega_b, g = symbols('omega_a, omega_b, g') H = (omega_a * a_dag * a + omega_b * b_dag * b + 2 * g * (a_dag * b + b_dag * a)) return H
def test_basis_change(): """Test that we can change the basis of an Expression's Hilbert space through substitution""" a = Destroy(hs=1) assert a.space == LocalSpace('1') assert not a.space.has_basis subs = {LocalSpace('1'): LocalSpace('1', basis=(-1, 0, 1))} b = a.substitute(subs) assert str(a) == str(b) assert a != b assert b.space.dimension == 3 assert b.space.basis_labels == ('-1', '0', '1')
def testSPreSPostRules(self): h1 = LocalSpace("h1") h2 = LocalSpace("h2") d = OperatorSymbol("d", hs=h1) e = OperatorSymbol("e", hs=h1) dpre = SPre(d) epre = SPre(e) dpost = SPost(d) epost = SPost(e) assert dpre * epre == SPre(d * e) assert dpost * epost == SPost(e * d) assert dpost * epre == SPre(e) * SPost(d)
def test_space_ordering(): h1 = LocalSpace("h1") h2 = LocalSpace("h2") h3 = LocalSpace("h3") assert h1 <= h1 assert h1 <= (h1 * h2) assert not (h1 <= h2) assert not (h1 < h1) assert TrivialSpace < h1 < FullSpace assert h1 >= h1 assert h1 * h2 > h2 assert not (h1 * h2 > h3)
def testOrdering(self): h1 = LocalSpace("h1") h2 = LocalSpace("h2") a = SuperOperatorSymbol("a", hs=h1) b = SuperOperatorSymbol("b", hs=h2) c = SuperOperatorSymbol("c", hs=h2) dpre = SPre(SuperOperatorSymbol("d", hs=h1)) epre = SPre(SuperOperatorSymbol("e", hs=h1)) dpost = SPost(SuperOperatorSymbol("d", hs=h1)) epost = SPost(SuperOperatorSymbol("e", hs=h1)) assert a * b == SuperOperatorTimes(a, b) assert b * a == a * b assert c * a * b * c * a == SuperOperatorTimes(a, a, c, b, c)
def test_operations(): h1 = LocalSpace("h1") h2 = LocalSpace("h2") h3 = LocalSpace("h3") h123 = h1 * h2 * h3 h12 = h1 * h2 h23 = h2 * h3 h13 = h1 * h3 assert h12 * h13 == h123 assert h12 / h13 == h2 assert h12 & h13 == h1 assert (h12 / h13) * (h13 & h12) == h12 assert h1 & h12 == h1
def test_exception_teardown(): """Test that teardown works when breaking out due to an exception""" class TemporaryRulesException(Exception): pass h1 = LocalSpace("h1") a = OperatorSymbol("a", hs=h1) b = OperatorSymbol("b", hs=h1) hs_repr = "LocalSpace('h1')" rule_name = 'extra' rule = (pattern_head(6, a), lambda: b) simplifications = OperatorPlus.simplifications try: with temporary_rules(ScalarTimesOperator, OperatorPlus): ScalarTimesOperator.add_rule(rule_name, rule[0], rule[1]) OperatorPlus.simplifications.remove(scalars_to_op) raise TemporaryRulesException except TemporaryRulesException: assert rule not in ScalarTimesOperator._rules.values() assert scalars_to_op in OperatorPlus.simplifications finally: # Even if this failed we don't want to make a mess for other tests try: ScalarTimesOperator.del_rules(rule_name) except KeyError: pass OperatorPlus.simplifications = simplifications
def testSubtraction(self): hs = LocalSpace("hs") a = SuperOperatorSymbol("a", hs=hs) b = SuperOperatorSymbol("b", hs=hs) z = ZeroSuperOperator assert a - a == z assert a - b == SuperOperatorPlus(a, ScalarTimesSuperOperator(-1, b))
def testCommutativity(self): h1 = LocalSpace("h1") assert SuperOperatorSymbol("A", hs=h1) + SuperOperatorSymbol( "B", hs=h1 ) == ( SuperOperatorSymbol("B", hs=h1) + SuperOperatorSymbol("A", hs=h1) )
def test_commutator_expand_evaluate(): """Test expansion and evaluation of commutators""" hs = LocalSpace("0") A = OperatorSymbol('A', hs=hs) B = OperatorSymbol('B', hs=hs) C = OperatorSymbol('C', hs=hs) D = OperatorSymbol('D', hs=hs) E = OperatorSymbol('E', hs=hs) expr = Commutator(A, B * C * D * E) res = (B * C * D * Commutator(A, E) + B * C * Commutator(A, D) * E + B * Commutator(A, C) * D * E + Commutator(A, B) * C * D * E) assert expand_commutators_leibniz(expr) == res assert expr.doit([Commutator]) == (A * B * C * D * E - B * C * D * E * A) assert res.doit([Commutator ]).expand() == (A * B * C * D * E - B * C * D * E * A) assert expand_commutators_leibniz(expr, expand_expr=False) == ( B * (C * (D * Commutator(A, E) + Commutator(A, D) * E) + Commutator(A, C) * D * E) + Commutator(A, B) * C * D * E) expr = Commutator(A * B * C, D) assert expand_commutators_leibniz(expr) == (A * B * Commutator(C, D) + A * Commutator(B, D) * C + Commutator(A, D) * B * C) expr = Commutator(A * B, C * D) assert expand_commutators_leibniz(expr) == (A * Commutator(B, C) * D + C * A * Commutator(B, D) + C * Commutator(A, D) * B + Commutator(A, C) * B * D)
def test_series_expand(): """Test series expension of commutator""" hs = LocalSpace("0") A = OperatorSymbol('A', hs=hs) B = OperatorSymbol('B', hs=hs) a3, a2, a1, a0, b3, b2, b1, b0, t, t0 = symbols( 'a_3, a_2, a_1, a_0, b_3, b_2, b_1, b_0, t, t_0') A_form = (a3 * t**3 + a2 * t**2 + a1 * t + a0) * A B_form = (b3 * t**3 + b2 * t**2 + b1 * t + b0) * B comm = Commutator.create(A_form, B_form) terms = comm.series_expand(t, 0, 2) assert terms == ( a0 * b0 * Commutator(A, B), (a0 * b1 + a1 * b0) * Commutator(A, B), (a0 * b2 + a1 * b1 + a2 * b0) * Commutator(A, B), ) A_form = (a1 * t + a0) * A B_form = (b1 * t + b0) * B comm = Commutator.create(A_form, B_form) terms = comm.series_expand(t, t0, 1) assert terms == ( ((a0 * b0 + a0 * b1 * t0 + a1 * b0 * t0 + a1 * b1 * t0**2) * Commutator(A, B)), (a0 * b1 + a1 * b0 + 2 * a1 * b1 * t0) * Commutator(A, B), ) comm = Commutator.create(A, B) terms = comm.series_expand(t, t0, 1) assert terms == (Commutator(A, B), ZeroOperator)
def test_exception_teardown(): """Test that teardown works when breaking out due to an exception""" class InstanceCachingException(Exception): pass h1 = LocalSpace("caching") a = OperatorSymbol("a", hs=h1) b = OperatorSymbol("b", hs=h1) c = OperatorSymbol("c", hs=h1) expr1 = a + b instance_caching = Expression.instance_caching try: with no_instance_caching(): expr2 = a + c raise InstanceCachingException except InstanceCachingException: expr3 = b + c assert expr1 in OperatorPlus._instances.values() assert expr2 not in OperatorPlus._instances.values() assert expr3 in OperatorPlus._instances.values() finally: # Even if this failed we don't want to make a mess for other tests Expression.instance_caching = instance_caching instances = OperatorPlus._instances try: with temporary_instance_cache(OperatorPlus): expr2 = a + c raise InstanceCachingException except InstanceCachingException: assert expr1 in OperatorPlus._instances.values() assert expr2 not in OperatorPlus._instances.values() finally: # Even if this failed we don't want to make a mess for other tests OperatorPlus._instances = instances