Beispiel #1
0
    def test_init_exceptions(self):
        M = 5
        st = np.array([], dtype=float)
        hs = HilbertSpace([make_space_fermion(i) for i in range(M)])

        # Multiple fermions
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_n_error_msg(M, M + 1)):
            NFermionSectorViewR(st, hs, M + 1)
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_n_error_msg(M, M + 1)):
            NFermionSectorViewC(st, hs, M + 1)

        # Fermions and bosons
        hs.add(make_space_boson(2, 5))
        hs.add(make_space_boson(3, 6))

        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_n_error_msg(M, M + 1)):
            NFermionSectorViewR(st, hs, M + 1)
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_n_error_msg(M, M + 1)):
            NFermionSectorViewC(st, hs, M + 1)

        # Purely bosonic Hilbert space
        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])

        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            NFermionSectorViewR(st, hs_b, 1)
        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            NFermionSectorViewC(st, hs_b, 1)
Beispiel #2
0
    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)
Beispiel #3
0
    def test_equality(self):
        hs_empty = HilbertSpace()
        self.assertTrue(hs_empty == hs_empty)
        self.assertFalse(hs_empty != hs_empty)

        hs = HilbertSpace([
            self.es_s32_i, self.es_s32_j, self.es_s1_i, self.es_s1_j,
            self.es_s_i, self.es_s_j, self.es_b_x, self.es_b_y, self.es_f_dn,
            self.es_f_up
        ])
        self.assertTrue(hs == hs)
        self.assertFalse(hs != hs)

        self.assertFalse(hs == hs_empty)
        self.assertTrue(hs != hs_empty)
Beispiel #4
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)
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
    def test_empty(self):
        expr0 = ExpressionR()
        hs = HilbertSpace(expr0)
        lop = LOperatorR(expr0, hs)

        sv = np.array([], dtype=float)
        assert_equal(lop * sv, sv)
        dst = np.array([], dtype=float)
        lop(sv, dst)
        assert_equal(sv, dst)
Beispiel #8
0
    def test_loperator(self):
        M = 5

        hs = HilbertSpace([make_space_boson(2, 0)])
        for i in range(M):
            hs.add(make_space_fermion(i))

        H = (n(0) + n(1) + n(2) + n(3) + n(4)) * (a_dag(0) + a(0))

        for src_type, dst_type, lop_type in [(float, float, LOperatorR),
                                             (float, complex, LOperatorR),
                                             (complex, complex, LOperatorR),
                                             (float, complex, LOperatorC),
                                             (complex, complex, LOperatorC)]:
            src_view_type = NFermionSectorViewR if (src_type == float) \
                else NFermionSectorViewC
            dst_view_type = NFermionSectorViewR if (dst_type == float) \
                else NFermionSectorViewC

            Hop = lop_type(H if lop_type == LOperatorR else make_complex(H),
                           hs)

            for N in range(M + 1):
                src = np.zeros(n_fermion_sector_size(hs, N), dtype=src_type)
                view_src = src_view_type(src, hs, N)
                dst = np.zeros(n_fermion_sector_size(hs, N), dtype=dst_type)
                view_dst = dst_view_type(dst, hs, N)

                # 1 boson, fermions in the first N modes
                index_in_f = sum(2**i for i in range(N))

                src[view_src.map_index(index_in_f + (2**M))] = 1

                Hop(view_src, view_dst)

                ref = np.zeros(n_fermion_sector_size(hs, N), dtype=dst_type)
                # 0 bosons
                ref[view_dst.map_index(index_in_f)] = N
                # 2 bosons
                ref[view_dst.map_index(index_in_f + (2 ** (M + 1)))] = \
                    N * np.sqrt(2)
                assert_allclose(dst, ref)
Beispiel #9
0
    def test_compositions_bosons(self):
        hs = HilbertSpace(a_dag(1) + a_dag(2) + a_dag(3) + a_dag(4), 4)

        O_list = [LOperatorR(a_dag(1), hs),
                  LOperatorR(a_dag(2), hs),
                  LOperatorR(a_dag(3), hs),
                  LOperatorR(a_dag(4), hs)]

        map_size_ref = [1, 4, 10, 20, 35, 56, 84, 120, 165, 220]
        for N in range(10):
            mapper = BasisMapper(O_list, hs, N)
            self.assertEqual(len(mapper), map_size_ref[N])
Beispiel #10
0
    def test_n_fermion_sector_basis_states(self):
        M = 8
        st = np.array([], dtype=float)

        hs = HilbertSpace()

        self.assertEqual(n_fermion_sector_basis_states(hs, 0), [])

        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_sector_basis_states(hs, 1)

        def build_basis_states_ref(hs, N):
            view = NFermionSectorViewR(st, hs, N)
            basis_states = [-1] * n_fermion_sector_size(hs, N)
            for index in range(hs.dim):
                if popcount(index, M) == N:
                    basis_states[view.map_index(index)] = index
            return basis_states

        # Purely fermionic Hilbert spaces
        for i in range(M):
            hs.add(make_space_fermion(i))

        for N in range(M + 1):
            ref = build_basis_states_ref(hs, N)
            self.assertEqual(n_fermion_sector_basis_states(hs, N), ref)

        # Fermions and bosons
        hs.add(make_space_boson(2, M))
        hs.add(make_space_boson(2, M + 1))

        for N in range(M + 1):
            ref = build_basis_states_ref(hs, N)
            self.assertEqual(n_fermion_sector_basis_states(hs, N), ref)

        # Purely bosonic Hilbert space
        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])

        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_sector_basis_states(hs_b, 1)

        ref = list(range(n_fermion_sector_size(hs_b, 0)))
        self.assertEqual(n_fermion_sector_basis_states(hs_b, 0), ref)
Beispiel #11
0
    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)
