示例#1
0
    def test_find_connections(self):
        expr = [ExpressionR(),
                c_dag("up", 0) * c("dn", 1),
                c_dag("up", 0) * c("dn", 1) + c_dag("dn", 0) * c("dn", 1),
                c_dag("dn", 1) * c_dag("up", 1),
                n("up", 2)
                ]

        sp, melem = make_space_partition(self.Hop, self.hs, False)
        op = LOperatorR(sum(expr[1:]), self.hs)
        conns = sp.find_connections(op, self.hs)

        conns_ref = set()
        in_state = np.zeros((sp.dim,), dtype=float)
        for i in range(sp.dim):
            in_state[i] = 1.0
            out_state = op * in_state
            for f, a in enumerate(out_state):
                if abs(a) > 1e-10:
                    conns_ref.add((sp[i], sp[f]))
            in_state[i] = 0.0

        self.assertEqual(conns, conns_ref)

        for expr1, expr2 in product(expr, expr):
            conns1 = sp.find_connections(LOperatorR(expr1, self.hs), self.hs)
            conns2 = sp.find_connections(LOperatorR(expr2, self.hs), self.hs)
            conns = sp.find_connections(LOperatorR(expr1 + expr2, self.hs),
                                        self.hs)
            self.assertEqual(conns, conns1.union(conns2))
示例#2
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)
示例#3
0
    def test_loperator(self):
        out = np.zeros((6,), dtype=float)
        dst = self.mapper(out)

        # Spin flips
        Hop = LOperatorR(self.Hex, self.hs)

        in1 = np.array([1, 1, 1, 1, 1, 1], dtype=float)
        src = self.mapper(in1)
        Hop(src, dst)
        assert_equal(out, np.array([0, 0, 2, 2, 0, 0], dtype=float))

        in2 = np.array([1, 1, 1, -1, 1, 1], dtype=float)
        src = self.mapper(in2)
        Hop(src, dst)
        assert_equal(out, np.array([0, 0, -2, 2, 0, 0], dtype=float))

        # Pair hops
        Hop = LOperatorR(self.Hp, self.hs)

        src = self.mapper(in1)
        Hop(src, dst)
        assert_equal(out, np.array([0, 2, 0, 0, 2, 0], dtype=float))

        in2 = np.array([1, 1, 1, 1, -1, 1], dtype=float)
        src = self.mapper(in2)
        Hop(src, dst)
        assert_equal(out, np.array([0, -2, 0, 0, 2, 0], dtype=float))
示例#4
0
    def test_compositions(self):
        mapper = BasisMapper([], self.hs, 0)
        self.assertEqual(len(mapper), 1)
        self.assertEqual(mapper.map[0], 0)

        O_list = [LOperatorR(c_dag("dn", 1), self.hs),
                  LOperatorR(c_dag("dn", 2), self.hs),
                  LOperatorR(c_dag("up", 1), self.hs),
                  LOperatorR(c_dag("up", 2), self.hs)]

        mapper_N0 = BasisMapper(O_list, self.hs, 0)
        self.assertEqual(len(mapper_N0), 1)
        self.assertEqual(mapper_N0.map[0], 0)

        mapper_N2 = BasisMapper(O_list, self.hs, 2)
        self.assert_equal_dicts_up_to_value_permutation(mapper_N2.map,
                                                        self.mapping)

        O_list_complex = [LOperatorC(1j * c_dag("dn", 1), self.hs),
                          LOperatorC(1j * c_dag("dn", 2), self.hs),
                          LOperatorC(1j * c_dag("up", 1), self.hs),
                          LOperatorC(1j * c_dag("up", 2), self.hs)]
        mapper_N2 = BasisMapper(O_list_complex, self.hs, 2)
        self.assert_equal_dicts_up_to_value_permutation(mapper_N2.map,
                                                        self.mapping)
示例#5
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])
示例#6
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)))
示例#7
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)
示例#8
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)
示例#9
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)
示例#10
0
    def test_merge_subspaces(self):
        sp, melem = make_space_partition(self.Hop, self.hs, False)

        Cd, C, all_ops = [], [], []
        for spin in ("dn", "up"):
            for o in range(self.n_orbs):
                Cd.append(LOperatorR(c_dag(spin, o), self.hs))
                C.append(LOperatorR(c(spin, o), self.hs))

                all_ops.append(Cd[-1])
                all_ops.append(C[-1])

                sp.merge_subspaces(Cd[-1], C[-1], self.hs)

        # Calculated classification of states
        v_cl = [set() for _ in range(sp.n_subspaces)]
        foreach(sp, lambda i, subspace: v_cl[subspace].add(i))
        cl = set(map(frozenset, v_cl))

        in_state = np.zeros((sp.dim,), dtype=float)

        for op in all_ops:
            for i_sp in cl:
                f_sp = set()
                for i in i_sp:
                    in_state[i] = 1.0
                    out_state = op * in_state
                    for f, a in enumerate(out_state):
                        if abs(a) > 1e-10:
                            f_sp.add(f)
                    in_state[i] = 0.0

                # op maps i_sp onto zero
                if len(f_sp) == 0:
                    continue

                # Check if op maps i_sp to only one subspace
                self.assertEqual(
                    sum(int(f_sp.issubset(f_sp_ref)) for f_sp_ref in cl),
                    1
                )
示例#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_O_vac(self):
        P = c_dag("dn", 1) * c_dag("dn", 2) + \
            c_dag("dn", 1) * c_dag("up", 1) + \
            c_dag("dn", 2) * c_dag("up", 1) + \
            c_dag("dn", 1) * c_dag("up", 2) + \
            c_dag("dn", 2) * c_dag("up", 2) + \
            c_dag("up", 1) * c_dag("up", 2)

        mapper = BasisMapper(LOperatorR(P, self.hs), self.hs)
        self.assertEqual(len(mapper), 6)
        self.assert_equal_dicts_up_to_value_permutation(mapper.map,
                                                        self.mapping)

        mapper = BasisMapper(LOperatorC(1j * P, self.hs), self.hs)
        self.assertEqual(len(mapper), 6)
        self.assert_equal_dicts_up_to_value_permutation(mapper.map,
                                                        self.mapping)
示例#13
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)
示例#14
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)
示例#15
0
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}
    psi = np.zeros(hs.dim)
    psi[i] = 1.0
    # Act with H_op on psi and store the result the i-th column of H_mat
    H_mat1[:, i] = H_op * psi

# Method II (automatic and faster).