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)
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
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)
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
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)
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
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
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)