def Kressner(A, b, factor, r, regParam): [U_, S_, VT_] = ctf.svd(A) S_ = 1 / (S_ + regParam * ctf.ones(S_.shape)) factor.set_zero() factor.i("r") << VT_.i("kr") * S_.i("k") * U_.i("tk") * b.i("t") return factor
def svd(self, a): if not isinstance(a, self.tensor): raise TypeError('the input should be {}'.format(self.tensor.__qualname__)) if a.ndim != 2: raise TypeError('the input tensor should be a matrix') u, s, vh = ctf.svd(a.unwrap()) return self.tensor(u), self.tensor(ctf.real(s)), self.tensor(vh)
def run_bench(num_iter, s, k): wrld = ctf.comm() M = ctf.random.random((s,s)) X = ctf.random.random((k,s)) [U,S,VT] = ctf.svd(M) S = np.arange(0,s)+1 M = ctf.dot(U*S,U.T()) te = ctf.timer_epoch("BENCHMARK: SPD SOLVE") te.begin() times = [] for i in range(num_iter): t0 = time.time() X = ctf.solve_spd(M,X) times.append(time.time()-t0) te.end() if ctf.comm().rank() == 0: print("ctf.solve_spd average time:",np.sum(times)/num_iter,"sec") print("ctf.solve_spd iteration timings:",times) te = ctf.timer_epoch("BENCHMARK: Manual Cholesky+TRSM SPD SOLVE") te.begin() times = [] for i in range(num_iter): t0 = time.time() L = ctf.cholesky(M) X = ctf.solve_tri(M,X,from_left=False) times.append(time.time()-t0) te.end() if ctf.comm().rank() == 0: print("ctf.cholesky+solve_tri average time:",np.sum(times)/num_iter,"sec") print("ctf.cholesky+solve_tri iteration timings:",times)
def CTFinverse(A): """Gets the pseudoinverse of matrix A""" U, sigma, VT = ctf.svd(A) sigmaInv = 1 / sigma Ainv = ctf.zeros((A.to_nparray().shape[1], U.to_nparray().shape[0])) Ainv.i("ad") << VT.i("ba") * sigmaInv.i("b") * U.i("db") return Ainv
def LS_SVD(Z,factor,r,Tbar,regParam,idx): [U_,S_,VT_] = ctf.svd(Z) S_ = S_/(S_*S_ + regParam*ctf.ones(S_.shape)) factor.set_zero() factor.i("r") << VT_.i("kr")*S_.i("k")*U_.i("tk")*Tbar.i("t") return factor
def test_svd(self): m = 9 n = 5 k = 5 for dt in [numpy.float32, numpy.float64]: A = ctf.random.random((m, n)) A = ctf.astensor(A, dtype=dt) [U, S, VT] = ctf.svd(A, k) [U1, S1, VT1] = la.svd(ctf.to_nparray(A), full_matrices=False) self.assertTrue(allclose(A, ctf.dot(U, ctf.dot(ctf.diag(S), VT)))) self.assertTrue(allclose(ctf.eye(k), ctf.dot(U.T(), U))) self.assertTrue(allclose(ctf.eye(k), ctf.dot(VT, VT.T()))) A = ctf.tensor((m, n), dtype=numpy.complex64) rA = ctf.tensor((m, n), dtype=numpy.float32) rA.fill_random() A.real(rA) iA = ctf.tensor((m, n), dtype=numpy.float32) iA.fill_random() A.imag(iA) [U, S, VT] = ctf.svd(A, k) self.assertTrue(allclose(A, ctf.dot(U, ctf.dot(ctf.diag(S), VT)))) self.assertTrue( allclose(ctf.eye(k, dtype=numpy.complex64), ctf.dot(ctf.conj(U.T()), U))) self.assertTrue( allclose(ctf.eye(k, dtype=numpy.complex64), ctf.dot(VT, ctf.conj(VT.T())))) A = ctf.tensor((m, n), dtype=numpy.complex128) rA = ctf.tensor((m, n), dtype=numpy.float64) rA.fill_random() A.real(rA) iA = ctf.tensor((m, n), dtype=numpy.float64) iA.fill_random() A.imag(iA) [U, S, VT] = ctf.svd(A, k) self.assertTrue(allclose(A, ctf.dot(U, ctf.dot(ctf.diag(S), VT)))) self.assertTrue( allclose(ctf.eye(k, dtype=numpy.complex128), ctf.dot(ctf.conj(U.T()), U))) self.assertTrue( allclose(ctf.eye(k, dtype=numpy.complex128), ctf.dot(VT, ctf.conj(VT.T()))))
def Kressner(A, b, factor, r, regParam): # t = time.time() [U_, S_, VT_] = ctf.svd(A) S_ = 1 / (S_ + regParam * ctf.ones(S_.shape)) factor.set_zero() factor.i("r") << VT_.i("kr") * S_.i("k") * U_.i("tk") * b.i("t") #assert(factor.sp==1) TODO!! # if ctf.comm().rank() == 0: # print("SVD cost %f seconds" %(np.round_(time.time()- t,4))) return factor
def test_svd(self): m = 9 n = 5 k = 5 for dt in [numpy.float32, numpy.float64, numpy.complex64, numpy.complex128]: A = ctf.random.random((m,n)) A = ctf.astensor(A,dtype=dt) [U,S,VT]=ctf.svd(A,k) [U1,S1,VT1]=la.svd(ctf.to_nparray(A),full_matrices=False) self.assertTrue(allclose(A, ctf.dot(U,ctf.dot(ctf.diag(S),VT)))) self.assertTrue(allclose(ctf.eye(k), ctf.dot(U.T(), U))) self.assertTrue(allclose(ctf.eye(k), ctf.dot(VT, VT.T())))
def updateU(T,U,V,W,regParam,omega,I,J,K,r): '''Update U matrix by using the formula''' M1 = ctf.tensor((J,K,r)) M1.i("jku") << V.i("ju")*W.i("ku") [U_,S_,V_] = ctf.svd(M1.reshape((J*K,r))) #S_ = 1./S_ S_ = S_/(S_*S_ + regParam*ctf.ones(r)) U.set_zero() U.i("iu") << V_.i("vu")*S_.i("v")*U_.reshape((J,K,r)).i("jkv")*T.i("ijk") U *= normalize(U,r) return U
def test_svd(self): m = 9 n = 5 k = 5 for dt in [numpy.float32, numpy.float64]: A = ctf.random.random((m,n)) A = ctf.astensor(A,dtype=dt) [U,S,VT]=ctf.svd(A,k) [U1,S1,VT1]=la.svd(ctf.to_nparray(A),full_matrices=False) self.assertTrue(allclose(A, ctf.dot(U,ctf.dot(ctf.diag(S),VT)))) self.assertTrue(allclose(ctf.eye(k), ctf.dot(U.T(), U))) self.assertTrue(allclose(ctf.eye(k), ctf.dot(VT, VT.T()))) A = ctf.tensor((m,n),dtype=numpy.complex64) rA = ctf.tensor((m,n),dtype=numpy.float32) rA.fill_random() A.real(rA) iA = ctf.tensor((m,n),dtype=numpy.float32) iA.fill_random() A.imag(iA) [U,S,VT]=ctf.svd(A,k) self.assertTrue(allclose(A, ctf.dot(U,ctf.dot(ctf.diag(S),VT)))) self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex64), ctf.dot(ctf.conj(U.T()), U))) self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex64), ctf.dot(VT, ctf.conj(VT.T())))) A = ctf.tensor((m,n),dtype=numpy.complex128) rA = ctf.tensor((m,n),dtype=numpy.float64) rA.fill_random() A.real(rA) iA = ctf.tensor((m,n),dtype=numpy.float64) iA.fill_random() A.imag(iA) [U,S,VT]=ctf.svd(A,k) self.assertTrue(allclose(A, ctf.dot(U,ctf.dot(ctf.diag(S),VT)))) self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex128), ctf.dot(ctf.conj(U.T()), U))) self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex128), ctf.dot(VT, ctf.conj(VT.T()))))
def updateW(T,U,V,W,regParam,omega,I,J,K,r): '''Update V matrix by using the formula''' M3 = ctf.tensor((I,J,r)) M3.i("iju") << U.i("iu")*V.i("ju") [U_,S_,V_] = ctf.svd(M3.reshape((I*J,r))) #S_ = 1./S_ S_ = S_/(S_*S_ + regParam*ctf.ones(r)) W.set_zero() W.i("ku") << V_.i("vu")*S_.i("v")*U_.reshape((I,J,r)).i("ijv")*T.i("ijk") W *= normalize(W,r) return W
def updateV(T,U,V,W,regParam,omega,I,J,K,r): '''Update V matrix by using the formula''' M2 = ctf.tensor((I,K,r)) M2.i("iku") << U.i("iu")*W.i("ku") [U_,S_,V_] = ctf.svd(M2.reshape((I*K,r))) #S_ = 1./S_ S_ = S_/(S_*S_ + regParam*ctf.ones(r)) V.set_zero() V.i("ju") << V_.i("vu")*S_.i("v")*U_.reshape((I,K,r)).i("ikv")*T.i("ijk") #normalize(V,r) V *= normalize(V,r) return V
def rsvd(a, rank, niter=2, oversamp=5): m, n = a.shape r = min(rank + oversamp, m, n) # find subspace q = ctf.random.random((n, r)) * 2 - 1. for i in range(niter): q = a.transpose() @ (a @ q) q, _ = ctf.qr(q) q = a @ q q, _ = ctf.qr(q) # svd a_sub = q.transpose() @ a u_sub, s, vh = ctf.svd(a_sub) u = q @ u_sub if rank < r: u, s, vh = u[:, :rank], s[:rank], vh[:rank, :] return u, s, vh
def test_svd_rand(self): m = 19 n = 15 k = 13 for dt in [numpy.float32, numpy.float64, numpy.complex64, numpy.complex128]: A = ctf.random.random((m,n)) A = ctf.astensor(A,dtype=dt) [U,S,VT]=ctf.svd_rand(A,k,5,1) self.assertTrue(allclose(ctf.eye(k),ctf.dot(U.T(),U))) self.assertTrue(allclose(ctf.eye(k),ctf.dot(VT,VT.T()))) [U2,S2,VT2]=ctf.svd(A,k) rs1 = ctf.vecnorm(A - ctf.dot(U*S,VT)) rs2 = ctf.vecnorm(A - ctf.dot(U2*S2,VT2)) rA = ctf.vecnorm(A) self.assertTrue(rs1 < rA) self.assertTrue(rs2 < rs1) self.assertTrue(numpy.abs(rs1 - rs2)<3.e-1)
def main(): t0 = time.time() ######## Inputs ############################## # SEP Model N = 50 alpha = 0.35 # In at left beta = 2. / 3. # Exit at right s = -1. # Exponential weighting gamma = 0. # Exit at left delta = 0. # In at right p = 1. # Jump right q = 0. # Jump Left # Optimization tol = 1e-5 maxIter = 0 maxBondDim = 10 useCTF = True ############################################## # Create MPS ################################# # PH - Make Isometries, Center Site mpiprint('Generating MPS') M = [] for i in range(int(N / 2)): tmp = np.random.rand(2, min(2**(i),maxBondDim), min(2**(i+1),maxBondDim))\ +0.j M.append(ctf.from_nparray(tmp)) for i in range(int(N / 2))[::-1]: tmp = np.random.rand(2, min(2**(i+1),maxBondDim), min(2**i,maxBondDim))\ +0.j M.append(ctf.from_nparray(tmp)) ############################################## # Create MPO ################################# mpiprint('Generating MPO') # Simple Operators Sp = np.array([[0., 1.], [0., 0.]]) Sm = np.array([[0., 0.], [1., 0.]]) n = np.array([[0., 0.], [0., 1.]]) v = np.array([[1., 0.], [0., 0.]]) I = np.array([[1., 0.], [0., 1.]]) z = np.array([[0., 0.], [0., 0.]]) # List to hold MPOs W = [] # First Site site_0 = ctf.astensor( [[alpha * (np.exp(-s) * Sm - v), np.exp(-s) * Sp, -n, I]]) W.append(site_0) # Central Sites for i in range(N - 2): site_i = ctf.astensor([[I, z, z, z], [Sm, z, z, z], [v, z, z, z], [z, np.exp(-s) * Sp, -n, I]]) W.append(site_i) # Last Site site_N = ctf.astensor([[I], [Sm], [v], [beta * (np.exp(-s) * Sp - n)]]) W.append(site_N) ############################################## # Canonicalize MPS ########################### for i in range(int(N) - 1, 0, -1): M_reshape = ctf.transpose(M[i], axes=[1, 0, 2]) (n1, n2, n3) = M_reshape.shape M_reshape = M_reshape.reshape(n1, n2 * n3) (U, S, V) = ctf.svd(M_reshape) M_reshape = V.reshape(n1, n2, n3) M[i] = ctf.transpose(M_reshape, axes=[1, 0, 2]) M[i - 1] = ctf.einsum('klj,ji,i->kli', M[i - 1], U, S) ############################################## # Canonicalize MPS ########################### def pick_eigs(w, v, nroots, x0): idx = np.argsort(np.real(w)) w = w[idx] v = v[:, idx] return w, v, idx ############################################## # Create Environment ######################### mpiprint('Generating Environment') # Allocate empty environment F = [] tmp = np.array([[[1.]]]) + 0.j F.append(ctf.from_nparray(tmp)) for i in range(int(N / 2)): tmp = np.zeros((min(2**(i + 1), maxBondDim), 4, min(2**(i + 1), maxBondDim))) + 0.j F.append(ctf.from_nparray(tmp)) for i in range(int(N / 2) - 1, 0, -1): tmp = np.zeros( (min(2**(i), maxBondDim), 4, min(2**i, maxBondDim))) + 0.j F.append(ctf.from_nparray(tmp)) tmp = np.array([[[1.]]]) + 0.j F.append(ctf.from_nparray(tmp)) # Calculate initial environment for i in range(int(N) - 1, 0, -1): tmp = ctf.einsum('eaf,cdf->eacd', M[i], F[i + 1]) tmp = ctf.einsum('ydbe,eacd->ybac', W[i], tmp) F[i] = ctf.einsum('bxc,ybac->xya', ctf.conj(M[i]), tmp) ############################################## # Optimization Sweeps ######################## converged = False iterCnt = 0 E_prev = 0 while not converged: # Right Sweep ---------------------------- tr = time.time() mpiprint('Start Right Sweep {}'.format(iterCnt)) for i in range(N - 1): (n1, n2, n3) = M[i].shape # Make Hx Function def Hfun(x): x_reshape = ctf.array(x) x_reshape = ctf.reshape(x_reshape, (n1, n2, n3)) tmp = ctf.einsum('ijk,lmk->ijlm', F[i + 1], x_reshape) tmp = ctf.einsum('njol,ijlm->noim', W[i], tmp) res = ctf.einsum('pnm,noim->opi', F[i], tmp) return -ctf.reshape(res, -1).to_nparray() def precond(dx, e, x0): return dx # Set up initial guess guess = ctf.reshape(M[i], -1).to_nparray() # Run eigenproblem u, v = eig(Hfun, guess, precond, pick=pick_eigs) E = -u v = ctf.array(v) M[i] = ctf.reshape(v, (n1, n2, n3)) # Print Results mpiprint('\tEnergy at site {} = {}'.format(i, E)) # Right Normalize M_reshape = ctf.reshape(M[i], (n1 * n2, n3)) (U, S, V) = ctf.svd(M_reshape) M[i] = ctf.reshape(U, (n1, n2, n3)) M[i + 1] = ctf.einsum('i,ij,kjl->kil', S, V, M[i + 1]) # Update F tmp = ctf.einsum('jlp,ijk->lpik', F[i], ctf.conj(M[i])) tmp = ctf.einsum('lmin,lpik->mpnk', W[i], tmp) F[i + 1] = ctf.einsum('npq,mpnk->kmq', M[i], tmp) mpiprint('Complete Right Sweep {}, {} sec'.format( iterCnt, time.time() - tr)) # Left Sweep ------------------------------ tl = time.time() mpiprint('Start Left Sweep {}'.format(iterCnt)) for i in range(N - 1, 0, -1): (n1, n2, n3) = M[i].shape # Make Hx Function def Hfun(x): x_reshape = ctf.array(x) x_reshape = ctf.reshape(x_reshape, (n1, n2, n3)) tmp = ctf.einsum('ijk,lmk->ijlm', F[i + 1], x_reshape) tmp = ctf.einsum('njol,ijlm->noim', W[i], tmp) res = ctf.einsum('pnm,noim->opi', F[i], tmp) return -ctf.reshape(res, -1).to_nparray() def precond(dx, e, x0): return dx # Set up initial guess guess = ctf.reshape(M[i], -1).to_nparray() # Run eigenproblem u, v = eig(Hfun, guess, precond, pick=pick_eigs) E = -u v = ctf.array(v) M[i] = ctf.reshape(v, (n1, n2, n3)) # Print Results mpiprint('\tEnergy at site {}= {}'.format(i, E)) # Right Normalize M_reshape = ctf.transpose(M[i], (1, 0, 2)) M_reshape = ctf.reshape(M_reshape, (n2, n1 * n3)) (U, S, V) = ctf.svd(M_reshape) M_reshape = ctf.reshape(V, (n2, n1, n3)) M[i] = ctf.transpose(M_reshape, (1, 0, 2)) M[i - 1] = ctf.einsum('klj,ji,i->kli', M[i - 1], U, S) # Update F tmp = ctf.einsum('eaf,cdf->eacd', M[i], F[i + 1]) tmp = ctf.einsum('ydbe,eacd->ybac', W[i], tmp) F[i] = ctf.einsum('bxc,ybac->xya', ctf.conj(M[i]), tmp) mpiprint('Left Sweep {}, {} sec'.format(iterCnt, time.time() - tl)) # Convergence Test ----------------------- if np.abs(E - E_prev) < tol: mpiprint('#' * 75 + '\nConverged at E = {}'.format(E) + '\n' + '#' * 75) converged = True elif iterCnt > maxIter: mpiprint('Convergence not acheived') converged = True else: iterCnt += 1 E_prev = E mpiprint('Total Time = {}'.format(time.time() - t0))
def inv(matrix): U, s, V = ctf.svd(matrix) return ctf.dot(ctf.transpose(V), ctf.dot(ctf.diag(s**-1), ctf.transpose(U)))
def svd(A, r=None): return ctf.svd(A, r)
#!/usr/bin/env python import ctf import sys from ctf import random A = ctf.random.random((32,32)) [U,S,VT]=ctf.svd(A) err = A-ctf.dot(U,ctf.dot(ctf.diag(S),VT)) success=True err_nrm = err.norm2() if err_nrm > 1.E-6: success=False if ctf.comm().rank() == 0: if success: print("success, norm is ", err_nrm) else: print("failure, norm is ", err_nrm) ctf.MPI_Stop() sys.exit(not success)
# Central Sites for i in range(N - 2): site_i = ctf.astensor([[I, z, z, z], [Sm, z, z, z], [v, z, z, z], [z, np.exp(-s) * Sp, -n, I]]) W.append(site_i) # Last Site site_N = ctf.astensor([[I], [Sm], [v], [beta * (np.exp(-s) * Sp - n)]]) W.append(site_N) ############################################## # Canonicalize MPS ########################### for i in range(int(N) - 1, 0, -1): M_reshape = ctf.transpose(M[i], axes=[1, 0, 2]) (n1, n2, n3) = M_reshape.shape M_reshape = M_reshape.reshape(n1, n2 * n3) (U, S, V) = ctf.svd(M_reshape) M_reshape = V.reshape(n1, n2, n3) M[i] = ctf.transpose(M_reshape, axes=[1, 0, 2]) M[i - 1] = ctf.einsum('klj,ji,i->kli', M[i - 1], U, S) ############################################## # Create Environment ######################### print('Generating Environment') # Allocate empty environment F = [] tmp = np.array([[[1.]]]) + 0.j F.append(ctf.from_nparray(tmp)) for i in range(int(N / 2)): tmp = np.zeros( (min(2**(i + 1), maxBondDim), 4, min(2**(i + 1), maxBondDim))) + 0.j F.append(ctf.from_nparray(tmp))
#!/usr/bin/env python import ctf from ctf import random A = ctf.random.random((32,32)) [U,S,VT]=ctf.svd(A) err = A-ctf.dot(U,ctf.dot(ctf.diag(S),VT)) success=True err_nrm = err.norm2() if err_nrm > 1.E-6: success=False if ctf.comm().rank() == 0: if success: print("success, norm is ", err_nrm) else: print("failure, norm is ", err_nrm) ctf.MPI_Stop()