Exemplo n.º 1
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
Exemplo n.º 2
0
def test_npc_grid_outer():
    ci = chinfo3
    p_leg = gen_random_legcharge(ci, 4)
    legs_op = [p_leg, p_leg.conj()]
    op_0 = 1.j * npc.Array.from_func(np.random.random, legs_op, qtotal=[0], shape_kw='size')
    op_pl = npc.Array.from_func(np.random.random, legs_op, qtotal=[1], shape_kw='size')
    op_min = npc.Array.from_func(np.random.random, legs_op, qtotal=[-1], shape_kw='size')
    op_id = npc.eye_like(op_0)
    grid = [[op_id, op_pl, op_min, op_0, None],
            [None, None, None, None, op_min],
            [None, None, None, None, op_pl],
            [None, None, None, None, op_0],
            [None, None, None, None, op_id]]  # yapf: disable
    leg_WL = npc.LegCharge.from_qflat(ci, ci.make_valid([[0], [1], [-1], [0], [0]]))
    leg_WR = npc.LegCharge.from_qflat(ci, ci.make_valid([[0], [1], [-1], [0], [0]]), -1)
    leg_WR_calc = npc.detect_grid_outer_legcharge(grid, [leg_WL, None], qconj=-1)[1]
    leg_WR.test_equal(leg_WR_calc)

    W = npc.grid_outer(grid, [leg_WL, leg_WR])
    W.test_sanity()
    Wflat = np.zeros([5, 5, 4, 4], dtype=W.dtype)
    for idx, op in [[(0, 0), op_id], [(0, 1), op_pl], [(0, 2), op_min], [(0, 3), op_0],
                    [(1, 4), op_min], [(2, 4), op_pl], [(3, 4), op_0], [(4, 4), op_id]]:
        Wflat[idx] = op.to_ndarray()
    npt.assert_equal(W.to_ndarray(), Wflat)
Exemplo n.º 3
0
def test_renyi_disentangler(L=4, eps=1.e-15):
    xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS='finite')
    M = XXZChain(xxz_pars)
    psi = purification_mps.PurificationMPS.from_infiniteT(M.lat.mps_sites(),
                                                          bc='finite')
    eng = PurificationTEBD(psi, M, {'verbose': 30, 'disentangle': 'renyi'})
    theta = eng.psi.get_theta(1, 2)
    print(theta[0, :, :, 0, :, :])
    # find random unitary: SVD of random matix
    pleg = psi.sites[0].leg
    pipe = npc.LegPipe([pleg, pleg])
    A = npc.Array.from_func_square(rmat.CUE, pipe).split_legs()
    A.iset_leg_labels(['p0', 'p1', 'p0*', 'p1*'])
    # Now we have unitary `A`, i.e. the optimal `U` should be `A^dagger`.
    theta = npc.tensordot(A, theta, axes=[['p0*', 'p1*'], ['p0', 'p1']])

    U0 = npc.outer(
        npc.eye_like(theta, 'q0').iset_leg_labels(['q0', 'q0*']),
        npc.eye_like(theta, 'q1').iset_leg_labels(['q1', 'q1*']))
    U = U0
    Sold = np.inf
    for i in range(20):
        S, U = eng.used_disentangler.iter(theta, U)
        if i == 0:
            S_0 = S
        print("iteration {i:d}: S={S:.5f}, DS={DS:.4e} ".format(i=i,
                                                                S=S,
                                                                DS=Sold - S))
        if abs(Sold - S) < eps:
            print("break: S converged down to {eps:.1e}".format(eps=eps))
            break
        Sold, S = S, Sold
    else:
        print("maximum number of iterations reached")
    theta = npc.tensordot(U, theta, axes=[['q0*', 'q1*'], ['q0', 'q1']])
    print("new theta = ")
    print(theta.itranspose(['vL', 'vR', 'p0', 'q0', 'p1', 'q1']))
    print(theta[0, 0])
    assert (S < S_0)  # this should always be true...
    if S > 100 * eps:
        print("final S =", S)
        warnings.warn("test of purification failed to find the optimum.")
Exemplo n.º 4
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)
Exemplo n.º 5
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!
Exemplo n.º 6
0
#         p*
#         |
#         ^
#         |
#  wL ->--W-->- wR
#         |
#         ^
#         |
#         p

# create physical spin-1/2 operators Sz, S+, S-
Sz = npc.Array.from_ndarray([[0.5, 0.], [0., -0.5]], [p_leg, p_leg.conj()])
Sp = npc.Array.from_ndarray([[0., 1.], [0., 0.]], [p_leg, p_leg.conj()])
Sm = npc.Array.from_ndarray([[0., 0.], [1., 0.]], [p_leg, p_leg.conj()])
Id = npc.eye_like(Sz)  # identity
for op in [Sz, Sp, Sm, Id]:
    op.iset_leg_labels(['p', 'p*'])  # physical in, physical out

mpo_leg = npc.LegCharge.from_qflat(chinfo, [[0], [2], [-2], [0], [0]])

W_grid = [[Id,   Sp,   Sm,   Sz,   None          ],
          [None, None, None, None, 0.5 * Jxx * Sm],
          [None, None, None, None, 0.5 * Jxx * Sp],
          [None, None, None, None, Jz * Sz       ],
          [None, None, None, None, Id            ]]  # yapf:disable

W = npc.grid_outer(W_grid, [mpo_leg, mpo_leg.conj()])
W.iset_leg_labels(['wL', 'wR', 'p',
                   'p*'])  # wL/wR = virtual left/right of the MPO