Beispiel #12
0
    def test_map_index(self):
        M = 8
        st = np.array([], dtype=float)

        hs = HilbertSpace()

        def check_map_index(view, m, n):
            mapped_indices = []
            for index in range(hs.dim):
                if popcount(index, m) == n:
                    mapped_indices.append(view.map_index(index))
            mapped_indices.sort()
            mapped_indices_ref = list(range(n_fermion_sector_size(hs, n)))
            self.assertEqual(mapped_indices, mapped_indices_ref)

        # Purely fermionic Hilbert spaces
        for i in range(M):
            hs.add(make_space_fermion(i))

        for N in range(M + 1):
            check_map_index(NFermionSectorViewR(st, hs, N), M, N)
            check_map_index(NFermionSectorViewC(st, hs, N), M, N)

        # Fermions and bosons
        hs.add(make_space_boson(2, M))
        hs.add(make_space_boson(2, M + 1))

        for N in range(M + 1):
            check_map_index(NFermionSectorViewR(st, hs, N), M, N)
            check_map_index(NFermionSectorViewC(st, hs, N), M, N)

        # Purely bosonic Hilbert space
        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])

        ref_indices = list(range(hs_b.dim))

        view = NFermionSectorViewR(st, hs_b, 0)
        indices = [view.map_index(index) for index in range(hs_b.dim)]
        self.assertEqual(indices, ref_indices)

        view = NFermionSectorViewC(st, hs_b, 0)
        indices = [view.map_index(index) for index in range(hs_b.dim)]
        self.assertEqual(indices, ref_indices)
Beispiel #13
0
    def test_LOperatorR(self):
        expr1 = 3 * c_dag("dn")
        expr2 = 3 * c("up")
        expr = 2 * expr1 - 2 * expr2

        hs = HilbertSpace(expr)
        lop1 = LOperatorR(expr1, hs)
        lop2 = LOperatorR(expr2, hs)
        lop = LOperatorR(expr, hs)

        src = np.array([1, 1, 1, 1])
        dst_real = np.zeros((4, ), dtype=float)
        dst_complex = np.zeros((4, ), dtype=complex)

        assert_equal(lop1 * src, np.array([0, 3, 0, 3]))
        lop1(src, dst_real)
        assert_equal(dst_real, np.array([0, 3, 0, 3]))
        lop1(src, dst_complex)
        assert_equal(dst_complex, np.array([0, 3, 0, 3], dtype=complex))

        assert_equal(lop2 * src, np.array([3, -3, 0, 0]))
        lop2(src, dst_real)
        assert_equal(dst_real, np.array([3, -3, 0, 0]))
        lop2(src, dst_complex)
        assert_equal(dst_complex, np.array([3, -3, 0, 0], dtype=complex))

        assert_equal(lop * src, np.array([-6, 12, 0, 6]))
        lop(src, dst_real)
        assert_equal(dst_real, np.array([-6, 12, 0, 6]))
        lop(src, dst_complex)
        assert_equal(dst_complex, np.array([-6, 12, 0, 6], dtype=complex))

        src_complex = 1j * np.array([1, 1, 1, 1])
        assert_equal(lop * src_complex, np.array([-6j, 12j, 0, 6j]))
        lop(src_complex, dst_complex)
        assert_equal(dst_complex, np.array([-6j, 12j, 0, 6j]))

        with self.assertRaisesRegex(
                RuntimeError, "^State vector must be a 1-dimensional array$"):
            lop * np.zeros((3, 3, 3))
        with self.assertRaisesRegex(
                RuntimeError,
                "^Source state vector must be a 1-dimensional array$"):
            lop(np.zeros((3, 3, 3)), np.zeros((5, )))
        with self.assertRaisesRegex(
                RuntimeError,
                "^Destination state vector must be a 1-dimensional array$"):
            lop(np.zeros((5, )), np.zeros((3, 3, 3)))
Beispiel #14
0
    def test_left_right_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=1 sector
        N1_basis_state_indices = [1, 2, 4, 8]
        # Basis of the N=2 sector
        N2_basis_state_indices = [3, 5, 6, 9, 10, 12]
        # Basis of the N=3 sector
        N3_basis_state_indices = [7, 11, 13, 14]

        for ind1, ind2 in product(indices, indices):
            op1 = LOperatorR(c(*ind1) * c(*ind2), hs)
            ref1 = self.c_mat(hs, *ind1) @ self.c_mat(hs, *ind2)
            ref1 = ref1[N1_basis_state_indices, :][:, N3_basis_state_indices]
            assert_equal(
                make_matrix(op1, N1_basis_state_indices,
                            N3_basis_state_indices), ref1)

            op2 = LOperatorC(1j * c(*ind1) * c(*ind2), hs)
            ref2 = 1j * self.c_mat(hs, *ind1) @ self.c_mat(hs, *ind2)
            ref2 = ref2[N1_basis_state_indices, :][:, N3_basis_state_indices]
            assert_equal(
                make_matrix(op2, N1_basis_state_indices,
                            N3_basis_state_indices), ref2)

        for ind in indices:
            op1 = LOperatorR(c(*ind), hs)
            ref1 = self.c_mat(hs, *ind)
            ref1 = ref1[N2_basis_state_indices, :][:, N3_basis_state_indices]
            assert_equal(
                make_matrix(op1, N2_basis_state_indices,
                            N3_basis_state_indices), ref1)

            op2 = LOperatorC(1j * c(*ind), hs)
            ref2 = 1j * self.c_mat(hs, *ind)
            ref2 = ref2[N2_basis_state_indices, :][:, N3_basis_state_indices]
            assert_equal(
                make_matrix(op2, N2_basis_state_indices,
                            N3_basis_state_indices), ref2)
