def test_inplace_multiplication(self): # Real expr_r = c(2, "dn") expr_r *= c_dag(1, "up") self.assertEqual(str(expr_r), "-1*C+(1,up)C(2,dn)") expr_r *= a(0, "x") self.assertEqual(str(expr_r), "-1*C+(1,up)C(2,dn)A(0,x)") expr_r *= a_dag(0, "y") self.assertEqual(str(expr_r), "-1*C+(1,up)C(2,dn)A+(0,y)A(0,x)") expr_r *= ExpressionR(2) self.assertEqual(str(expr_r), "-2*C+(1,up)C(2,dn)A+(0,y)A(0,x)") expr_r *= ExpressionR() self.assertEqual(str(expr_r), "0") # Complex expr_c = make_complex(c(2, "dn")) expr_c *= make_complex(c_dag(1, "up")) self.assertEqual(str(expr_c), "(-1,0)*C+(1,up)C(2,dn)") expr_c *= make_complex(a(0, "x")) self.assertEqual(str(expr_c), "(-1,0)*C+(1,up)C(2,dn)A(0,x)") expr_c *= make_complex(a_dag(0, "y")) self.assertEqual(str(expr_c), "(-1,0)*C+(1,up)C(2,dn)A+(0,y)A(0,x)") expr_c *= ExpressionC(2) self.assertEqual(str(expr_c), "(-2,0)*C+(1,up)C(2,dn)A+(0,y)A(0,x)") expr_c *= ExpressionC() self.assertEqual(str(expr_c), "(0,0)")
def test_find_connections(self): expr = [ExpressionR(), c_dag("up", 0) * c("dn", 1), c_dag("up", 0) * c("dn", 1) + c_dag("dn", 0) * c("dn", 1), c_dag("dn", 1) * c_dag("up", 1), n("up", 2) ] sp, melem = make_space_partition(self.Hop, self.hs, False) op = LOperatorR(sum(expr[1:]), self.hs) conns = sp.find_connections(op, self.hs) conns_ref = set() in_state = np.zeros((sp.dim,), dtype=float) for i in range(sp.dim): in_state[i] = 1.0 out_state = op * in_state for f, a in enumerate(out_state): if abs(a) > 1e-10: conns_ref.add((sp[i], sp[f])) in_state[i] = 0.0 self.assertEqual(conns, conns_ref) for expr1, expr2 in product(expr, expr): conns1 = sp.find_connections(LOperatorR(expr1, self.hs), self.hs) conns2 = sp.find_connections(LOperatorR(expr2, self.hs), self.hs) conns = sp.find_connections(LOperatorR(expr1 + expr2, self.hs), self.hs) self.assertEqual(conns, conns1.union(conns2))
def test_multiplication_const(self): # Real expr_r = c_dag(1, "up") self.assertIsInstance(expr_r * 2, ExpressionR) self.assertIsInstance(2 * expr_r, ExpressionR) self.assertEqual(str(expr_r * 0), "0") self.assertEqual(str(0 * expr_r), "0") self.assertEqual(str(expr_r * 2), "2*C+(1,up)") self.assertEqual(str(2 * expr_r), "2*C+(1,up)") # Complex and real expr_c = make_complex(c_dag(1, "up")) self.assertIsInstance(expr_c * 2.0, ExpressionC) self.assertIsInstance(2.0 * expr_c, ExpressionC) self.assertEqual(str(expr_c * 0.0), "(0,0)") self.assertEqual(str(0.0 * expr_c), "(0,0)") self.assertEqual(str(expr_c * 2.0), "(2,0)*C+(1,up)") self.assertEqual(str(2.0 * expr_c), "(2,0)*C+(1,up)") # Real and complex expr_r = c_dag(1, "up") self.assertIsInstance(expr_r * 2.0j, ExpressionC) self.assertIsInstance(2.0j * expr_r, ExpressionC) self.assertEqual(str(expr_r * 0.0j), "(0,0)") self.assertEqual(str(0.0j * expr_r), "(0,0)") self.assertEqual(str(expr_r * 2.0j), "(0,2)*C+(1,up)") self.assertEqual(str(2.0j * expr_r), "(0,2)*C+(1,up)")
def test_tight_binding(self): indices = [("a", 0), ("b", 1), ("c", 2)] t = np.array([[1.0, 0.0, 0.5], [0.0, 2.0, 0.0], [0.5, 0.0, 3.0]]) H1 = tight_binding(t) self.assertIsInstance(H1, ExpressionR) ref1 = c_dag(0) * c(0) + 2 * c_dag(1) * c(1) + 3.0 * c_dag(2) * c(2) ref1 += 0.5 * c_dag(0) * c(2) + 0.5 * c_dag(2) * c(0) self.assertEqual(H1, ref1) H2 = tight_binding(1j * t) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = tight_binding(t, statistics=FERMION) self.assertIsInstance(H3, ExpressionR) ref3 = ref1 self.assertEqual(H3, ref3) H4 = tight_binding(t, indices=indices) self.assertIsInstance(H4, ExpressionR) ref4 = c_dag("a", 0) * c("a", 0) + 2 * c_dag("b", 1) * c("b", 1) \ + 3.0 * c_dag("c", 2) * c("c", 2) ref4 += 0.5 * c_dag("a", 0) * c("c", 2) \ + 0.5 * c_dag("c", 2) * c("a", 0) self.assertEqual(H4, ref4) H5 = tight_binding(t, statistics=BOSON) self.assertIsInstance(H5, ExpressionR) ref5 = a_dag(0) * a(0) + 2 * a_dag(1) * a(1) + 3.0 * a_dag(2) * a(2) ref5 += 0.5 * a_dag(0) * a(2) + 0.5 * a_dag(2) * a(0) self.assertEqual(H5, ref5)
def test_overload_selection(self): expr = 6 * c_dag("dn") - 6 * c("up") hs = HilbertSpace(expr) lop = LOperatorR(expr, hs) src_int = np.array([1, 1, 1, 1], dtype=int) src_real = np.array([1, 1, 1, 1], dtype=float) src_complex = np.array([1, 1, 1, 1], dtype=complex) ref_real = np.array([-6, 12, 0, 6], dtype=float) ref_complex = np.array([-6, 12, 0, 6], dtype=complex) self.assertEqual((lop * src_int).dtype, np.float64) self.assertEqual((lop * src_real).dtype, np.float64) self.assertEqual((lop * src_complex).dtype, np.complex128) dst_int = np.zeros(4, dtype=int) dst_real = np.zeros(4, dtype=float) dst_complex = np.zeros(4, dtype=complex) self.assertRaises(TypeError, lop, src_int, dst_int) self.assertRaises(TypeError, lop, src_real, dst_int) self.assertRaises(TypeError, lop, src_complex, dst_int) self.assertRaises(TypeError, lop, src_complex, dst_real) lop(src_int, dst_real) assert_equal(dst_real, ref_real) lop(src_int, dst_complex) assert_equal(dst_complex, ref_complex) lop(src_real, dst_real) assert_equal(dst_real, ref_real) lop(src_real, dst_complex) assert_equal(dst_complex, ref_complex) lop(src_complex, dst_complex) assert_equal(dst_complex, ref_complex) expr = 6j * c_dag("dn") - 6j * c("up") hs = HilbertSpace(expr) lop = LOperatorC(expr, hs) self.assertEqual((lop * src_int).dtype, np.complex128) self.assertEqual((lop * src_real).dtype, np.complex128) self.assertEqual((lop * src_complex).dtype, np.complex128) ref_complex = np.array([-6j, 12j, 0, 6j], dtype=complex) self.assertRaises(TypeError, lop, src_int, dst_int) self.assertRaises(TypeError, lop, src_real, dst_int) self.assertRaises(TypeError, lop, src_complex, dst_int) self.assertRaises(TypeError, lop, src_int, dst_real) self.assertRaises(TypeError, lop, src_real, dst_real) self.assertRaises(TypeError, lop, src_complex, dst_real) lop(src_int, dst_complex) assert_equal(dst_complex, ref_complex) lop(src_real, dst_complex) assert_equal(dst_complex, ref_complex) lop(src_complex, dst_complex) assert_equal(dst_complex, ref_complex)
def test_hc(self): # Real expr = 2 * c_dag("up", 1) * c("up", 2) self.assertEqual(expr + hc, expr + conj(expr)) self.assertEqual(expr - hc, expr - conj(expr)) # Complex expr = (2 + 2j) * c_dag("up", 1) * c("up", 2) self.assertEqual(expr + hc, expr + conj(expr)) self.assertEqual(expr - hc, expr - conj(expr))
def test_HilbertSpace(self): indices = [("dn", 0), ("dn", 1), ("up", 0), ("up", 1)] hs = HilbertSpace([make_space_fermion(*ind) for ind in indices]) for ind in indices: c_op = LOperatorR(c(*ind), hs) assert_equal(make_matrix(c_op, hs), self.c_mat(hs, *ind)) c_dag_op = LOperatorR(c_dag(*ind), hs) assert_equal(make_matrix(c_dag_op, hs), self.c_dag_mat(hs, *ind)) H1 = 1.0 * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H1 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H1op = LOperatorR(H1, hs) ref1 = 1.0 * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref1 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) assert_equal(make_matrix(H1op, hs), ref1) H2 = 1.0j * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H2 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H2op = LOperatorC(H2, hs) ref2 = 1.0j * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref2 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) assert_equal(make_matrix(H2op, hs), ref2)
def test_powers_of_S_z(self): s = ExpressionR() for n in range(1, 12): p = c_dag() for _ in range(n): p *= S_z() p *= a() s += p self.assertEqual( s, c_dag() * (341.0 / 1024 + (1365.0 / 1024) * S_z()) * a())
def test_S_z_products(self): mon_sz = Monomial([make_fermion(True, 1)] + [make_spin(SpinComponent.Z, 1)] * 4 + [make_fermion(True, 2)] + [make_spin(SpinComponent.Z, 2)] * 4 + [make_spin(SpinComponent.Z, 3)] * 3 + [make_fermion(True, 4)] + [make_spin(SpinComponent.Z, 4)] * 3) expr_sz = ExpressionR(1.0, mon_sz) self.assertEqual( expr_sz, c_dag(1) * 0.25 * 0.25 * c_dag(2) * 0.25 * 0.25 * 0.25 * S_z(3) * c_dag(4) * 0.25 * S_z(4))
def test_inplace_multiplication_const(self): # Real expr_r = c_dag(1, "up") expr_r *= 4.0 self.assertEqual(str(expr_r), "4*C+(1,up)") expr_r *= 0.0 self.assertEqual(str(expr_r), "0") # Real and complex expr_c = make_complex(c_dag(1, "up")) expr_c *= 4.0 self.assertEqual(str(expr_c), "(4,0)*C+(1,up)") expr_c *= 0.0 self.assertEqual(str(expr_c), "(0,0)")
def setUpClass(cls): # Finite system of 4 fermions: 2 orbitals, two spin projections # Hamiltonian: spin flips cls.Hex = \ 2 * c_dag("up", 1) * c("up", 2) * c_dag("dn", 2) * c("dn", 1) \ + 2 * c_dag("up", 2) * c("up", 1) * c_dag("dn", 1) * c("dn", 2) cls.Hp = \ 2 * c_dag("up", 1) * c("up", 2) * c_dag("dn", 1) * c("dn", 2) \ + 2 * c_dag("up", 2) * c("up", 1) * c_dag("dn", 2) * c("dn", 1) cls.hs = HilbertSpace(cls.Hex + cls.Hp) # 3 = 1 + 2 -> |dn>_1 |dn>_2 # 5 = 1 + 4 -> |dn>_1 |up>_1 # 6 = 2 + 4 -> |dn>_2 |up>_1 # 9 = 1 + 8 -> |dn>_1 |up>_2 # 10 = 2 + 8 -> |dn>_2 |up>_2 # 12 = 4 + 8 -> |up>_1 |up>_2 # Map all basis states with 2 electrons so that their indices # are contiguous cls.mapping = {i: j for j, i in enumerate([3, 5, 6, 9, 10, 12])} cls.mapper = BasisMapper([3, 5, 6, 9, 10, 12]) cls.st = np.array([0, 1, 2, 3, 4, 5], dtype=float)
def test_compositions(self): mapper = BasisMapper([], self.hs, 0) self.assertEqual(len(mapper), 1) self.assertEqual(mapper.map[0], 0) O_list = [LOperatorR(c_dag("dn", 1), self.hs), LOperatorR(c_dag("dn", 2), self.hs), LOperatorR(c_dag("up", 1), self.hs), LOperatorR(c_dag("up", 2), self.hs)] mapper_N0 = BasisMapper(O_list, self.hs, 0) self.assertEqual(len(mapper_N0), 1) self.assertEqual(mapper_N0.map[0], 0) mapper_N2 = BasisMapper(O_list, self.hs, 2) self.assert_equal_dicts_up_to_value_permutation(mapper_N2.map, self.mapping) O_list_complex = [LOperatorC(1j * c_dag("dn", 1), self.hs), LOperatorC(1j * c_dag("dn", 2), self.hs), LOperatorC(1j * c_dag("up", 1), self.hs), LOperatorC(1j * c_dag("up", 2), self.hs)] mapper_N2 = BasisMapper(O_list_complex, self.hs, 2) self.assert_equal_dicts_up_to_value_permutation(mapper_N2.map, self.mapping)
def test_basis_state_indices(self): indices = [("dn", 0), ("dn", 1), ("up", 0), ("up", 1)] hs = HilbertSpace([make_space_fermion(*ind) for ind in indices]) # Basis of the N=2 sector basis_state_indices = [3, 5, 6, 9, 10, 12] H1 = 1.0 * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H1 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H1op = LOperatorR(H1, hs) ref1 = 1.0 * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref1 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) ref1 = ref1[basis_state_indices, :][:, basis_state_indices] assert_equal(make_matrix(H1op, basis_state_indices), ref1) H2 = 1.0j * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H2 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H2op = LOperatorC(H2, hs) ref2 = 1.0j * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref2 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) ref2 = ref2[basis_state_indices, :][:, basis_state_indices] assert_equal(make_matrix(H2op, basis_state_indices), ref2)
def test_real_complex(self): # Fermion self.check_monomial(c_dag(1, "up"), 1, make_fermion(True, 1, "up")) self.check_monomial(c(2, "dn"), 1, make_fermion(False, 2, "dn")) self.check_monomial(n(1, "dn"), 1, make_fermion(True, 1, "dn"), make_fermion(False, 1, "dn")) # Boson self.check_monomial(a_dag(0, "x"), 1, make_boson(True, 0, "x")) self.check_monomial(a(0, "y"), 1, make_boson(False, 0, "y")) # Spin 1/2 self.check_monomial(S_p(0, "x"), 1, make_spin(SpinComponent.PLUS, 0, "x")) self.check_monomial(S_m(0, "x"), 1, make_spin(SpinComponent.MINUS, 0, "x")) self.check_monomial(S_z(0, "x"), 1, make_spin(SpinComponent.Z, 0, "x")) # Spin 1 self.check_monomial(S_p(0, "x", spin=1), 1, make_spin(1.0, SpinComponent.PLUS, 0, "x")) self.check_monomial(S_m(0, "x", spin=1), 1, make_spin(1.0, SpinComponent.MINUS, 0, "x")) self.check_monomial(S_z(0, "x", spin=1), 1, make_spin(1.0, SpinComponent.Z, 0, "x")) # Spin 3/2 self.check_monomial(S_p(0, "x", spin=3 / 2), 1, make_spin(3 / 2, SpinComponent.PLUS, 0, "x")) self.check_monomial(S_m(0, "x", spin=3 / 2), 1, make_spin(3 / 2, SpinComponent.MINUS, 0, "x")) self.check_monomial(S_z(0, "x", spin=3 / 2), 1, make_spin(3 / 2, SpinComponent.Z, 0, "x"))
def test_mixed_indices(self): expr = c_dag(0, "up") * c(1, "dn") \ + a_dag("x") * n() + a("y") * n() + S_p() * S_m() self.assertEqual( str(expr), "0.5 + 1*Sz() + 1*C+(0,up)C(1,dn) + 1*C+()C()A+(x) + 1*C+()C()A(y)" )
def test_inplace_subtraction_const(self): # Real expr_r = c_dag(1, "up") expr_r -= 4.0 self.assertEqual(str(expr_r), "-4 + 1*C+(1,up)") expr_r -= 0.0 self.assertEqual(str(expr_r), "-4 + 1*C+(1,up)") expr_r -= -4.0 self.assertEqual(str(expr_r), "1*C+(1,up)") # Real and complex expr_c = make_complex(c_dag(1, "up")) expr_c -= 4.0 self.assertEqual(str(expr_c), "(-4,0) + (1,0)*C+(1,up)") expr_c -= 0.0 self.assertEqual(str(expr_c), "(-4,0) + (1,0)*C+(1,up)") expr_c -= -4.0 self.assertEqual(str(expr_c), "(1,0)*C+(1,up)")
def test_subtraction_const(self): # Real expr_r = c_dag(1, "up") self.assertIsInstance(expr_r - 2, ExpressionR) self.assertIsInstance(2 - expr_r, ExpressionR) self.assertEqual(str(expr_r - 0), "1*C+(1,up)") self.assertEqual(str(0 - expr_r), "-1*C+(1,up)") self.assertEqual(str(expr_r - 2), "-2 + 1*C+(1,up)") self.assertEqual(str(2 - expr_r), "2 + -1*C+(1,up)") expr_r -= 2.0 self.assertEqual(str(expr_r - 0), "-2 + 1*C+(1,up)") self.assertEqual(str(0 - expr_r), "2 + -1*C+(1,up)") self.assertEqual(str(expr_r - 2), "-4 + 1*C+(1,up)") self.assertEqual(str(2 - expr_r), "4 + -1*C+(1,up)") self.assertEqual(str(expr_r - (-2)), "1*C+(1,up)") self.assertEqual(str((-2) - expr_r), "-1*C+(1,up)") # Complex and real expr_c = make_complex(c_dag(1, "up")) self.assertIsInstance(expr_c - 2.0, ExpressionC) self.assertIsInstance(2.0 - expr_c, ExpressionC) self.assertEqual(str(expr_c - 0.0), "(1,0)*C+(1,up)") self.assertEqual(str(0.0 - expr_c), "(-1,-0)*C+(1,up)") self.assertEqual(str(expr_c - 2.0), "(-2,0) + (1,0)*C+(1,up)") self.assertEqual(str(2.0 - expr_c), "(2,0) + (-1,-0)*C+(1,up)") expr_c -= 2.0 self.assertEqual(str(expr_c - 0.0), "(-2,0) + (1,0)*C+(1,up)") self.assertEqual(str(0.0 - expr_c), "(2,-0) + (-1,-0)*C+(1,up)") self.assertEqual(str(expr_c - 2.0), "(-4,0) + (1,0)*C+(1,up)") self.assertEqual(str(2.0 - expr_c), "(4,-0) + (-1,-0)*C+(1,up)") self.assertEqual(str(expr_c - (-2.0)), "(1,0)*C+(1,up)") self.assertEqual(str((-2.0) - expr_c), "(-1,-0)*C+(1,up)") # Real and complex expr_r = c_dag(1, "up") self.assertIsInstance(expr_r - 2j, ExpressionC) self.assertIsInstance(2j - expr_r, ExpressionC) self.assertEqual(str(expr_r - 0.0j), "(1,0)*C+(1,up)") self.assertEqual(str(0.0j - expr_r), "(-1,0)*C+(1,up)") self.assertEqual(str(expr_r - 2.0j), "(0,-2) + (1,0)*C+(1,up)") self.assertEqual(str(2.0j - expr_r), "(0,2) + (-1,0)*C+(1,up)") expr_r -= 2.0 self.assertEqual(str(expr_r - 0.0j), "(-2,0) + (1,0)*C+(1,up)") self.assertEqual(str(0.0j - expr_r), "(2,0) + (-1,0)*C+(1,up)") self.assertEqual(str(expr_r - 2.0 + 0j), "(-4,0) + (1,0)*C+(1,up)") self.assertEqual(str(2.0 + 0j - expr_r), "(4,0) + (-1,0)*C+(1,up)") self.assertEqual(str(expr_r - (-2.0 + 0j)), "(1,0)*C+(1,up)") self.assertEqual(str((-2.0 + 0j) - expr_r), "(-1,0)*C+(1,up)")
def test_inplace_subtraction(self): # Real expr_r = c_dag(1, "up") expr_r -= c(2, "dn") self.assertEqual(str(expr_r), "1*C+(1,up) + -1*C(2,dn)") expr_r -= ExpressionR() self.assertEqual(str(expr_r), "1*C+(1,up) + -1*C(2,dn)") expr_r -= c_dag(1, "up") self.assertEqual(str(expr_r), "-1*C(2,dn)") # Complex expr_c = make_complex(c_dag(1, "up")) expr_c -= c(2, "dn") self.assertEqual(str(expr_c), "(1,0)*C+(1,up) + (-1,0)*C(2,dn)") expr_c -= ExpressionC() self.assertEqual(str(expr_c), "(1,0)*C+(1,up) + (-1,0)*C(2,dn)") expr_c -= c_dag(1, "up") self.assertEqual(str(expr_c), "(-1,0)*C(2,dn)")
def test_addition_const(self): # Real expr_r = c_dag(1, "up") self.assertIsInstance(expr_r + 2, ExpressionR) self.assertIsInstance(2 + expr_r, ExpressionR) self.assertEqual(str(expr_r + 0), "1*C+(1,up)") self.assertEqual(str(0 + expr_r), "1*C+(1,up)") self.assertEqual(str(expr_r + 2), "2 + 1*C+(1,up)") self.assertEqual(str(2 + expr_r), "2 + 1*C+(1,up)") expr_r += 2.0 self.assertEqual(str(expr_r + 0), "2 + 1*C+(1,up)") self.assertEqual(str(0 + expr_r), "2 + 1*C+(1,up)") self.assertEqual(str(expr_r + 2), "4 + 1*C+(1,up)") self.assertEqual(str(2 + expr_r), "4 + 1*C+(1,up)") self.assertEqual(str(expr_r + (-2)), "1*C+(1,up)") self.assertEqual(str((-2) + expr_r), "1*C+(1,up)") # Complex and real expr_c = make_complex(c_dag(1, "up")) self.assertIsInstance(expr_c + 2.0, ExpressionC) self.assertIsInstance(2.0 + expr_c, ExpressionC) self.assertEqual(str(expr_c + 0.0), "(1,0)*C+(1,up)") self.assertEqual(str(0.0 + expr_c), "(1,0)*C+(1,up)") self.assertEqual(str(expr_c + 2.0), "(2,0) + (1,0)*C+(1,up)") self.assertEqual(str(2.0 + expr_c), "(2,0) + (1,0)*C+(1,up)") expr_c += 2.0 self.assertEqual(str(expr_c + 0.0), "(2,0) + (1,0)*C+(1,up)") self.assertEqual(str(0.0 + expr_c), "(2,0) + (1,0)*C+(1,up)") self.assertEqual(str(expr_c + 2.0), "(4,0) + (1,0)*C+(1,up)") self.assertEqual(str(2.0 + expr_c), "(4,0) + (1,0)*C+(1,up)") self.assertEqual(str(expr_c + (-2.0)), "(1,0)*C+(1,up)") self.assertEqual(str((-2.0) + expr_c), "(1,0)*C+(1,up)") # Real and complex expr_r = c_dag(1, "up") self.assertIsInstance(expr_r + 2.0j, ExpressionC) self.assertIsInstance(2.0j + expr_r, ExpressionC) self.assertEqual(str(expr_r + 0.0j), "(1,0)*C+(1,up)") self.assertEqual(str(0.0j + expr_r), "(1,0)*C+(1,up)") self.assertEqual(str(expr_r + 2.0j), "(0,2) + (1,0)*C+(1,up)") self.assertEqual(str(2.0j + expr_r), "(0,2) + (1,0)*C+(1,up)") expr_r += 2.0 self.assertEqual(str(expr_r + 0.0j), "(2,0) + (1,0)*C+(1,up)") self.assertEqual(str(0.0j + expr_r), "(2,0) + (1,0)*C+(1,up)") self.assertEqual(str(expr_r + 2 + 0j), "(4,0) + (1,0)*C+(1,up)") self.assertEqual(str(2 + 0j + expr_r), "(4,0) + (1,0)*C+(1,up)") self.assertEqual(str(expr_r + (-2 + 0j)), "(1,0)*C+(1,up)") self.assertEqual(str((-2 + 0j) + expr_r), "(1,0)*C+(1,up)")
def test_inplace_addition(self): # Real expr_r = c_dag(1, "up") expr_r += c(2, "dn") self.assertEqual(str(expr_r), "1*C+(1,up) + 1*C(2,dn)") expr_r += ExpressionR() self.assertEqual(str(expr_r), "1*C+(1,up) + 1*C(2,dn)") expr_r += -c_dag(1, "up") self.assertEqual(str(expr_r), "1*C(2,dn)") # Complex expr_c = make_complex(c_dag(1, "up")) expr_c += c(2, "dn") self.assertEqual(str(expr_c), "(1,0)*C+(1,up) + (1,0)*C(2,dn)") expr_c += ExpressionC() self.assertEqual(str(expr_c), "(1,0)*C+(1,up) + (1,0)*C(2,dn)") expr_c += -c_dag(1, "up") self.assertEqual(str(expr_c), "(1,0)*C(2,dn)")
def test_inplace_addition_const(self): # Real expr_r = c_dag(1, "up") expr_r += 4.0 self.assertEqual(str(expr_r), "4 + 1*C+(1,up)") expr_r += 0.0 self.assertEqual(str(expr_r), "4 + 1*C+(1,up)") expr_r += -4.0 self.assertEqual(str(expr_r), "1*C+(1,up)") # Real and complex expr_c = make_complex(c_dag(1, "up")) expr_c += 4.0 self.assertEqual(str(expr_c), "(4,0) + (1,0)*C+(1,up)") expr_c += 0.0 self.assertEqual(str(expr_c), "(4,0) + (1,0)*C+(1,up)") expr_c += -4.0 self.assertEqual(str(expr_c), "(1,0)*C+(1,up)")
def test_subtraction(self): # Real expr_r = c_dag(1, "up") self.assertIsInstance(expr_r - c(2, "dn"), ExpressionR) self.assertIsInstance(c(2, "dn") - expr_r, ExpressionR) self.assertEqual(str(ExpressionR() - ExpressionR()), "0") self.assertEqual(str(expr_r - ExpressionR()), "1*C+(1,up)") self.assertEqual(str(ExpressionR() - expr_r), "-1*C+(1,up)") self.assertEqual(str(expr_r - c(2, "dn")), "1*C+(1,up) + -1*C(2,dn)") self.assertEqual(str(c(2, "dn") - expr_r), "-1*C+(1,up) + 1*C(2,dn)") expr_r -= c(2, "dn") self.assertEqual(str(expr_r + ExpressionR()), "1*C+(1,up) + -1*C(2,dn)") self.assertEqual(str(ExpressionR() - expr_r), "-1*C+(1,up) + 1*C(2,dn)") self.assertEqual(str(expr_r - a(0, "x")), "1*C+(1,up) + -1*C(2,dn) + -1*A(0,x)") self.assertEqual(str(a(0, "x") - expr_r), "-1*C+(1,up) + 1*C(2,dn) + 1*A(0,x)") self.assertEqual(str(expr_r - c_dag(1, "up")), "-1*C(2,dn)") self.assertEqual(str(c_dag(1, "up") - expr_r), "1*C(2,dn)") self.assertEqual( str((c_dag(1, "up") + c(2, "dn")) - (c(2, "dn") + 2.0)), "-2 + 1*C+(1,up)") # Real and complex expr1 = make_complex(c_dag(1, "up")) expr2 = c(2, "dn") self.assertIsInstance(expr1 - expr2, ExpressionC) self.assertIsInstance(expr2 - expr1, ExpressionC) self.assertEqual(str(ExpressionC() - ExpressionR()), "(0,0)") self.assertEqual(str(ExpressionR() - ExpressionC()), "(0,0)") self.assertEqual(str(expr1 - ExpressionR()), "(1,0)*C+(1,up)") self.assertEqual(str(ExpressionR() - expr1), "(-1,-0)*C+(1,up)") self.assertEqual(str(expr2 - ExpressionC()), "(1,-0)*C(2,dn)") self.assertEqual(str(ExpressionC() - expr2), "(-1,0)*C(2,dn)") self.assertEqual(str(expr1 - expr2), "(1,0)*C+(1,up) + (-1,0)*C(2,dn)") self.assertEqual(str(expr2 - expr1), "(-1,-0)*C+(1,up) + (1,-0)*C(2,dn)") expr1 -= expr2 self.assertEqual(str(expr1 - ExpressionR()), "(1,0)*C+(1,up) + (-1,0)*C(2,dn)") self.assertEqual(str(ExpressionR() - expr1), "(-1,-0)*C+(1,up) + (1,-0)*C(2,dn)") self.assertEqual(str(expr1 - a(0, "x")), "(1,0)*C+(1,up) + (-1,0)*C(2,dn) + (-1,0)*A(0,x)") self.assertEqual(str(a(0, "x") - expr1), "(-1,-0)*C+(1,up) + (1,-0)*C(2,dn) + (1,-0)*A(0,x)") self.assertEqual(str(expr1 - make_complex(c_dag(1, "up"))), "(-1,0)*C(2,dn)") self.assertEqual(str(make_complex(c_dag(1, "up")) - expr1), "(1,0)*C(2,dn)") self.assertEqual( str( make_complex(c_dag(1, "up") + c(2, "dn")) - (c(2, "dn") + 2.0)), "(-2,0) + (1,0)*C+(1,up)")
def test_addition(self): # Real expr_r = c_dag(1, "up") self.assertIsInstance(expr_r + c(2, "dn"), ExpressionR) self.assertIsInstance(c(2, "dn") + expr_r, ExpressionR) self.assertEqual(str(ExpressionR() + ExpressionR()), "0") self.assertEqual(str(expr_r + ExpressionR()), "1*C+(1,up)") self.assertEqual(str(ExpressionR() + expr_r), "1*C+(1,up)") self.assertEqual(str(expr_r + c(2, "dn")), "1*C+(1,up) + 1*C(2,dn)") self.assertEqual(str(c(2, "dn") + expr_r), "1*C+(1,up) + 1*C(2,dn)") expr_r += c(2, "dn") self.assertEqual(str(expr_r + ExpressionR()), "1*C+(1,up) + 1*C(2,dn)") self.assertEqual(str(ExpressionR() + expr_r), "1*C+(1,up) + 1*C(2,dn)") self.assertEqual(str(expr_r + a(0, "x")), "1*C+(1,up) + 1*C(2,dn) + 1*A(0,x)") self.assertEqual(str(a(0, "x") + expr_r), "1*C+(1,up) + 1*C(2,dn) + 1*A(0,x)") self.assertEqual(str(expr_r + (-c_dag(1, "up"))), "1*C(2,dn)") self.assertEqual(str((-c_dag(1, "up")) + expr_r), "1*C(2,dn)") self.assertEqual( str((c_dag(1, "up") + c(2, "dn")) + (c(2, "dn") + 2.0)), "2 + 1*C+(1,up) + 2*C(2,dn)") # Real and complex expr1 = make_complex(c_dag(1, "up")) expr2 = c(2, "dn") self.assertIsInstance(expr1 + expr2, ExpressionC) self.assertIsInstance(expr2 + expr1, ExpressionC) self.assertEqual(str(ExpressionC() + ExpressionR()), "(0,0)") self.assertEqual(str(ExpressionR() + ExpressionC()), "(0,0)") self.assertEqual(str(expr1 + ExpressionR()), "(1,0)*C+(1,up)") self.assertEqual(str(ExpressionR() + expr1), "(1,0)*C+(1,up)") self.assertEqual(str(expr2 + ExpressionC()), "(1,0)*C(2,dn)") self.assertEqual(str(ExpressionC() + expr2), "(1,0)*C(2,dn)") self.assertEqual(str(expr1 + expr2), "(1,0)*C+(1,up) + (1,0)*C(2,dn)") self.assertEqual(str(expr2 + expr1), "(1,0)*C+(1,up) + (1,0)*C(2,dn)") expr1 += expr2 self.assertEqual(str(expr1 + ExpressionR()), "(1,0)*C+(1,up) + (1,0)*C(2,dn)") self.assertEqual(str(ExpressionR() + expr1), "(1,0)*C+(1,up) + (1,0)*C(2,dn)") self.assertEqual(str(expr1 + a(0, "x")), "(1,0)*C+(1,up) + (1,0)*C(2,dn) + (1,0)*A(0,x)") self.assertEqual(str(a(0, "x") + expr1), "(1,0)*C+(1,up) + (1,0)*C(2,dn) + (1,0)*A(0,x)") self.assertEqual(str(expr1 + (-make_complex(c_dag(1, "up")))), "(1,0)*C(2,dn)") self.assertEqual(str((-make_complex(c_dag(1, "up"))) + expr1), "(1,0)*C(2,dn)") self.assertEqual( str( make_complex(c_dag(1, "up") + c(2, "dn")) + (c(2, "dn") + 2.0)), "(2,0) + (1,0)*C+(1,up) + (2,0)*C(2,dn)")
def test_iter(self): expr0 = ExpressionR() self.assertEqual([_ for _ in expr0], []) expr = 4.0 * c_dag(1, "up") * c(2, "dn") + 1.0 \ + 3.0 * a(0, "x") + 2.0 * a_dag(0, "y") ref = [(Monomial(), 1.0), (Monomial([make_boson(True, 0, "y")]), 2.0), (Monomial([make_boson(False, 0, "x")]), 3.0), (Monomial( [make_fermion(True, 1, "up"), make_fermion(False, 2, "dn")]), 4.0)] self.assertEqual([_ for _ in expr], ref)
def test_multiplication(self): # Real expr_r = c_dag(1, "up") self.assertIsInstance(expr_r * c(2, "dn"), ExpressionR) self.assertIsInstance(c(2, "dn") * expr_r, ExpressionR) self.assertEqual(str(ExpressionR() * ExpressionR()), "0") self.assertEqual(str(expr_r * ExpressionR()), "0") self.assertEqual(str(ExpressionR() * expr_r), "0") self.assertEqual(str(expr_r * c(2, "dn")), "1*C+(1,up)C(2,dn)") self.assertEqual(str(c(2, "dn") * expr_r), "-1*C+(1,up)C(2,dn)") expr_r *= c(2, "dn") self.assertEqual(str(expr_r * a(0, "x")), "1*C+(1,up)C(2,dn)A(0,x)") self.assertEqual(str(a(0, "x") * expr_r), "1*C+(1,up)C(2,dn)A(0,x)") self.assertEqual(str(expr_r * c_dag(1, "up")), "0") self.assertEqual(str(c_dag(1, "up") * expr_r), "0") # Real and complex expr1 = make_complex(c_dag(1, "up")) expr2 = c(2, "dn") self.assertIsInstance(expr1 * expr2, ExpressionC) self.assertIsInstance(expr2 * expr1, ExpressionC) self.assertEqual(str(ExpressionC() * ExpressionR()), "(0,0)") self.assertEqual(str(ExpressionR() * ExpressionC()), "(0,0)") self.assertEqual(str(expr1 * ExpressionR()), "(0,0)") self.assertEqual(str(ExpressionR() * expr1), "(0,0)") self.assertEqual(str(expr2 * ExpressionC()), "(0,0)") self.assertEqual(str(ExpressionC() * expr2), "(0,0)") self.assertEqual(str(expr1 * expr2), "(1,0)*C+(1,up)C(2,dn)") self.assertEqual(str(expr2 * expr1), "(-1,0)*C+(1,up)C(2,dn)") expr1 *= expr2 self.assertEqual(str(expr1 * a(0, "x")), "(1,0)*C+(1,up)C(2,dn)A(0,x)") self.assertEqual(str(a(0, "x") * expr1), "(1,0)*C+(1,up)C(2,dn)A(0,x)") self.assertEqual(str(expr1 * make_complex(c_dag(1, "up"))), "(0,0)") self.assertEqual(str(make_complex(c_dag(1, "up")) * expr1), "(0,0)")
def test_t_j_int(self): J = np.array([[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3], [0, 0, 0, 0]], dtype=float) indices_up = [("up", 0), ("up", 1), ("up", 2), ("up", 3)] indices_dn = [("dn", 0), ("dn", 1), ("dn", 2), ("dn", 3)] H1 = t_j_int(J) self.assertIsInstance(H1, ExpressionR) sp = [c_dag(i, "up") * c(i, "dn") for i in range(4)] sm = [c_dag(i, "dn") * c(i, "up") for i in range(4)] sz = [0.5 * (n(i, "up") - n(i, "dn")) for i in range(4)] ni = [n(i, "up") + n(i, "dn") for i in range(4)] ref1 = 0.5 * (sp[0] * sm[1] + sm[0] * sp[1]) + sz[0] * sz[1] ref1 += -0.25 * ni[0] * ni[1] ref1 += 2.0 * (0.5 * (sp[1] * sm[2] + sm[1] * sp[2]) + sz[1] * sz[2]) ref1 += -0.5 * ni[1] * ni[2] ref1 += 3.0 * (0.5 * (sp[2] * sm[3] + sm[2] * sp[3]) + sz[2] * sz[3]) ref1 += -0.75 * ni[2] * ni[3] self.assertEqual(H1, ref1) H2 = t_j_int(1j * J) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = t_j_int(J, indices_up=indices_up, indices_dn=indices_dn) self.assertIsInstance(H3, ExpressionR) sp = [c_dag("up", i) * c("dn", i) for i in range(4)] sm = [c_dag("dn", i) * c("up", i) for i in range(4)] sz = [0.5 * (n("up", i) - n("dn", i)) for i in range(4)] ni = [n("up", i) + n("dn", i) for i in range(4)] ref3 = 0.5 * (sp[0] * sm[1] + sm[0] * sp[1]) + sz[0] * sz[1] ref3 += -0.25 * ni[0] * ni[1] ref3 += 2.0 * (0.5 * (sp[1] * sm[2] + sm[1] * sp[2]) + sz[1] * sz[2]) ref3 += -0.5 * ni[1] * ni[2] ref3 += 3.0 * (0.5 * (sp[2] * sm[3] + sm[2] * sp[3]) + sz[2] * sz[3]) ref3 += -0.75 * ni[2] * ni[3] self.assertEqual(H3, ref3)
def test_kondo_int(self): J = np.array([1, 2, 3, 4], dtype=float) indices_up = [("up", 0), ("up", 1), ("up", 2), ("up", 3)] indices_dn = [("dn", 0), ("dn", 1), ("dn", 2), ("dn", 3)] indices_spin = [('a', 0), ('b', 1), ('c', 2), ('d', 3)] H1 = kondo_int(J) self.assertIsInstance(H1, ExpressionR) sp = [c_dag(i, "up") * c(i, "dn") for i in range(4)] sm = [c_dag(i, "dn") * c(i, "up") for i in range(4)] sz = [0.5 * (n(i, "up") - n(i, "dn")) for i in range(4)] ref1 = 1.0 * (0.5 * (sp[0] * S_m(0) + sm[0] * S_p(0)) + sz[0] * S_z(0)) ref1 += 2.0 * (0.5 * (sp[1] * S_m(1) + sm[1] * S_p(1)) + sz[1] * S_z(1)) ref1 += 3.0 * (0.5 * (sp[2] * S_m(2) + sm[2] * S_p(2)) + sz[2] * S_z(2)) ref1 += 4.0 * (0.5 * (sp[3] * S_m(3) + sm[3] * S_p(3)) + sz[3] * S_z(3)) self.assertEqual(H1, ref1) H2 = kondo_int(1j * J) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = kondo_int(J, indices_up=indices_up, indices_dn=indices_dn, indices_spin=indices_spin) self.assertIsInstance(H3, ExpressionR) sp = [c_dag("up", i) * c("dn", i) for i in range(4)] sm = [c_dag("dn", i) * c("up", i) for i in range(4)] sz = [0.5 * (n("up", i) - n("dn", i)) for i in range(4)] ref3 = 1.0 * (0.5 * (sp[0] * S_m('a', 0) + sm[0] * S_p('a', 0)) + sz[0] * S_z('a', 0)) ref3 += 2.0 * (0.5 * (sp[1] * S_m('b', 1) + sm[1] * S_p('b', 1)) + sz[1] * S_z('b', 1)) ref3 += 3.0 * (0.5 * (sp[2] * S_m('c', 2) + sm[2] * S_p('c', 2)) + sz[2] * S_z('c', 2)) ref3 += 4.0 * (0.5 * (sp[3] * S_m('d', 3) + sm[3] * S_p('d', 3)) + sz[3] * S_z('d', 3)) self.assertEqual(H3, ref3) H4 = kondo_int(J, spin=1) self.assertIsInstance(H4, ExpressionR) sp = [c_dag(i, "up") * c(i, "dn") for i in range(4)] sm = [c_dag(i, "dn") * c(i, "up") for i in range(4)] sz = [0.5 * (n(i, "up") - n(i, "dn")) for i in range(4)] ref4 = 1.0 * (0.5 * (sp[0] * S1_m(0) + sm[0] * S1_p(0)) + sz[0] * S1_z(0)) ref4 += 2.0 * (0.5 * (sp[1] * S1_m(1) + sm[1] * S1_p(1)) + sz[1] * S1_z(1)) ref4 += 3.0 * (0.5 * (sp[2] * S1_m(2) + sm[2] * S1_p(2)) + sz[2] * S1_z(2)) ref4 += 4.0 * (0.5 * (sp[3] * S1_m(3) + sm[3] * S1_p(3)) + sz[3] * S1_z(3)) self.assertEqual(H4, ref4)
def test_dispersion(self): indices = [("a", 0), ("b", 1), ("c", 2)] eps = np.array([1.0, 2.0, 3.0]) H1 = dispersion(eps) self.assertIsInstance(H1, ExpressionR) ref1 = c_dag(0) * c(0) + 2 * c_dag(1) * c(1) + 3.0 * c_dag(2) * c(2) self.assertEqual(H1, ref1) H2 = dispersion(1j * eps) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = dispersion(eps, statistics=FERMION) self.assertIsInstance(H3, ExpressionR) ref3 = ref1 self.assertEqual(H3, ref3) H4 = dispersion(eps, indices=indices) self.assertIsInstance(H4, ExpressionR) ref4 = c_dag("a", 0) * c("a", 0) + 2 * c_dag("b", 1) * c("b", 1) \ + 3.0 * c_dag("c", 2) * c("c", 2) self.assertEqual(H4, ref4) H5 = dispersion(eps, statistics=BOSON) self.assertIsInstance(H5, ExpressionR) ref5 = a_dag(0) * a(0) + 2 * a_dag(1) * a(1) + 3.0 * a_dag(2) * a(2) self.assertEqual(H5, ref5)
def test_transform(self): expr = 4.0 * c_dag(1, "up") * c(2, "dn") + 1.0 \ + 3.0 * a(0, "x") + 2.0 * a_dag(0, "y") # Multiply coefficients in front of bosonic operators by 2j def f(m, c): if len(m) > 0 and isinstance(m[0], GeneratorBoson): return 2 * c else: return 0 new_expr = transform(expr, f) self.assertEqual(new_expr, 6.0 * a(0, "x") + 4.0 * a_dag(0, "y"))
def test_strided_arrays(self): expr = 6 * c_dag("dn") - 6 * c("up") hs = HilbertSpace(expr) lop = LOperatorR(expr, hs) src_real = 999 * np.ones((10, ), dtype=float) src_real[3:10:2] = 1 src_complex = np.array(src_real, dtype=complex) assert_equal(lop * src_real[3:10:2], np.array([-6, 12, 0, 6], dtype=float)) assert_equal(lop * src_complex[3:10:2], np.array([-6, 12, 0, 6], dtype=complex)) dst_real = 777 * np.ones((10, ), dtype=float) dst_complex = np.array(dst_real, dtype=complex) ref_real = np.array([777, 777, -6, 777, 12, 777, 0, 777, 6, 777], dtype=float) ref_complex = np.array(ref_real, dtype=complex) lop(src_real[3:10:2], dst_real[2:9:2]) assert_equal(dst_real, ref_real) lop(src_real[3:10:2], dst_complex[2:9:2]) assert_equal(dst_complex, ref_complex) lop(src_complex[3:10:2], dst_complex[2:9:2]) assert_equal(dst_complex, ref_complex) expr = 6j * c_dag("dn") - 6j * c("up") hs = HilbertSpace(expr) lop = LOperatorC(expr, hs) ref_complex = np.array([777, 777, -6j, 777, 12j, 777, 0, 777, 6j, 777], dtype=complex) lop(src_real[3:10:2], dst_complex[2:9:2]) assert_equal(dst_complex, ref_complex) lop(src_complex[3:10:2], dst_complex[2:9:2]) assert_equal(dst_complex, ref_complex)