Пример #1
0
def test_MultiCouplingModel_explicit():
    fermion_lat_cyl = lattice.Square(1,
                                     2,
                                     fermion_site,
                                     bc='periodic',
                                     bc_MPS='infinite')
    M = model.MultiCouplingModel(fermion_lat_cyl)
    # create a wired fermionic model with 3-body interactions
    M.add_onsite(0.125, 0, 'N')
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1))
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), 'JW')
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), 'JW')
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), 'JW')
    M.add_multi_coupling(4., 0, 'N', [(0, 'N', (2, 1))],
                         'Id')  # a full unit cell inbetween!
    # some wired mediated hopping along the diagonal
    M.add_multi_coupling(1.125,
                         0,
                         'N',
                         other_ops=[(0, 'Cd', (0, 1)), (0, 'C', (1, 0))])
    H_mpo = M.calc_H_MPO()
    W0_new = H_mpo.get_W(0)
    W1_new = H_mpo.get_W(1)
    W2_new = H_mpo.get_W(2)
    Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N
    Cd, C = fermion_site.Cd, fermion_site.C
    CdJW = Cd.matvec(JW)
    JWC = JW.matvec(C)
    NJW = N.matvec(JW)
    # yapf: disable
    W0_ex = [[Id,   None, None, CdJW, None, JWC,  N,    None, None, None, N*0.125],
             [None, None, Id,   None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, JW,   None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, Cd*1.5],
             [None, Id,   None, None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, C*1.125],
             [None, None, None, None, None, None, None, JW,   None, None, None],
             [None, None, None, None, None, None, None, None, JW,   None, None],
             [None, None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, None, Id]]
    W1_ex = [[Id,   None, None, None, None, None, None, None, CdJW, JWC,  N,    N*0.125],
             [None, Id,   None, None, None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, JW,   NJW,  None, None, None, None, None, None, C*0.5],
             [None, None, None, None, None, None, None, None, None, None, None, C*1.125],
             [None, None, None, None, None, JW,   None, None, None, None, None, Cd*0.5],
             [None, None, None, None, None, None, Id,   CdJW, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, None, None, None, None, None, None, None, Cd*1.5],
             [None, None, Id,   None, None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, None, Id]]
    # yapf: enable
    W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2])
    W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2])
    assert npc.norm(W0_new -
                    W0_ex) == 0.  # coupling constants: no rounding errors
    assert npc.norm(W1_new -
                    W1_ex) == 0.  # coupling constants: no rounding errors
Пример #2
0
def test_model_H_conversion(L=6):
    bc = 'finite'
    model_params = {'L': L, 'hz': np.random.random([L]), 'bc_MPS': bc}
    m = XXZChain(model_params)
    # can we run the conversion?
    # conversion from bond to MPO in NearestNeighborModel
    H_MPO = m.calc_H_MPO_from_bond()
    # conversion from MPO to bond in MPOModel
    H_bond = m.calc_H_bond_from_MPO()
    # compare: did we get the correct result?
    ED = ExactDiag(m)
    ED.build_full_H_from_bonds()
    H0 = ED.full_H  # this should be correct
    ED.full_H = None
    m.H_MPO = H_MPO
    ED.build_full_H_from_mpo()
    full_H_mpo = ED.full_H  # the one generated by NearstNeighborModel.calc_H_MPO_from_bond()
    print("npc.norm(H0 - full_H_mpo) = ", npc.norm(H0 - full_H_mpo))
    assert npc.norm(H0 -
                    full_H_mpo) < 1.e-14  # round off errors on order of 1.e-15
    m.H_bond = H_bond
    ED.full_H = None
    ED.build_full_H_from_bonds()
    full_H_bond = ED.full_H  # the one generated by NearstNeighborModel.calc_H_MPO_from_bond()
    print("npc.norm(H0 - full_H_bond) = ", npc.norm(H0 - full_H_bond))
    assert npc.norm(
        H0 - full_H_bond) < 1.e-14  # round off errors on order of 1.e-15
Пример #3
0
def make_uniform(psi):
    _chis = psi.chi

    #RCF
    TB = TransferMatrix(psi, psi, shift_bra=1, shift_ket=0)
    es_B, evs_B = TB.eigenvectors()
    U = evs_B[0].split_legs(['(vL.vL*)']).iset_leg_labels(['vL','vR'])
    _B = psi.get_B(1)
    B = npc.tensordot(_B, U, axes=('vR','vL'))
    B = (B/npc.norm(B))*np.sqrt(_chis[1])

    #LCF
    TA = TransferMatrix(psi, psi, shift_bra=1, shift_ket=0, form='A', transpose=True)
    es_A, evs_A = TA.eigenvectors()
    V = evs_A[0].split_legs(['(vR*.vR)'])
    Vdag = V.conj()
    _A = psi.get_B(1, form='A')
    A = npc.tensordot(_A, Vdag, axes=('vR','vR*'))
    A = (A/npc.norm(A))*np.sqrt(_chis[1])

    s = 0.5*(psi.get_SL(0) + psi.get_SL(1))
    upsi = make_uMPS(psi)
    upsi.set_B(0, A, form='A')
    upsi.set_B(0, B)
    upsi.set_SL(0, s)
    return upsi
