예제 #1
0
def gauge_match_SVD(A_C, C, thresh=1E-13):
    """
    Return approximately gauge-matched A_L and A_R from A_C and C
    using an SVD. If 
    """
    Ashape = A_C.shape
    Cdag = np.conj(C.T)

    AC_mat_l = ct.fuse_left(A_C)  #A_C.reshape(d*chi, chi)
    ACl_Cd = np.dot(AC_mat_l, Cdag)
    Ul, Sl, Vld = np.linalg.svd(ACl_Cd, full_matrices=False)
    AL_mat = np.dot(Ul, Vld)
    A_L = ct.unfuse_left(AL_mat, Ashape)

    AC_mat_r = ct.fuse_right(A_C)
    d, chi, chi = Ashape
    AC_mat_r = A_C.reshape(chi, d * chi)
    Cd_ACr = np.dot(Cdag, AC_mat_r)
    Ur, Sr, Vrd = np.linalg.svd(Cd_ACr, full_matrices=False)
    AR_mat = np.dot(Ur, Vrd)
    A_R = ct.unfuse_right(AR_mat, Ashape)

    smallest = min(min(Sl), min(Sr))
    SVD_ok = smallest > thresh
    if not SVD_ok:
        print("Singular values fell beneath threshold.")
    return (A_L, A_R, SVD_ok)
예제 #2
0
def qrpos(A):
    """
    QR decomp. of A, with phase convention such that R has only positive
    elements on the main diagonal. 

    If A is an MPS tensor (d, chiL, chiR), it is reshaped appropriately
    before the throughput begins. In that case, Q will be a tensor
    of the same size, while R will be a chiR x chiR matrix.
    """
    Ashp = A.shape
    if len(Ashp) == 2:
        return qrmat(A)
    elif len(Ashp) != 3:
        print("A had invalid dimensions, ", A.shape)

    A = ct.fuse_left(A)  #d*chiL, chiR
    Q, R = qrmat(A, mode="economic")
    Q = ct.unfuse_left(Q, Ashp)
    return (Q, R)
예제 #3
0
def gauge_match_polar(A_C, C):
    """
    Return approximately gauge-matched A_L and A_R from A_C and C
    using a polar decomposition.
    """
    Ashape = A_C.shape
    AC_mat_l = ct.fuse_left(A_C)
    AC_mat_r = ct.fuse_right(A_C)

    UAc_l, PAc_l = sp.linalg.polar(AC_mat_l, side="right")
    UAc_r, PAc_r = sp.linalg.polar(AC_mat_r, side="left")
    UC_l, PC_l = sp.linalg.polar(C, side="right")
    UC_r, PC_r = sp.linalg.polar(C, side="left")

    A_L = np.dot(UAc_l, np.conj(UC_l.T))
    A_L = ct.unfuse_left(A_L, Ashape)
    A_R = np.dot(np.conj(UC_r.T), UAc_r)
    A_R = ct.unfuse_right(A_R, Ashape)
    return (A_L, A_R)
예제 #4
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)