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_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_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_spin12_products(self): self.assertEqual(S_z() * S_z(), ExpressionR(0.25)) self.assertEqual(S_p() * S_p(), ExpressionR()) self.assertEqual(S_m() * S_m(), ExpressionR()) self.assertEqual(S_p() * S_z(), -0.5 * S_p()) self.assertEqual(S_z() * S_m(), -0.5 * S_m()) self.assertEqual(S_z() * S_p(), 0.5 * S_p()) self.assertEqual(S_m() * S_z(), 0.5 * S_m()) self.assertEqual(S_p() * S_m(), 0.5 + S_z()) self.assertEqual(S_m() * S_p(), 0.5 - S_z())
def test_complex_only(self): # Spin 1/2 self.assertEqual(make_complex(S_p(0, "x")), S_x(0, "x") + 1j * S_y(0, "x")) self.assertEqual(make_complex(S_m(0, "x")), S_x(0, "x") - 1j * S_y(0, "x")) # Spin 1 self.assertEqual(make_complex(S_p(0, "x", spin=1)), S_x(0, "x", spin=1) + 1j * S_y(0, "x", spin=1)) self.assertEqual(make_complex(S_m(0, "x", spin=1)), S_x(0, "x", spin=1) - 1j * S_y(0, "x", spin=1)) # Spin 3/2 self.assertEqual( make_complex(S_p(0, "x", spin=3 / 2)), S_x(0, "x", spin=3 / 2) + 1j * S_y(0, "x", spin=3 / 2)) self.assertEqual( make_complex(S_m(0, "x", spin=3 / 2)), S_x(0, "x", spin=3 / 2) - 1j * S_y(0, "x", spin=3 / 2))
def test_from_expression(self): expr = 2.0 * S_p("i", 0, spin=3 / 2) * S_m("j", 0, spin=3 / 2) \ + 5.0 * n("up", 0) * n("dn", 0) hs1 = HilbertSpace(expr) self.assertEqual(len(hs1), 4) self.assertEqual(hs1.total_n_bits, 6) self.assertEqual(hs1.dim, 64) self.assertTrue(self.es_f_dn in hs1) self.assertEqual(hs1.index(self.es_f_dn), 0) self.assertEqual(hs1.bit_range(self.es_f_dn), (0, 0)) self.assertTrue(self.es_f_up in hs1) self.assertEqual(hs1.index(self.es_f_up), 1) self.assertEqual(hs1.bit_range(self.es_f_up), (1, 1)) self.assertTrue(self.es_s32_i in hs1) self.assertEqual(hs1.index(self.es_s32_i), 2) self.assertEqual(hs1.bit_range(self.es_s32_i), (2, 3)) self.assertTrue(self.es_s32_j in hs1) self.assertEqual(hs1.index(self.es_s32_j), 3) self.assertEqual(hs1.bit_range(self.es_s32_j), (4, 5)) # foreach() count = 0 def counter(i): nonlocal count count += i foreach(hs1, counter) self.assertEqual(count, 2016) expr += a_dag("x", 0) + a("y", 0) hs2 = HilbertSpace(expr, bits_per_boson=4) self.assertEqual(len(hs2), 6) self.assertEqual(hs2.total_n_bits, 14) self.assertEqual(hs2.dim, 16384) self.assertTrue(self.es_f_dn in hs2) self.assertEqual(hs2.index(self.es_f_dn), 0) self.assertEqual(hs2.bit_range(self.es_f_dn), (0, 0)) self.assertTrue(self.es_f_up in hs2) self.assertEqual(hs2.index(self.es_f_up), 1) self.assertEqual(hs2.bit_range(self.es_f_up), (1, 1)) self.assertTrue(self.es_b_x in hs2) self.assertEqual(hs2.index(self.es_b_x), 2) self.assertEqual(hs2.bit_range(self.es_b_x), (2, 5)) self.assertTrue(self.es_b_y in hs2) self.assertEqual(hs2.index(self.es_b_y), 3) self.assertEqual(hs2.bit_range(self.es_b_y), (6, 9)) self.assertTrue(self.es_s32_i in hs2) self.assertEqual(hs2.index(self.es_s32_i), 4) self.assertEqual(hs2.bit_range(self.es_s32_i), (10, 11)) self.assertTrue(self.es_s32_j in hs2) self.assertEqual(hs2.index(self.es_s32_j), 5) self.assertEqual(hs2.bit_range(self.es_s32_j), (12, 13))
def test_biquadratic_spin_int(self): J = np.array([[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3], [0, 0, 0, 0]], dtype=float) indices = [('a', 0), ('b', 1), ('c', 2), ('d', 3)] S0S1 = 0.5 * (S1_p(0) * S1_m(1) + S1_m(0) * S1_p(1)) \ + S1_z(0) * S1_z(1) S1S2 = 0.5 * (S1_p(1) * S1_m(2) + S1_m(1) * S1_p(2)) \ + S1_z(1) * S1_z(2) S2S3 = 0.5 * (S1_p(2) * S1_m(3) + S1_m(2) * S1_p(3)) \ + S1_z(2) * S1_z(3) H1 = biquadratic_spin_int(J) self.assertIsInstance(H1, ExpressionR) ref1 = 1.0 * S0S1 * S0S1 + 2.0 * S1S2 * S1S2 + 3.0 * S2S3 * S2S3 self.assertEqual(H1, ref1) H2 = biquadratic_spin_int(1j * J) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = biquadratic_spin_int(J, indices=indices) self.assertIsInstance(H3, ExpressionR) S0S1 = 0.5 * (S1_p('a', 0) * S1_m('b', 1) + S1_m('a', 0) * S1_p('b', 1)) \ + S1_z('a', 0) * S1_z('b', 1) S1S2 = 0.5 * (S1_p('b', 1) * S1_m('c', 2) + S1_m('b', 1) * S1_p('c', 2)) \ + S1_z('b', 1) * S1_z('c', 2) S2S3 = 0.5 * (S1_p('c', 2) * S1_m('d', 3) + S1_m('c', 2) * S1_p('d', 3)) \ + S1_z('c', 2) * S1_z('d', 3) ref3 = 1.0 * S0S1 * S0S1 + 2.0 * S1S2 * S1S2 + 3.0 * S2S3 * S2S3 self.assertEqual(H3, ref3) H4 = biquadratic_spin_int(J, indices=indices, spin=1 / 2) self.assertIsInstance(H4, ExpressionR) S0S1 = 0.5 * (S_p('a', 0) * S_m('b', 1) + S_m('a', 0) * S_p('b', 1)) + S_z('a', 0) * S_z('b', 1) S1S2 = 0.5 * (S_p('b', 1) * S_m('c', 2) + S_m('b', 1) * S_p('c', 2)) + S_z('b', 1) * S_z('c', 2) S2S3 = 0.5 * (S_p('c', 2) * S_m('d', 3) + S_m('c', 2) * S_p('d', 3)) + S_z('c', 2) * S_z('d', 3) ref4 = 1.0 * S0S1 * S0S1 + 2.0 * S1S2 * S1S2 + 3.0 * S2S3 * S2S3 self.assertEqual(H4, ref4)
def test_jaynes_cummings(self): eps = np.array([1, 2, 3], dtype=float) omega = np.array([4, 5], dtype=float) g = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], dtype=float) indices_atom = [('a', 0), ('b', 1), ('c', 2)] indices_boson = [('x', 0), ('y', 1)] self.assertIsInstance(jaynes_cummings(eps, omega, g), ExpressionR) self.assertIsInstance(jaynes_cummings(1j * eps, omega, g), ExpressionC) self.assertIsInstance(jaynes_cummings(eps, 1j * omega, g), ExpressionC) self.assertIsInstance(jaynes_cummings(eps, omega, 1j * g), ExpressionC) H1 = jaynes_cummings(eps, omega, 1j * g) ref1 = S_z(0) + 2.0 * S_z(1) + 3.0 * S_z(2) ref1 += 4.0 * a_dag(0) * a(0) + 5.0 * a_dag(1) * a(1) ref1 += 0.1j * a_dag(0) * S_m(0) - 0.1j * a(0) * S_p(0) ref1 += 0.2j * a_dag(1) * S_m(0) - 0.2j * a(1) * S_p(0) ref1 += 0.3j * a_dag(0) * S_m(1) - 0.3j * a(0) * S_p(1) ref1 += 0.4j * a_dag(1) * S_m(1) - 0.4j * a(1) * S_p(1) ref1 += 0.5j * a_dag(0) * S_m(2) - 0.5j * a(0) * S_p(2) ref1 += 0.6j * a_dag(1) * S_m(2) - 0.6j * a(1) * S_p(2) self.assertEqual(H1, ref1) H2 = jaynes_cummings(eps, omega, 1j * g, indices_atom=indices_atom, indices_boson=indices_boson) ref2 = S_z('a', 0) + 2.0 * S_z('b', 1) + 3.0 * S_z('c', 2) ref2 += 4.0 * a_dag('x', 0) * a('x', 0) \ + 5.0 * a_dag('y', 1) * a('y', 1) ref2 += 0.1j * a_dag('x', 0) * S_m('a', 0) \ - 0.1j * a('x', 0) * S_p('a', 0) ref2 += 0.2j * a_dag('y', 1) * S_m('a', 0) \ - 0.2j * a('y', 1) * S_p('a', 0) ref2 += 0.3j * a_dag('x', 0) * S_m('b', 1) \ - 0.3j * a('x', 0) * S_p('b', 1) ref2 += 0.4j * a_dag('y', 1) * S_m('b', 1) \ - 0.4j * a('y', 1) * S_p('b', 1) ref2 += 0.5j * a_dag('x', 0) * S_m('c', 2) \ - 0.5j * a('x', 0) * S_p('c', 2) ref2 += 0.6j * a_dag('y', 1) * S_m('c', 2) \ - 0.6j * a('y', 1) * S_p('c', 2) self.assertEqual(H2, ref2) H3 = jaynes_cummings(eps, omega, 1j * g, spin=1) ref3 = S1_z(0) + 2.0 * S1_z(1) + 3.0 * S1_z(2) ref3 += 4.0 * a_dag(0) * a(0) + 5.0 * a_dag(1) * a(1) ref3 += 0.1j * a_dag(0) * S1_m(0) - 0.1j * a(0) * S1_p(0) ref3 += 0.2j * a_dag(1) * S1_m(0) - 0.2j * a(1) * S1_p(0) ref3 += 0.3j * a_dag(0) * S1_m(1) - 0.3j * a(0) * S1_p(1) ref3 += 0.4j * a_dag(1) * S1_m(1) - 0.4j * a(1) * S1_p(1) ref3 += 0.5j * a_dag(0) * S1_m(2) - 0.5j * a(0) * S1_p(2) ref3 += 0.6j * a_dag(1) * S1_m(2) - 0.6j * a(1) * S1_p(2) self.assertEqual(H3, ref3)
def test_heisenberg(self): J = np.array([[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3], [0, 0, 0, 0]], dtype=float) h = np.array([[0.3, 0, 0], [0, 0.4, 0], [0, 0, 0.5], [0, 0, 0]]) indices = [('a', 0), ('b', 1), ('c', 2), ('d', 3)] H1 = heisenberg(J) self.assertIsInstance(H1, ExpressionR) ref1 = - 0.5 * S_p(0) * S_m(1) \ - 0.5 * S_m(0) * S_p(1) \ - 1.0 * S_z(0) * S_z(1) \ - 1.0 * S_p(1) * S_m(2) \ - 1.0 * S_m(1) * S_p(2) \ - 2.0 * S_z(1) * S_z(2) \ - 1.5 * S_p(2) * S_m(3) \ - 1.5 * S_m(2) * S_p(3) \ - 3.0 * S_z(2) * S_z(3) self.assertEqual(H1, ref1) H2 = heisenberg(1j * J) self.assertIsInstance(H2, ExpressionC) ref2 = 1j * ref1 self.assertEqual(H2, ref2) H3 = heisenberg(J, h) self.assertIsInstance(H3, ExpressionC) ref3 = ref1 - 0.3 * S_x(0) - 0.4 * S_y(1) - 0.5 * S_z(2) self.assertEqual(H3, ref3) H4 = heisenberg(J, h, indices=indices) self.assertIsInstance(H4, ExpressionC) ref4 = - 0.5 * S_p('a', 0) * S_m('b', 1) \ - 0.5 * S_m('a', 0) * S_p('b', 1) \ - 1.0 * S_z('a', 0) * S_z('b', 1) \ - 1.0 * S_p('b', 1) * S_m('c', 2) \ - 1.0 * S_m('b', 1) * S_p('c', 2) \ - 2.0 * S_z('b', 1) * S_z('c', 2) \ - 1.5 * S_p('c', 2) * S_m('d', 3) \ - 1.5 * S_m('c', 2) * S_p('d', 3) \ - 3.0 * S_z('c', 2) * S_z('d', 3) \ - 0.3 * S_x('a', 0) - 0.4 * S_y('b', 1) - 0.5 * S_z('c', 2) self.assertEqual(H4, ref4) H5 = heisenberg(J, h, indices=indices, spin=1) self.assertIsInstance(H5, ExpressionC) ref5 = - 0.5 * S1_p('a', 0) * S1_m('b', 1) \ - 0.5 * S1_m('a', 0) * S1_p('b', 1) \ - 1.0 * S1_z('a', 0) * S1_z('b', 1) \ - 1.0 * S1_p('b', 1) * S1_m('c', 2) \ - 1.0 * S1_m('b', 1) * S1_p('c', 2) \ - 2.0 * S1_z('b', 1) * S1_z('c', 2) \ - 1.5 * S1_p('c', 2) * S1_m('d', 3) \ - 1.5 * S1_m('c', 2) * S1_p('d', 3) \ - 3.0 * S1_z('c', 2) * S1_z('d', 3) \ - 0.3 * S1_x('a', 0) - 0.4 * S1_y('b', 1) - 0.5 * S1_z('c', 2) self.assertEqual(H5, ref5)