Beispiel #15
0
    def test_very_big_space(self):
        hs1 = HilbertSpace()
        for i in range(32):
            hs1.add(make_space_spin(3 / 2, "s", i))

        with self.assertRaisesRegex(
                RuntimeError,
                "Hilbert space size is not representable by a 64-bit integer "
                "\\(n_bits = 66\\)"):
            hs1.add(make_space_spin(3 / 2, "s", 32))

        expr = ExpressionR(1.0)
        for i in range(32):
            expr *= S_p("s", i, spin=3 / 2)
        hs2 = HilbertSpace(expr)
        self.assertEqual(hs2.total_n_bits, 64)

        expr *= S_p("s", 32, spin=3 / 2)
        with self.assertRaisesRegex(
                RuntimeError,
                "Hilbert space size is not representable by a 64-bit integer "
                "\\(n_bits = 66\\)"):
            HilbertSpace(expr)
Beispiel #16
0
    def setUpClass(cls):
        # Parameters of the 3 orbital Hubbard-Kanamori atom
        cls.n_orbs = 3
        cls.mu = 0.7
        cls.U = 3.0
        cls.J = 0.3

        indices_up = [("up", o) for o in range(cls.n_orbs)]
        indices_dn = [("dn", o) for o in range(cls.n_orbs)]

        # Hamiltonian
        cls.H = dispersion(-cls.mu * np.ones(cls.n_orbs), indices=indices_up)
        cls.H += dispersion(-cls.mu * np.ones(cls.n_orbs), indices=indices_dn)
        cls.H += kanamori_int(cls.n_orbs,
                              cls.U,
                              cls.J,
                              indices_up=indices_up,
                              indices_dn=indices_dn)

        # Hilbert space
        cls.hs = HilbertSpace(cls.H)
        # Linear operator form of the Hamiltonian
        cls.Hop = LOperatorR(cls.H, cls.hs)
Beispiel #17
0
    def test_map_index(self):
        st = np.array([], dtype=float)

        # Check that values returned by map_index() form a continuous
        # sequence [0; expected_multisector_size)
        def check_map_index(view, hs, selector, expected_multisector_size):
            mapped_indices = []
            for index in range(hs.dim):
                if selector(index):
                    mapped_indices.append(view.map_index(index))
            mapped_indices.sort()
            mapped_indices_ref = list(range(expected_multisector_size))
            self.assertEqual(mapped_indices, mapped_indices_ref)

        #
        # Purely fermionic Hilbert spaces
        #

        hs = HilbertSpace([make_space_fermion(i) for i in range(self.M_total)])

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            for N in range(self.N5_max + 1):
                check_map_index(ViewType(st, hs, [self.sd5(N)]), hs,
                                self.sd5_index_selector(N),
                                2**(self.M_total - 1))

            for N1, N2 in product(range(self.Na_max + 1),
                                  range(self.Nb_max + 1)):
                check_map_index(
                    ViewType(st, hs, [self.sda(N1), self.sdb(N2)]), hs,
                    self.sdab_index_selector(N1, N2),
                    comb(4, N1) * comb(4, N2) * (2**(self.M_total - 8)))

            for N1, N2, N3 in product(range(self.Na_max + 1),
                                      range(self.N5_max + 1),
                                      range(self.Nb_max + 1)):
                check_map_index(
                    ViewType(st, hs,
                             [self.sda(N1),
                              self.sd5(N2),
                              self.sdb(N3)]), hs,
                    self.sda5b_index_selector(N1, N2, N3),
                    comb(4, N1) * comb(4, N3) * (2**(self.M_total - 9)))

        #
        # Fermions and bosons
        #

        hs.add(make_space_boson(2, self.M_total))
        hs.add(make_space_boson(2, self.M_total + 1))

        M = self.M_total + 4

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            for N in range(self.N5_max + 1):
                check_map_index(ViewType(st, hs, [self.sd5(N)]), hs,
                                self.sd5_index_selector(N), 2**(M - 1))

            for N1, N2 in product(range(self.Na_max + 1),
                                  range(self.Nb_max + 1)):
                check_map_index(ViewType(
                    st, hs, [self.sda(N1), self.sdb(N2)]), hs,
                                self.sdab_index_selector(N1, N2),
                                comb(4, N1) * comb(4, N2) * (2**(M - 8)))

            for N1, N2, N3 in product(range(self.Na_max + 1),
                                      range(self.N5_max + 1),
                                      range(self.Nb_max + 1)):
                check_map_index(
                    ViewType(st, hs,
                             [self.sda(N1),
                              self.sd5(N2),
                              self.sdb(N3)]), hs,
                    self.sda5b_index_selector(N1, N2, N3),
                    comb(4, N1) * comb(4, N3) * (2**(M - 9)))

        #
        # Purely bosonic Hilbert space
        #

        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            view = ViewType(st, hs_b, [self.sde(0)])
            for index in range(hs_b.dim):
                self.assertEqual(view.map_index(index), index)
Beispiel #18
0
    def test_n_fermion_sector_size(self):
        hs = HilbertSpace()

        # Empty Hilbert space
        self.assertEqual(n_fermion_sector_size(hs, 0), 0)
        self.assertEqual(n_fermion_sector_size(hs, 1), 0)

        # Purely fermionic Hilbert spaces
        hs.add(make_space_fermion(0))
        self.assertEqual(n_fermion_sector_size(hs, 0), 1)
        self.assertEqual(n_fermion_sector_size(hs, 1), 1)
        hs.add(make_space_fermion(1))
        self.assertEqual(n_fermion_sector_size(hs, 0), 1)
        self.assertEqual(n_fermion_sector_size(hs, 1), 2)
        self.assertEqual(n_fermion_sector_size(hs, 2), 1)
        hs.add(make_space_fermion(2))
        self.assertEqual(n_fermion_sector_size(hs, 0), 1)
        self.assertEqual(n_fermion_sector_size(hs, 1), 3)
        self.assertEqual(n_fermion_sector_size(hs, 2), 3)
        self.assertEqual(n_fermion_sector_size(hs, 3), 1)

        # Fermions and bosons
        hs.add(make_space_boson(4, 3))
        self.assertEqual(n_fermion_sector_size(hs, 0), 16)
        self.assertEqual(n_fermion_sector_size(hs, 1), 48)
        self.assertEqual(n_fermion_sector_size(hs, 2), 48)
        self.assertEqual(n_fermion_sector_size(hs, 3), 16)

        # Purely bosonic Hilbert space
        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])
        self.assertEqual(n_fermion_sector_size(hs_b, 0), 32)
        self.assertEqual(n_fermion_sector_size(hs_b, 1), 0)