Пример #4
0
def test_CouplingModel_multi_couplings_explicit(use_plus_hc, JW):
    fermion_lat_cyl = lattice.Square(1,
                                     2,
                                     fermion_site,
                                     bc='periodic',
                                     bc_MPS='infinite')
    M = model.CouplingModel(fermion_lat_cyl)
    # create a wired fermionic model with 3-body interactions
    M.add_onsite(0.125, 0, 'N')
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), plus_hc=use_plus_hc)
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), JW, plus_hc=use_plus_hc)
    if not use_plus_hc:
        M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), JW)
        M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), JW)
    # multi_coupling with a full unit cell inbetween the operators!
    M.add_multi_coupling(4., [('N', (0, 0), 0), ('N', (-2, -1), 0)])
    # some wired mediated hopping along the diagonal
    M.add_multi_coupling(1.125, [('N', (0, 0), 0), ('Cd', (0, 1), 0),
                                 ('C', (1, 0), 0)])
    H_mpo = M.calc_H_MPO()
    W0_new = H_mpo.get_W(0)
    W1_new = H_mpo.get_W(1)
    Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N
    Cd, C = fermion_site.Cd, fermion_site.C
    CdJW = Cd.matvec(JW)  # = Cd
    CJW = C.matvec(JW)  # = -C
    NJW = N.matvec(JW)
    # print(M.H_MPO_graph._build_grids())
    # yapf: disable
    W0_ex = [[Id,   CJW,  CdJW, None, N,    None, None, None, None, None, N*0.125],
             [None, None, None, None, None, None, None, None, None, None, Cd*-1.5],
             [None, None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, JW,   None, None, None, None, None, None, None],
             [None, None, None, None, None, Id,   None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, C*1.125],
             [None, None, None, None, None, None, Id,   None, None, None, None],
             [None, None, None, None, None, None, None, JW,   None, None, None],
             [None, None, None, None, None, None, None, None, JW,   None, None],
             [None, None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, None, Id]]
    W1_ex = [[Id,   None, None, None, None, None, None, CJW,  CdJW, N,    None, N*0.125],
             [None, JW,   None, None, None, None, None, None, None, None, None, Cd*-0.5],
             [None, None, JW,   NJW,  None, None, None, None, None, None, None, C*0.5],
             [None, None, None, None, None, None, None, None, None, None, None, C*1.125],
             [None, None, None, None, Id,   CdJW, None, None, None, None, None, None],
             [None, None, None, None, None, None, Id,   None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, None, None, Cd*-1.5],
             [None, None, None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, None, None, Id]]
    # yapf: enable
    W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2])
    W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2])
    assert npc.norm(W0_new -
                    W0_ex) == 0.  # coupling constants: no rounding errors
    assert npc.norm(W1_new -
                    W1_ex) == 0.  # coupling constants: no rounding errors
Пример #5
0
 def calculate_error_left_right(self, i):
     Lp = self.environment.get_LP(i)
     Rp = self.environment.get_RP(i)
     W = self.H_MPO.get_W(i)
     B = self.psi.get_B(i)
     p_h_phi = npc.tensordot(Lp, W, axes=['wR', 'wL'])
     p_h_phi = npc.tensordot(p_h_phi, Rp, axes=['wR', 'wL'])
     p_h_phi = npc.tensordot(p_h_phi,
                             B,
                             axes=[('p*', 'vR', 'vL'), ('p', 'vL', 'vR')])
     npc.norm(p_h_phi)
Пример #6
0
def test_random_matrix_CUE():
    for size in [1, 3, 4]:
        a = rmat.CUE((size, size))
        print(a)
        assert (a.dtype == np.complex)
        npt.assert_allclose(np.dot(a, a.T.conj()), np.eye(size), EPS, EPS)
    b = npc.Array.from_func_square(rmat.CUE, leg)
    b.test_sanity()
    assert (b.dtype == np.complex)
    print("b =", b)
    id = npc.eye_like(b)
    assert (npc.norm(npc.tensordot(b, b.conj().itranspose(), axes=[1, 0]) - id) < EPS)
    assert (npc.norm(npc.tensordot(b.conj().itranspose(), b, axes=[1, 0]) - id) < EPS)
Пример #7
0
def test_CouplingModel_explicit():
    fermion_lat_cyl = lattice.Square(1,
                                     2,
                                     fermion_site,
                                     bc='periodic',
                                     bc_MPS='infinite')
    M = model.CouplingModel(fermion_lat_cyl)
    M.add_onsite(0.125, 0, 'N')
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1),
                   None)  # auto-determine JW-string!
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), None)
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), None)
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), None)
    M.add_coupling(4., 0, 'N', 0, 'N', (-2, -1),
                   None)  # a full unit cell inbetween!
    H_mpo = M.calc_H_MPO()
    W0_new = H_mpo.get_W(0)
    W1_new = H_mpo.get_W(1)
    Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N
    Cd, C = fermion_site.Cd, fermion_site.C
    CdJW = Cd.matvec(JW)  # = Cd
    CJW = C.matvec(JW)  # = -C
    # yapf: disable
    W0_ex = [[Id,   CJW,  CdJW, N,    None, None, None, None, None, N*0.125],
             [None, None, None, None, None, None, None, None, None, Cd*-1.5],
             [None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, Id,   None, None, None, None, None],
             [None, None, None, None, None, Id,   None, None, None, None],
             [None, None, None, None, None, None, JW,   None, None, None],
             [None, None, None, None, None, None, None, JW,   None, None],
             [None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, Id]]
    W1_ex = [[Id,   None, None, None, None, CJW,  CdJW, N,    None, N*0.125],
             [None, JW,   None, None, None, None, None, None, None, Cd*-0.5],
             [None, None, JW,   None, None, None, None, None, None, C*0.5],
             [None, None, None, Id,   None, None, None, None, None, None],
             [None, None, None, None, Id,   None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, Cd*-1.5],
             [None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, Id]]

    # yapf: enable
    W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2])
    W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2])
    assert npc.norm(W0_new -
                    W0_ex) == 0.  # coupling constants: no rounding errors
    assert npc.norm(W1_new -
                    W1_ex) == 0.  # coupling constants: no rounding errors
Пример #8
0
def test_CouplingModel_explicit():
    fermion_lat_cyl = lattice.SquareLattice(1,
                                            2,
                                            fermion_site,
                                            bc_MPS='infinite')
    M = model.CouplingModel(fermion_lat_cyl, 'periodic')
    M.add_onsite(0.125, 0, 'N')
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), 'JW')
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), 'JW')
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), 'JW')
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), 'JW')
    M.add_coupling(4., 0, 'N', 0, 'N', (2, 1),
                   'Id')  # a full unit cell inbetween!
    H_mpo = M.calc_H_MPO()
    # MPO should be translation invariant!
    W0_new = H_mpo.get_W(0)
    W1_new = H_mpo.get_W(1)
    Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N
    Cd, C = fermion_site.Cd, fermion_site.C
    CdJW = Cd.matvec(JW)
    JWC = JW.matvec(C)
    # yapf: disable
    W0_ex = [[Id,   None, None, CdJW, JWC,  N,    None, None, None, N*0.125],
             [None, None, Id,   None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, None, None, None, None, None, Cd*1.5],
             [None, Id,   None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, JW,   None, None, None],
             [None, None, None, None, None, None, None, JW,   None, None],
             [None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, Id]]
    W1_ex = [[Id,  None, None, None, None, None,  CdJW, JWC,  N,    N*0.125],
             [None, Id,   None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, JW,   None, None, None, None, None, C*0.5],
             [None, None, None, None, JW,   None, None, None, None, Cd*0.5],
             [None, None, None, None, None, Id,   None, None, None, None],
             [None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, None, None, None, None, None, Cd*1.5],
             [None, None, Id,   None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, Id]]
    # yapf: enable
    W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2])
    W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2])
    assert npc.norm(W0_new -
                    W0_ex) == 0.  # coupling constants: no rounding errors
    assert npc.norm(W1_new -
                    W1_ex) == 0.  # coupling constants: no rounding errors
