def two_site_hamiltonian(coupling=1, ferro=True):
    """ returns the two site gate h = -ZZ - gX for ferro=True and h = ZZ - gX otherwise
        the gX term is symmetrised as 1/2 (1*Sx + Sx*1)

        Index convention

          p1*   p2*
          ^     ^
          |     |
        |---------|
        |    h    |
        |---------|
          |     |
          ^     ^
          p1    p2

    """
    h = -npc.outer(Sz, Sz)
    sign = -1. if ferro else 1.
    h = h + sign * coupling * .5 * (npc.outer(Sx, S0) + npc.outer(S0, Sx))
    h.iset_leg_labels(['p1*', 'p1', 'p2*', 'p2'])
    return h
示例#2
0
def gen_disentangler_psi_prod(psiP, psiQ):
    """generate a PurificationMPS as tensorproduct (psi_P x psi_Q).

    psiQ should have the same `sites` as psiP."""
    L = psiP.L
    Bs = []
    for i in range(L):
        BP = psiP.get_B(i)
        BQ = psiQ.get_B(i)
        B2 = npc.outer(BP, BQ.conj())
        B2 = B2.combine_legs([['vL', 'vL*'], ['vR', 'vR*']], qconj=[+1, -1])
        B2.ireplace_labels(['(vL.vL*)', '(vR.vR*)', 'p*'], ['vL', 'vR', 'q'])
        Bs.append(B2)
    Ss = [np.outer(S, S2).flatten() for S, S2 in zip(psiP._S, psiQ._S)]
    return purification_mps.PurificationMPS(psiP.sites, Bs, Ss)
示例#3
0
文件: test_mps.py 项目: iwrache/tenpy
def test_expectation_value_multisite():
    s = spin_half
    psi = mps.MPS.from_singlets(s, 6, [(0, 1), (2, 3), (4, 5)], lonely=[], bc='finite')
    SpSm = npc.outer(s.Sp.replace_labels(['p', 'p*'], ['p0', 'p0*']),
                     s.Sm.replace_labels(['p', 'p*'], ['p1', 'p1*']))
    psi1 = psi.copy()
    ev = psi.expectation_value(SpSm)
    npt.assert_almost_equal(ev, [-0.5, 0., -0.5, 0., -0.5])
    env1 = mps.MPSEnvironment(psi1, psi)
    ev = env1.expectation_value(SpSm)
    npt.assert_almost_equal(ev, [-0.5, 0., -0.5, 0., -0.5])

    psi1.apply_local_op(2, SpSm)  # multi-site operator
    ev = psi1.expectation_value(SpSm)  # normalized!
    npt.assert_almost_equal(ev, [-0.5, 0., 0.0, 0., -0.5])
    env1 = mps.MPSEnvironment(psi1, psi)
    ev = env1.expectation_value(SpSm) / psi1.overlap(psi)  # normalize
    npt.assert_almost_equal(ev, [-0.5, 0., -1., 0., -0.5])
示例#4
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.")
示例#5
0
def test_npc_outer():
    for sort in [True, False]:
        print("sort =", sort)
        a = random_Array((6, 7), chinfo3, sort=sort)
        b = random_Array((5, 5), chinfo3, sort=sort)
        aflat = a.to_ndarray()
        bflat = b.to_ndarray()
        c = npc.outer(a, b)
        c.test_sanity()
        cflat = np.tensordot(aflat, bflat, axes=0)
        npt.assert_equal(c.to_ndarray(), cflat)
        c = npc.tensordot(a, b, axes=0)  # (should as well call npc.outer)
        npt.assert_equal(c.to_ndarray(), cflat)

    print("for trivial charge")
    a = npc.Array.from_func(np.random.random, [lcTr, lcTr.conj()], shape_kw='size')
    aflat = a.to_ndarray()
    b = npc.tensordot(a, a, axes=0)
    bflat = np.tensordot(aflat, aflat, axes=0)
    npt.assert_array_almost_equal_nulp(b.to_ndarray(), bflat, sum(a.shape))
示例#6
0
"""Explicit definition of charges and spin-1/2 operators."""

import tenpy.linalg.np_conserved as npc

# consider spin-1/2 with Sz-conservation
chinfo = npc.ChargeInfo([1])  # just a U(1) charge
# charges for up, down state
p_leg = npc.LegCharge.from_qflat(chinfo, [[1], [-1]])
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()])

Hxy = 0.5 * (npc.outer(Sp, Sm) + npc.outer(Sm, Sp))
Hz = npc.outer(Sz, Sz)
H = Hxy + Hz
# here, H has 4 legs
H.iset_leg_labels(["s1", "t1", "s2", "t2"])
H = H.combine_legs([["s1", "s2"], ["t1", "t2"]], qconj=[+1, -1])
# here, H has 2 legs
print(H.legs[0].to_qflat().flatten())
# prints [-2  0  0  2]
E, U = npc.eigh(H)  # diagonalize blocks individually
print(E)
# [ 0.25 -0.75  0.25  0.25]