Beispiel #19
0
# adjacency matrix of the lattice.
hopping_matrix = -t * adjacency_matrix(lat).todense()
H = tight_binding(hopping_matrix, indices=indices_up) \
    + tight_binding(hopping_matrix, indices=indices_dn)

# Add the chemical potential terms
H += dispersion(-mu * np.ones(len(indices_up)), indices=indices_up)
H += dispersion(-mu * np.ones(len(indices_dn)), indices=indices_dn)

# Add the Hubbard interaction term
H += hubbard_int(U * np.ones(len(indices_up)),
                 indices_up=indices_up,
                 indices_dn=indices_dn)

# Analyze structure of H and construct a suitable Hilbert space.
hs = HilbertSpace(H)
print("Full Hilbert space dimension:", hs.dim)

# Construct a linear operator corresponding to H and acting in the Hilbert
# space 'hs'.
H_op = LOperatorR(H, hs)

#
# Diagonalize the N = 2 sector of the model using 'NFermionSectorViewR'
#

N = 2

sector_size = n_fermion_sector_size(hs, N)
print("Size of the N = 2 sector:", sector_size)
Beispiel #20
0
 def test_attributes(self):
     hs = HilbertSpace([
         self.es_s32_i, self.es_s32_j, self.es_s1_j, self.es_s_i,
         self.es_s_j, self.es_b_x, self.es_f_dn, self.es_f_up
     ])
     self.assertEqual(len(hs), 8)
     self.assertEqual(hs.total_n_bits, 14)
     self.assertEqual(hs.dim, 16384)
     self.assertTrue(hs.has_algebra(FERMION))
     self.assertTrue(hs.has_algebra(BOSON))
     self.assertTrue(hs.has_algebra(SPIN))
     self.assertEqual(hs.algebra_bit_range(FERMION), (0, 1))
     self.assertEqual(hs.algebra_bit_range(BOSON), (2, 5))
     self.assertEqual(hs.algebra_bit_range(SPIN), (6, 13))
     self.assertTrue(self.es_f_dn in hs)
     self.assertEqual(hs.index(self.es_f_dn), 0)
     self.assertEqual(hs.bit_range(self.es_f_dn), (0, 0))
     self.assertEqual(hs.basis_state_index(self.es_f_dn, 0), 0)
     self.assertEqual(hs.basis_state_index(self.es_f_dn, 1), 1)
     self.assertTrue(self.es_f_up in hs)
     self.assertEqual(hs.index(self.es_f_up), 1)
     self.assertEqual(hs.bit_range(self.es_f_up), (1, 1))
     self.assertEqual(hs.basis_state_index(self.es_f_up, 0), 0)
     self.assertEqual(hs.basis_state_index(self.es_f_up, 1), 2)
     self.assertTrue(self.es_b_x in hs)
     self.assertEqual(hs.index(self.es_b_x), 2)
     self.assertEqual(hs.bit_range(self.es_b_x), (2, 5))
     self.assertEqual(hs.basis_state_index(self.es_b_x, 0), 0)
     self.assertEqual(hs.basis_state_index(self.es_b_x, 1), 4)
     self.assertEqual(hs.basis_state_index(self.es_b_x, 5), 20)
     self.assertFalse(self.es_b_y in hs)
     with self.assertRaisesRegex(RuntimeError,
                                 "^Elementary space not found$"):
         hs.bit_range(self.es_b_y)
     self.assertTrue(self.es_s_i in hs)
     self.assertEqual(hs.index(self.es_s_i), 3)
     self.assertEqual(hs.bit_range(self.es_s_i), (6, 6))
     self.assertEqual(hs.basis_state_index(self.es_s_i, 0), 0)
     self.assertEqual(hs.basis_state_index(self.es_s_i, 1), 64)
     self.assertTrue(self.es_s_j in hs)
     self.assertEqual(hs.index(self.es_s_j), 4)
     self.assertEqual(hs.bit_range(self.es_s_j), (7, 7))
     self.assertFalse(self.es_s1_i in hs)
     with self.assertRaisesRegex(RuntimeError,
                                 "^Elementary space not found$"):
         hs.bit_range(self.es_s1_i)
     self.assertTrue(self.es_s1_j in hs)
     self.assertEqual(hs.index(self.es_s1_j), 5)
     self.assertEqual(hs.bit_range(self.es_s1_j), (8, 9))
     self.assertEqual(hs.basis_state_index(self.es_s1_j, 0), 0)
     self.assertEqual(hs.basis_state_index(self.es_s1_j, 1), 256)
     self.assertEqual(hs.basis_state_index(self.es_s1_j, 2), 512)
     self.assertTrue(self.es_s32_i in hs)
     self.assertEqual(hs.index(self.es_s32_i), 6)
     self.assertEqual(hs.bit_range(self.es_s32_i), (10, 11))
     self.assertEqual(hs.basis_state_index(self.es_s32_i, 0), 0)
     self.assertEqual(hs.basis_state_index(self.es_s32_i, 1), 1024)
     self.assertEqual(hs.basis_state_index(self.es_s32_i, 2), 2048)
     self.assertEqual(hs.basis_state_index(self.es_s32_i, 3), 3072)
     self.assertTrue(self.es_s32_j in hs)
     self.assertEqual(hs.index(self.es_s32_j), 7)
     self.assertEqual(hs.bit_range(self.es_s32_j), (12, 13))
     self.assertEqual(hs.basis_state_index(self.es_s32_j, 0), 0)
     self.assertEqual(hs.basis_state_index(self.es_s32_j, 1), 4096)
     self.assertEqual(hs.basis_state_index(self.es_s32_j, 2), 8192)
     self.assertEqual(hs.basis_state_index(self.es_s32_j, 3), 12288)
