def test_fourfold_rotation_symm_3x3(self):
        """
        Test rotation symmetry by diagonalizing random spin system with and without using it
        :return:
        """
        cluster = geom.Geometry.createSquareGeometry(3,
                                                     3,
                                                     0,
                                                     0,
                                                     bc1_open=False,
                                                     bc2_open=False)
        jx = np.random.rand()
        jy = np.random.rand()
        jz = np.random.rand()
        hx = np.random.rand()
        hy = np.random.rand()
        hz = np.random.rand()

        # diagonalize full hamiltonian
        spin_model = tvi.spinSystem(cluster,
                                    jx,
                                    jy,
                                    jz,
                                    hx,
                                    hy,
                                    hz,
                                    use_ryd_detunes=0)
        hamiltonian_full = spin_model.createH()
        eig_vals_full, eig_vects_full = spin_model.diagH(hamiltonian_full)

        # use rotationl symmetry
        cx, cy = spin_model.geometry.get_center_of_mass()
        rot_fn = symm.getRotFn(4, cx=cx, cy=cy)
        rot_cycles, max_cycle_len_rot = symm.findSiteCycles(
            rot_fn, spin_model.geometry)
        rot_op = spin_model.get_xform_op(rot_cycles)
        symm_projs, _ = symm.getZnProjectors(rot_op, 4)

        eig_vals_sectors = []
        for ii, proj in enumerate(symm_projs):
            h_sector = spin_model.createH(projector=proj)
            eig_vals_sector, eig_vects_sector = spin_model.diagH(h_sector)
            eig_vals_sectors.append(eig_vals_sector)

        # why only accurate to 10 decimal places?
        eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors))
        max_diff = np.abs(eig_vals_full - eigs_all_sectors).max()

        self.assertAlmostEqual(max_diff, 0, 10)
Пример #2
0
    def test_c4_symmetry_3by3(self):
        """
        Test fourfold rotational symmetry (generated by 90 degree rotation) on a 3x3 Hubbard cluster with open
         boundary conditions.
        :return:
        """
        U = 20 * (np.random.rand() - 0.5)
        t = np.random.rand()

        gm = geom.Geometry.createSquareGeometry(3,
                                                3,
                                                0,
                                                0,
                                                bc1_open=False,
                                                bc2_open=False)
        model = ed_fermions.fermions(gm, U, t, ns=np.array([1, 1]))

        # no symmetry
        hamiltonian_full = model.createH(projector=model.n_projector)
        eig_vals_full, eig_vects_full = model.diagH(hamiltonian_full)

        # use rotationl symmetry
        cx, cy = model.geometry.get_center_of_mass()
        rot_fn = symm.getRotFn(4, cx=cx, cy=cy)
        rot_cycles, max_cycle_len_rot = symm.findSiteCycles(
            rot_fn, model.geometry)
        rot_op = model.n_projector.dot(
            model.get_xform_op(rot_cycles).dot(
                model.n_projector.conj().transpose()))
        symm_projs, _ = symm.getZnProjectors(rot_op, 4)

        eig_vals_sectors = []
        for ii, proj in enumerate(symm_projs):
            h_sector = model.createH(projector=proj.dot(model.n_projector))
            eig_vals_sector, eig_vects_sector = model.diagH(h_sector)
            eig_vals_sectors.append(eig_vals_sector)

        # why only accurate to 10 decimal places?
        eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors))
        max_diff = np.abs(eig_vals_full - eigs_all_sectors).max()

        self.assertAlmostEqual(max_diff, 0, 10)
Пример #3
0
n_list = np.array([])
k_list = np.array([])
projector_list = []
sf = ed_fermions.fermions(gm, 0, t, us_same_species=0, potentials=0, nspecies=1)

# number subspace projectors
n_species_op = sf.get_sum_op(sf.n_op, 0, format="boson")
n_projs, ns = sf.get_subspace_projs(n_species_op, print_results=False)

# translation op
xtransl_op_full = sf.get_xform_op(xtransl_cycles)

# get all projectors
for n, n_proj in zip(ns, n_projs):
    xtransl_op = n_proj * xtransl_op_full * n_proj.conj().transpose()
    symm_projs, kxs = symm.getZnProjectors(xtransl_op, max_cycle_len_translx)

    for kx, symm_proj in zip(kxs, symm_projs):
        curr_proj = symm_proj * n_proj
        if curr_proj.size > 0:
            projector_list.append(curr_proj)
            k_list = np.concatenate((k_list, np.array([kx])))
            n_list = np.concatenate((n_list, np.array([n])))

max_proj_size = np.max([p.shape[0] for p in projector_list])
mean_proj_size = np.mean([p.shape[0] for p in projector_list])

print("Subspace projectors: max size=%d, mean size=%.1f, number=%d" %
      (max_proj_size, mean_proj_size, len(projector_list)))

# loop over interactions_4 and solve for each symmetry sector
Пример #4
0
inv_fn = symm.getInversionFn(cx, cy)
inv_cycles, _ = symm.findSiteCycles(inv_fn, ss.geometry)
inv_op = ss.get_xform_op(inv_cycles)

# get projectors on mz subspace
mz_projs, mzs = ss.get_subspace_projs(sz_op.tocsr())

