Пример #1
0
 def setUpClass(cls):
     # Fermionic elementary spaces
     cls.fermion_es = [
         make_space_fermion("dn", 0),
         make_space_fermion("up", 0)
     ]
     # Bosonic elementary spaces (4 bits)
     cls.boson_es = [
         make_space_boson(4, "x", 0),
         make_space_boson(4, "y", 0)
     ]
     # Spin-1/2 algebra elementary spaces
     cls.spin_es = [
         make_space_spin(0.5, "i", 0),
         make_space_spin(0.5, "j", 0)
     ]
     # Spin-1 algebra elementary spaces
     cls.spin1_es = [
         make_space_spin(1.0, "i", 0),
         make_space_spin(1.0, "j", 0)
     ]
     # Spin-3/2 algebra elementary spaces
     cls.spin32_es = [
         make_space_spin(3 / 2, "i", 0),
         make_space_spin(3 / 2, "j", 0)
     ]
Пример #2
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)
Пример #3
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)
Пример #4
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)
Пример #5
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)
Пример #6
0
 def c_mat(self, hs, *args):
     n_fermions = len(hs)
     op_index = hs.index(make_space_fermion(*args))
     states = list(product((0, 1), repeat=n_fermions))
     states = [st[::-1] for st in states]
     mat = np.zeros((hs.dim, hs.dim))
     for m, n in product(range(hs.dim), range(hs.dim)):
         if states[m] == tuple(
             (states[n][i] - 1 if i == op_index else states[n][i])
                 for i in range(n_fermions)):
             mat[m, n] = (-1)**sum(states[n][:op_index])
     return mat
Пример #7
0
 def setUpClass(cls):
     # Fermionic elementary spaces
     cls.es_f_dn = make_space_fermion("dn", 0)
     cls.es_f_up = make_space_fermion("up", 0)
     cls.fermion_es = [cls.es_f_dn, cls.es_f_up]
     # Bosonic elementary spaces (4 bits)
     cls.es_b_x = make_space_boson(4, "x", 0)
     cls.es_b_y = make_space_boson(4, "y", 0)
     cls.boson_es = [cls.es_b_x, cls.es_b_y]
     # Spin-1/2 elementary spaces
     cls.es_s_i = make_space_spin(0.5, "i", 0)
     cls.es_s_j = make_space_spin(0.5, "j", 0)
     cls.spin_es = [cls.es_s_i, cls.es_s_j]
     # Spin-1 elementary spaces
     cls.es_s1_i = make_space_spin(1.0, "i", 0)
     cls.es_s1_j = make_space_spin(1.0, "j", 0)
     cls.spin1_es = [cls.es_s1_i, cls.es_s1_j]
     # Spin-3/2 elementary spaces
     cls.es_s32_i = make_space_spin(3 / 2, "i", 0)
     cls.es_s32_j = make_space_spin(3 / 2, "j", 0)
     cls.spin32_es = [cls.es_s32_i, cls.es_s32_j]
Пример #8
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)
Пример #9
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)
Пример #10
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)
Пример #11
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)
Пример #12
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)])
Пример #13
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)
Пример #14
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)])
Пример #15
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)
Пример #16
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)])