Beispiel #21
0
    def test_constructors(self):
        hs_empty = HilbertSpace()
        self.assertEqual(len(hs_empty), 0)
        self.assertEqual(hs_empty.total_n_bits, 0)
        self.assertEqual(hs_empty.dim, 1)

        hs1 = HilbertSpace([
            self.es_s32_i, self.es_s32_j, self.es_s1_i, self.es_s1_j,
            self.es_s_i, self.es_s_j, self.es_b_x, self.es_b_y, self.es_f_dn,
            self.es_f_up
        ])
        self.assertEqual(len(hs1), 10)
        self.assertEqual(hs1.total_n_bits, 20)
        self.assertEqual(hs1.dim, 1048576)

        with self.assertRaisesRegex(RuntimeError,
                                    "^Elementary space already exists$"):
            HilbertSpace(
                [self.es_s32_i, self.es_s_i, self.es_s_i, self.es_f_dn])

        self.assertEqual(HilbertSpace(self.fermion_es),
                         HilbertSpace([self.es_f_dn, self.es_f_up]))
        self.assertEqual(HilbertSpace(self.boson_es),
                         HilbertSpace([self.es_b_x, self.es_b_y]))
        self.assertEqual(HilbertSpace(self.spin_es),
                         HilbertSpace([self.es_s_i, self.es_s_j]))
        self.assertEqual(HilbertSpace(self.spin1_es),
                         HilbertSpace([self.es_s1_i, self.es_s1_j]))
        self.assertEqual(HilbertSpace(self.spin32_es),
                         HilbertSpace([self.es_s32_i, self.es_s32_j]))
Beispiel #22
0
omega = np.array([0.8])

# Qubit-oscillator coupling constants as a 2x1 array.
g = np.array([[0.5], [0.6]])

# Create the Tavis-Cummings Hamiltonian.
H = jaynes_cummings(eps, omega, g)

# Construct state space of our problem as a direct product of two
# two-dimensional Hilbert spaces (qubits) and one truncated bosonic Hilbert
# space.
# make_space_boson(4) returns the truncated bosonic space with allowed
# occupation numbers N = 0, 1, ..., (2^4-1).
hs = HilbertSpace([
    make_space_spin(1 / 2, 0),  # Qubit 1: spin-1/2, index 0
    make_space_spin(1 / 2, 1),  # Qubit 2: spin-1/2, index 1
    make_space_boson(4, 0)  # Oscillator, index 0
])

# Construct a linear operator corresponding to 'H' and acting in the Hilbert
# space 'hs'.
H_op = LOperatorR(H, hs)

#
# Prepare a matrix representation of 'H_op'
#

# Method I (manual).
H_mat1 = np.zeros((hs.dim, hs.dim))
for i in range(hs.dim):
    # A column vector psi = {0, 0, ..., 1, ..., 0}
Beispiel #23
0
    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))
Beispiel #24
0
    def test_add(self):
        hs = HilbertSpace([self.es_s32_i])

        def check_hs(es, index, size, total_n_bits, b, e, fermion, boson,
                     spin):
            self.assertEqual(len(hs), size)
            self.assertEqual(hs.total_n_bits, total_n_bits)
            self.assertEqual(hs.dim, 1 << total_n_bits)
            self.assertTrue(es in hs)
            self.assertEqual(hs.index(es), index)
            self.assertEqual(hs.bit_range(es), (b, e))

            if fermion is not None:
                self.assertTrue(hs.has_algebra(FERMION))
                self.assertEqual(hs.algebra_bit_range(FERMION), fermion)
            else:
                self.assertFalse(hs.has_algebra(FERMION))
                with self.assertRaisesRegex(
                        RuntimeError,
                        "^No elementary spaces with algebra ID %i$" % FERMION):
                    hs.algebra_bit_range(FERMION)

            if boson is not None:
                self.assertTrue(hs.has_algebra(BOSON))
                self.assertEqual(hs.algebra_bit_range(BOSON), boson)
            else:
                self.assertFalse(hs.has_algebra(BOSON))
                with self.assertRaisesRegex(
                        RuntimeError,
                        "^No elementary spaces with algebra ID %i$" % BOSON):
                    hs.algebra_bit_range(BOSON)

            if spin is not None:
                self.assertTrue(hs.has_algebra(SPIN))
                self.assertEqual(hs.algebra_bit_range(SPIN), spin)
            else:
                self.assertFalse(hs.has_algebra(SPIN))
                with self.assertRaisesRegex(
                        RuntimeError,
                        "^No elementary spaces with algebra ID %i$" % SPIN):
                    hs.algebra_bit_range(SPIN)

        check_hs(self.es_s32_i, 0, 1, 2, 0, 1, None, None, (0, 1))
        hs.add(self.es_s32_j)
        check_hs(self.es_s32_j, 1, 2, 4, 2, 3, None, None, (0, 3))
        hs.add(self.es_s1_j)
        check_hs(self.es_s1_j, 0, 3, 6, 0, 1, None, None, (0, 5))
        hs.add(self.es_s_i)
        check_hs(self.es_s_i, 0, 4, 7, 0, 0, None, None, (0, 6))
        hs.add(self.es_s_j)
        check_hs(self.es_s_j, 1, 5, 8, 1, 1, None, None, (0, 7))
        hs.add(self.es_b_x)
        check_hs(self.es_b_x, 0, 6, 12, 0, 3, None, (0, 3), (4, 11))
        hs.add(self.es_f_dn)
        check_hs(self.es_f_dn, 0, 7, 13, 0, 0, (0, 0), (1, 4), (5, 12))
        hs.add(self.es_f_up)
        check_hs(self.es_f_up, 1, 8, 14, 1, 1, (0, 1), (2, 5), (6, 13))

        with self.assertRaisesRegex(RuntimeError,
                                    "^Elementary space already exists$"):
            hs.add(self.es_s_j)

        check_hs(self.es_f_dn, 0, 8, 14, 0, 0, (0, 1), (2, 5), (6, 13))
        check_hs(self.es_f_up, 1, 8, 14, 1, 1, (0, 1), (2, 5), (6, 13))
        check_hs(self.es_b_x, 2, 8, 14, 2, 5, (0, 1), (2, 5), (6, 13))
        check_hs(self.es_s_i, 3, 8, 14, 6, 6, (0, 1), (2, 5), (6, 13))
        check_hs(self.es_s_j, 4, 8, 14, 7, 7, (0, 1), (2, 5), (6, 13))
        check_hs(self.es_s1_j, 5, 8, 14, 8, 9, (0, 1), (2, 5), (6, 13))
        check_hs(self.es_s32_i, 6, 8, 14, 10, 11, (0, 1), (2, 5), (6, 13))
        check_hs(self.es_s32_j, 7, 8, 14, 12, 13, (0, 1), (2, 5), (6, 13))
        self.assertEqual(hs.algebra_bit_range(FERMION), (0, 1))
        self.assertEqual(hs.algebra_bit_range(BOSON), (2, 5))
        self.assertEqual(hs.algebra_bit_range(SPIN), (6, 13))