Пример #9
0
def test_FlatHermitianOperator(n=30, k=5, tol=5.e-15):
    leg = gen_random_legcharge(ch, n)
    H = npc.Array.from_func_square(rmat.GUE, leg)
    H_flat = H.to_ndarray()
    E_flat, psi_flat = np.linalg.eigh(H_flat)
    E0_flat, psi0_flat = E_flat[0], psi_flat[:, 0]
    qtotal = npc.detect_qtotal(psi0_flat, [leg])

    H_sparse = sparse.FlatHermitianOperator.from_NpcArray(H,
                                                          charge_sector=qtotal)
    psi_init = npc.Array.from_func(np.random.random, [leg], qtotal=qtotal)
    psi_init /= npc.norm(psi_init)
    psi_init_flat = H_sparse.npc_to_flat(psi_init)

    # check diagonalization
    E, psi = scipy.sparse.linalg.eigsh(H_sparse,
                                       k,
                                       v0=psi_init_flat,
                                       which='SA')
    E0, psi0 = E[0], psi[:, 0]
    print("full spectrum:", E_flat)
    print("E0 = {E0:.14f} vs exact {E0_flat:.14f}".format(E0=E0,
                                                          E0_flat=E0_flat))
    print("|E0-E0_flat| / |E0_flat| =", abs((E0 - E0_flat) / E0_flat))
    assert (abs((E0 - E0_flat) / E0_flat) < tol)
    psi0_H_psi0 = np.inner(psi0.conj(), H_sparse.matvec(psi0)).item()
    print("<psi0|H|psi0> / E0 = 1. + ", psi0_H_psi0 / E0 - 1.)
    assert (abs(psi0_H_psi0 / E0 - 1.) < tol)
Пример #10
0
def test_random_matrix_U_close_1():
    for x in [0., 0.001]:
        for size in [1, 3, 4]:
            a = rmat.U_close_1((size, size), x)
            print(a)
            assert (a.dtype == np.complex)
            npt.assert_allclose(np.dot(a, a.T.conj()), np.eye(size), EPS, EPS)
            npt.assert_allclose(a, np.eye(size), 10 * x, 10 * x + EPS)  # not exact for x=0!
        b = npc.Array.from_func_square(rmat.U_close_1, leg, func_args=[x])
        b.test_sanity()
        assert (b.dtype == np.complex)
        print("b =", b)
        id = npc.eye_like(b)
        assert (npc.norm(npc.tensordot(b, b.conj().itranspose(), axes=[1, 0]) - id) < EPS)
        assert (npc.norm(npc.tensordot(b.conj().itranspose(), b, axes=[1, 0]) - id) < EPS)
        assert (npc.norm(b - id) <= 10 * x + EPS)  # not exact for x=0!
Пример #11
0
def test_ED():
    # just quickly check that it runs without errors for a small system
    xxz_pars = dict(L=4, Jxx=1., Jz=1., hz=0.0, bc_MPS='finite')
    M = XXZChain(xxz_pars)
    ED = ExactDiag(M)
    ED.build_full_H_from_mpo()
    H, ED.full_H = ED.full_H, None
    ED.build_full_H_from_bonds()
    H2 = ED.full_H
    assert (npc.norm(H - H2, np.inf) < 1.e-14)
    ED.full_diagonalization()
    psi = ED.groundstate()
    print("select charge_sector =", psi.qtotal)
    ED2 = ExactDiag(M, psi.qtotal)
    ED2.build_full_H_from_mpo()
    ED2.full_diagonalization()
    psi2 = ED2.groundstate()
    full_psi2 = psi.zeros_like()
    full_psi2[ED2._mask] = psi2
    ov = npc.inner(psi, full_psi2, do_conj=True)
    print("overlab <psi | psi2> = 1. -", 1. - ov)
    assert (abs(abs(ov) - 1.) < 1.e-15)
    # starting from a random guess in the correct charge sector,
    # check if we can also do lanczos.
    np.random.seed(12345)
    psi3 = npc.Array.from_func(np.random.random,
                               psi2.legs,
                               qtotal=psi2.qtotal,
                               shape_kw='size')
    E0, psi3, N = lanczos(ED2, psi3)
    print("Lanczos E0 =", E0)
    ov = npc.inner(psi3, psi2, do_conj=True)
    print("overlab <psi2 | psi3> = 1. -", 1. - ov)
    assert (abs(abs(ov) - 1.) < 1.e-15)
Пример #12
0
def test_qr():
    for shape in [(4, 4), (6, 8), (8, 6)]:
        tol = shape[0] * shape[1] * 100
        for qtotal_A in [None, [1]]:
            A = random_Array(shape, chinfo3, qtotal=qtotal_A, sort=False)
            A_flat = A.to_ndarray()
            for qtotal_Q in [None, [1]]:
                for mode in ['reduced', 'complete']:
                    for qconj in [+1, -1]:
                        for pos in [False, True]:
                            print(
                                f"shape={shape!s} qtot_A={qtotal_A!s} qtot_Q={qtotal_Q!s}"
                                f"mode={mode!s} pos_diag_R={pos!s} inner_qconj={qconj:+d}"
                            )
                            Q, R = npc.qr(A,
                                          mode=mode,
                                          pos_diag_R=pos,
                                          qtotal_Q=qtotal_Q,
                                          inner_qconj=qconj)
                            #  print(q._qdata)
                            Q.test_sanity()
                            R.test_sanity()
                            assert np.all(
                                Q.qtotal) == A.chinfo.make_valid(qtotal_Q)
                            assert R.legs[0].qconj == qconj
                            QR = npc.tensordot(Q, R, axes=1)
                            npt.assert_array_almost_equal_nulp(
                                A_flat, QR.to_ndarray(), tol)
                            QdaggerQ = npc.tensordot(Q.conj(), Q, axes=[0, 0])
                            assert npc.norm(QdaggerQ -
                                            npc.eye_like(QdaggerQ)) < 1.e-10