# sequentially get projectors on mz the x-translation (then spin flip for mz=0 sector only)
projs = []
mzs_all = []
kxs_all = []
spin_parity_all = []
space_parity_all = []
for p, mz in zip(mz_projs, mzs):
    tx_op_sub = p * tx_op * p.conj().transpose()
    tx_projs, kxs = symm.getZnProjectors(tx_op_sub, ss.geometry.nsites)

    if mz == 0:
        for tp, kx in zip(tx_projs, kxs):
            sz_flip_op_sub = tp * p * sz_flip_op * p.conj().transpose() * tp.conj().transpose()
            sz_projs, spin_parities = symm.getZnProjectors(sz_flip_op_sub, 2)
            spin_parities = np.round(np.exp(1j * spin_parities).real)

            for pp, parity in zip(sz_projs, spin_parities):
                if (pp * tp * p).shape[0] != 0:

                    if kx == 0 or kx == np.pi:
                        inv_op_sub = pp * tp * p * inv_op * \
                                     p.conj().transpose() * tp.conj().transpose() * pp.conj().transpose()
                        inv_projs, space_parities = symm.getZnProjectors(inv_op_sub, 2)
                        space_parities = np.round(np.exp(1j * space_parities).real)
# y-translations
if not bc2_open:
    ytransl_fn = symm.getTranslFn(np.array([[0], [1]]))
    ytransl_cycles, max_cycle_len_transly = symm.findSiteCycles(ytransl_fn, gm)
    ytransl_op = h.n_projector * h.get_xform_op(
        ytransl_cycles) * h.n_projector.conj().transpose()

# get projectors
if not bc1_open and not bc2_open:
    projs, kxs, kys = symm.get2DTranslationProjectors(xtransl_op,
                                                      max_cycle_len_translx,
                                                      ytransl_op,
                                                      max_cycle_len_transly,
                                                      print_all)
elif not bc2_open:
    projs, kys = symm.getZnProjectors(ytransl_op, max_cycle_len_transly,
                                      print_all)
    kxs = np.zeros(kys.shape)
elif not bc1_open:
    projs, kxs = symm.getZnProjectors(xtransl_op, max_cycle_len_translx,
                                      print_all)
    kys = np.zeros(kxs.shape)
else:
    projs = [sp.identity(h.geometry.nsites)]

# produce operators and structures for storing operators
current_op_x = h.n_projector * h.get_current_op(np.array(
    [[1], [0]])) * h.n_projector.conj().transpose()
eigvals_sectors = []
kx_ops_sectors = []
current_ops_x_sector = []
# creation op, site 0
    def test_ising_model_5x5(self):
        """
        Test diagonalization of 5x5 ising model with periodic boundary conditions.

        reference: J. Phys. A: Math. Gen 33 6683 (2000).
        "Finite-size scaling in the transverse Ising model on a square lattice" by C J Hamer
        https://doi.org/10.1088/0305-4470/33/38/303

        :return:
        """

        cluster = geom.Geometry.createSquareGeometry(5,
                                                     5,
                                                     0,
                                                     0,
                                                     bc1_open=False,
                                                     bc2_open=False)
        # paper definition of hamiltonian differs by a factor of two from mine
        jz_critical = -2 * 0.32669593806
        h_transverse = 2 * 1.0
        spin_model = tvi.spinSystem(cluster,
                                    jx=0.0,
                                    jy=0.0,
                                    jz=jz_critical,
                                    hx=h_transverse,
                                    hy=0.0,
                                    hz=0.0,
                                    use_ryd_detunes=0)

        # symmetry swapping up/down spins
        spin_swap_op = spin_model.get_swap_up_down_op()

        # x-translations
        xtransl_fn = symm.getTranslFn(np.array([[1], [0]]))
        xtransl_cycles, max_cycle_len_translx = symm.findSiteCycles(
            xtransl_fn, spin_model.geometry)
        xtransl_op = spin_model.get_xform_op(xtransl_cycles)
        xtransl_op = xtransl_op

        # y-translations
        ytransl_fn = symm.getTranslFn(np.array([[0], [1]]))
        ytransl_cycles, max_cycle_len_transly = symm.findSiteCycles(
            ytransl_fn, spin_model.geometry)
        ytransl_op = spin_model.get_xform_op(ytransl_cycles)
        ytransl_op = ytransl_op

        symm_projs, kxs, kys = symm.get2DTranslationProjectors(
            xtransl_op, max_cycle_len_translx, ytransl_op,
            max_cycle_len_transly)

        eig_vals_sectors = []
        full_proj_list = []
        hfull = spin_model.createH()
        for ii, proj in enumerate(symm_projs):
            spin_swap_proj_op = proj * spin_swap_op * proj.conj().transpose()

            # char_table = np.array([[1, 1], [1, -1]])
            # ccs = [[sp.eye(spin_swap_proj_op.shape[0], format="csr")], [spin_swap_proj_op]]
            swap_projs, phase = symm.getZnProjectors(spin_swap_proj_op, 2)

            for jj, sproj in enumerate(swap_projs):
                full_proj_list.append(sproj * proj)

                h_sector = sproj * proj * hfull * proj.conj().transpose(
                ) * sproj.conj().transpose()
                eig_vals_sector, eig_vects_sector = spin_model.diagH(
                    h_sector, print_results=True)
                eig_vals_sectors.append(eig_vals_sector)

        # why only accurate to 10 decimal places?
        eigs_all_sectors = np.sort(np.concatenate(eig_vals_sectors))
        min_eig_per_site = eigs_all_sectors[0] / spin_model.geometry.nsites + 1

        self.assertAlmostEqual(min_eig_per_site, -0.064637823298, 11)