def test_linear_operator_eigs(self): for tm in self.transfer_matrices: r = rotate_to_hermitian( arnoldi(tm.aslinearoperator(), k=1)[1].reshape(tm.A.shape[1:])) l = rotate_to_hermitian( arnoldi(tm.aslinearoperator().H, k=1)[1].reshape(tm.A.shape[1:])) r, l = r / sign(r[0, 0]), l / sign(l[0, 0]) self.assertTrue(allclose(r, r.conj().T)) self.assertTrue(allclose(l, l.conj().T)) self.assertTrue(all(eigvals(r) > 0)) self.assertTrue(all(eigvals(l) > 0))
def eigs(self, l0=None, r0=None): A = self.A if l0 is not None: l0 = l0.reshape(self.shape[1]) if r0 is not None: r0 = r0.reshape(self.shape[1]) _, r = arnoldi(self.aslinearoperator(), k=1, v0=r0) eta, l = arnoldi(self.aslinearoperator().H, k=1, v0=l0) r, l = (rotate_to_hermitian(r.reshape(A.shape[1:]))/sign(r[0]), rotate_to_hermitian(l.reshape(A.shape[1:]))/sign(l[0])) n = tr(l @ r) q = 1#tr(l@l) return real_if_close(eta), l*sqrt(q)/sqrt(n), r/sqrt(q*n)
def left_fixed_point(self, l0=None, tol=0): d, D = self.d, self.D if l0 is not None: l0 = l0.reshape(D**2) η, l = arnoldi(self.aslinearoperator().H, k=1, v0=l0, tol=tol) l = rotate_to_hermitian(l)/sign(l[0]) l = l.reshape(D, D) return η*np.sqrt(tr(l.conj().T@l)), l/np.sqrt(tr(l.conj().T@l))
def right_fixed_point(self, r0=None, tol=0, rotate=True): d, D = self.d, self.D if r0 is not None: r0 = r0.reshape(D**2) η, r = arnoldi(self.aslinearoperator(), k=1, v0=r0, tol=tol) if rotate: w, r = rotate_to_hermitian(r, ret_phase=True) r = r.reshape(D, D)/sign(r[0]) return η, r
def calc_eigs_arnoldi(mpsL, W, F, site, nStates, nStatesCalc=None, preserveState=False, orthonormalize=False, oneSite=True, edgePreserveState=True): if oneSite: guess = np.reshape(mpsL[0][site], -1) else: guess = np.reshape( einsum('ijk,lkm->iljm', mpsL[state][site], mpsL[state][site + 1]), -1) Hfun, _ = make_ham_func(mpsL[0], W, F, site, oneSite=oneSite) (n1, n2, n3) = mpsL[0][site].shape H = LinearOperator((n1 * n2 * n3, n1 * n2 * n3), matvec=Hfun) if nStatesCalc is None: nStatesCalc = nStates nStates, nStatesCalc = min(nStates, n1 * n2 * n3 - 2), min(nStatesCalc, n1 * n2 * n3 - 2) try: vals, vecs = arnoldi(H, k=nStatesCalc, which='SR', v0=guess, tol=1e-5) except Exception as exc: vals = exc.eigenvalues vecs = exc.eigenvectors inds = np.argsort(vals) E = -vals[inds[:nStates]] vecs = vecs[:, inds[:nStates]] # Orthonormalize (when gap is too small?) - PH, Why? if (nStates > 1) and orthonormalize: vecs = sla.orth(vecs) # At the ends, we do not want to switch states when preserving state is off if ((site == 0) or (site == len(mpsL[0]) - 1)) and edgePreserveState: preserveState = True E, vecs, ovlp = check_overlap(guess, vecs, E, preserveState=preserveState) return E, vecs, ovlp
def l_eigenmatrix(M): """eigenmatrix: solve |--:- |- V M = e V |--:- |- for largest (magnitude) e and V. :param M: tensor as above: shape (K, K, K, K) for some K. right facing indices are 2, 3, left facing 0, 1 """ assert all(x == M.shape[0] for x in M.shape) assert len(M.shape) == 4 K = M.shape[0] M = M.reshape(K**2, K**2) # e_, v_ = neig(M.conj().T) # right eig of reshaped, transposed M # e_max_, v_max_ = e[argmax(abs(e))], v[:, argmax(abs(e))].reshape(K, K) # maxima e, v = arnoldi(M.conj().T, k=1, which='LM') e_max, v_max = squeeze(e), rotate_to_hermitian(v.reshape(K, K)) / sign( v[0]) return e_max, v_max.conj()
def arnoldi1(mps, mpo, envl, envr): """ Calculate the eigenvalues and eigenvectors with the arnoldi algorithm Args: mps : 1d array of np or ctf tensors a list containing the mps tensor for each desired state at the optimization site mpo : 1d array of np or ctf tensors a list containing the mpo tensor for each operator at the optimization site envl : 1d array of np or ctf tensors a list containing the left env tensor for each operator at the optimization site envr : 1d array of np or ctf tensors a list containing the right env tensor for each operator at the optimization site Returns: E : 1d array a 1d array of the energy associated with each state of the system mps : 1d array of np or ctf tensors a list containing the resulting mps tensor for each state from the optimization ovlp : float the overlap between the input guess and output state """ print('ARNOLDI NOT WORKING') import sys sys.exit() mpiprint(6, 'Doing Arnoldi optimization routine') # Compute the number of states nStates = len(mps) (n1, n2, n3) = mps[0].shape # Make the hamiltonian function hop, _ = make_ham_func1(mps, mpo, envl, envr) hop = LinearOperator((n1 * n2 * n3, n1 * n2 * n3), matvec=hop) # Determine initial guess if USE_CTF: guess = to_nparray(ravel(mps[0])) else: guess = ravel(mps[0]) #guess = np.zeros((n1*n2*n3,nStates),dtype=type(mps[0][0,0,0])) #for state in range(nStates): # if USE_CTF: # guess[:,state] = to_nparray(ravel(mps[state])) # else: # guess[:,state] = ravel(mps[state]) # Send to davidson algorithm try: E, vecs = arnoldi(hop, k=nStates, which='SR', v0=guess, tol=ARNOLDI_TOL, maxiter=ARNOLDI_MAX_ITER) except Exception as exc: E = exc.eigenvalues vecs = exc.eigenvectors E = -E # Sort results inds = npargsort(E)[::-1] E = E[inds[:nStates]] vecs = vecs[:, inds[:nStates]] # Convert vecs back to ctf if needed if USE_CTF: vecs = from_nparray(vecs) # convert vecs into original mps shape _mps = mps mps = vec2mps(vecs, mps) # check the overlap ovlp = calc_ovlp(mps, _mps) return E, mps, ovlp