Пример #13
0
def test_eig():
    size = 10
    max_nulp = 10 * size**3
    ci = chinfo3
    l = gen_random_legcharge(ci, size)
    A = npc.Array.from_func(np.random.random, [l, l.conj()],
                            qtotal=None,
                            shape_kw='size')
    print("hermitian A")
    A += A.conj().itranspose()
    Aflat = A.to_ndarray()
    W, V = npc.eigh(A, sort='m>')
    V.test_sanity()
    V_W = V.scale_axis(W, axis=-1)
    recalc = npc.tensordot(V_W, V.conj(), axes=[1, 1])
    npt.assert_array_almost_equal_nulp(Aflat, recalc.to_ndarray(), max_nulp)
    Wflat, Vflat = np.linalg.eigh(Aflat)
    npt.assert_array_almost_equal_nulp(np.sort(W), Wflat, max_nulp)
    W2 = npc.eigvalsh(A, sort='m>')
    npt.assert_array_almost_equal_nulp(W, W2, max_nulp)

    print("check complex B")
    B = 1.j * npc.Array.from_func(np.random.random, [l, l.conj()],
                                  shape_kw='size')
    B += B.conj().itranspose()
    B = A + B
    Bflat = B.to_ndarray()
    W, V = npc.eigh(B, sort='m>')
    V.test_sanity()
    recalc = npc.tensordot(V.scale_axis(W, axis=-1), V.conj(), axes=[1, 1])
    npt.assert_array_almost_equal_nulp(Bflat, recalc.to_ndarray(), max_nulp)
    Wflat, Vflat = np.linalg.eigh(Bflat)
    npt.assert_array_almost_equal_nulp(np.sort(W), Wflat, max_nulp)

    print("calculate without 'hermitian' knownledge")
    W, V = npc.eig(B, sort='m>')
    assert (np.max(np.abs(W.imag)) < EPS * max_nulp)
    npt.assert_array_almost_equal_nulp(np.sort(W.real), Wflat, max_nulp)

    print("sparse speigs")
    qi = 1
    ch_sect = B.legs[0].get_charge(qi)
    k = min(3, B.legs[0].slices[qi + 1] - B.legs[0].slices[qi])
    Wsp, Vsp = npc.speigs(B, ch_sect, k=k, which='LM')
    for W_i, V_i in zip(Wsp, Vsp):
        V_i.test_sanity()
        diff = npc.tensordot(B, V_i, axes=1) - V_i * W_i
        assert (npc.norm(diff, np.inf) < EPS * max_nulp)

    print("for trivial charges")
    A = npc.Array.from_func(np.random.random, [lcTr, lcTr.conj()],
                            shape_kw='size')
    A = A + A.conj().itranspose()
    Aflat = A.to_ndarray()
    W, V = npc.eigh(A)
    recalc = npc.tensordot(V.scale_axis(W, axis=-1), V.conj(), axes=[1, 1])
    npt.assert_array_almost_equal_nulp(Aflat, recalc.to_ndarray(),
                                       10 * A.shape[0]**3)
Пример #14
0
def test_npc_addition_transpose():
    # addition with labels and transposed axes
    a1 = np.random.random([3, 3, 4])
    a2 = np.swapaxes(a1, 0, 1)
    t1 = npc.Array.from_ndarray_trivial(a1, labels=['a', 'b', 'c'])
    t2 = npc.Array.from_ndarray_trivial(a2, labels=['b', 'a', 'c'])
    # TODO: for now warning
    with pytest.warns(FutureWarning):
        diff = npc.norm(t1 - t2)
Пример #15
0
def test_npc_Array_norm():
    a = random_Array((15, 10), chinfo3, sort=True)
    aflat = a.to_ndarray()
    for ord in [np.inf, -np.inf, 0, 1, 2, 3.]:  # divides by 0 for neg. ord
        print("ord = ", ord)
        anorm = a.norm(ord)
        aflnorm = npc.norm(aflat, ord)
        print(abs(anorm - aflnorm))
        assert (abs(anorm - aflnorm) < 100 * EPS)
Пример #16
0
def test_random_matrix_GUE():
    for size in [1, 3, 4]:
        a = rmat.GUE((size, size))
        assert (a.dtype == np.complex)
        print(a)
        npt.assert_array_equal(a, a.T.conj())
    b = npc.Array.from_func_square(rmat.GUE, leg)
    b.test_sanity()
    assert (b.dtype == np.complex)
    print("b =", b)
    assert (npc.norm(b - b.conj().itranspose()) == 0)
Пример #17
0
def test_npc_tensordot_extra():
    # check that the sorting of charges is fine with special test matrices
    # which gave me some headaches at some point :/
    chinfo = npc.ChargeInfo([1], ['Sz'])
    leg = npc.LegCharge.from_qflat(chinfo, [-1, 1])
    legs = [leg, leg, leg.conj(), leg.conj()]
    idx = [(0, 0, 0, 0), (0, 1, 0, 1), (0, 1, 1, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 1, 1, 1)]
    Uflat = np.eye(4).reshape([2, 2, 2, 2])  # up to numerical rubbish the identity
    Uflat[0, 1, 1, 0] = Uflat[1, 0, 0, 1] = 1.e-20
    U = npc.Array.from_ndarray(Uflat, legs, cutoff=0.)
    theta_flat = np.zeros([2, 2, 2, 2])
    vals = np.random.random(len(idx))
    vals /= np.linalg.norm(vals)
    for i, val in zip(idx, vals):
        theta_flat[i] = val
    theta = npc.Array.from_ndarray(theta_flat, [leg, leg, leg.conj(), leg.conj()], cutoff=0.)
    assert abs(np.linalg.norm(theta_flat) - npc.norm(theta)) < 1.e-14
    Utheta_flat = np.tensordot(Uflat, theta_flat, axes=2)
    Utheta = npc.tensordot(U, theta, axes=2)
    npt.assert_array_almost_equal_nulp(Utheta.to_ndarray(), Utheta_flat, 10)
    assert abs(np.linalg.norm(theta_flat) - npc.norm(Utheta)) < 1.e-10
Пример #18
0
def test_XXZChain_general(tol=1.e-14):
    check_general_model(XXZChain, dict(L=4, Jxx=1., hz=0., bc_MPS='finite'), {
        'Jz': [0., 1., 2.],
        'hz': [0., 0.2]
    })
    model_param = dict(L=3, Jxx=1., Jz=1.5, hz=0.25, bc_MPS='finite')
    m1 = XXZChain(model_param)
    m2 = XXZChain2(model_param)
    for Hb1, Hb2 in zip(m1.H_bond, m2.H_bond):
        if Hb1 is None:
            assert Hb2 is None
            continue
        assert npc.norm(Hb1 - Hb2) < tol