Ws = [W] * L
Exemplo n.º 7
0
def test_MPOTransferMatrix(eps=1.e-13):
    s = spin_half
    # exponential decay in Sz term to make it harder
    gamma = 0.5
    Jxy, Jz = 4., 1.
    hz = 0.
    grid = [[s.Id, s.Sp, s.Sm, s.Sz, hz * s.Sz],
            [None, None, None, None, Jxy*0.5*s.Sm],
            [None, None, None, None, Jxy*0.5*s.Sp],
            [None, None, None, gamma*s.Id, Jz*s.Sz],
            [None, None, None, None, s.Id]]  # yapf: disable
    H = mpo.MPO.from_grids([s] * 3, [grid] * 3,
                           'infinite',
                           0,
                           4,
                           max_range=np.inf)
    psi = mps.MPS.from_singlets(s, 3, [(0, 1)], lonely=[2], bc='infinite')
    psi.roll_mps_unit_cell(
        -1)  # -> nontrivial chi at the cut between unit cells
    exact_E = ((-0.25 - 0.25) *
               Jxy  # singlet <0.5*Sp_i Sm_{i+1}> = 0.25 = <0.5*Sm_i Sp_{i+1}>
               - 0.25 * Jz  # singlet <Sz_i Sz_{i+1}>
               + 1. * (0.25 * gamma**2 / (1. - gamma**3))
               )  # exponentially decaying "lonely" states
    # lonely: <Sz_{i} gamma gamma Sz_{i+2}
    exact_E = exact_E / psi.L  # energy per site
    for transpose in [False, True]:
        print(f"transpose={transpose!s}")
        TM = mpo.MPOTransferMatrix(H, psi, transpose=transpose)
        TM.matvec(TM.guess, project=False)
        TM.matvec(TM.guess, project=True)
        val, vec = TM.dominant_eigenvector()
        assert abs(val - 1.) < eps
        E0 = TM.energy(vec)
        print(E0, exact_E)
        assert abs(E0 - exact_E) < eps
        if not transpose:
            vec.itranspose(['vL', 'wL', 'vL*'])
            assert (vec[:, 4, :] - npc.eye_like(vec, 0)).norm() < eps
        else:
            vec.itranspose(['vR*', 'wR', 'vR'])
            assert (vec[:, 0, :] - npc.eye_like(vec, 0)).norm() < eps
    # get non-trivial psi
    psi.perturb(
        {
            'N_steps': 10,
            'trunc_params': {
                'chi_max': 3,
                'svd_min': 1.e-14
            }
        },
        close_1=False,
        canonicalize=False)
    psi.canonical_form_infinite2()
    # now find eigenvector again
    # and check TM |vec> = |vec> + val * |v0>
    # with |v0> = eye(chi) * IdL/IdR
    for transpose in [False, True]:
        print(f"transpose={transpose!s}")
        TM = mpo.MPOTransferMatrix(H, psi, transpose=transpose)
        val, vec = TM.dominant_eigenvector()
        E0 = TM.energy(vec)
        assert abs(val - 1.) < eps
        if not transpose:
            vec.itranspose(['vL', 'wL', 'vL*'])
            assert (vec[:, 4, :] - npc.eye_like(vec, 0)).norm() < eps
            v0 = npc.eye_like(vec, 0,
                              labels=['vL',
                                      'vL*']).add_leg(vec.get_leg('wL'), 0, 1,
                                                      'wL')
        else:
            vec.itranspose(['vR*', 'wR', 'vR'])
            assert (vec[:, 0, :] - npc.eye_like(vec, 0)).norm() < eps
            v0 = npc.eye_like(vec, 0,
                              labels=['vR*',
                                      'vR']).add_leg(vec.get_leg('wR'), 4, 1,
                                                     'wR')
        TM_vec = TM.matvec(vec, project=False)
        TM_vec.itranspose(vec.get_leg_labels())
        assert (TM_vec - (vec + E0 * 3 * v0)).norm() < eps
Exemplo n.º 8
0
#         |
#  wL ->--W-->- wR
#         |
#         ^
#         |
#         p

# create physical spin-1/2 operators Sz, S+, S-
Sz = npc.Array.from_ndarray([[0.5, 0.], [0., -0.5]],
                            [p_leg, p_leg.conj()],
                            labels=['p', 'p*'])
Sp = npc.Array.from_ndarray([[0., 1.], [0., 0.]], [p_leg, p_leg.conj()],
                            labels=['p', 'p*'])
Sm = npc.Array.from_ndarray([[0., 0.], [1., 0.]], [p_leg, p_leg.conj()],
                            labels=['p', 'p*'])
Id = npc.eye_like(Sz, labels=Sz.get_leg_labels())  # identity

mpo_leg = npc.LegCharge.from_qflat(chinfo, [[0], [2], [-2], [0], [0]])

W_grid = [[Id,   Sp,   Sm,   Sz,   None          ],
          [None, None, None, None, 0.5 * Jxx * Sm],
          [None, None, None, None, 0.5 * Jxx * Sp],
          [None, None, None, None, Jz * Sz       ],
          [None, None, None, None, Id            ]]  # yapf:disable

W = npc.grid_outer(W_grid, [mpo_leg, mpo_leg.conj()], grid_labels=['wL', 'wR'])
# wL/wR = virtual left/right of the MPO
Ws = [W] * L

print("3) define 'environments' left and right")