def test_qr(self): m = 8 n = 4 for dt in [numpy.float32, numpy.float64]: A = ctf.random.random((m,n)) A = ctf.astensor(A,dtype=dt) [Q,R]=ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q,R))) self.assertTrue(allclose(ctf.eye(n), ctf.dot(Q.T(), Q))) 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) [Q,R]=ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q,R))) self.assertTrue(allclose(ctf.eye(n,dtype=numpy.complex64), ctf.dot(ctf.conj(Q.T()), Q))) 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) [Q,R]=ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q,R))) self.assertTrue(allclose(ctf.eye(n,dtype=numpy.complex128), ctf.dot(ctf.conj(Q.T()), Q)))
def test_qr(self): m = 8 n = 4 for dt in [numpy.float32, numpy.float64, numpy.complex64, numpy.complex128]: A = ctf.random.random((m,n)) A = ctf.astensor(A,dtype=dt) [Q,R]=ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q,R))) self.assertTrue(allclose(ctf.eye(n), ctf.dot(Q.T(), Q))) 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) [Q,R]=ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q,R))) self.assertTrue(allclose(ctf.eye(n,dtype=numpy.complex64), ctf.dot(ctf.conj(Q.T()), Q))) 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) [Q,R]=ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q,R))) self.assertTrue(allclose(ctf.eye(n,dtype=numpy.complex128), ctf.dot(ctf.conj(Q.T()), Q)))
def test_conj(self): a0 = ctf.zeros((2,3)) self.assertTrue(ctf.conj(a0).dtype == numpy.double) self.assertTrue(a0.conj().dtype == numpy.double) a0 = ctf.zeros((2,3), dtype=numpy.complex) self.assertTrue(ctf.conj(a0).dtype == numpy.complex128) self.assertTrue(a0.conj().dtype == numpy.complex128) a0[:] = 1j a0 = a0.conj() self.assertTrue(ctf.all(a0 == -1j))
def test_qr(self): for (m, n) in [(8, 4), (4, 7), (3, 3)]: for dt in [np.float32, np.float64, np.complex64, np.complex128]: A = ctf.random.random((m, n)) A = ctf.astensor(A, dtype=dt) [Q, R] = ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q, R))) if (m >= n): self.assertTrue(allclose(ctf.eye(n), ctf.dot(Q.T(), Q))) else: self.assertTrue(allclose(ctf.eye(m), ctf.dot(Q, Q.T()))) A = ctf.tensor((m, n), dtype=np.complex64) rA = ctf.tensor((m, n), dtype=np.float32) rA.fill_random() A.real(rA) iA = ctf.tensor((m, n), dtype=np.float32) iA.fill_random() A.imag(iA) [Q, R] = ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q, R))) if (m >= n): self.assertTrue( allclose(ctf.eye(n, dtype=np.complex64), ctf.dot(ctf.conj(Q.T()), Q))) else: self.assertTrue( allclose(ctf.eye(m, dtype=np.complex64), ctf.dot(Q, ctf.conj(Q.T())))) A = ctf.tensor((m, n), dtype=np.complex128) rA = ctf.tensor((m, n), dtype=np.float64) rA.fill_random() A.real(rA) iA = ctf.tensor((m, n), dtype=np.float64) iA.fill_random() A.imag(iA) [Q, R] = ctf.qr(A) self.assertTrue(allclose(A, ctf.dot(Q, R))) if (m >= n): self.assertTrue( allclose(ctf.eye(n, dtype=np.complex128), ctf.dot(ctf.conj(Q.T()), Q))) else: self.assertTrue( allclose(ctf.eye(m, dtype=np.complex128), ctf.dot(Q, ctf.conj(Q.T()))))
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 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()))))
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 ---------------------------- print('Right Sweep {}'.format(iterCnt)) for i in range(N - 1): H = ctf.einsum('jlp,lmin,kmq->ijknpq', F[i], W[i], F[i + 1]) (n1, n2, n3, n4, n5, n6) = H.shape H = ctf.reshape(H, (n1 * n2 * n3, n4 * n5 * n6)) u, v = np.linalg.eig(ctf.to_nparray(H)) # Select max eigenvalue
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))
tmp = np.array([[[1.]]]) F.append(ctf.from_nparray(tmp)) print(F[0]) for i in range(int(N/2)): tmp = np.zeros((min(2**(i+1),maxBondDim),4,min(2**(i+1),maxBondDim))) 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))) F.append(ctf.from_nparray(tmp)) tmp = np.array([[[1.]]]) F.append(ctf.from_nparray(tmp)) # Calculate initial environment for i in range(int(N)-1,0,-1): tmp = np.einsum('eaf,cdf->eacd',M[i],F[i+1]) tmp = np.einsum('ydbe,eacd->ybac',W[i],tmp) F[i] = np.einsum('bxc,ybac->xya',ctf.conj(M[i]),tmp) ############################################## # Optimization Sweeps ######################## """ # Optimization Sweeps ######################## converged = False iterCnt = 0 E_prev = 0 while not converged: # Right Sweep ---------------------------- print('Right Sweep {}'.format(iterCnt)) for i in range(N-1):