Пример #19
0
def check_model_sanity(M, hermitian=True):
    """call M.test_sanity() for all different subclasses of M"""
    if isinstance(M, model.CouplingModel):
        model.CouplingModel.test_sanity(M)
    if isinstance(M, model.NearestNeighborModel):
        model.NearestNeighborModel.test_sanity(M)
        if hermitian:
            for i, H in enumerate(M.H_bond):
                if H is not None:
                    err = npc.norm(H - H.conj().transpose(H.get_leg_labels()))
                    if err > 1.e-14:
                        print(H)
                        raise ValueError("H on bond {i:d} not hermitian".format(i=i))
    if isinstance(M, model.MPOModel):
        model.MPOModel.test_sanity(M)
        test_mpo.check_hermitian(M.H_MPO)
Пример #20
0
def test_XXZChain():
    pars = dict(L=4, Jxx=1., Jz=1., hz=0., bc_MPS='finite')
    chain = XXZChain(pars)
    chain.test_sanity()
    for Hb in chain.H_bond[1:]:  # check bond eigenvalues
        Hb2 = Hb.combine_legs([['p0', 'p1'], ['p0*', 'p1*']], qconj=[+1, -1])
        print(Hb2.to_ndarray())
        W = npc.eigvalsh(Hb2)
        npt.assert_array_almost_equal_nulp(np.sort(W),
                                           np.sort([-0.75, 0.25, 0.25, 0.25]),
                                           16**3)
    # now check with non-trivial onsite terms
    pars['hz'] = 0.2
    print("hz =", pars['hz'])
    chain = XXZChain(pars)
    chain.test_sanity()
    Hb = chain.H_bond[
        2]  # the only central bonds: boundaries have different hz.
    Hb2 = Hb.combine_legs([['p0', 'p1'], ['p0*', 'p1*']], qconj=[+1, -1])
    print(Hb2.to_ndarray())
    W = npc.eigvalsh(Hb2)
    print(W)
    npt.assert_array_almost_equal_nulp(
        np.sort(W),
        np.sort([
            -0.75, 0.25 - 2 * 0.5 * 0.5 * pars['hz'], 0.25,
            0.25 + 2. * 0.5 * 0.5 * pars['hz']
        ]), 16**3)
    pars['bc_MPS'] = 'infinite'

    for L in [2, 3, 4, 5, 6]:
        print("L =", L)
        pars['L'] = L
        chain = XXZChain(pars)
        pprint.pprint(chain.coupling_terms)
        assert len(chain.H_bond) == L
        Hb0 = chain.H_bond[0]
        for Hb in chain.H_bond[1:]:
            assert (npc.norm(Hb - Hb0, np.inf) == 0.)  # exactly equal
    pars['Jxx'] = 0.
    chain = XXZChain(pars)
    chain.test_sanity()
Пример #21
0
    def sweep_right_left_two(self):
        """Performs the sweep left->right of the second order TDVP scheme with two sites update.

        Evolve from 0.5*dt
        """
        theta_old = self.psi.get_theta(self.L - 1, 1)
        for j in range(self.L - 2, -1, -1):
            theta = npc.tensordot(theta_old, self.psi.get_B(j, form='A'),
                                  ('vL', 'vR'))
            theta.ireplace_label('p0', 'p1')
            theta.ireplace_label('p', 'p0')
            #theta=self.psi.get_theta(j,2)
            Lp = self.environment.get_LP(j)
            Rp = self.environment.get_RP(j + 1)
            W1 = self.environment.H.get_W(j)
            W2 = self.environment.H.get_W(j + 1)
            theta = self.update_theta_h2(Lp, Rp, theta, W1, W2,
                                         -1j * 0.5 * self.dt)
            theta = theta.combine_legs([['vL', 'p0'], ['vR', 'p1']],
                                       qconj=[+1, -1])
            # SVD and update environment
            U, s, V, err, renorm = svd_theta(theta, self.trunc_params)
            s = s / npc.norm(s)
            U = U.split_legs('(vL.p0)')
            U.ireplace_label('p0', 'p')
            V = V.split_legs('(vR.p1)')
            V.ireplace_label('p1', 'p')
            self.psi.set_B(j, U, form='A')
            self._del_correct(j)
            self.psi.set_SR(j, s)
            self.psi.set_B(j + 1, V, form='B')
            self._del_correct(j + 1)
            if j > 0:
                # Apply expm (-dt H) for 1-site
                theta = self.psi.get_theta(j, 1)
                theta.ireplace_label('p0', 'p')
                Lp = self.environment.get_LP(j)
                Rp = self.environment.get_RP(j)
                theta = self.update_theta_h1(Lp, Rp, theta, W1,
                                             1j * 0.5 * self.dt)
                theta_old = theta
                theta.ireplace_label('p', 'p0')
Пример #22
0
def assert_equal_data(data_imported, data_expected, max_recursion_depth=10):
    """Check that the imported data is as expected."""
    assert isinstance(data_imported, type(data_expected))
    if hasattr(data_expected, 'test_sanity'):
        data_imported.test_sanity()
    if isinstance(data_expected, dict):
        assert set(data_imported.keys()) == set(data_expected.keys())
        if max_recursion_depth > 0:
            for ki in data_imported.keys():
                assert_equal_data(data_imported[ki], data_expected[ki], max_recursion_depth - 1)
    elif isinstance(data_expected, (list, tuple)):
        if max_recursion_depth > 0:
            for vi, ve in zip(data_imported, data_expected):
                assert_equal_data(vi, ve, max_recursion_depth - 1)
    elif isinstance(data_expected, npc.Array):
        assert npc.norm(data_imported - data_expected) == 0.  # should be exactly equal!
    elif isinstance(data_expected, np.ndarray):
        np.testing.assert_array_equal(data_imported, data_expected)
    elif isinstance(data_expected, (int, float, np.int64, np.float64, complex, str)):
        assert data_imported == data_expected
