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) ]
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)
def test_basis_state_indices(self): indices = [("dn", 0), ("dn", 1), ("up", 0), ("up", 1)] hs = HilbertSpace([make_space_fermion(*ind) for ind in indices]) # Basis of the N=2 sector basis_state_indices = [3, 5, 6, 9, 10, 12] H1 = 1.0 * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H1 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H1op = LOperatorR(H1, hs) ref1 = 1.0 * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref1 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) ref1 = ref1[basis_state_indices, :][:, basis_state_indices] assert_equal(make_matrix(H1op, basis_state_indices), ref1) H2 = 1.0j * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H2 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H2op = LOperatorC(H2, hs) ref2 = 1.0j * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref2 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) ref2 = ref2[basis_state_indices, :][:, basis_state_indices] assert_equal(make_matrix(H2op, basis_state_indices), ref2)
def test_HilbertSpace(self): indices = [("dn", 0), ("dn", 1), ("up", 0), ("up", 1)] hs = HilbertSpace([make_space_fermion(*ind) for ind in indices]) for ind in indices: c_op = LOperatorR(c(*ind), hs) assert_equal(make_matrix(c_op, hs), self.c_mat(hs, *ind)) c_dag_op = LOperatorR(c_dag(*ind), hs) assert_equal(make_matrix(c_dag_op, hs), self.c_dag_mat(hs, *ind)) H1 = 1.0 * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H1 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H1op = LOperatorR(H1, hs) ref1 = 1.0 * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref1 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) assert_equal(make_matrix(H1op, hs), ref1) H2 = 1.0j * (c_dag("up", 0) * c("up", 1) + c_dag("up", 1) * c("up", 0)) H2 += 2.0 * (c_dag("dn", 0) * c("dn", 1) + c_dag("dn", 1) * c("dn", 0)) H2op = LOperatorC(H2, hs) ref2 = 1.0j * (self.c_dag_mat(hs, "up", 0) @ self.c_mat(hs, "up", 1) + self.c_dag_mat(hs, "up", 1) @ self.c_mat(hs, "up", 0)) ref2 += 2.0 * (self.c_dag_mat(hs, "dn", 0) @ self.c_mat(hs, "dn", 1) + self.c_dag_mat(hs, "dn", 1) @ self.c_mat(hs, "dn", 0)) assert_equal(make_matrix(H2op, hs), ref2)
def test_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)
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
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]
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)
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)
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)
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)
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)])
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)
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)])
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)
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)])