Beispiel #25
0
    def test_n_fermion_multisector_size(self):
        hs = HilbertSpace()

        #
        # Empty Hilbert space
        #

        self.assertEqual(n_fermion_multisector_size(hs, []), 0)
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_indices_error_msg(1)):
            n_fermion_multisector_size(hs, [self.sda(1)])

        #
        # Empty sectors
        #

        self.assertEqual(n_fermion_multisector_size(hs, [self.sde(0)]), 0)
        self.assertEqual(n_fermion_multisector_size(hs, [self.sde(1)]), 0)
        self.assertEqual(
            n_fermion_multisector_size(hs,
                                       [self.sde(0), self.sde(0)]), 0)
        self.assertEqual(
            n_fermion_multisector_size(hs,
                                       [self.sde(1), self.sde(1)]), 0)

        #
        # Purely fermionic Hilbert spaces
        #

        for i in range(self.M_total):
            hs.add(make_space_fermion(i))

        # Empty sectors
        self.assertEqual(n_fermion_multisector_size(hs, [self.sde(0)]), 2048)
        self.assertEqual(n_fermion_multisector_size(hs, [self.sde(1)]), 0)
        self.assertEqual(
            n_fermion_multisector_size(hs,
                                       [self.sde(0), self.sde(0)]), 2048)
        self.assertEqual(
            n_fermion_multisector_size(hs,
                                       [self.sde(1), self.sde(1)]), 0)

        with self.assertRaisesRegex(RuntimeError,
                                    "^Some of the sectors overlap$"):
            n_fermion_multisector_size(hs, [self.sda(2), ([(6, )], 1)])

        self.assertEqual(n_fermion_multisector_size(hs, []), 2048)

        # One sector
        for N in range(self.Na_max + 1):
            self.assertEqual(n_fermion_multisector_size(hs, [self.sda(N)]),
                             self.ab_size_ref[N] * 128)
        for N in range(self.N5_max + 1):
            self.assertEqual(n_fermion_multisector_size(hs, [self.sd5(N)]),
                             1024)
        for N in range(self.Nb_max + 1):
            self.assertEqual(n_fermion_multisector_size(hs, [self.sdb(N)]),
                             self.ab_size_ref[N] * 128)

        # Two sectors
        for N1, N2 in product(range(self.Na_max + 1), range(self.Nb_max + 1)):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sda(N1), self.sdb(N2)]),
                self.ab_size_ref[N1] * self.ab_size_ref[N2] * 8)

        # Three sectors
        for N1, N2, N3 in product(range(self.Na_max + 1),
                                  range(self.N5_max + 1),
                                  range(self.Nb_max + 1)):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs,
                    [self.sda(N1), self.sd5(N2),
                     self.sdb(N3)]),
                self.ab_size_ref[N1] * self.ab_size_ref[N3] * 4)

        # Mixture with the empty sector
        for N in range(self.Na_max + 1):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sda(N), self.sde(0)]), self.ab_size_ref[N] * 128)
        for N in range(self.N5_max + 1):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sd5(N), self.sde(0)]), 1024)
        for N in range(self.Nb_max + 1):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sdb(N), self.sde(0)]), self.ab_size_ref[N] * 128)

        #
        # Fermions and bosons
        #

        hs.add(make_space_boson(2, 0))

        self.assertEqual(n_fermion_multisector_size(hs, []), 8192)

        # One sector
        for N in range(self.Na_max + 1):
            self.assertEqual(n_fermion_multisector_size(hs, [self.sda(N)]),
                             self.ab_size_ref[N] * 512)
        for N in range(self.N5_max + 1):
            self.assertEqual(n_fermion_multisector_size(hs, [self.sd5(N)]),
                             4096)
        for N in range(self.Nb_max + 1):
            self.assertEqual(n_fermion_multisector_size(hs, [self.sdb(N)]),
                             self.ab_size_ref[N] * 512)

        # Two sectors
        for N1, N2 in product(range(self.Na_max + 1), range(self.Nb_max + 1)):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sda(N1), self.sdb(N2)]),
                self.ab_size_ref[N1] * self.ab_size_ref[N2] * 32)

        # Three sectors
        for N1, N2, N3 in product(range(self.Na_max + 1),
                                  range(self.N5_max + 1),
                                  range(self.Nb_max + 1)):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs,
                    [self.sda(N1), self.sd5(N2),
                     self.sdb(N3)]),
                self.ab_size_ref[N1] * self.ab_size_ref[N3] * 16)

        # Mixture with the empty sector
        for N in range(self.Na_max + 1):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sda(N), self.sde(0)]), self.ab_size_ref[N] * 512)
        for N in range(self.N5_max + 1):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sd5(N), self.sde(0)]), 4096)
        for N in range(self.Nb_max + 1):
            self.assertEqual(
                n_fermion_multisector_size(
                    hs, [self.sdb(N), self.sde(0)]), self.ab_size_ref[N] * 512)

        #
        # Purely bosonic Hilbert space
        #

        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])
        self.assertEqual(n_fermion_multisector_size(hs_b, []), 32)
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_indices_error_msg(1)):
            n_fermion_multisector_size(hs_b, [self.sda(1)])