Пример #23
0
def test_lanczos_evolve(n, N_cache, tol=5.e-14):
    # generate Hermitian test array
    leg = gen_random_legcharge(ch, n)
    H = npc.Array.from_func_square(rmat.GUE, leg) - npc.diag(1., leg)
    H_flat = H.to_ndarray()
    H_Op = H  # use `matvec` of the array
    qtotal = leg.to_qflat()[0]
    psi_init = npc.Array.from_func(np.random.random, [leg], qtotal=qtotal)
    #psi_init /= npc.norm(psi_init) # not necessary
    psi_init_flat = psi_init.to_ndarray()
    lanc = lanczos.LanczosEvolution(H_Op, psi_init, {'N_cache': N_cache})
    for delta in [-0.1j, 0.1j, 1.j, 0.1, 1.]:
        psi_final_flat = expm(H_flat * delta).dot(psi_init_flat)
        norm = np.linalg.norm(psi_final_flat)
        psi_final, N = lanc.run(delta, normalize=False)
        diff = np.linalg.norm(psi_final.to_ndarray() - psi_final_flat)
        print("norm(|psi_final> - |psi_final_flat>)/norm = ",
              diff / norm)  # should be 1.
        assert diff / norm < tol
        psi_final2, N = lanc.run(delta, normalize=True)
        assert npc.norm(psi_final / norm - psi_final2) < tol
Пример #24
0
def test_lanczos_evolve(n, N_cache, tol=5.e-15):
    # generate Hermitian test array
    leg = gen_random_legcharge(ch, n)
    H = npc.Array.from_func_square(rmat.GUE, leg) - npc.diag(1., leg)
    H_flat = H.to_ndarray()
    H_Op = H  # use `matvec` of the array
    qtotal = leg.to_qflat()[0]
    psi_init = npc.Array.from_func(np.random.random, [leg], qtotal=qtotal)
    psi_init /= npc.norm(psi_init)
    psi_init_flat = psi_init.to_ndarray()
    lanc = lanczos.LanczosEvolution(H_Op, psi_init, {
        'verbose': 1,
        'N_cache': N_cache
    })
    for delta in [-0.1j, 0.1j, 1.j]:  #, 0.1, 1.]:
        psi_final_flat = expm(H_flat * delta).dot(psi_init_flat)
        psi_final, N = lanc.run(delta)
        ov = np.inner(psi_final.to_ndarray().conj(), psi_final_flat)
        ov /= np.linalg.norm(psi_final_flat)
        print("<psi1|psi1_flat>/norm=", ov)
        assert (abs(1. - abs(ov)) < tol)
Пример #25
0
def test_MPO_conversion():
    L = 8
    sites = []
    for i in range(L):
        s = site.Site(spin_half.leg)
        s.add_op("X_{i:d}".format(i=i), np.diag([2., 1.]))
        s.add_op("Y_{i:d}".format(i=i), np.diag([1., 2.]))
        sites.append(s)
    terms = [
        [("X_0", 0)],
        [("X_0", 0), ("X_1", 1)],
        [("X_0", 0), ("X_3", 3)],
        [("X_4", 4), ("Y_5", 5), ("Y_7", 7)],
        [("X_4", 4), ("Y_5", 5), ("X_7", 7)],
        [("X_4", 4), ("Y_6", 6), ("Y_7", 7)],
    ]
    prefactors = [0.25, 10., 11., 101., 102., 103.]
    term_list = TermList(terms, prefactors)
    g1 = mpo.MPOGraph.from_term_list(term_list,
                                     sites,
                                     bc='finite',
                                     insert_all_id=False)
    ct_add = MultiCouplingTerms(L)
    ct_add.add_coupling_term(12., 4, 5, "X_4", "X_5")
    ct_add.add_multi_coupling_term(0.5, [4, 5, 7], ["X_4", "Y_5", "X_7"], "Id")
    ct_add.add_to_graph(g1)
    H1 = g1.build_MPO()
    grids = [
        [['Id', 'X_0', [('X_0', 0.25)]]  # site 0
         ],
        [
            ['Id', None, None],  # site 1
            [None, 'Id', [('X_1', 10.0)]],
            [None, None, 'Id']
        ],
        [
            ['Id', None, None],  # site 2
            [None, [('Id', 11.0)], None],
            [None, None, 'Id']
        ],
        [
            ['Id', None],  # site 3
            [None, 'X_3'],
            [None, 'Id']
        ],
        [
            ['X_4', None],  #site 4
            [None, 'Id']
        ],
        [
            ['Id', 'Y_5', [('X_5', 12.0)]],  # site 5
            [None, None, 'Id']
        ],
        [
            # site 6
            [None, [('Y_6', 103.0)], None],
            [[('Id', 102.5)], [('Id', 101.0)], None],
            [None, None, 'Id']
        ],
        [
            ['X_7'],  # site 7
            ['Y_7'],
            ['Id']
        ]
    ]
    H2 = mpo.MPO.from_grids(sites, grids, 'finite', [0] * 4 + [None] * 5,
                            [None] * 5 + [-1] * 4)
    for w1, w2 in zip(H1._W, H2._W):
        assert npc.norm(w1 - w2, np.inf) == 0.
    pass
