def test_too_many_terms(self): """Test exception raised for wrong number of terms""" with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0.1, 0.2) H -= BosonOperator('0^ 0^ 0^ 0^') extract_onsite_chemical(H) with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0.1, 0.2) H -= BosonOperator('5^ 5 5^ 5') extract_onsite_chemical(H)
def test_too_many_terms(self): """Test exception raised for wrong number of terms""" with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0) H -= BosonOperator('0^ 1^') extract_tunneling(H) with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0) H -= BosonOperator('0^ 1') H -= BosonOperator('1^ 0') extract_tunneling(H)
def test_tunneling_2x2(self): """Test extracted tunneling on 2x2 grid""" H = bose_hubbard(2, 2, 0.5, 0) res = extract_tunneling(H) res[0] = sorted(res[0], key=lambda x: x[1]) expected = [[(0, 1), (0, 2), (1, 3), (2, 3)], 0.5] assert res == expected
def test_1x2_tf(self, hbar, tol): """Test a 1x2 lattice Bose-Hubbard model using TF""" try: import tensorflow as tf except (ImportError, ModuleNotFoundError): pytest.skip("TensorFlow not installed.") if tf.__version__[:3] != "1.3": pytest.skip("Incorrect TensorFlow version") sf.hbar = hbar prog = sf.Program(2) H = bose_hubbard(1, 2, self.J, self.U) with prog.context as q: Fock(2) | q[0] BoseHubbardPropagation(H, self.t, self.k) | q eng = sf.Engine("tf", backend_options={"cutoff_dim": 7}) state = eng.run(prog).state Hm = -self.J*np.sqrt(2)*np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]]) \ + self.U*np.diag([1, 0, 1]) init_state = np.array([1, 0, 0]) exp = np.abs(np.dot(expm(-1j * self.t * Hm), init_state))**2 assert np.allclose(state.fock_prob([2, 0]), exp[0], rtol=tol) assert np.allclose(state.fock_prob([1, 1]), exp[1], rtol=tol) assert np.allclose(state.fock_prob([0, 2]), exp[2], rtol=tol)
def test_ladder_wrong_form(self): """Test exception raised for wrong ladder operators""" with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 1, 1, 0.5) H += BosonOperator('5^ 5 6^ 6^') H -= BosonOperator('6 5') extract_dipole(H)
def test_wrong_term_length(self): """Test exception raised for wrong terms""" with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0.1, 0.2) H -= BosonOperator('5^ 5 5^') H += BosonOperator('5^ 5') extract_onsite_chemical(H)
def test_ladder_wrong_form(self): """Test exception raised for wrong ladder operators""" with self.assertRaises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0) H -= BosonOperator('5^ 6^') H -= BosonOperator('6 5') extract_tunneling(H)
def test_incorrect_ladders(self): """Test exception raised for wrong ladder operators""" with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0.1, 0.2) H -= BosonOperator('5^ 5^ 5^ 5^') H -= BosonOperator('5 5^ 5 5^') extract_onsite_chemical(H)
def test_both(self): """Test case where there is non-zero mu and non-zero U""" self.logTestName() H = bose_hubbard(2, 2, 1, 0.1, 0.2) res = extract_onsite_chemical(H) expected = ([[0, 1, 2, 3], 0.1], [[0, 1, 2, 3], 0.2]) self.assertEqual(res, expected)
def test_2x2(self): """Test extracted dipole terms on 2x2 grid""" H = bose_hubbard(2, 2, 1, 0, 0, 0.5) res = extract_dipole(H) res[0] = sorted(res[0], key=lambda x: x[0]) expected = [[(0, 1), (0, 2), (1, 3), (2, 3)], 0.5] assert res == expected
def test_too_many_terms(self): """Test exception raised for wrong number of terms""" self.logTestName() with self.assertRaises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 1, 1, 0.5) H += BosonOperator('0^ 0 1^ 2', 0.5) extract_dipole(H)
def test_tunneling_1x2(self): """Test extracted tunneling on 1x2 grid""" self.logTestName() H = bose_hubbard(1, 2, 0.5, 0) res = extract_tunneling(H) expected = [[(0, 1)], 0.5] self.assertEqual(res, expected)
def test_differing_chemical_potential(self): """Test exception raised for differing coefficients""" self.logTestName() with self.assertRaises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0.1, 0.2) H -= BosonOperator('5^ 5') extract_onsite_chemical(H)
def test_bose_hubbard_2x2_aperiodic(): hubbard_model = bose_hubbard(2, 2, 1.0, 4.0, chemical_potential=0.5, dipole=0.3, periodic=False) assert str(hubbard_model).strip() == """ -1.0 [0 1^] + -1.0 [0 2^] + -2.5 [0^ 0] + 2.0 [0^ 0 0^ 0] + 0.3 [0^ 0 1^ 1] + 0.3 [0^ 0 2^ 2] + -1.0 [0^ 1] + -1.0 [0^ 2] + -1.0 [1 3^] + -2.5 [1^ 1] + 2.0 [1^ 1 1^ 1] + 0.3 [1^ 1 3^ 3] + -1.0 [1^ 3] + -1.0 [2 3^] + -2.5 [2^ 2] + 2.0 [2^ 2 2^ 2] + 0.3 [2^ 2 3^ 3] + -1.0 [2^ 3] + -2.5 [3^ 3] + 2.0 [3^ 3 3^ 3] """.strip()
def test_differing_onsite(self): """Test exception raised for differing coefficients""" with pytest.raises(BoseHubbardError): H = bose_hubbard(2, 2, 1, 0.1, 0.2) H -= BosonOperator('5^ 5 5^ 5') H += BosonOperator('5^ 5') extract_onsite_chemical(H)
def test_2x2(self): """Test extracted dipole terms on 2x2 grid""" self.logTestName() H = bose_hubbard(2, 2, 1, 0, 0, 0.5) res = extract_dipole(H) res[0] = sorted(res[0], key=lambda x: x[0]) expected = [[(0, 1), (0, 2), (1, 3), (2, 3)], 0.5] self.assertEqual(res, expected)
def test_tunneling_2x2(self): """Test extracted tunneling on 2x2 grid""" self.logTestName() H = bose_hubbard(2, 2, 0.5, 0) res = extract_tunneling(H) res[0] = sorted(res[0], key=lambda x: x[1]) expected = [[(0, 1), (0, 2), (1, 3), (2, 3)], 0.5] self.assertEqual(res, expected)
def test_two_by_two_periodic_rudimentary(self): hubbard_model = bose_hubbard(self.x_dimension, self.y_dimension, self.tunneling, self.interaction, self.chemical_potential, self.dipole, periodic=True)
def test_tunneling_2x2(self): """Test non-interacting 2x2 grid""" H = bose_hubbard(2, 2, self.J, 0, 0) res = trotter_layer(H, self.t, self.k) theta = -self.t * self.J / self.k phi = np.pi / 2 expected = {'BS': (theta, phi, [(0, 1), (0, 2), (1, 3), (2, 3)])} self.assertEqual(res, expected)
def setUp(self): self.hbar = 2. self.eng, _ = sf.Engine(3, hbar=self.hbar) self.J = -1 self.U = 1.5 self.t = 1.086 self.k = 20 self.tol = 1e-2 self.H = bose_hubbard(1, 2, self.J, self.U)
def test_tunneling_2x2(self): """Test non-interacting 2x2 grid""" H = bose_hubbard(2, 2, self.J, 0, 0) res = trotter_layer(H, self.t, self.k) theta = -self.t * self.J / self.k phi = np.pi / 2 expected = {'BS': (theta, phi, [(0, 1), (0, 2), (1, 3), (2, 3)])} res['BS'] = res['BS'][:2] + (sorted(res['BS'][2], key=lambda x: x[0]), ) assert res == expected
def test_three_by_two_periodic_rudimentary(self): hubbard_model = bose_hubbard(3, 2, self.tunneling, self.interaction, self.chemical_potential, self.dipole, periodic=True) # Check up top/bottom hopping terms. self.assertAlmostEqual(hubbard_model.terms[((0, 0), (2, 1))], -self.tunneling)
def setUp(self): """parameters""" self.hbar = 2. self.eng, _ = sf.Engine(2, hbar=self.hbar) self.J = -1 self.U = 1.5 self.t = 1.086 self.k = 20 self.tol = 1e-2 self.H = bose_hubbard(1, 2, self.J, self.U) self.Hquad = get_quad_operator(self.H, hbar=self.hbar)
def test_chemical_potential_2x2(self): """Test on-site interacting and chemical potential on a 2x2 grid""" H = bose_hubbard(2, 2, self.J, self.U, self.mu) res = trotter_layer(H, self.t, self.k) theta = -self.t * self.J / self.k phi = np.pi / 2 kappa = -self.t * self.U / (2 * self.k) r = self.t * (0.5 * self.U + self.mu) / (2 * self.k) expected = { 'BS': (theta, phi, [(0, 1), (0, 2), (1, 3), (2, 3)]), 'K': (kappa, [0, 1, 2, 3]), 'R': (r, [0, 1, 2, 3]), } self.assertEqual(res, expected)
def test_onsite_2x2(self): """Test on-site interacting 2x2 grid""" H = bose_hubbard(2, 2, self.J, self.U, 0) res = trotter_layer(H, self.t, self.k) theta = -self.t * self.J / self.k phi = np.pi / 2 kappa = -self.t * self.U / (2 * self.k) r = -kappa expected = { 'BS': (theta, phi, [(0, 1), (0, 2), (1, 3), (2, 3)]), 'K': (kappa, [0, 1, 2, 3]), 'R': (r, [0, 1, 2, 3]), } self.assertEqual(res, expected)
def test_bose_hubbard_3x2(): hubbard_model = bose_hubbard(3, 2, 1.0, 4.0, chemical_potential=0.5, dipole=0.3) assert str(hubbard_model).strip() == """ -1.0 [0 1^] + -1.0 [0 2^] + -1.0 [0 3^] + -2.5 [0^ 0] + 2.0 [0^ 0 0^ 0] + 0.3 [0^ 0 1^ 1] + 0.3 [0^ 0 3^ 3] + -1.0 [0^ 1] + -1.0 [0^ 2] + -1.0 [0^ 3] + -1.0 [1 2^] + -1.0 [1 4^] + -2.5 [1^ 1] + 2.0 [1^ 1 1^ 1] + 0.3 [1^ 1 2^ 2] + 0.3 [1^ 1 4^ 4] + -1.0 [1^ 2] + -1.0 [1^ 4] + -1.0 [2 5^] + -2.5 [2^ 2] + 0.3 [2^ 2 0^ 0] + 2.0 [2^ 2 2^ 2] + 0.3 [2^ 2 5^ 5] + -1.0 [2^ 5] + -1.0 [3 4^] + -1.0 [3 5^] + -2.5 [3^ 3] + 2.0 [3^ 3 3^ 3] + 0.3 [3^ 3 4^ 4] + -1.0 [3^ 4] + -1.0 [3^ 5] + -1.0 [4 5^] + -2.5 [4^ 4] + 2.0 [4^ 4 4^ 4] + 0.3 [4^ 4 5^ 5] + -1.0 [4^ 5] + -2.5 [5^ 5] + 0.3 [5^ 5 3^ 3] + 2.0 [5^ 5 5^ 5] """.strip()
def test_bose_hubbard_2x3(): hubbard_model = bose_hubbard(2, 3, 1.0, 4.0, chemical_potential=0.5, dipole=0.3) assert str(hubbard_model).strip() == """ -1.0 [0 1^] + -1.0 [0 2^] + -1.0 [0 4^] + -2.5 [0^ 0] + 2.0 [0^ 0 0^ 0] + 0.3 [0^ 0 1^ 1] + 0.3 [0^ 0 2^ 2] + -1.0 [0^ 1] + -1.0 [0^ 2] + -1.0 [0^ 4] + -1.0 [1 3^] + -1.0 [1 5^] + -2.5 [1^ 1] + 2.0 [1^ 1 1^ 1] + 0.3 [1^ 1 3^ 3] + -1.0 [1^ 3] + -1.0 [1^ 5] + -1.0 [2 3^] + -1.0 [2 4^] + -2.5 [2^ 2] + 2.0 [2^ 2 2^ 2] + 0.3 [2^ 2 3^ 3] + 0.3 [2^ 2 4^ 4] + -1.0 [2^ 3] + -1.0 [2^ 4] + -1.0 [3 5^] + -2.5 [3^ 3] + 2.0 [3^ 3 3^ 3] + 0.3 [3^ 3 5^ 5] + -1.0 [3^ 5] + -1.0 [4 5^] + -2.5 [4^ 4] + 0.3 [4^ 4 0^ 0] + 2.0 [4^ 4 4^ 4] + 0.3 [4^ 4 5^ 5] + -1.0 [4^ 5] + -2.5 [5^ 5] + 0.3 [5^ 5 1^ 1] + 2.0 [5^ 5 5^ 5] """.strip()
def test_chemical_potential_2x2(self): """Test on-site interacting and chemical potential on a 2x2 grid""" H = bose_hubbard(2, 2, self.J, self.U, self.mu) res = trotter_layer(H, self.t, self.k) theta = -self.t * self.J / self.k phi = np.pi / 2 kappa = -self.t * self.U / (2 * self.k) r = self.t * (0.5 * self.U + self.mu) / (2 * self.k) expected = { 'BS': (theta, phi, [(0, 1), (0, 2), (1, 3), (2, 3)]), 'K': (kappa, [0, 1, 2, 3]), 'R': (r, [0, 1, 2, 3]), } res['BS'] = res['BS'][:2] + (sorted(res['BS'][2], key=lambda x: x[0]), ) assert res == expected
def test_onsite_2x2(self): """Test on-site interacting 2x2 grid""" H = bose_hubbard(2, 2, self.J, self.U, 0) res = trotter_layer(H, self.t, self.k) theta = -self.t * self.J / self.k phi = np.pi / 2 kappa = -self.t * self.U / (2 * self.k) r = -kappa expected = { 'BS': (theta, phi, [(0, 1), (0, 2), (1, 3), (2, 3)]), 'K': (kappa, [0, 1, 2, 3]), 'R': (r, [0, 1, 2, 3]), } res['BS'] = res['BS'][:2] + (sorted(res['BS'][2], key=lambda x: x[0]), ) assert res == expected
def test_two_by_two(self): # Initialize the Hamiltonian. hubbard_model = bose_hubbard(self.x_dimension, self.y_dimension, self.tunneling, self.interaction, self.chemical_potential, self.dipole, self.periodic) # Check on on-site interaction and chemical-potential terms. chem_coeff = -self.interaction / 2 - self.chemical_potential on_site_coeff = self.interaction / 2 for i in range(4): self.assertAlmostEqual(hubbard_model.terms[((i, 1), (i, 0))], chem_coeff) self.assertAlmostEqual( hubbard_model.terms[((i, 1), (i, 0), (i, 1), (i, 0))], on_site_coeff) # Check right/left hopping terms. t_coeff = -self.tunneling self.assertAlmostEqual(hubbard_model.terms[((0, 1), (1, 0))], t_coeff) self.assertAlmostEqual(hubbard_model.terms[((0, 0), (1, 1))], t_coeff) self.assertAlmostEqual(hubbard_model.terms[((2, 0), (3, 1))], t_coeff) self.assertAlmostEqual(hubbard_model.terms[((2, 1), (3, 0))], t_coeff) # Check top/bottom hopping terms. self.assertAlmostEqual(hubbard_model.terms[((0, 1), (2, 0))], t_coeff) self.assertAlmostEqual(hubbard_model.terms[((0, 0), (2, 1))], t_coeff) self.assertAlmostEqual(hubbard_model.terms[((1, 0), (3, 1))], t_coeff) self.assertAlmostEqual(hubbard_model.terms[((1, 1), (3, 0))], t_coeff) # Check left/right dipole interaction terms. d_coeff = self.dipole self.assertAlmostEqual( hubbard_model.terms[((0, 1), (0, 0), (1, 1), (1, 0))], d_coeff) self.assertAlmostEqual( hubbard_model.terms[((2, 1), (2, 0), (3, 1), (3, 0))], d_coeff) # Check top/bottom interaction terms. self.assertAlmostEqual( hubbard_model.terms[((0, 1), (0, 0), (2, 1), (2, 0))], d_coeff) self.assertAlmostEqual( hubbard_model.terms[((1, 1), (1, 0), (3, 1), (3, 0))], d_coeff) # Check that there are no other interaction terms. self.assertNotIn(((0, 1), (0, 0), (3, 1), (3, 0)), hubbard_model.terms) self.assertNotIn(((1, 1), (1, 0), (2, 1), (2, 0)), hubbard_model.terms)