Beispiel #26
0
    def test_loperator(self):
        hs = HilbertSpace([make_space_boson(2, 0)])
        for i in range(self.M_total):
            hs.add(make_space_fermion(i))

        sector_a_modes = [1, 2, 6, 7]
        sector_b_modes = [3, 4, 8, 9]

        Ha = (n(1) + n(2) + n(6) + n(7)) * (a_dag(0) + a(0))
        Hb = (n(3) + n(4) + n(8) + n(9)) * (a_dag(0) + a(0))

        for src_type, dst_type, lop_type in [(float, float, LOperatorR),
                                             (float, complex, LOperatorR),
                                             (complex, complex, LOperatorR),
                                             (float, complex, LOperatorC),
                                             (complex, complex, LOperatorC)]:
            src_view_type = NFermionMultiSectorViewR if (src_type == float) \
                else NFermionMultiSectorViewC
            dst_view_type = NFermionMultiSectorViewR if (dst_type == float) \
                else NFermionMultiSectorViewC

            lop_is_real = lop_type == LOperatorR

            Hopa = lop_type(Ha if lop_is_real else make_complex(Ha), hs)
            Hopb = lop_type(Hb if lop_is_real else make_complex(Hb), hs)

            for N1, N2 in product(range(self.Na_max + 1),
                                  range(self.Nb_max + 1)):
                sectors = [self.sda(N1), self.sdb(N2)]

                src = np.zeros(n_fermion_multisector_size(hs, sectors),
                               dtype=src_type)
                view_src = src_view_type(src, hs, sectors)
                dst = np.zeros(n_fermion_multisector_size(hs, sectors),
                               dtype=dst_type)
                view_dst = dst_view_type(dst, hs, sectors)

                # Input:
                # First N1 modes of sector A are occupied
                # First N2 modes of sector B are occupied
                # 1 boson

                index_in_f = sum(2**sector_a_modes[n1] for n1 in range(N1))
                index_in_f += sum(2**sector_b_modes[n2] for n2 in range(N2))

                src[view_src.map_index(index_in_f + (2**self.M_total))] = 1

                Hopa(view_src, view_dst)
                ref = np.zeros(n_fermion_multisector_size(hs, sectors),
                               dtype=dst_type)
                # 0 bosons
                ref[view_dst.map_index(index_in_f)] = N1
                # 2 bosons
                ref[view_dst.map_index(index_in_f + (2 ** (self.M_total + 1)))]\
                    = N1 * np.sqrt(2)
                assert_allclose(dst, ref)

                Hopb(view_src, view_dst)
                ref = np.zeros(n_fermion_multisector_size(hs, sectors),
                               dtype=dst_type)
                # 0 bosons
                ref[view_dst.map_index(index_in_f)] = N2
                # 2 bosons
                ref[view_dst.map_index(index_in_f + (2 ** (self.M_total + 1)))]\
                    = N2 * np.sqrt(2)
                assert_allclose(dst, ref)