Пример #26
0
def test_CouplingModel_explicit():
    fermion_lat_cyl = lattice.Square(1,
                                     2,
                                     fermion_site,
                                     bc='periodic',
                                     bc_MPS='infinite')
    M = model.CouplingModel(fermion_lat_cyl)
    M.add_onsite(0.125, 0, 'N')
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1),
                   None)  # auto-determine JW-string!
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), None)
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), None)
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), None)
    M.add_coupling(4., 0, 'N', 0, 'N', (-2, -1),
                   None)  # a full unit cell inbetween!
    H_mpo = M.calc_H_MPO()
    W0_new = H_mpo.get_W(0)
    W1_new = H_mpo.get_W(1)
    Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N
    Cd, C = fermion_site.Cd, fermion_site.C
    CdJW = Cd.matvec(JW)  # = Cd
    JWC = JW.matvec(C)  # = C
    #  H_MPO_graph = tenpy.networks.mpo.MPOGraph.from_terms((M.all_onsite_terms(),
    #                                                        M.all_coupling_terms(),
    #                                                        M.exp_decaying_terms),
    #                                                       M.lat.mps_sites(),
    #                                                       M.lat.bc_MPS)
    #  H_MPO_graph._set_ordered_states()
    #  from pprint import pprint
    #  pprint(H_MPO_graph._ordered_states)
    #  print(M.all_coupling_terms().to_TermList())
    #  [{'IdL': 0,
    #    ('left', 0, 'Cd JW', 'JW'): 1,
    #    ('left', 0, 'JW C', 'JW'): 2,
    #    ('left', 0, 'N', 'Id'): 3,
    #    ('left', 1, 'Cd JW', 'JW'): 4,
    #    ('left', 1, 'JW C', 'JW'): 5,
    #    ('left', 1, 'N', 'Id'): 6,
    #    ('left', 0, 'N', 'Id', 2, 'Id', 'Id'): 7,
    #    ('left', 1, 'N', 'Id', 3, 'Id', 'Id'): 8},
    #    'IdR': 9,
    #   {'IdL': 0,
    #    ('left', 0, 'Cd JW', 'JW'): 1,
    #    ('left', 0, 'JW C', 'JW'): 2,
    #    ('left', 0, 'N', 'Id'): 3,
    #    ('left', 1, 'Cd JW', 'JW'): 4,
    #    ('left', 1, 'JW C', 'JW'): 5,
    #    ('left', 1, 'N', 'Id'): 6},
    #    ('left', 0, 'N', 'Id', 2, 'Id', 'Id'): 7,
    #    ('left', 0, 'N', 'Id', 2, 'Id', 'Id', 4, 'Id', 'Id'): 8,
    #    'IdR': 9,
    #  0.50000 * Cd JW_0 C_1 +
    #  1.50000 * Cd JW_0 C_2 +
    #  0.50000 * JW C_0 Cd_1 +
    #  1.50000 * JW C_0 Cd_2 +
    #  4.00000 * N_0 N_5 +
    #  1.50000 * Cd JW_1 C_3 +
    #  1.50000 * JW C_1 Cd_3 +
    #  4.00000 * N_1 N_4
    # yapf: disable
    W0_ex = [[Id,   CdJW, JWC,  N,    None, None, None, None, None, N*0.125],
             [None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, None, None, None, None, None, Cd*1.5],
             [None, None, None, None, None, None, None, Id,   None, None],
             [None, None, None, None, JW,   None, None, None, None, None],
             [None, None, None, None, None, JW,   None, None, None, None],
             [None, None, None, None, None, None, Id,   None, None, None],
             [None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, Id]]
    W1_ex = [[Id,   None, None, None, CdJW, JWC,  N,    None, None, N*0.125],
             [None, JW,   None, None, None, None, None, None, None, C*0.5],
             [None, None, JW,   None, None, None, None, None, None, Cd*0.5],
             [None, None, None, Id,   None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None, None, C*1.5],
             [None, None, None, None, None, None, None, None, None, Cd*1.5],
             [None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, Id,   None, None],
             [None, None, None, None, None, None, None, None, None, N*4.0],
             [None, None, None, None, None, None, None, None, None, Id]]

    # yapf: enable
    W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2])
    W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2])
    assert npc.norm(W0_new -
                    W0_ex)**2 == 0.  # coupling constants: no rounding errors
    assert npc.norm(W1_new -
                    W1_ex)**2 == 0.  # coupling constants: no rounding errors
Пример #27
0
print("6) calculate exp(H2) by diagonalization of H2")
# diagonalization requires to view H2 as a matrix
H2 = H2.combine_legs([('p0', 'p1'), ('p0*', 'p1*')], qconj=[+1, -1])
print("labels after combine_legs:", H2.get_leg_labels())
E2, U2 = npc.eigh(H2)
print("Eigenvalues of H2:", E2)
U_expE2 = U2.scale_axis(np.exp(-1.j * dt * E2), axis=1)  # scale_axis ~= apply a diagonal matrix
exp_H2 = npc.tensordot(U_expE2, U2.conj(), axes=(1, 1))
exp_H2.iset_leg_labels(H2.get_leg_labels())
exp_H2 = exp_H2.split_legs()  # by default split all legs which are `LegPipe`
# (this restores the originial labels ['p0', 'p1', 'p0*', 'p1*'] of `H2` in `exp_H2`)

# alternative way: use :func:`~tenpy.linalg.np_conserved.expm`
exp_H2_alternative = npc.expm(-1.j * dt * H2).split_legs()
assert (npc.norm(exp_H2_alternative - exp_H2) < 1.e-14)

print("7) apply exp(H2) to even/odd bonds of the MPS and truncate with svd")
# (this implements one time step of first order TEBD)
trunc_par = {'svd_min': cutoff, 'trunc_cut': None, 'verbose': 0}
for even_odd in [0, 1]:
    for i in range(even_odd, L - 1, 2):
        theta = psi.get_theta(i, 2)  # handles canonical form (i.e. scaling with 'S')
        theta = npc.tensordot(exp_H2, theta, axes=(['p0*', 'p1*'], ['p0', 'p1']))
        # view as matrix for SVD
        theta = theta.combine_legs([('vL', 'p0'), ('p1', 'vR')], new_axes=[0, 1], qconj=[+1, -1])
        # now theta has labels '(vL.p0)', '(p1.vR)'
        U, S, V, err, invsq = svd_theta(theta, trunc_par, inner_labels=['vR', 'vL'])
        psi.set_SR(i, S)
        A_L = U.split_legs('(vL.p0)').ireplace_label('p0', 'p')
        B_R = V.split_legs('(p1.vR)').ireplace_label('p1', 'p')
