Exemple #1
0
def leftorth(A, C=None, tol=1E-13, maxiter=100):
    if C is None:
        C = np.eye(A.shape[1], dtype=A.dtype)
    #print(np.trace(ct.XopL(A))/A.shape[1])
    lam2, rho = tmeigs(A,
                       which="LM",
                       tol=tol,
                       direction="left",
                       v0=np.dot(np.conj(C.T), C),
                       nev=1)
    rho = rho + np.conj(rho.T)
    rho /= np.trace(rho)
    U, S, VH = np.linalg.svd(rho)
    C = ct.leftmult(np.sqrt(S), np.conj(VH))
    _, C = qrmat(C)
    AL, R = qrpos(ct.leftmult(C, A))
    lam = np.linalg.norm(R)
    R /= lam
    numiter = 1
    ldelt = np.abs(np.abs(np.trace(ct.XopL(AL)) / A.shape[1]) - 1)
    while ldelt > tol and numiter < maxiter:
        _, C = tmeigs(A, B=np.conj(AL), v0=R, tol=ldelt / 10, nev=1)
        _, C = qrpos(C)
        C /= np.linalg.norm(C)
        AL, R = qrpos(ct.leftmult(C, A))
        lam = np.linalg.norm(R)
        R = R / lam
        numiter += 1
        ldelt = np.abs(np.abs(np.trace(ct.XopL(AL)) / A.shape[1]) - 1)
    C = R
    return (AL, C, lam)
Exemple #2
0
def compute_eR(A_R, C, A_C):
    """
    Approximate right loss function
    eR = ||A_C - C . A_R||
    """
    eRmid = A_C - ct.leftmult(C, A_R)
    eR = np.linalg.norm(ct.fuse_left(eRmid))
    return eR
Exemple #3
0
def gauge_match_QR(A_C, C):
    QAC, RAC = qrpos(A_C)
    QC, RC = qrpos(C)
    A_L = ct.rightmult(QAC, np.conj(RC.T))
    errL = np.linalg.norm(RAC-RC)
    QAC, LAC = rqpos(A_C)
    QC, LC = rqpos(C)
    A_R = ct.leftmult(QC.T, QAC)
    errR = np.linalg.norm(LAC-LC)
    err = max(errL, errR)
    return (A_L, A_R, err)
Exemple #4
0
def mixed_canonical_old(A, lam=None):
    # """
    # Bring a uniform MPS tensor into mixed canonical form.
    # """
    lam, gam = tm.canonicalized_gamma(A, lam=lam)
    A_L = ct.leftmult(lam, gam)
    A_R = ct.rightmult(gam, lam)
    chi = lam.size
    C = np.zeros(chi, dtype=A.dtype)
    C[:] = lam.real[:]
    C = np.diag(C)
    mpslist = [A_L, C, A_R]
    return mpslist
Exemple #5
0
def vumps_truncate(mpslist, maxchi=None, writer=None, Niter=None):
    """
    Use an SVD to adjust the bond dimension of the MPS.
    """
    A_L, C, A_R = mpslist
    A_C = ct.leftmult(C, A_R)
    th = ct.twositecontract(A_L, A_C)
    gam_L, gam_R, lam, newchi, err = ct.svd(th, maxchi=maxchi)

    A_L = ct.leftmult(lam, gam_L)
    A_R = ct.rightmult(gam_R, lam)
    C = np.zeros((lam.size, lam.size), dtype=C.dtype)
    C += np.diag(lam)
    newmpslist = [A_L, C, A_R]
    if writer is not None:
        vumps_print(writer, "Adjusting bond dimension...")
        vumps_print(writer, "\tNew chi: ", str(newchi))
        vumps_print("\tTruncation error: ", str(err))
        truncarr = np.array([err])
        truncfile = "TruncationError.txt"
        writer.writearray(truncfile, truncarr, Niter, header="TruncationError")
    return (newmpslist, newchi, err)
Exemple #6
0
def apply_HAc(A_C, A_L, A_R, Hlist):
    """
    Compute A'C via eq 11 of vumps paper (131 of tangent space methods).
    """
    H, LH, RH = Hlist
    to_contract_1 = [A_L, np.conj(A_L), A_C, H]
    idxs_1 = [(2, 1, 4), (3, 1, -2), (5, 4, -3), (3, -1, 2, 5)]
    term1 = scon(to_contract_1, idxs_1)

    to_contract_2 = [A_C, A_R, np.conj(A_R), H]
    idxs_2 = [(5, -2, 4), (2, 4, 1), (3, -3, 1), (-1, 3, 5, 2)]
    term2 = scon(to_contract_2, idxs_2)

    term3 = ct.leftmult(LH, A_C)
    term4 = ct.rightmult(A_C, RH.T)
    A_C_prime = term1 + term2 + term3 + term4
    return A_C_prime
Exemple #7
0
def twositeexpect(mpslist, H, real=True, divide_by_norm=False, lvec=None,
        rvec=None):
    """
    The expectation value of the two-site operator H.
    """
    A_L, C, A_R = mpslist
    A_CR = ct.leftmult(C, A_R)
    E = ct.chainwithops([A_L, A_CR], ops=[(H, 0)], lvec=lvec, rvec=rvec)
    #ER = ct.chainwithops([A_CL, A_R], ops=[(H, 0)], lvec=lvec, rvec=rvec)
    if real:
        if np.abs(E.imag) > 1E-14:
            print("Warning: EV had large imaginary part ", str(E.imag))
        E = E.real
    if divide_by_norm:
        norm = compute_norm(mpslist, real=real)
        E /= norm
    return E.real
Exemple #8
0
def expand_tensors(oldlist, newlist, Dchi):
    NL, NR = null_spaces(oldlist)
    #AL, C, AR = newlist
    AL, C, AR = oldlist
    d, chi, _ = AL.shape
    B2 = B2_tensor(oldlist, newlist)
    #U, S, VH = sp.linalg.svd(B2)
    print("B2: ", B2.shape)
    try:
        U, s, V = np.linalg.svd(B2, full_matrices=False, compute_uv=True)
    except:
        print("Divide-and-conquer SVD failed. Trying gesvd...")
        U, s, V = sp.linalg.svd(B2,
                                full_matrices=False,
                                overwrite_a=False,
                                check_finite=True,
                                lapack_driver='gesvd')

    U = U[:, :Dchi]
    Vh = dag(V[:Dchi, :])
    newchi = chi + Dchi

    NLU = ct.rightmult(NL, U)
    newAL = np.zeros((d, newchi, newchi), dtype=oldlist[0].dtype)
    newAL[:, :chi, :chi] = AL[:, :, :]
    newAL[:, chi:, chi:] = NLU[:, :]

    newAL = ct.unfuse_left(newAL, (d, newchi, newchi))

    newC = np.zeros((newchi, newchi), dtype=oldlist[0].dtype)
    newC[:chi, :chi] = C[:, :]

    VhNR = ct.leftmult(Vh, NR)
    newAR = np.zeros((d, newchi, newchi), dtype=oldlist[0].dtype)
    newAR[:, :chi, :chi] = AR[:, :chi, :chi]
    newAR[:, chi:, chi:] = VhNR[:, :, :]
    newmpslist = [newAL, newC, newAR]
    newAC = ct.rightmult(newAL, newC)
    return (newmpslist, newAC)