Beispiel #27
0
    def test_n_fermion_sector_basis_states(self):
        st = np.array([], dtype=float)

        # Build a reference list of basis states for
        # n_fermion_multisector_basis_states() by repeatedly calling map_index()
        def build_basis_states_ref(hs, sectors, selector):
            view = NFermionMultiSectorViewR(st, hs, sectors)
            basis_states = [-1] * n_fermion_multisector_size(hs, sectors)
            for index in range(hs.dim):
                if selector(index):
                    basis_states[view.map_index(index)] = index
            return basis_states

        hs = HilbertSpace()

        #
        # Empty Hilbert space
        #

        self.assertEqual(n_fermion_multisector_basis_states(hs, []), [])
        self.assertEqual(n_fermion_multisector_basis_states(hs, [self.sde(0)]),
                         [])

        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(hs, [self.sde(1)])

        self.assertEqual(
            n_fermion_multisector_basis_states(
                hs, [self.sde(0), self.sde(0)]), [])

        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(hs, [self.sde(0), self.sde(1)])
        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(hs, [self.sde(1), self.sde(0)])
        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(hs, [self.sde(1), self.sde(1)])
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_indices_error_msg(0)):
            n_fermion_multisector_basis_states(hs, [self.sd0(0)])
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_indices_error_msg(0)):
            n_fermion_multisector_basis_states(hs, [self.sd0(1)])

        #
        # Purely fermionic Hilbert spaces
        #

        for i in range(self.M_total):
            hs.add(make_space_fermion(i))

        for N in range(self.N5_max + 1):
            sectors = [self.sd5(N)]
            ref = build_basis_states_ref(hs, sectors,
                                         self.sd5_index_selector(N))
            self.assertEqual(n_fermion_multisector_basis_states(hs, sectors),
                             ref)

        for N1, N2 in product(range(self.Na_max + 1), range(self.Nb_max + 1)):
            sectors = [self.sda(N1), self.sdb(N2)]
            ref = build_basis_states_ref(hs, sectors,
                                         self.sdab_index_selector(N1, N2))
            self.assertEqual(n_fermion_multisector_basis_states(hs, sectors),
                             ref)

        for N1, N2, N3 in product(range(self.Na_max + 1),
                                  range(self.N5_max + 1),
                                  range(self.Nb_max + 1)):
            sectors = [self.sda(N1), self.sd5(N2), self.sdb(N3)]
            ref = build_basis_states_ref(hs, sectors,
                                         self.sda5b_index_selector(N1, N2, N3))
            self.assertEqual(n_fermion_multisector_basis_states(hs, sectors),
                             ref)

        #
        # Fermions and bosons
        #

        hs.add(make_space_boson(2, self.M_total))
        hs.add(make_space_boson(2, self.M_total + 1))

        for N in range(self.N5_max + 1):
            sectors = [self.sd5(N)]
            ref = build_basis_states_ref(hs, sectors,
                                         self.sd5_index_selector(N))
            self.assertEqual(n_fermion_multisector_basis_states(hs, sectors),
                             ref)

        for N1, N2 in product(range(self.Na_max + 1), range(self.Nb_max + 1)):
            sectors = [self.sda(N1), self.sdb(N2)]
            ref = build_basis_states_ref(hs, sectors,
                                         self.sdab_index_selector(N1, N2))
            self.assertEqual(n_fermion_multisector_basis_states(hs, sectors),
                             ref)

        for N1, N2, N3 in product(range(self.Na_max + 1),
                                  range(self.N5_max + 1),
                                  range(self.Nb_max + 1)):
            sectors = [self.sda(N1), self.sd5(N2), self.sdb(N3)]
            ref = build_basis_states_ref(hs, sectors,
                                         self.sda5b_index_selector(N1, N2, N3))
            self.assertEqual(n_fermion_multisector_basis_states(hs, sectors),
                             ref)

        #
        # Purely bosonic Hilbert space
        #

        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])

        ref = list(range(n_fermion_multisector_size(hs_b, [])))

        self.assertEqual(n_fermion_multisector_basis_states(hs_b, []), ref)
        self.assertEqual(
            n_fermion_multisector_basis_states(hs_b, [self.sde(0)]), ref)

        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(hs_b, [self.sde(1)])

        self.assertEqual(
            n_fermion_multisector_basis_states(
                hs_b, [self.sde(0), self.sde(0)]), ref)

        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(
                hs_b, [self.sde(0), self.sde(1)])
        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(
                hs_b, [self.sde(1), self.sde(0)])
        with self.assertRaisesRegex(RuntimeError, self.wrong_n_error_msg(0,
                                                                         1)):
            n_fermion_multisector_basis_states(
                hs_b, [self.sde(1), self.sde(1)])
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_indices_error_msg(0)):
            n_fermion_multisector_basis_states(hs_b, [self.sd0(0)])
        with self.assertRaisesRegex(RuntimeError,
                                    self.wrong_indices_error_msg(0)):
            n_fermion_multisector_basis_states(hs_b, [self.sd0(1)])
Beispiel #28
0
    def test_init_exceptions(self):
        st = np.array([], dtype=float)
        hs = HilbertSpace()

        #
        # Empty Hilbert space
        #

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_indices_error_msg(1)):
                ViewType(st, hs, [self.sda(0)])
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_indices_error_msg(1)):
                ViewType(st, hs, [self.sda(1)])

        #
        # One fermion
        #

        hs.add(make_space_fermion(0))

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_n_error_msg(1, 2)):
                ViewType(st, hs, [self.sd0(2)])
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_indices_error_msg(1)):
                ViewType(st, hs, [self.sda(0)])
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_indices_error_msg(1)):
                ViewType(st, hs, [self.sda(1)])

        #
        # Multiple fermions
        #

        for i in range(1, self.M_total):
            hs.add(make_space_fermion(i))

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            for N in range(self.Na_max):
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sda(N), self.sda(N)])
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sde(0), self.sda(N), self.sda(N)])
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sda(N), self.sde(0), self.sda(N)])
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sda(N), self.sda(N), self.sde(0)])
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_n_error_msg(1, 2)):
                ViewType(st, hs, [self.sd0(2)])

        #
        # Fermions and bosons
        #

        hs.add(make_space_boson(1, 5))
        hs.add(make_space_boson(2, 6))

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            for N in range(self.Na_max):
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sda(N), self.sda(N)])
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sde(0), self.sda(N), self.sda(N)])
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sda(N), self.sde(0), self.sda(N)])
                with self.assertRaisesRegex(RuntimeError,
                                            "^Some of the sectors overlap$"):
                    ViewType(st, hs, [self.sda(N), self.sda(N), self.sde(0)])
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_n_error_msg(1, 2)):
                ViewType(st, hs, [self.sd0(2)])

        #
        # Purely bosonic Hilbert space
        #

        hs_b = HilbertSpace([make_space_boson(2, 0), make_space_boson(3, 1)])

        for ViewType in (NFermionMultiSectorViewR, NFermionMultiSectorViewC):
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_indices_error_msg(0)):
                ViewType(st, hs_b, [self.sd0(0)])
            with self.assertRaisesRegex(RuntimeError,
                                        self.wrong_indices_error_msg(0)):
                ViewType(st, hs_b, [self.sd0(1)])