Пример #28
0
def test_FlatHermitianOperator(n=30, k=5, tol=1.e-14):
    leg = gen_random_legcharge(ch, n // 2)
    leg2 = gen_random_legcharge(ch, 2)
    pipe = npc.LegPipe([leg, leg2], qconj=+1)
    H = npc.Array.from_func_square(rmat.GUE, pipe)
    H.iset_leg_labels(["(a.b)", "(a*.b*)"])
    H_flat = H.to_ndarray()
    E_flat, psi_flat = np.linalg.eigh(H_flat)
    E0_flat, psi0_flat = E_flat[0], psi_flat[:, 0]
    qtotal = npc.detect_qtotal(psi0_flat, [pipe])

    H_sparse = sparse.FlatHermitianOperator.from_NpcArray(H,
                                                          charge_sector=qtotal)
    psi_init = npc.Array.from_func(np.random.random, [pipe], qtotal=qtotal)
    psi_init /= npc.norm(psi_init)
    psi_init.iset_leg_labels(["(a.b)"])
    psi_init_flat = H_sparse.npc_to_flat(psi_init)

    # check diagonalization
    E, psi = scipy.sparse.linalg.eigsh(H_sparse,
                                       k,
                                       v0=psi_init_flat,
                                       which='SA')
    E0, psi0 = E[0], psi[:, 0]
    print("full spectrum:", E_flat)
    print("E0 = {E0:.14f} vs exact {E0_flat:.14f}".format(E0=E0,
                                                          E0_flat=E0_flat))
    print("|E0-E0_flat| / |E0_flat| =", abs((E0 - E0_flat) / E0_flat))
    assert (abs((E0 - E0_flat) / E0_flat) < tol)
    psi0_H_psi0 = np.inner(psi0.conj(), H_sparse.matvec(psi0)).item()
    print("<psi0|H|psi0> / E0 = 1. + ", psi0_H_psi0 / E0 - 1.)
    assert (abs(psi0_H_psi0 / E0 - 1.) < tol)

    # split H to check `FlatHermitianOperator.from_guess_with_pipe`.
    print("=========")
    print("split legs and define separate matvec")
    assert psi_init.legs[0] is pipe
    psi_init_split = psi_init.split_legs([0])
    H_split = H.split_legs()

    def H_split_matvec(vec):
        vec = npc.tensordot(H_split, vec, [["a*", "b*"], ["a", "b"]])
        # TODO as additional challenge, transpose the resulting vector
        return vec

    H_sparse_split, psi_init_split_flat = sparse.FlatLinearOperator.from_guess_with_pipe(
        H_split_matvec, psi_init_split, dtype=H_split.dtype)

    # diagonalize
    E, psi = scipy.sparse.linalg.eigsh(H_sparse_split,
                                       k,
                                       v0=psi_init_split_flat,
                                       which='SA')
    E0, psi0 = E[0], psi[:, 0]
    print("full spectrum:", E_flat)
    print("E0 = {E0:.14f} vs exact {E0_flat:.14f}".format(E0=E0,
                                                          E0_flat=E0_flat))
    print("|E0-E0_flat| / |E0_flat| =", abs((E0 - E0_flat) / E0_flat))
    assert (abs((E0 - E0_flat) / E0_flat) < tol)
    psi0_H_psi0 = np.inner(psi0.conj(), H_sparse.matvec(psi0)).item()
    print("<psi0|H|psi0> / E0 = 1. + ", psi0_H_psi0 / E0 - 1.)
    assert (abs(psi0_H_psi0 / E0 - 1.) < tol)
Пример #29
0
def test_CouplingModel_multi_couplings_explicit(use_plus_hc, JW):
    fermion_lat_cyl = lattice.Square(1,
                                     2,
                                     fermion_site,
                                     bc='periodic',
                                     bc_MPS='infinite')
    M = model.CouplingModel(fermion_lat_cyl)
    # create a weird fermionic model with 3-body interactions
    M.add_onsite(0.125, 0, 'N')
    M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, 1), plus_hc=use_plus_hc)
    M.add_coupling(1.5, 0, 'Cd', 0, 'C', (1, 0), JW, plus_hc=use_plus_hc)
    if not use_plus_hc:
        M.add_coupling(0.25, 0, 'Cd', 0, 'C', (0, -1), JW)
        M.add_coupling(1.5, 0, 'Cd', 0, 'C', (-1, 0), JW)
    # multi_coupling with a full unit cell inbetween the operators!
    M.add_multi_coupling(4., [('N', (0, 0), 0), ('N', (-2, -1), 0)])
    # some weird mediated hopping along the diagonal
    M.add_multi_coupling(1.125, [('N', (0, 0), 0), ('Cd', (0, 1), 0),
                                 ('C', (1, 0), 0)])
    H_mpo = M.calc_H_MPO()
    W0_new = H_mpo.get_W(0)
    W1_new = H_mpo.get_W(1)
    Id, JW, N = fermion_site.Id, fermion_site.JW, fermion_site.N
    Cd, C = fermion_site.Cd, fermion_site.C
    CdJW = Cd.matvec(JW)  # = Cd
    JWC = JW.matvec(C)  # = C
    NJW = N.matvec(JW)
    # yapf: disable
    H_MPO_graph = tenpy.networks.mpo.MPOGraph.from_terms((M.all_onsite_terms(),
                                                          M.all_coupling_terms(),
                                                          M.exp_decaying_terms),
                                                         M.lat.mps_sites(),
                                                         M.lat.bc_MPS)
    H_MPO_graph._set_ordered_states()
    from pprint import pprint
    pprint(H_MPO_graph._ordered_states)
    pprint(H_MPO_graph._build_grids())
    print(M.all_coupling_terms().to_TermList())
    #  0.50000 * Cd JW_0 C_1 +
    #  1.50000 * Cd JW_0 C_2 +
    #  0.50000 * JW C_0 Cd_1 +
    #  1.50000 * JW C_0 Cd_2 +
    #  1.50000 * Cd JW_1 C_3 +
    #  1.50000 * JW C_1 Cd_3 +
    #  4.00000 * N_0 N_5 +
    #  4.00000 * N_1 N_4 +
    #  1.12500 * N_0 Cd JW_1 C_2 +
    #  1.12500 * Cd JW_0 N JW_1 C_3

    W0_ex = [[Id,   CdJW, JWC,  N,    None, None, None, None, None, N*0.125],
             [None, None, None, None, None, Id,   None, None, None, None],
             [None, None, None, None, None, None, JW*1.5,   None, None, None],
             [None, None, None, None, None, None, None, JW*1.5,   None, None],
             [None, None, None, None, Id,   None, None, None, None, None],
             [None, None, None, None, None, None, JW*1.125, None, None, None],
             [None, None, None, None, None, None, None, None, None, C],
             [None, None, None, None, None, None, None, None, None, Cd],
             [None, None, None, None, None, None, None, None, None, N],
             [None, None, None, None, None, None, None, None, Id,   None],
             [None, None, None, None, None, None, None, None, None, Id]]

    W1_ex = [[Id,   None, CdJW, JWC,  N,    None, None, None, None, None, N*0.125],
             [None, None, None, None, None, NJW,  JW*1.5, None, None, None, C*0.5],
             [None, None, None, None, None, None, None, JW*1.5, None, None, Cd*0.5],
             [None, Id,   None, None, None, None, CdJW*1.125, None, None, None, None],
             [None, None, None, None, None, None, None, None, Id*4., None, None],
             [None, None, None, None, None, None, None, None, None, Id*4., None],
             [None, None, None, None, None, None, None, None, None, None, C],
             [None, None, None, None, None, None, None, None, None, None, Cd],
             [None, None, None, None, None, None, None, None, None, None, N],
             [None, None, None, None, None, None, None, None, None, None, Id]]
    # yapf: enable
    W0_ex = npc.grid_outer(W0_ex, W0_new.legs[:2])
    assert npc.norm(W0_new -
                    W0_ex) == 0.  # coupling constants: no rounding errors
    W1_ex = npc.grid_outer(W1_ex, W1_new.legs[:2])

    assert npc.norm(W1_new -
                    W1_ex) == 0.  # coupling constants: no rounding errors