def XopR(A, O=None, X=None, B=None): if B is None: B = np.conj(A) B = rightmult(B, X) if O is not None: B = Bop(O, B) idx = [(2, -2, 1), (2, -1, 1)] return scon([A, B], idx)
def proj(A, B): """ Contract A with B to find <A|B>. """ idxs = [[0, 1], [0, 1]] contract = [A, B] ans = scon(contract, idxs) return ans
def thetaleft(theta, hL): to_contract = (theta, hL) idxs = [(2, 1, -3, -4), (-2, -1, 1, 2)] try: ans = scon(to_contract, idxs) except ValueError: errstr = "Theta shape: " + str(theta.shape) + "\n" errstr += "hL shape: " + str(hL.shape) + "\n" raise ValueError(errstr) return ans
def DMRG_hR1(B, Bdag, hR): d = B.shape[0] I = np.eye(d, dtype=B.dtype) to_contract = (B, Bdag, hR, I) B_idxs = (4, -4, 2) Bdag_idxs = (3, -2, 1) h_idxs = (3, 1, 4, 2) I_idxs = (-1, -3) answer = scon(to_contract, (B_idxs, Bdag_idxs, h_idxs, I_idxs)) return answer
def XopL(A, O=None, X=None, B=None): if B is None: B = np.conj(A) A = leftmult(X, A) if O is not None: B = Bop(O, B) #return np.einsum("jia, jib", A, B) #return np.einsum("ija, ijb", A, B) idx = [(2, 1, -2), (2, 1, -1)] return scon([A, B], idx) #the scon call is much faster
def DMRG_hL1(A, Adag, hL): d = A.shape[0] I = np.eye(d, dtype=A.dtype) to_contract = (A, Adag, hL, I) A_idxs = (4, 3, -3) Adag_idxs = (2, 1, -1) h_idxs = (1, 2, 3, 4) I_idxs = (-2, -4) answer = scon(to_contract, (A_idxs, Adag_idxs, h_idxs, I_idxs)) return answer
def compute_hLgen(A_L1, A_L2, A_L3, A_L4, htilde): """ --A_L1--A_L2-- | |____| | | h | | | | |-A_L3-A_L4- """ to_contract = [A_L1, A_L2, A_L3, A_L4, htilde] idxs = [(2, 4, 1), (3, 1, -2), (5, 4, 7), (6, 7, -1), (5, 6, 2, 3)] h_L = scon(to_contract, idxs) return h_L
def compute_hR(A_R, htilde): """ --A_R--A_R-- |____| | | h | | | | | --A_R*-A_R*- """ A_R_d = np.conj(A_R) to_contract = [A_R, A_R, A_R_d, A_R_d, htilde] idxs = [(2, -2, 1), (3, 1, 4), (5, -1, 7), (6, 7, 4), (5, 6, 2, 3)] h_R = scon(to_contract, idxs) return h_R
def compute_hL(A_L, htilde): """ --A_L--A_L-- | |____| | | h | | | | |-A_L*-A_L*- """ A_L_d = np.conj(A_L) to_contract = [A_L, A_L, A_L_d, A_L_d, htilde] idxs = [(2, 4, 1), (3, 1, -2), (5, 4, 7), (6, 7, -1), (5, 6, 2, 3)] h_L = scon(to_contract, idxs) return h_L
def apply_Hc(C, A_L, A_R, Hlist): """ Compute C' via eq 16 of vumps paper (132 of tangent space methods). """ H, LH, RH = Hlist A_Lstar = np.conj(A_L) A_C = ct.rightmult(A_L, C) to_contract = [A_C, A_Lstar, A_R, np.conj(A_R), H] idxs = [(4, 1, 3), (6, 1, -1), (5, 3, 2), (7, -2, 2), (6, 7, 4, 5)] term1 = scon(to_contract, idxs) term2 = np.dot(LH, C) term3 = np.dot(C, RH.T) C_prime = term1 + term2 + term3 return C_prime
def Hc_dense(A_L, A_R, Hlist): """ Construct Hc as a dense matrix. """ H, LH, RH = Hlist chi = LH.shape[0] I = np.eye(chi, dtype=LH.dtype) to_contract_1 = [A_L, A_R, np.conj(A_L), np.conj(A_R), H] idx_1 = [[2, 1, -4], [4, -3, 6], [3, 1, -2], [5, -1, 6], [3, 5, 2, 4]] term1 = scon(to_contract_1, idx_1) term2 = np.kron(I.T, LH).reshape((chi, chi, chi, chi)) term3 = np.kron(RH.T, I).reshape((chi, chi, chi, chi)) H_C = term1 + term2 + term3 H_C = H_C.transpose((1, 0, 3, 2)) return H_C
def leftmult(lam, gam): if lam is None: return gam ngam = len(gam.shape) nlam = len(lam.shape) if nlam == 1: return lam[:, None] * gam if nlam == 2: if ngam == 2: return np.dot( lam, gam) #lambda is a matrix, note this assumes lam[2] hits gam[2] if ngam == 3: idx = ([-2, 1], [-1, 1, -3]) return scon([lam, gam], idx) #return np.einsum('bi, aic', lam, gam) raise IndexError("Invalid shapes. Gamma: ", gam.shape, "Lambda: ", lam.shape)
def rholoc(A1, A2, B1=None, B2=None): """ -----A1-----A2----- | |(3) |(4) | | | | | | |(1) |(2) | -----B1-----B2------ returned as a (1:2)x(3:4) matrix. Assuming the appropriate Schmidt vectors have been contracted into the As, np.trace(np.dot(op, rholoc.T)) is the expectation value of the two-site operator op coupling A1 to A2. """ if B1 is None: B1 = np.conj(A1) if B2 is None: B2 = np.conj(A2) d = A1.shape[0] to_contract = [A1, A2, B1, B2] idxs = [(-3, 1, 2), (-4, 2, 3), (-1, 1, 4), (-2, 4, 3)] rholoc = scon(to_contract, idxs).reshape((d**2, d**2)) return rholoc
def mpoleftchainop(As, Op=None, X=None): if Op is None: return mpoleftchain(As, X=X) As[0] = mpoleftmult(As[0], X=X) N = len(As) botds = list(range(1, 3 * N, 3)) topds = list(range(2, 3 * N, 3)) chis = [ -1, ] + list(range(3, 3 * N, 3)) + [ -2, ] to_contract = [ Op, ] + As opidxs = [list(topds) + list(botds)] Aidxs = list(zip(botds, topds, chis[:-1], chis[1:])) idxs = opidxs + Aidxs newX = scon(to_contract, idxs) #newX = newX.reshape((newX.shape[-1])) return newX
def outermat(A, B): chi = A.shape[0] contract = [A, B] idxs = [[-2, -1], [-3, -4]] return scon(contract, idxs).reshape((chi**2, chi**2))
def XopLmixed(A, B, X): out = scon([B, A, np.conj(B), X], [[1, 3, -1], [1, 2, 4, -2], [2, 5, -3], [3, 4, 5]]) raise NotImplementedError() return out
def thetaright(theta, hR): to_contract = (theta, hR) idxs = [(-1, -2, 1, 2), (-3, -4, 1, 2)] return scon(to_contract, idxs)
def twositecontracttheta(theta, U): to_contract = (theta, U) idxs = [(1, -2, 3, -4), (-1, 1, -3, 3)] return scon(to_contract, idxs)
def XopRmixed(A, B, X): out = scon([B, A, np.conj(B), X], [[1, -1, 3], [1, 2, -2, 4], [2, -3, 5], [3, 4, 5]]) raise NotImplementedError() return out
def Bop(O, B): return scon([O, B], [(1, -1), (1, -2, -3)])