def test_project(self): def random_tanget_space_point(X): coresX = tt.tensor.to_list(X) point = 0 * tt.ones(X.n) for dim in range(X.d): curr = deepcopy(coresX) curr[dim] = np.random.rand(curr[dim].shape[0], curr[dim].shape[1], curr[dim].shape[2]) point += tt.tensor.from_list(curr) return point for debug_mode in [False, True]: for use_jit in [False, True]: X = tt.rand([4, 4, 4], 3, [1, 4, 4, 1]) Z = random_tanget_space_point(X) PZ = riemannian.project(X, Z, use_jit=use_jit, debug=debug_mode) np.testing.assert_array_almost_equal(Z.full(), PZ.full()) X = tt.rand([2, 3, 4], 3, [1, 5, 4, 1]) Z = random_tanget_space_point(X) PZ = riemannian.project(X, Z, use_jit=use_jit, debug=debug_mode) np.testing.assert_array_almost_equal(Z.full(), PZ.full())
def gen_zero_energy_guess(H, rank): """ Generate psi such that <psi|H|psi> = 0 Parameters: ----------- H: tt.matrix hamiltonian in the TT-matrix format rank: int Rank of the guess """ v = 1.0 while v > 1e-12: # Create two random TT vectors and normalize them psi1 = tt.rand(H.n, r=rank) psi2 = tt.rand(H.n, r=1) psi1 = psi1 * (1.0 / psi1.norm()) psi2 = psi2 * (1.0 / psi2.norm()) # Calculate coefficients of the quadratic equation h22 = tt.dot(tt.matvec(H, psi2), psi2) h21 = tt.dot(tt.matvec(H, psi2), psi1) h11 = tt.dot(tt.matvec(H, psi1), psi1) # find vectors such that <psi|H|psi> = 0 rs = np.roots([h22, 2 * h21, h11]) v = np.linalg.norm(np.imag(rs)) psi = psi1 + rs[0] * psi2 psi = psi * (1.0 / psi.norm()) return psi
def test_project_sum_equal_ranks(self): for debug_mode in [False, True]: for use_jit in [False, True]: X = tt.rand([4, 4, 4], 3, [1, 4, 4, 1]) Z = [0] * 7 for idx in range(7): Z[idx] = tt.rand([4, 4, 4], 3, [1, 2, 3, 1]) project_sum = riemannian.project(X, Z, use_jit=use_jit, debug=debug_mode) sum_project = X * 0 for idx in range(len(Z)): sum_project += riemannian.project(X, Z[idx], use_jit=use_jit, debug=debug_mode) np.testing.assert_array_almost_equal(sum_project.full(), project_sum.full())
def test_gradient_wrt_core(self): w = tt.rand([2, 2, 2], 3, [1, 2, 2, 1]) x_1 = all_subsets.subset_tensor([3, 4, 5]) x_2 = all_subsets.subset_tensor([-1, 12, 5]) X = np.array([[3, 4, 5], [-1, 12, 5]]) eps = 1e-8 def loss(core): new_w = w.copy() new_w.core = copy.copy(core) res = (tt.dot(new_w, x_1))**2 # Quadratic. res += tt.dot(new_w, x_2) # Linear. return res # Derivatives of the quadratic and linear functions in the loss. dfdz = [2 * tt.dot(w, x_1), 1] core = w.core value = loss(core) numerical_grad = np.zeros(len(core)) for i in range(len(core)): new_core = copy.copy(core) # print(new_core) new_core[i] += eps numerical_grad[i] = (loss(new_core) - value) / eps w_cores = tt.tensor.to_list(w) gradient = all_subsets.gradient_wrt_cores(w_cores, X, dfdz) np.testing.assert_array_almost_equal(numerical_grad, gradient, decimal=3)
def gen_projected_gaussian_guess(H, r, eps=1e-10): """ Generate full N(0,1) vector and then project it to a random unitary TT of given rank Parameters: ----------- H: tt.matrix Matrix used to infer dimension of a guess vector r: int TT rank of the guess """ # generate tensor with haar distributed cores x = tt.rand(H.n, r=r) x = x.round(eps) x_cores = gen_haar_cores_like(x, left_to_right=True) x = x.from_list(x_cores) # project full dimensional gaussian vector to x dimensions = x.n Z = np.random.randn(*(dimensions)) Z = tt.tensor(Z) PZ = tt_project(x, Z) PZ = PZ.round(eps, rmax=r) return PZ * (1.0 / PZ.norm())
def tt_from_factors(u0, u1, u2): F = tt.rand([np.size(u0), np.size(u1), np.size(u2)], 3, [1, 1, 1, 1]) F_list = F.to_list(F) F_list[0][0, :, 0] = u0 F_list[1][0, :, 0] = u1 F_list[2][0, :, 0] = u2 F = F.from_list(F_list) return F
def test_base(self): def sf(k): return np.array([0.1] * k) n = np.array([5, 6, 7, 8, 9]) r = 4 Z = tt.rand(n, r=r, samplefunc=sf) Y = teneva.rand(n, r, sf) self.assertTrue(_err(Z, Y) < self.e)
def test_project_all_subsets(self): reg = 0.7 for debug_mode in [False, True]: w = tt.rand([2, 2, 2, 2], 4, [1, 2, 3, 2, 1]) X = np.random.randn(10, 4) exact_answ = reg * w.full() for obj_idx in range(10): obj = all_subsets.subset_tensor(X[obj_idx, :]) exact_answ += riemannian.project(w, obj).full() res = all_subsets.project_all_subsets(w, X, reg=reg, debug=debug_mode) np.testing.assert_array_almost_equal(res.full(), exact_answ)
def load_tt(filename, L, N): """ Load the solution from a file """ F = np.load(filename) f = list() for i in range(L): f.append(tt.rand([N, N, N], 3, F[:4, i])) f[i].core = F[4:f[i].core.size + 4, i] return f
def load_restart(self): """ Load the solution from a file """ F = np.load(self.config.init_filename) f = list() for i in range(self.mesh.nc): f.append(tt.rand([self.v.nvx, self.v.nvy, self.v.nvz], 3, F[:4, i])) f[i].core = F[4:f[i].core.size + 4, i] return f
def div_tt(a, b): a_list = a.to_list(a) b_list = a.to_list(b) c = tt.rand(a.n, 3, a.r) c_list = c.to_list(c) c_list[0] = a_list[0] / b_list[0] c_list[1] = a_list[1] / b_list[1] c_list[2] = a_list[2] / b_list[2] c = c.from_list(c_list) return c
def gen_haar_rmps_guess(H, r): """ Generates a random MPS as described in "Typicality in random matrix product states" by Garnerone et al. Parameters: ----------- H: tt.matrix Matrix used to infer dimension of a guess vector r: int TT rank of the guess """ # generate tensor with haar distributed cores x = tt.rand(H.n, r=r) x = x.round(0) x_cores = gen_haar_cores_like(x, left_to_right=True) x = x.from_list(x_cores) return x
def gen_implicit_gaussian_guess(H, r): """ Generates an implicit projection of a normal vector in tangent space to a random TT (with cores drawn from normal distribution) Parameters: ----------- H: tt.matrix Matrix used to infer dimension of a guess vector r: int TT rank of the guess """ dimensions = H.n X = tt.rand(dimensions, r=r).round(1e-14) psi = project_gaussian_to_x_implicit(X) psi = psi.round(0, rmax=r) psi = 1. / psi.norm() * psi return psi
def gen_implicit_guess_from_distrib(H, r, sample_function=half_normal_distribution, normalize=True): """ Generates an implicit projection of a vector in tangent space of a random TT (with cores drawn from normal distribution). The vector is generated by the sample_function Parameters: ----------- H: tt.matrix Matrix used to infer dimension of a guess vector r: int TT rank of the guess """ dimensions = H.n X = tt.rand(dimensions, r=r).round(1e-14) psi = project_distribution_to_x_implicit(X, sample_function) psi.round(0, rmax=r) if normalize: psi = 1. / psi.norm() * psi return psi
#Generate the initial condition psi = None pp1 = np.exp(-0.5*((x-2)**2)) pp1 = tt.tensor(pp1,1e-12) for i in xrange(f): psi = tt.kron(psi,pp1) pol = None for i in xrange(f): pol = pol + xx[i]*xx[i] pol = pol.round(1e-8) psi = psi * pol psi = psi.round(1e-12) radd = 5 rnd = tt.rand(psi.n,psi.d,radd) psi = psi + 0*rnd t = 0 tf = 1 tau = 1e-2 t1 = time.time() while t <= tf: psi = kls(-1.0*A,psi,tau) t += tau t2 = time.time() print('Total time: %f' % (t2-t1))
def multifuncrs2(X, funs, eps = 1e-6, \ nswp = 10, \ rmax = 9999999, \ verb = 1, \ kickrank = 5, \ kickrank2 = 0, \ d2 = 1, \ eps_exit = None, \ y0 = None, \ do_qr = False, \ restart_it = 0): dtype = np.float64 if len(filter(lambda x: x.is_complex, X)) > 0: dtype = np.complex128 if eps_exit is None: eps_exit = eps nx = len(X) d = X[0].d n = X[0].n rx = np.transpose(np.array([ttx.r for ttx in X])) crx = np.empty((nx, d), dtype = np.object) i = 0 for ttx in X: v = tt.tensor.to_list(ttx) j = 0 for w in v: crx[i, j] = w j = j + 1 i = i+1 crx = crx.T wasrand = False if y0 is None: ry = d2 * np.ones((d + 1,), dtype=np.int32) ry[0] = 1 y = tt.rand(n, d, ry) wasrand = True else: #Initial guess available y = y0.copy() ry = y.r.copy() #Error vector z = tt.rand(n, d, kickrank) rz = z.r z = tt.tensor.to_list(z) ry = y.r cry = tt.tensor.to_list(y) #Interface matrices - for solution one_arr = np.ones((1, 1), dtype=dtype) Ry = np.zeros((d + 1, ), dtype=np.object) Ry[0] = one_arr Ry[d] = one_arr Rx = np.zeros((d+1, nx), dtype=np.object) Rx[0, :] = np.ones(nx, dtype=dtype) Rx[d, :] = np.ones(nx, dtype=dtype) Ryz = np.zeros((d + 1, ), dtype = np.object) Ryz[0] = one_arr Ryz[d] = one_arr Rz = np.zeros((d + 1, ), dtype = np.object) Rz[0] = one_arr Rz[d] = one_arr Rxz = np.zeros((d + 1, nx), dtype = np.object) Rxz[0, :] = np.ones(nx, dtype=dtype) Rxz[d, :] = np.ones(nx, dtype=dtype) block_order = [+d, -d] # orth for i in range(0, d-1): cr = cry[i].copy() cr = reshape(cr, (ry[i] * n[i], ry[i+1])) cr, rv = np.linalg.qr(cr) cr2 = cry[i+1].copy() cr2 = reshape(cr2, (ry[i+1], n[i+1] * ry[i+2])) cr2 = np.dot(rv, cr2) # matrix multiplication ry[i+1] = cr.shape[1] cr = reshape(cr, (ry[i], n[i], ry[i+1])) cry[i+1] = reshape(cr2, (ry[i+1], n[i+1], ry[i+2])) cry[i] = cr Ry[i+1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i+1]))) Ry[i+1] = reshape(Ry[i+1], (ry[i] * n[i], ry[i+1])) curind = [] if wasrand: # EVERY DAY I'M SHUFFLIN' curind = np.random.permutation(n[i] * ry[i])[:ry[i+1]] else: curind = maxvol(Ry[i+1]) Ry[i+1] = Ry[i+1][curind, :] #Interface matrices for X for j in range(0, nx): Rx[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) Rx[i+1, j] = np.dot(Rx[i, j], Rx[i+1, j]) Rx[i+1, j] = reshape(Rx[i+1, j], (ry[i] * n[i], rx[i+1, j])) Rx[i+1, j] = Rx[i+1, j][curind, :] #Error for kick crz = z[i] crz = reshape(crz, (rz[i] * n[i], rz[i+1])) crz, rv = np.linalg.qr(crz) cr2 = z[i+1] cr2 = reshape(cr2, (rz[i+1], n[i+1] * rz[i+2])) cr2 = np.dot(rv, cr2) rz[i+1] = crz.shape[1] crz = reshape(crz, (rz[i], n[i], rz[i+1])) z[i+1] = reshape(cr2, (rz[i+1], n[i+1], rz[i+2])) z[i] = crz #Interfaces for error Rz[i+1] = np.dot(Rz[i], reshape(crz, [rz[i], n[i] * rz[i+1]])) Rz[i+1] = reshape(Rz[i+1], [rz[i] * n[i], rz[i+1]]) Ryz[i+1] = np.dot(Ryz[i], reshape(cr, [ry[i], n[i] * ry[i+1]])) Ryz[i+1] = reshape(Ryz[i+1], [rz[i] * n[i], ry[i+1]]) #Pick random initial indices curind = np.random.permutation(n[i] * rz[i])[:rz[i+1]] Ryz[i+1] = Ryz[i+1][curind, :] Rz[i+1] = Rz[i+1][curind, :] #Interface matrices for X for j in range(0, nx): Rxz[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) Rxz[i+1, j] = np.dot(Rxz[i, j], Rxz[i+1, j]) Rxz[i+1, j] = reshape(Rxz[i+1, j], (rz[i] * n[i], rx[i+1, j])) Rxz[i+1, j] = Rxz[i+1, j][curind, :] d2 = ry[d] ry[d] = 1 cry[d-1] = np.transpose(cry[d-1], [2, 0, 1]) # permute swp = 1 max_dy = 0.0 cur_order = copy.copy(block_order) order_index = 1 i = d-1 dirn = int(math.copysign(1, cur_order[order_index])) # can't use 'dir' identifier in python #DMRG sweeps while swp <= nswp or dirn > 0: oldy = reshape(cry[i].copy(), (d2 * ry[i] * n[i] * ry[i+1], )) #Compute X superblocks curbl = np.zeros((ry[i] * n[i] * ry[i+1], nx), dtype) for j in range(0, nx): cr = reshape(crx[i, j].copy(), (rx[i, j], n[i] * rx[i+1, j])) cr = np.dot(Rx[i, j], cr) cr = reshape(cr, (ry[i] * n[i], rx[i+1, j])) cr = np.dot(cr, Rx[i+1, j]) curbl[:, j] = cr.flatten('F') newy = funs(curbl) #multiply with inverted Ry newy = reshape(newy, (ry[i], n[i] * ry[i+1] * d2)) newy = np.linalg.solve(Ry[i], newy) # y = R \ y newy = reshape(newy, (ry[i] * n[i] * ry[i+1], d2)) newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i+1])) newy = np.transpose(np.linalg.solve(np.transpose(Ry[i+1]), np.transpose(newy))) # y=y/R newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i+1],)) try: dy = np.linalg.norm(newy - oldy) / np.linalg.norm(newy) except ZeroDivisionError: print 'Bad initial indices, the solution is exactly zero. Restarting' return max_dy = max(max_dy, dy) # truncation if dirn > 0: # left-to-right newy = reshape(newy, (d2, ry[i] * n[i] * ry[i+1])) newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i+1] * d2)) else: newy = reshape(newy, (d2 * ry[i], n[i] * ry[i+1])) if kickrank >= 0: try: u, s, v = np.linalg.svd(newy, full_matrices = False) except: tmp = np.array(np.random.randn(newy.shape[1], newy.shape[1]), dtype=dtype) tmp, ru_tmp = np.linalg.qr(tmp) u, s, v = np.linalg.svd(np.dot(newy, tmp)) #u * s * v = A * tmp v = np.dot(v, np.conj(tmp).T) v = np.conj(np.transpose(v)) r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s)) else: if dirn > 0: u, v = np.linalg.qr(newy) v = np.conj(np.transpose(v)) r = u.shape[1] s = np.ones((r, )) else: v, u = np.linalg.qr(np.transpose(newy)) v = np.conj(v) u = np.transpose(u) r = u.shape[1] s = np.ones((r, )) if verb > 1: print '=multifuncrs2= block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy, r) #Kicks and interfaces if dirn > 0 and i < d-1: u = u[:, :r] v = np.dot(v[:, :r], np.diag(s[:r])) # kick radd = 0 rv = 1 if kickrank > 0: #Compute the function at residual indices curbl_y = np.zeros((ry[i] * n[i] * rz[i+1], nx), dtype=dtype) curbl_z = np.zeros((rz[i] * n[i] * rz[i+1], nx), dtype=dtype) for j in xrange(nx): #For kick cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) cr = np.dot(Rx[i, j], cr) cr = reshape(cr, (ry[i] * n[i], rx[i+1, j])) cr = np.dot(cr, Rxz[i+1, j]) curbl_y[:, j] = cr.flatten('F') #For z update cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) cr = np.dot(Rxz[i, j], cr) cr = reshape(cr, (rz[i] * n[i], rx[i+1, j])) cr = np.dot(cr, Rxz[i+1, j]) curbl_z[:, j] = cr.flatten('F') #Call the function zy = reshape(funs(curbl_y), (-1, d2)) zz = reshape(funs(curbl_z), (-1, d2)) #Assemble y at z indices (sic!) and subtract dzy = reshape(np.dot(u, v.T), (ry[i] * n[i] * ry[i+1], d2)) dzy = reshape(dzy.T, (d2 * ry[i] * n[i], ry[i+1])) #Cast dzy from core items to samples at right indices dzy = np.dot(dzy, Ryz[i+1]) dzy = reshape(dzy, (d2, ry[i] * n[i] * rz[i+1])) dzy = dzy.T #zy still requires casting from samples to core entities zy = reshape(zy, (ry[i], n[i] * rz[i+1] * d2)) zy = np.linalg.solve(Ry[i], zy) zy = reshape(zy, (ry[i] * n[i] * rz[i+1], d2)) zy = zy - dzy dzy = reshape(dzy, (ry[i], n[i] * rz[i+1] * d2)) dzy = np.dot(Ryz[i], dzy) dzy = reshape(dzy, (rz[i] * n[i] * rz[i+1], d2)) #Sample from both sizes zz = zz - dzy #Interpolate all remaining samples into core elements zy = reshape(zy.T, (d2 * ry[i] * n[i], rz[i+1])) zy = np.linalg.solve(Rz[i+1].T, zy.T).T zy = reshape(zy, (d2, ry[i] * n[i] * rz[i+1])) zy = reshape(zy.T, (ry[i] * n[i], rz[i+1] * d2)) #SVD to eliminate d2 and possibly overestimated rz zy, sz, vz = np.linalg.svd(zy, full_matrices = False) zy = zy[:, :min(kickrank, zy.shape[1])] # For z update zz = reshape(zz, (rz[i], n[i] * rz[i+1] * d2)) zz = np.linalg.solve(Rz[i], zz) zz = reshape(zz, (rz[i] * n[i] * rz[i+1], d2)) zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i+1])) zz = np.linalg.solve(Rz[i+1].T, zz.T).T zz = reshape(zz, (d2, rz[i] * n[i] * rz[i+1])) zz = reshape(zz.T, (rz[i] * n[i], rz[i+1] * d2)) zz, sz, vz = np.linalg.svd(zz, full_matrices = False) zz = zz[:, :min(kickrank, zz.shape[1])] #Second random kick rank zz = np.hstack((zz, np.random.randn(rz[i] * n[i], kickrank2))) u, rv = np.linalg.qr(np.hstack((u, zy))) radd = zy.shape[1] v = np.hstack((v, np.zeros((ry[i+1] * d2, radd), dtype=dtype))) v = np.dot(rv, v.T) r = u.shape[1] cr2 = cry[i+1].copy() cr2 = reshape(cr2, (ry[i+1], n[i+1] * ry[i+2])) v = reshape(v, (r * ry[i+1], d2)) v = reshape(v.T, (d2 * r, ry[i+1])) v = np.dot(v, cr2) ry[i+1] = r u = reshape(u, (ry[i], n[i], r)) v = reshape(v, (d2, r, n[i+1], ry[i+2])) #Stuff back cry[i] = u cry[i+1] = v # Update kick zz, rv = np.linalg.qr(zz) rz[i+1] = zz.shape[1] z[i] = reshape(zz, (rz[i], n[i], rz[i+1])) #z[i+1] is recomputed from scratch we do not need it now #Compute left interface matrices #Interface matrix for Y Ry[i+1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i+1]))) Ry[i+1] = reshape(Ry[i+1], (ry[i] * n[i], ry[i+1])) curind = maxvol(Ry[i+1]) Ry[i+1] = Ry[i+1][curind, :] #Interface matrices for X for j in xrange(nx): Rx[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) Rx[i+1, j] = np.dot(Rx[i, j], Rx[i+1, j]) Rx[i+1, j] = reshape(Rx[i+1, j], (ry[i] * n[i], rx[i+1, j])) Rx[i+1, j] = Rx[i+1, j][curind, :] #for kick Ryz[i+1] = np.dot(Ryz[i], reshape(u, (ry[i], n[i] * ry[i+1]))) Ryz[i+1] = reshape(Ryz[i+1], (rz[i] * n[i], ry[i+1])) Rz[i+1] = np.dot(Rz[i], reshape(zz, (rz[i], n[i] * rz[i+1]))) Rz[i+1] = reshape(Rz[i+1], (rz[i] * n[i], rz[i+1])) curind = maxvol(Rz[i+1]) Ryz[i+1] = Ryz[i+1][curind, :] Rz[i+1] = Rz[i+1][curind, :] #Interface matrices for X for j in xrange(nx): Rxz[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) Rxz[i+1, j] = np.dot(Rxz[i, j], Rxz[i+1, j]) Rxz[i+1, j] = reshape(Rxz[i+1, j], (rz[i] * n[i], rx[i+1, j])) Rxz[i+1, j] = Rxz[i+1, j][curind, :] elif dirn < 0 and i > 0: # Right to left u = np.dot(u[:, :r], np.diag(s[:r])) v = np.conj(v[:, :r]) #kick radd = 0 rv = 0 if kickrank > 0: #AMEN kick #Compute the function at residual indices curbl_y = np.zeros((rz[i] * n[i] * ry[i+1], nx), dtype=dtype) curbl_z = np.zeros((rz[i] * n[i] * rz[i+1], nx), dtype=dtype) for j in xrange(nx): cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) cr = np.dot(Rxz[i, j], cr) cr = reshape(cr, (rz[i] * n[i], rx[i+1, j])) cr = np.dot(cr, Rx[i+1, j]) curbl_y[:, j] = cr.flatten('F') #for z update cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j])) cr = np.dot(Rxz[i, j], cr) cr = reshape(cr, (rz[i] * n[i], rx[i+1, j])) cr = np.dot(cr, Rxz[i+1, j]) curbl_z[:, j] = cr.flatten('F') #Call the function zy = reshape(funs(curbl_y), (-1, d2)) zz = reshape(funs(curbl_z), (-1, d2)) #Assemble y at z indices (sic!) and subtract dzy = reshape(np.dot(u, v.T), (ry[i], n[i] * ry[i+1] * d2)) dzy = np.dot(Ryz[i], dzy) dzy = reshape(dzy, (rz[i] * n[i] * ry[i+1], d2)) # zy still requires casting from samples to core entries zy = zy.T zy = reshape(zy, (d2 * rz[i] * n[i], ry[i+1])) zy = np.linalg.solve(Ry[i+1].T, zy.T).T zy = reshape(zy, (d2, rz[i] * n[i] * ry[i+1])) zy = zy.T zy = zy - dzy dzy = reshape(dzy.T, (d2 * rz[i] * n[i], ry[i+1])) dzy = np.dot(dzy, Ryz[i+1]) dzy = reshape(dzy, (d2, rz[i] * n[i] * rz[i+1])) zz = zz - dzy.T # Cast sample indices to core elements # ...for kick zy = reshape(zy, (rz[i], n[i] * ry[i+1] * d2)) zy = np.linalg.solve(Rz[i], zy) zy = reshape(zy, (rz[i] * n[i] * ry[i+1], d2)) zy = zy.T zy = reshape(zy, (d2 * rz[i], n[i] * ry[i+1])) zu, zs, zy = np.linalg.svd(zy, full_matrices = False) zy = zy[:min(kickrank, zy.shape[0]), :] zy = zy.T # ...for z update zz = reshape(zz, (rz[i], n[i] * rz[i+1] * d2)) zz = np.linalg.solve(Rz[i], zz) zz = reshape(zz, (rz[i] * n[i] * rz[i+1], d2)) zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i+1])) zz = np.linalg.solve(Rz[i+1].T, zz.T).T zz = reshape(zz, (d2 * rz[i], n[i] * rz[i+1])) zu, zs, zz = np.linalg.svd(zz, full_matrices = False) zz = zz[:min(kickrank, zz.shape[0]), :] zz = zz.T zz = np.hstack((zz, np.random.randn(n[i] * rz[i+1], kickrank2))) v, rv = np.linalg.qr(np.hstack((v, zy))) radd = zy.shape[1] u = np.hstack((u, np.zeros((d2 * ry[i], radd), dtype=dtype))) u = np.dot(u, rv.T) r = v.shape[1] cr2 = cry[i-1].copy() cr2 = reshape(cr2, (ry[i-1] * n[i-1], ry[i])) u = reshape(u, (d2, ry[i] * r)) u = reshape(u.T, (ry[i], r * d2)) u = np.dot(cr2, u) u = reshape(u, (ry[i-1] * n[i-1] * r, d2)) u = reshape(u.T, (d2, ry[i-1], n[i-1], r)) v = reshape(v.T, (r, n[i], ry[i+1])) # Stuff back ry[i] = r cry[i-1] = u cry[i] = v #kick zz, rv = np.linalg.qr(zz) rz[i] = zz.shape[1] zz = reshape(zz.T, (rz[i], n[i], rz[i+1])) z[i] = zz #z[i-1] is recomputed from scratch we do not need it # Recompute left interface matrices # Interface matrix for Y Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i+1])), Ry[i+1]) Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i+1])) curind = maxvol(Ry[i].T) Ry[i] = Ry[i][:, curind] # Interface matrices for X for j in xrange(nx): Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i+1, j])) Rx[i, j] = np.dot(Rx[i, j], Rx[i+1, j]) Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i+1])) Rx[i, j] = Rx[i, j][:, curind] # for kick Rz[i] = np.dot(reshape(zz, (rz[i] * n[i], rz[i+1])), Rz[i+1]) Rz[i] = reshape(Rz[i], (rz[i], n[i] * rz[i+1])) Ryz[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i+1])), Ryz[i+1]) Ryz[i] = reshape(Ryz[i], (ry[i], n[i] * rz[i+1])) curind = maxvol(Rz[i].T) Ryz[i] = Ryz[i][:, curind] Rz[i] = Rz[i][:, curind] # Interface matrices for X for j in xrange(nx): Rxz[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i+1, j])) Rxz[i, j] = np.dot(Rxz[i, j], Rxz[i+1, j]) Rxz[i, j] = reshape(Rxz[i, j], (rx[i, j], n[i] * rz[i+1])) Rxz[i, j] = Rxz[i, j][:, curind] elif dirn > 0 and i == d-1: #Just stuff back the last core newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]), np.conj(v[:, :r].T))) newy = reshape(newy, (ry[i] * n[i] * ry[i+1], d2)) cry[i] = reshape(newy.T, (d2, ry[i], n[i], ry[i+1])) elif dirn < 0 and i == 0: newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]), np.conj(v[:, :r].T))) newy = reshape(newy, (d2, ry[i], n[i], ry[i+1])) cry[i] = newy i += dirn # Reversing, residue check, etc cur_order[order_index] = cur_order[order_index] - dirn # New direction if cur_order[order_index] == 0: order_index = order_index + 1 if verb > 0: print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy, \ math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n))) if max_dy < eps_exit and dirn > 0: break if order_index >= len(cur_order): #New global sweep cur_order = copy.copy(block_order) order_index = 0 max_dy = 0 swp = swp + 1 dirn = int(math.copysign(1, cur_order[order_index])) i = i + dirn cry[d-1] = np.transpose(cry[d-1][:, :, :, 0], [1, 2, 0]) y = tt.tensor.from_list(cry) return y
#%% from __future__ import print_function, absolute_import, division import sys sys.path.append('../') import numpy as np import tt from tt.eigb import * import time """ This code computes many eigenvalus of the Laplacian operator """ d = 8 f = 8 A = tt.qlaplace_dd([d] * f) #A = (-1)*A #A = tt.eye(2,d) n = [2] * (d * f) r = [8] * (d * f + 1) r[0] = 1 r[d * f] = 8 #Number of eigenvalues sought x = tt.rand(n, d * f, r) #x = tt_ones(2,d) t = time.time() y, lam = eigb(A, x, 1e-6) t1 = time.time() print('Eigenvalues:', lam) print('Time is:', t1 - t) # %%
def multifuncrs(X, funs, eps=1E-6, \ nswp=10, \ kickrank=5, \ y0=None, \ rmax=999999,#TODO:infinity \ kicktype='amr-two', \ pcatype='svd', \ trunctype='fro', \ d2=1, \ do_qr=False, \ verb=1): """Cross approximation of a (vector-)function of several TT-tensors. :param X: tuple of TT-tensors :param funs: multivariate function :param eps: accuracy """ dtype = np.float64 if len(filter(lambda x: x.is_complex, X)) > 0: dtype = np.complex128 y = y0 wasrand = False nx = len(X) d = X[0].d n = X[0].n rx = np.transpose(np.array([ttx.r for ttx in X])) #crx = [tt.tensor.to_list(ttx) for x in X] #crx = zip(*crx) crx = np.transpose(np.array([tt.tensor.to_list(ttx) for ttx in X], dtype=np.object)) crx = np.empty((nx, d), dtype = np.object) i = 0 for ttx in X: v = tt.tensor.to_list(ttx) j = 0 for w in v: crx[i, j] = w j = j + 1 i = i + 1 crx = crx.T if y is None: ry = d2 * np.ones((d + 1,), dtype=np.int32) ry[0] = 1 y = tt.rand(n, d, ry) wasrand = True ry = y.r cry = tt.tensor.to_list(y) Ry = np.zeros((d + 1, ), dtype=np.object) Ry[0] = np.array([[1.0]], dtype=dtype) Ry[d] = np.array([[1.0]], dtype=dtype) Rx = np.zeros((d+1, nx), dtype=np.object) Rx[0, :] = np.ones(nx, dtype=dtype) Rx[d, :] = np.ones(nx, dtype=dtype) block_order = [+d, -d] # orth for i in range(0, d - 1): cr = cry[i] cr = reshape(cr, (ry[i] * n[i], ry[i + 1])) cr, rv = np.linalg.qr(cr) cr2 = cry[i + 1] cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2])) cr2 = np.dot(rv, cr2) # matrix multiplication ry[i + 1] = cr.shape[1] cr = reshape(cr, (ry[i], n[i], ry[i + 1])) cry[i + 1] = reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2])) cry[i] = cr Ry[i + 1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i + 1]))) Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1])) curind = [] if wasrand: # EVERY DAY I'M SHUFFLIN' curind = np.random.permutation(n[i] * ry[i])[:ry[i + 1]] else: curind = maxvol(Ry[i + 1]) Ry[i + 1] = Ry[i + 1][curind, :] for j in range(0, nx): try: Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) except: pass Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j])) Rx[i + 1, j] = Rx[i + 1, j][curind, :] d2 = ry[d] ry[d] = 1 cry[d - 1] = np.transpose(cry[d - 1], [2, 0, 1]) # permute last_sweep = False swp = 1 dy = np.zeros((d, )) max_dy = 0 cur_order = copy.copy(block_order) order_index = 1 i = d - 1 dirn = int(math.copysign(1, cur_order[order_index])) # can't use 'dir' identifier in python # DMRG sweeps while swp <= nswp or dirn > 0: oldy = reshape(cry[i], (d2 * ry[i] * n[i] * ry[i + 1],)) if not last_sweep: # compute the X superblocks curbl = np.zeros((ry[i] * n[i] * ry[i + 1], nx), dtype=dtype) for j in range(0, nx): cr = reshape(crx[i,j], (rx[i, j], n[i] * rx[i + 1, j])) cr = np.dot(Rx[i, j], cr) cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j])) cr = np.dot(cr, Rx[i + 1, j]) curbl[:, j] = cr.flatten('F'); # call the function newy = funs(curbl) # multiply with inverted Ry newy = reshape(newy, (ry[i], n[i] * ry[i + 1] * d2)) newy = np.linalg.solve(Ry[i], newy) # y = R \ y newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2)) newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i + 1])) newy = np.transpose(np.linalg.solve(np.transpose(Ry[i + 1]), np.transpose(newy))) # y=y/R newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i + 1],)) else: newy = oldy dy[i] = np.linalg.norm(newy - oldy) / np.linalg.norm(newy) max_dy = max(max_dy, dy[i]) # truncation if dirn > 0: # left-to-right newy = reshape(newy, (d2, ry[i] * n[i] * ry[i + 1])) newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i + 1] * d2)) else: newy = reshape(newy, (d2 * ry[i], n[i] * ry[i + 1])) r = 0 # defines a variable in global scope if kickrank >= 0: u, s, v = np.linalg.svd(newy, full_matrices=False) v = np.conj(np.transpose(v)) if trunctype == "fro" or last_sweep: r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s)) else: # truncate taking into account the (r+1) overhead in the cross (T.S.: what?) cums = abs(s * np.arange(2, len(s) + 2)) ** 2 cums = np.cumsum(cums[::-1])[::-1] cums = cums / cums[0] ff = [i for i in range(len(cums)) if cums[i] < eps ** 2 / d] if len(ff) == 0: r = len(s) else: r = np.amin(ff) r = min(r, rmax, len(s)) else: if dirn > 0: u, v = np.linalg.qr(newy) v = np.conj(np.transpose(v)) r = u.shape[1] s = np.ones((r, )) else: v, u = np.linalg.qr(np.transpose(newy)) v = np.conj(v) u = np.transpose(u) r = u.shape[1] s = np.ones((r, )) if verb > 1: print '=multifuncrs= block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy[i], r) # kicks and interfaces if dirn > 0 and i < d - 1: u = u[:, :r] v = np.dot(v[:, :r], np.diag(s[:r])) # kick radd = 0 rv = 1 if not last_sweep and kickrank > 0: uk = None if kicktype == 'amr-two': # AMR(two)-like kick. # compute the X superblocks ind2 = np.unique(np.random.randint(0, ry[i + 2] * n[i + 1], ry[i + 1])) #ind2 = np.unique(np.floor(np.random.rand(ry[i + 1]) * (ry[i + 2] * n[i + 1]))) rkick = len(ind2) curbl = np.zeros((ry[i] * n[i] * rkick, nx), dtype=dtype) for j in range(nx): cr1 = reshape(crx[i,j], (rx[i, j], n[i] * rx[i + 1, j])) cr1 = np.dot(Rx[i, j], cr1) cr1 = reshape(cr1, (ry[i] * n[i], rx[i + 1, j])) cr2 = reshape(crx[i + 1,j], (rx[i + 1, j] * n[i + 1], rx[i + 2, j])) cr2 = np.dot(cr2, Rx[i + 2, j]) cr2 = reshape(cr2, (rx[i + 1, j], n[i + 1] * ry[i + 2])) cr2 = cr2[:, ind2] curbl[:, j] = reshape(np.dot(cr1, cr2), (ry[i] * n[i] * rkick,)) # call the function uk = funs(curbl) uk = reshape(uk, (ry[i], n[i] * rkick * d2)) uk = np.linalg.solve(Ry[i], uk) uk = reshape(uk, (ry[i] * n[i], rkick * d2)) if pcatype == 'svd': uk, sk, vk = np.linalg.svd(uk, full_matrices=False) vk = np.conj(np.transpose(vk)) uk = uk[:, :min(kickrank, uk.shape[1])] else: # uk = uchol(np.transpose(uk), kickrank + 1) # TODO uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1] else: uk = np.random.rand(ry[i] * n[i], kickrank) u, rv = np.linalg.qr(np.concatenate((u, uk), axis=1)) radd = uk.shape[1] v = np.concatenate((v, np.zeros((ry[i + 1] * d2, radd), dtype=dtype)), axis=1) v = np.dot(rv, np.conj(np.transpose(v))) r = u.shape[1] cr2 = cry[i + 1] cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2])) v = reshape(v, (r * ry[i + 1], d2)) v = reshape(np.transpose(v), (d2 * r, ry[i + 1])) v = np.dot(v, cr2) ry[i + 1] = r u = reshape(u, (ry[i], n[i], r)) v = reshape(v, (d2, r, n[i + 1], ry[i + 2])) cry[i] = u cry[i + 1] = v Ry[i + 1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i + 1]))) Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1])) curind = maxvol(Ry[i + 1]) Ry[i + 1] = Ry[i + 1][curind, :] for j in range(nx): Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j])) Rx[i + 1, j] = Rx[i + 1, j][curind, :] elif dirn < 0 and i > 0: u = np.dot(u[:, :r], np.diag(s[:r])) v = np.conj(v[:, :r]) radd = 0 rv = 1 if not last_sweep and kickrank > 0: if kicktype == 'amr-two': # compute the X superblocks ind2 = np.unique(np.random.randint(0, ry[i - 1] * n[i - 1], ry[i])) rkick = len(ind2) curbl = np.zeros((rkick * n[i] * ry[i + 1], nx), dtype=dtype) for j in range(nx): cr1 = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j])) cr1 = np.dot(cr1, Rx[i + 1, j]) cr1 = reshape(cr1, (rx[i, j], n[i] * ry[i + 1])) cr2 = reshape(crx[i - 1, j], (rx[i - 1, j], n[i - 1] * rx[i, j])) cr2 = np.dot(Rx[i - 1, j], cr2) cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], rx[i, j])) cr2 = cr2[ind2, :] curbl[:, j] = reshape(np.dot(cr2, cr1), (rkick * n[i] * ry[i + 1],)) # calling the function uk = funs(curbl) uk = reshape(uk, (rkick * n[i] * ry[i + 1], d2)) uk = reshape(np.transpose(uk), (d2 * rkick * n[i], ry[i + 1])) uk = np.transpose(np.linalg.solve(np.transpose(Ry[i + 1]), np.transpose(uk))) uk = reshape(uk, (d2 * rkick, n[i] * ry[i + 1])) if pcatype == 'svd': vk, sk, uk = np.linalg.svd(uk, full_matrices=False) uk = np.conj(np.transpose(uk)) uk = uk[:, :min(kickrank, uk.shape[1])] # TODO: refactor else: # uk = uchol(uk, kickrank + 1) # TODO uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1] else: uk = np.random.rand(n[i] * ry[i + 1], kickrank) v, rv = np.linalg.qr(np.concatenate((v, uk), axis=1)) radd = uk.shape[1] u = np.concatenate((u, np.zeros((d2 * ry[i], radd), dtype=dtype)), axis=1) u = np.dot(u, np.transpose(rv)) r = v.shape[1] cr2 = cry[i - 1] cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], ry[i])) u = reshape(u, (d2, ry[i] * r)) u = reshape(np.transpose(u), (ry[i], r * d2)) u = np.dot(cr2, u) u = reshape(u, (ry[i - 1] * n[i - 1] * r, d2)) u = reshape(np.transpose(u), (d2, ry[i - 1], n[i - 1], r)) v = reshape(np.transpose(v), (r, n[i], ry[i + 1])) ry[i] = r cry[i - 1] = u cry[i] = v Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ry[i + 1]) Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i + 1])) curind = maxvol(np.transpose(Ry[i])) Ry[i] = Ry[i][:, curind] for j in range(nx): Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j])) Rx[i, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i + 1])) Rx[i, j] = Rx[i, j][:, curind] elif dirn > 0 and i == d - 1: newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])), np.conj(np.transpose(v[:, :r]))) newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2)) cry[i] = reshape(np.transpose(newy), (d2, ry[i], n[i], ry[i + 1])) elif dirn < 0 and i == 0: newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])), np.conj(np.transpose(v[:, :r]))) newy = reshape(newy, (d2, ry[i], n[i], ry[i + 1])) cry[i] = newy i = i + dirn cur_order[order_index] = cur_order[order_index] - dirn if cur_order[order_index] == 0: order_index = order_index + 1 if verb > 0: print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy, \ math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n))) if last_sweep: break if max_dy < eps and dirn < 0: last_sweep = True kickrank = 0 if order_index >= len(cur_order): cur_order = copy.copy(block_order) order_index = 0 if last_sweep: cur_order = [d - 1] max_dy = 0 swp = swp + 1 dirn = int(math.copysign(1, cur_order[order_index])) i = i + dirn cry[d - 1] = np.transpose(cry[d - 1][:, :, :, 0], [1, 2, 0]) y = tt.tensor.from_list(cry) return y
def amen_mv(A, x, tol, y=None, z=None, nswp=20, kickrank=4, kickrank2=0, verb=True, init_qr=True, renorm='direct', fkick=False): ''' Approximate the matrix-by-vector via the AMEn iteration [y,z]=amen_mv(A, x, tol, varargin) Attempts to approximate the y = A*x with accuracy TOL using the AMEn+ALS iteration. Matrix A has to be given in the TT-format, right-hand side x should be given in the TT-format also. Options are provided in form 'PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2 and so on. The parameters are set to default (in brackets in the following) The list of option names and default values are: o y0 - initial approximation to Ax [rand rank-2] o nswp - maximal number of sweeps [20] o verb - verbosity level, 0-silent, 1-sweep info, 2-block info [1] o kickrank - compression rank of the error, i.e. enrichment size [3] o init_qr - perform QR of the input (save some time in ts, etc) [true] o renorm - Orthog. and truncation methods: direct (svd,qr) or gram (apply svd to the gram matrix, faster for m>>n) [direct] o fkick - Perform solution enrichment during forward sweeps [false] (rather questionable yet; false makes error higher, but "better structured": it does not explode in e.g. subsequent matvecs) o z0 - initial approximation to the error Ax-y [rand rank-kickrank] ******** For description of adaptive ALS please see Sergey V. Dolgov, Dmitry V. Savostyanov, Alternating minimal energy methods for linear systems in higher dimensions. Part I: SPD systems, http://arxiv.org/abs/1301.6068, Part II: Faster algorithm and application to nonsymmetric systems, http://arxiv.org/abs/1304.1222 Use {sergey.v.dolgov, dmitry.savostyanov}@gmail.com for feedback ******** ''' if renorm is 'gram': print("Not implemented yet. Renorm is switched to 'direct'") renorm = 'direct' if isinstance(x, _tt.vector): d = x.d m = x.n rx = x.r x = _tt.vector.to_list(x) vectype = 1 # tt_tensor elif isinstance(x, list): d = len(x) m = _np.zeros(d) rx = _np.ones(d + 1, dtype=_np.int32) for i in xrange(d): [_, m[i], rx[i + 1]] = x[i].shape vectype = 0 # cell else: raise Exception('x: use tt.tensor or list of cores as numpy.arrays') if isinstance(A, _tt.matrix): n = A.n ra = A.tt.r A = _tt.matrix.to_list(A) # prepare A for fast ALS-mv for i in xrange(d): A[i] = _reshape(A[i], (ra[i] * n[i], m[i] * ra[i + 1])) atype = 1 # tt_matrix # Alternative: A is a cell of cell: sparse canonical format elif isinstance(A, list): n = _np.zeros(d) for i in xrange(d): n[i] = A[i][0].shape[0] ra = len(A[0]) atype = 0 # cell else: raise Exception('A: use tt.matrix or list of cores as numpy.arrays') if y is None: y = _tt.rand(n, d, 2) y = _tt.vector.to_list(y) else: if isinstance(y, _tt.vector): y = _tt.vector.to_list(y) ry = _np.ones(d + 1, dtype=_np.int32) for i in range(d): ry[i + 1] = y[i].shape[2] if (kickrank + kickrank2 > 0): if z is None: z = _tt.rand(n, d, kickrank + kickrank2) rz = z.r z = _tt.vector.to_list(z) else: if isinstance(z, _tt.vector): z = _tt.vector.to_list(z) rz = _np.ones(d + 1, dtype=_np.int32) for i in range(d): rz[i + 1] = z[i].shape[2] phizax = [None] * (d + 1) # cell(d+1,1); if (atype == 1): phizax[0] = _np.ones((1, 1, 1)) # 1 phizax[d] = _np.ones((1, 1, 1)) # 1 else: phizax[0] = _np.ones((1, ra)) # 33 phizax[d] = _np.ones((1, ra)) phizy = [None] * (d + 1) phizy[0] = _np.ones((1)) # , 1)) phizy[d] = _np.ones((1)) # , 1)) phiyax = [None] * (d + 1) if (atype == 1): phiyax[0] = _np.ones((1, 1, 1)) # 1 phiyax[d] = _np.ones((1, 1, 1)) # 1 else: phiyax[0] = _np.ones((1, ra)) # 3 phiyax[d] = _np.ones((1, ra)) nrms = _np.ones(d) # Initial ort for i in range(d - 1): if init_qr: cr = _reshape(y[i], (ry[i] * n[i], ry[i + 1])) if (renorm is 'gram') and (ry[i] * n[i] > 5 * ry[i + 1]): [cr, s, R] = _svdgram(cr) else: [cr, R] = _np.linalg.qr(cr) nrmr = _np.linalg.norm(R) # , 'fro') if (nrmr > 0): R = R / nrmr cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2])) cr2 = _np.dot(R, cr2) ry[i + 1] = cr.shape[1] y[i] = _reshape(cr, (ry[i], n[i], ry[i + 1])) y[i + 1] = _reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2])) [phiyax[i + 1], nrms[i] ] = _compute_next_Phi(phiyax[i], y[i], x[i], 'lr', A[i]) if (kickrank + kickrank2 > 0): cr = _reshape(z[i], (rz[i] * n[i], rz[i + 1])) if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]): [cr, s, R] = _svdgram(cr) else: [cr, R] = _np.linalg.qr(cr) nrmr = _np.linalg.norm(R) # , 'fro') if (nrmr > 0): R = R / nrmr cr2 = _reshape(z[i + 1], (rz[i + 1], n[i + 1] * rz[i + 2])) cr2 = _np.dot(R, cr2) rz[i + 1] = cr.shape[1] z[i] = _reshape(cr, (rz[i], n[i], rz[i + 1])) z[i + 1] = _reshape(cr2, (rz[i + 1], n[i + 1], rz[i + 2])) phizax[ i + 1] = _compute_next_Phi( phizax[i], z[i], x[i], 'lr', A[i], nrms[i], return_norm=False) phizy[ i + 1] = _compute_next_Phi( phizy[i], z[i], y[i], 'lr', return_norm=False) i = d - 1 direct = -1 swp = 1 max_dx = 0 while swp <= nswp: # Project the MatVec generating vector crx = _reshape(x[i], (rx[i] * m[i] * rx[i + 1], 1)) cry = _bfun3(phiyax[i], A[i], phiyax[i + 1], crx) nrms[i] = _np.linalg.norm(cry) # , 'fro') # The main goal is to keep y[i] of norm 1 if (nrms[i] > 0): cry = cry / nrms[i] else: nrms[i] = 1 y[i] = _reshape(y[i], (ry[i] * n[i] * ry[i + 1], 1)) dx = _np.linalg.norm(cry - y[i]) max_dx = max(max_dx, dx) # Truncation and enrichment if ((direct > 0) and (i < d - 1)): # ?? i<d cry = _reshape(cry, (ry[i] * n[i], ry[i + 1])) if (renorm == 'gram'): [u, s, v] = _svdgram(cry, tol / d**0.5) v = v.T r = u.shape[1] else: [u, s, vt] = _np.linalg.svd(cry, full_matrices=False) #s = diag(s) r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5) u = u[:, :r] # ????? s - matrix or vector v = _np.dot(_tconj(vt[:r, :]), _np.diag(s[:r])) # Prepare enrichment, if needed if (kickrank + kickrank2 > 0): cry = _np.dot(u, v.T) cry = _reshape(cry, (ry[i] * n[i], ry[i + 1])) # For updating z crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx) crz = _reshape(crz, (rz[i] * n[i], rz[i + 1])) ys = _np.dot(cry, phizy[i + 1]) yz = _reshape(ys, (ry[i], n[i] * rz[i + 1])) yz = _np.dot(phizy[i], yz) yz = _reshape(yz, (rz[i] * n[i], rz[i + 1])) crz = crz / nrms[i] - yz nrmz = _np.linalg.norm(crz) # , 'fro') if (kickrank2 > 0): [crz, _, _] = _np.linalg.svd(crz, full_matrices=False) crz = crz[:, : min(crz.shape[1], kickrank)] crz = _np.hstack( (crz, _np.random.randn( rz[i] * n[i], kickrank2))) # For adding into solution if fkick: crs = _bfun3(phiyax[i], A[i], phizax[i + 1], crx) crs = _reshape(crs, (ry[i] * n[i], rz[i + 1])) crs = crs / nrms[i] - ys u = _np.hstack((u, crs)) if (renorm == 'gram') and ( ry[i] * n[i] > 5 * (ry[i + 1] + rz[i + 1])): [u, s, R] = _svdgram(u) else: [u, R] = _np.linalg.qr(u) v = _np.hstack((v, _np.zeros((ry[i + 1], rz[i + 1])))) v = _np.dot(v, R.T) r = u.shape[1] y[i] = _reshape(u, (ry[i], n[i], r)) cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2])) v = _reshape(v, (ry[i + 1], r)) cr2 = _np.dot(v.T, cr2) y[i + 1] = _reshape(cr2, (r, n[i + 1], ry[i + 2])) ry[i + 1] = r [phiyax[i + 1], nrms[i] ] = _compute_next_Phi(phiyax[i], y[i], x[i], 'lr', A[i]) if (kickrank + kickrank2 > 0): if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]): [crz, s, R] = _svdgram(crz) else: [crz, R] = _np.linalg.qr(crz) rz[i + 1] = crz.shape[1] z[i] = _reshape(crz, (rz[i], n[i], rz[i + 1])) # z[i+1] will be recomputed from scratch in the next step phizax[ i + 1] = _compute_next_Phi( phizax[i], z[i], x[i], 'lr', A[i], nrms[i], return_norm=False) phizy[ i + 1] = _compute_next_Phi( phizy[i], z[i], y[i], 'lr', return_norm=False) elif ((direct < 0) and (i > 0)): cry = _reshape(cry, (ry[i], n[i] * ry[i + 1])) if (renorm == 'gram'): [v, s, u] = _svdgram(cry.T, tol / d**0.5) u = u.T r = v.shape[1] else: #[v, s, u] = _np.linalg.svd(cry.T, full_matrices=False) [u, s, vt] = _np.linalg.svd(cry, full_matrices=False) #s = diag(s); r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5) v = _tconj(vt[:r, :]) #v = vt[:r, :] #v = _np.dot(v[:, :r], _np.diag(s[:r])) u = _np.dot(u[:, :r], _np.diag(s[:r])) # ?????????????????? # Prepare enrichment, if needed if (kickrank + kickrank2 > 0): cry = _np.dot(u, v.T) # .T) cry = _reshape(cry, (ry[i], n[i] * ry[i + 1])) # For updating z crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx) crz = _reshape(crz, (rz[i], n[i] * rz[i + 1])) ys = _np.dot(phizy[i], cry) yz = _reshape(ys, (rz[i] * n[i], ry[i + 1])) yz = _np.dot(yz, phizy[i + 1]) yz = _reshape(yz, (rz[i], n[i] * rz[i + 1])) crz = crz / nrms[i] - yz nrmz = _np.linalg.norm(crz) # , 'fro') if (kickrank2 > 0): [_, _, crz] = _np.linalg.svd(crz, full_matrices=False) crz = crz[:, : min(crz.shape[1], kickrank)] crz = _tconj(crz) crz = _np.vstack( (crz, _np.random.randn(kickrank2, n[i] * rz[i + 1]))) # For adding into solution crs = _bfun3(phizax[i], A[i], phiyax[i + 1], crx) crs = _reshape(crs, (rz[i], n[i] * ry[i + 1])) crs = crs / nrms[i] - ys v = _np.hstack((v, crs.T)) # .T #v = v.T if (renorm == 'gram') and ( n[i] * ry[i + 1] > 5 * (ry[i] + rz[i])): [v, s, R] = _svdgram(v) else: [v, R] = _np.linalg.qr(v) u = _np.hstack((u, _np.zeros((ry[i], rz[i])))) u = _np.dot(u, R.T) r = v.shape[1] cr2 = _reshape(y[i - 1], (ry[i - 1] * n[i - 1], ry[i])) cr2 = _np.dot(cr2, u) y[i - 1] = _reshape(cr2, (ry[i - 1], n[i - 1], r)) y[i] = _reshape(v.T, (r, n[i], ry[i + 1])) ry[i] = r [phiyax[i], nrms[i]] = _compute_next_Phi( phiyax[i + 1], y[i], x[i], 'rl', A[i]) if (kickrank + kickrank2 > 0): if (renorm == 'gram') and (n[i] * rz[i + 1] > 5 * rz[i]): [crz, s, R] = _svdgram(crz.T) else: [crz, R] = _np.linalg.qr(crz.T) rz[i] = crz.shape[1] z[i] = _reshape(crz.T, (rz[i], n[i], rz[i + 1])) # don't update z[i-1], it will be recomputed from scratch phizax[i] = _compute_next_Phi( phizax[ i + 1], z[i], x[i], 'rl', A[i], nrms[i], return_norm=False) phizy[i] = _compute_next_Phi( phizy[i + 1], z[i], y[i], 'rl', return_norm=False) if (verb > 1): print('amen-mv: swp=[%d,%d], dx=%.3e, r=%d, |y|=%.3e, |z|=%.3e' % (swp, i, dx, r, _np.linalg.norm(cry), nrmz)) # Stopping or reversing if ((direct > 0) and (i == d - 1)) or ((direct < 0) and (i == 0)): if (verb > 0): print('amen-mv: swp=%d{%d}, max_dx=%.3e, max_r=%d' % (swp, (1 - direct) // 2, max_dx, max(ry))) if ((max_dx < tol) or (swp == nswp)) and (direct > 0): break else: # We are at the terminal block y[i] = _reshape(cry, (ry[i], n[i], ry[i + 1])) if (direct > 0): swp = swp + 1 max_dx = 0 direct = -direct else: i = i + direct # if (direct>0) y[d - 1] = _reshape(cry, (ry[d - 1], n[d - 1], ry[d])) # else # y{1} = reshape(cry, ry(1), n(1), ry(2)); # end; # Distribute norms equally... nrms = _np.exp(sum(_np.log(nrms)) / d) # ... and plug them into y for i in xrange(d): y[i] = _np.dot(y[i], nrms) if (vectype == 1): y = _tt.vector.from_list(y) if kickrank == 0: z = None else: z = _tt.vector.from_list(z) return y, z
"""Example of using tt.optimize module.""" import tt from tt.optimize import tt_min from scipy.optimize import rosen def my_rosen(x): return rosen(x.T) print("Minimize 4-d Rosenbrock function on a 4-dimensional grid (512 points " + "along each dimension). The global minimum is 0 in the (1, 1, 1, 1) point.") val, x_full = tt_min.min_func(my_rosen, -2, 2, d=4, n0=512, rmax=10, nswp=30) tens = tt.rand([3, 4, 5, 4, 3], 5, 3) min_element = min(tens.full().flatten()) print("Minimize random 5-dimensional TT tensor with ranks equal to 3. " + "The minimal element is %f" % min_element) val, point = tt_min.min_tens(tens, rmax=10, nswp=30)
def multifuncrs2(X, funs, eps = 1e-6, \ nswp = 10, \ rmax = 9999999, \ verb = 1, \ kickrank = 5, \ kickrank2 = 0, \ d2 = 1, \ eps_exit = None, \ y0 = None, \ do_qr = False, \ restart_it = 0): dtype = np.float64 if len(filter(lambda x: x.is_complex, X)) > 0: dtype = np.complex128 if eps_exit is None: eps_exit = eps y = y0 nx = len(X) d = X[0].d n = X[0].n rx = np.transpose(np.array([ttx.r for ttx in X])) crx = np.empty((nx, d), dtype=np.object) i = 0 for ttx in X: v = tt.tensor.to_list(ttx) j = 0 for w in v: crx[i, j] = w j = j + 1 i = i + 1 crx = crx.T wasrand = False if y is None: ry = d2 * np.ones((d + 1, ), dtype=np.int32) ry[0] = 1 y = tt.rand(n, d, ry) wasrand = True #Error vector z = tt.rand(n, d, kickrank) rz = z.r z = tt.tensor.to_list(z) ry = y.r cry = tt.tensor.to_list(y) #Interface matrices - for solution one_arr = np.ones((1, 1), dtype=dtype) Ry = np.zeros((d + 1, ), dtype=np.object) Ry[0] = one_arr Ry[d] = one_arr Rx = np.zeros((d + 1, nx), dtype=np.object) Rx[0, :] = np.ones(nx, dtype=dtype) Rx[d, :] = np.ones(nx, dtype=dtype) Ryz = np.zeros((d + 1, ), dtype=np.object) Ryz[0] = one_arr Ryz[d] = one_arr Rz = np.zeros((d + 1, ), dtype=np.object) Rz[0] = one_arr Rz[d] = one_arr Rxz = np.zeros((d + 1, nx), dtype=np.object) Rxz[0, :] = np.ones(nx, dtype=dtype) Rxz[d, :] = np.ones(nx, dtype=dtype) block_order = [+d, -d] # orth for i in range(0, d - 1): cr = cry[i] cr = reshape(cr, (ry[i] * n[i], ry[i + 1])) cr, rv = np.linalg.qr(cr) cr2 = cry[i + 1] cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2])) cr2 = np.dot(rv, cr2) # matrix multiplication ry[i + 1] = cr.shape[1] cr = reshape(cr, (ry[i], n[i], ry[i + 1])) cry[i + 1] = reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2])) cry[i] = cr Ry[i + 1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i + 1]))) Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1])) curind = [] if wasrand: # EVERY DAY I'M SHUFFLIN' curind = np.random.permutation(n[i] * ry[i])[:ry[i + 1]] else: curind = maxvol(Ry[i + 1]) Ry[i + 1] = Ry[i + 1][curind, :] #Interface matrices for X for j in range(0, nx): Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j])) Rx[i + 1, j] = Rx[i + 1, j][curind, :] #Error for kick crz = z[i] crz = reshape(crz, (rz[i] * n[i], rz[i + 1])) crz, rv = np.linalg.qr(crz) cr2 = z[i + 1] cr2 = reshape(cr2, (rz[i + 1], n[i + 1] * rz[i + 2])) cr2 = np.dot(rv, cr2) rz[i + 1] = crz.shape[1] crz = reshape(crz, (rz[i], n[i], rz[i + 1])) z[i + 1] = reshape(cr2, (rz[i + 1], n[i + 1], rz[i + 2])) z[i] = crz #Interfaces for error Rz[i + 1] = np.dot(Rz[i], reshape(crz, [rz[i], n[i] * rz[i + 1]])) Rz[i + 1] = reshape(Rz[i + 1], [rz[i] * n[i], rz[i + 1]]) Ryz[i + 1] = np.dot(Ryz[i], reshape(cr, [ry[i], n[i] * ry[i + 1]])) Ryz[i + 1] = reshape(Ryz[i + 1], [rz[i] * n[i], ry[i + 1]]) #Pick random initial indices curind = np.random.permutation(n[i] * rz[i])[:rz[i + 1]] Ryz[i + 1] = Ryz[i + 1][curind, :] Rz[i + 1] = Rz[i + 1][curind, :] #Interface matrices for X for j in range(0, nx): Rxz[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) Rxz[i + 1, j] = np.dot(Rxz[i, j], Rxz[i + 1, j]) Rxz[i + 1, j] = reshape(Rxz[i + 1, j], (rz[i] * n[i], rx[i + 1, j])) Rxz[i + 1, j] = Rxz[i + 1, j][curind, :] d2 = ry[d] ry[d] = 1 cry[d - 1] = np.transpose(cry[d - 1], [2, 0, 1]) # permute swp = 1 max_dy = 0.0 cur_order = copy.copy(block_order) order_index = 1 i = d - 1 dirn = int(math.copysign( 1, cur_order[order_index])) # can't use 'dir' identifier in python #DMRG sweeps while swp <= nswp or dirn > 0: oldy = reshape(cry[i], (d2 * ry[i] * n[i] * ry[i + 1], )) #Compute X superblocks curbl = np.zeros((ry[i] * n[i] * ry[i + 1], nx), dtype) for j in range(0, nx): cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) cr = np.dot(Rx[i, j], cr) cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j])) cr = np.dot(cr, Rx[i + 1, j]) curbl[:, j] = cr.flatten('F') newy = funs(curbl) # multiply with inverted Ry newy = reshape(newy, (ry[i], n[i] * ry[i + 1] * d2)) newy = np.linalg.solve(Ry[i], newy) # y = R \ y newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2)) newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i + 1])) newy = np.transpose( np.linalg.solve(np.transpose(Ry[i + 1]), np.transpose(newy))) # y=y/R newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i + 1], )) try: dy = np.linalg.norm(newy - oldy) / np.linalg.norm(newy) except ZeroDivisionError: print 'Bad initial indices, the solution is exactly zero. Restarting' return max_dy = max(max_dy, dy) # truncation if dirn > 0: # left-to-right newy = reshape(newy, (d2, ry[i] * n[i] * ry[i + 1])) newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i + 1] * d2)) else: newy = reshape(newy, (d2 * ry[i], n[i] * ry[i + 1])) if kickrank >= 0: try: u, s, v = np.linalg.svd(newy, full_matrices=False) except: tmp = np.array(np.random.randn(newy.shape[1], newy.shape[1]), dtype=dtype) tmp, ru_tmp = np.linalg.qr(tmp) u, s, v = np.linalg.svd(np.dot(newy, tmp)) #u * s * v = A * tmp v = np.dot(v, np.conj(tmp).T) v = np.conj(np.transpose(v)) r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s)) else: if dirn > 0: u, v = np.linalg.qr(newy) v = np.conj(np.transpose(v)) r = u.shape[1] s = np.ones((r, )) else: v, u = np.linalg.qr(np.transpose(newy)) v = np.conj(v) u = np.transpose(u) r = u.shape[1] s = np.ones((r, )) if verb > 1: print '=multifuncrs= block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy, r) #Kicks and interfaces if dirn > 0 and i < d - 1: u = u[:, :r] v = np.dot(v[:, :r], np.diag(s[:r])) # kick radd = 0 rv = 1 if kickrank > 0: #Compute the function at residual indices curbl_y = np.zeros((ry[i] * n[i] * rz[i + 1], nx), dtype=dtype) curbl_z = np.zeros((rz[i] * n[i] * rz[i + 1], nx), dtype=dtype) for j in xrange(nx): #For kick cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) cr = np.dot(Rx[i, j], cr) cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j])) cr = np.dot(cr, Rxz[i + 1, j]) curbl_y[:, j] = cr.flatten('F') #For z update cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) cr = np.dot(Rxz[i, j], cr) cr = reshape(cr, (rz[i] * n[i], rx[i + 1, j])) cr = np.dot(cr, Rxz[i + 1, j]) curbl_z[:, j] = cr.flatten('F') #Call the function zy = reshape(funs(curbl_y), (-1, d2)) zz = reshape(funs(curbl_z), (-1, d2)) #Assemble y at z indices (sic!) and subtract dzy = reshape(np.dot(u, v.T), (ry[i] * n[i] * ry[i + 1], d2)) dzy = reshape(dzy.T, (d2 * ry[i] * n[i], ry[i + 1])) #Cast dzy from core items to samples at right indices dzy = np.dot(dzy, Ryz[i + 1]) dzy = reshape(dzy, (d2, ry[i] * n[i] * rz[i + 1])) dzy = dzy.T #zy still requires casting from samples to core entities zy = reshape(zy, (ry[i], n[i] * rz[i + 1] * d2)) zy = np.linalg.solve(Ry[i], zy) zy = reshape(zy, (ry[i] * n[i] * rz[i + 1], d2)) zy = zy - dzy dzy = reshape(dzy, (ry[i], n[i] * rz[i + 1] * d2)) dzy = np.dot(Ryz[i], dzy) dzy = reshape( dzy, (rz[i] * n[i] * rz[i + 1], d2)) #Sample from both sizes zz = zz - dzy #Interpolate all remaining samples into core elements zy = reshape(zy.T, (d2 * ry[i] * n[i], rz[i + 1])) zy = np.linalg.solve(Rz[i + 1].T, zy.T).T zy = reshape(zy, (d2, ry[i] * n[i] * rz[i + 1])) zy = reshape(zy.T, (ry[i] * n[i], rz[i + 1] * d2)) #SVD to eliminate d2 and possibly overestimated rz zy, sz, vz = np.linalg.svd(zy, full_matrices=False) zy = zy[:, :min(kickrank, zy.shape[1])] # For z update zz = reshape(zz, (rz[i], n[i] * rz[i + 1] * d2)) zz = np.linalg.solve(Rz[i], zz) zz = reshape(zz, (rz[i] * n[i] * rz[i + 1], d2)) zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i + 1])) zz = np.linalg.solve(Rz[i + 1].T, zz.T).T zz = reshape(zz, (d2, rz[i] * n[i] * rz[i + 1])) zz = reshape(zz.T, (rz[i] * n[i], rz[i + 1] * d2)) zz, sz, vz = np.linalg.svd(zz, full_matrices=False) zz = zz[:, :min(kickrank, zz.shape[1])] #Second random kick rank zz = np.hstack((zz, np.random.randn(rz[i] * n[i], kickrank2))) u, rv = np.linalg.qr(np.hstack((u, zy))) radd = zy.shape[1] v = np.hstack((v, np.zeros((ry[i + 1] * d2, radd), dtype=dtype))) v = np.dot(rv, v.T) r = u.shape[1] cr2 = cry[i + 1] cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2])) v = reshape(v, (r * ry[i + 1], d2)) v = reshape(v.T, (d2 * r, ry[i + 1])) v = np.dot(v, cr2) ry[i + 1] = r u = reshape(u, (ry[i], n[i], r)) v = reshape(v, (d2, r, n[i + 1], ry[i + 2])) #Stuff back cry[i] = u cry[i + 1] = v # Update kick zz, rv = np.linalg.qr(zz) rz[i + 1] = zz.shape[1] z[i] = reshape(zz, (rz[i], n[i], rz[i + 1])) #z[i + 1] is recomputed from scratch we do not need it now #Compute left interface matrices #Interface matrix for Y Ry[i + 1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i + 1]))) Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1])) curind = maxvol(Ry[i + 1]) Ry[i + 1] = Ry[i + 1][curind, :] #Interface matrices for X for j in xrange(nx): Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j])) Rx[i + 1, j] = Rx[i + 1, j][curind, :] #for kick Ryz[i + 1] = np.dot(Ryz[i], reshape(u, (ry[i], n[i] * ry[i + 1]))) Ryz[i + 1] = reshape(Ryz[i + 1], (rz[i] * n[i], ry[i + 1])) Rz[i + 1] = np.dot(Rz[i], reshape(zz, (rz[i], n[i] * rz[i + 1]))) Rz[i + 1] = reshape(Rz[i + 1], (rz[i] * n[i], rz[i + 1])) curind = maxvol(Rz[i + 1]) Ryz[i + 1] = Ryz[i + 1][curind, :] Rz[i + 1] = Rz[i + 1][curind, :] #Interface matrices for X for j in xrange(nx): Rxz[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) Rxz[i + 1, j] = np.dot(Rxz[i, j], Rxz[i + 1, j]) Rxz[i + 1, j] = reshape(Rxz[i + 1, j], (rz[i] * n[i], rx[i + 1, j])) Rxz[i + 1, j] = Rxz[i + 1, j][curind, :] elif dirn < 0 and i > 0: # Right to left u = np.dot(u[:, :r], np.diag(s[:r])) v = np.conj(v[:, :r]) #kick radd = 0 rv = 0 if kickrank > 0: #AMEN kick #Compute the function at residual indices curbl_y = np.zeros((rz[i] * n[i] * ry[i + 1], nx), dtype=dtype) curbl_z = np.zeros((rz[i] * n[i] * rz[i + 1], nx), dtype=dtype) for j in xrange(nx): cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) cr = np.dot(Rxz[i, j], cr) cr = reshape(cr, (rz[i] * n[i], rx[i + 1, j])) cr = np.dot(cr, Rx[i + 1, j]) curbl_y[:, j] = cr.flatten('F') #for z update cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) cr = np.dot(Rxz[i, j], cr) cr = reshape(cr, (rz[i] * n[i], rx[i + 1, j])) cr = np.dot(cr, Rxz[i + 1, j]) curbl_z[:, j] = cr.flatten('F') #Call the function zy = reshape(funs(curbl_y), (-1, d2)) zz = reshape(funs(curbl_z), (-1, d2)) #Assemble y at z indices (sic!) and subtract dzy = reshape(np.dot(u, v.T), (ry[i], n[i] * ry[i + 1] * d2)) dzy = np.dot(Ryz[i], dzy) dzy = reshape(dzy, (rz[i] * n[i] * ry[i + 1], d2)) # zy still requires casting from samples to core entries zy = zy.T zy = reshape(zy, (d2 * rz[i] * n[i], ry[i + 1])) zy = np.linalg.solve(Ry[i + 1].T, zy.T).T zy = reshape(zy, (d2, rz[i] * n[i] * ry[i + 1])) zy = zy.T zy = zy - dzy dzy = reshape(dzy.T, (d2 * rz[i] * n[i], ry[i + 1])) dzy = np.dot(dzy, Ryz[i + 1]) dzy = reshape(dzy, (d2, rz[i] * n[i] * rz[i + 1])) zz = zz - dzy.T # Cast sample indices to core elements # ...for kick zy = reshape(zy, (rz[i], n[i] * ry[i + 1] * d2)) zy = np.linalg.solve(Rz[i], zy) zy = reshape(zy, (rz[i] * n[i] * ry[i + 1], d2)) zy = zy.T zy = reshape(zy, (d2 * rz[i], n[i] * ry[i + 1])) zu, zs, zy = np.linalg.svd(zy, full_matrices=False) zy = zy[:min(kickrank, zy.shape[0]), :] zy = zy.T # ...for z update zz = reshape(zz, (rz[i], n[i] * rz[i + 1] * d2)) zz = np.linalg.solve(Rz[i], zz) zz = reshape(zz, (rz[i] * n[i] * rz[i + 1], d2)) zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i + 1])) zz = np.linalg.solve(Rz[i + 1].T, zz.T).T zz = reshape(zz, (d2 * rz[i], n[i] * rz[i + 1])) zu, zs, zz = np.linalg.svd(zz, full_matrices=False) zz = zz[:min(kickrank, zz.shape[0]), :] zz = zz.T zz = np.hstack((zz, np.random.randn(n[i] * rz[i + 1], kickrank2))) v, rv = np.linalg.qr(np.hstack((v, zy))) radd = zy.shape[1] u = np.hstack((u, np.zeros((d2 * ry[i], radd), dtype=dtype))) u = np.dot(u, rv.T) r = v.shape[1] cr2 = cry[i - 1] cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], ry[i])) u = reshape(u, (d2, ry[i] * r)) u = reshape(u.T, (ry[i], r * d2)) u = np.dot(cr2, u) u = reshape(u, (ry[i - 1] * n[i - 1] * r, d2)) u = reshape(u.T, (d2, ry[i - 1], n[i - 1], r)) v = reshape(v.T, (r, n[i], ry[i + 1])) # Stuff back ry[i] = r cry[i - 1] = u cry[i] = v #kick zz, rv = np.linalg.qr(zz) rz[i] = zz.shape[1] zz = reshape(zz.T, (rz[i], n[i], rz[i + 1])) z[i] = zz #z[i - 1] is recomputed from scratch we do not need it # Recompute left interface matrices # Interface matrix for Y Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ry[i + 1]) Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i + 1])) curind = maxvol(Ry[i].T) Ry[i] = Ry[i][:, curind] # Interface matrices for X for j in xrange(nx): Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j])) Rx[i, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i + 1])) Rx[i, j] = Rx[i, j][:, curind] # for kick Rz[i] = np.dot(reshape(zz, (rz[i] * n[i], rz[i + 1])), Rz[i + 1]) Rz[i] = reshape(Rz[i], (rz[i], n[i] * rz[i + 1])) Ryz[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ryz[i + 1]) Ryz[i] = reshape(Ryz[i], (ry[i], n[i] * rz[i + 1])) curind = maxvol(Rz[i].T) Ryz[i] = Ryz[i][:, curind] Rz[i] = Rz[i][:, curind] # Interface matrices for X for j in xrange(nx): Rxz[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j])) Rxz[i, j] = np.dot(Rxz[i, j], Rxz[i + 1, j]) Rxz[i, j] = reshape(Rxz[i, j], (rx[i, j], n[i] * rz[i + 1])) Rxz[i, j] = Rxz[i, j][:, curind] elif dirn > 0 and i == d - 1: #Just stuff back the last core newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]), np.conj(v[:, :r].T))) newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2)) cry[i] = reshape(newy.T, (d2, ry[i], n[i], ry[i + 1])) elif dirn < 0 and i is 0: newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]), np.conj(v[:, :r].T))) newy = reshape(newy, (d2, ry[i], n[i], ry[i + 1])) cry[i] = newy i += dirn # Reversing, residue check, etc cur_order[order_index] = cur_order[order_index] - dirn # New direction if cur_order[order_index] == 0: order_index = order_index + 1 if verb > 0: print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy, \ math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n))) if max_dy < eps_exit: break if order_index >= len(cur_order): #New global sweep cur_order = copy.copy(block_order) order_index = 0 max_dy = 0 swp = swp + 1 dirn = int(math.copysign(1, cur_order[order_index])) i = i + dirn cry[d - 1] = np.transpose(cry[d - 1][:, :, :, 0], [1, 2, 0]) y = tt.tensor.from_list(cry) return y
# Simulate artificial covariates x = np.random.randn(d * np.size(y)) / d x = np.reshape(x, [d, np.size(y)], order='F') # short index function for cross myfun = lambda ind: crossfun(ind, theta, x, y, censind, beta_mean, beta_var) print('Running ' + repr(runs) + ' tests for ' + repr(d) + ' covariates, producing ' + repr(2**log2N) + ' samples') print('') Q_py = runs * [None] tau = runs * [None] for irun in range(0, runs): # Run cross f0 = tt.rand(n, d + 2, 8) f = rect_cross.cross(myfun, f0, nswp=50, kickrank=2, rf=2, eps=tol) print(f) # Seed points M = 2**log2N q = np.random.random([M, d + 2]) q = np.reshape(q, [M, d + 2], order='F') ttt = time.time() # Sample Z, lPz = tt_irt1(q, f, theta_f) ttimes_invcdf = time.time() - ttt print('Sampling time = ' + repr(ttimes_invcdf)) Z = np.reshape(Z, [M, d + 2], order='F') # Proposed samples
"""Example of using tt.optimize module.""" import tt from tt.optimize import tt_min from scipy.optimize import rosen def my_rosen(x): return rosen(x.T) print( "Minimize 4-d Rosenbrock function on a 4-dimensional grid (512 points " + "along each dimension). The global minimum is 0 in the (1, 1, 1, 1) point." ) val, x_full = tt_min.min_func(my_rosen, -2, 2, d=4, n0=512, rmax=10, nswp=30) tens = tt.rand([3, 4, 5, 4, 3], 5, 3) min_element = min(tens.full().flatten()) print("Minimize random 5-dimensional TT tensor with ranks equal to 3. " + "The minimal element is %f" % min_element) val, point = tt_min.min_tens(tens, rmax=10, nswp=30)
def multifuncrs(X, funs, eps=1E-6, nswp=10, kickrank=5, y0=None, rmax=999999, # TODO:infinity \ kicktype='amr-two', \ pcatype='svd', \ trunctype='fro', \ d2=1, \ do_qr=False, \ verb=1): """Cross approximation of a (vector-)function of several TT-tensors. :param X: tuple of TT-tensors :param funs: multivariate function :param eps: accuracy """ dtype = np.float64 if len(filter(lambda x: x.is_complex, X)) > 0: dtype = np.complex128 y = y0 wasrand = False nx = len(X) d = X[0].d n = X[0].n rx = np.transpose(np.array([ttx.r for ttx in X])) #crx = [tt.tensor.to_list(ttx) for x in X] #crx = zip(*crx) crx = np.transpose(np.array([tt.tensor.to_list(ttx) for ttx in X], dtype=np.object)) crx = np.empty((nx, d), dtype=np.object) i = 0 for ttx in X: v = tt.tensor.to_list(ttx) j = 0 for w in v: crx[i, j] = w j = j + 1 i = i + 1 crx = crx.T if y is None: ry = d2 * np.ones((d + 1,), dtype=np.int32) ry[0] = 1 y = tt.rand(n, d, ry) wasrand = True ry = y.r cry = tt.tensor.to_list(y) Ry = np.zeros((d + 1, ), dtype=np.object) Ry[0] = np.array([[1.0]], dtype=dtype) Ry[d] = np.array([[1.0]], dtype=dtype) Rx = np.zeros((d + 1, nx), dtype=np.object) Rx[0, :] = np.ones(nx, dtype=dtype) Rx[d, :] = np.ones(nx, dtype=dtype) block_order = [+d, -d] # orth for i in range(0, d - 1): cr = cry[i] cr = reshape(cr, (ry[i] * n[i], ry[i + 1])) cr, rv = np.linalg.qr(cr) cr2 = cry[i + 1] cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2])) cr2 = np.dot(rv, cr2) # matrix multiplication ry[i + 1] = cr.shape[1] cr = reshape(cr, (ry[i], n[i], ry[i + 1])) cry[i + 1] = reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2])) cry[i] = cr Ry[i + 1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i + 1]))) Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1])) curind = [] if wasrand: # EVERY DAY I'M SHUFFLIN' curind = np.random.permutation(n[i] * ry[i])[:ry[i + 1]] else: curind = maxvol(Ry[i + 1]) Ry[i + 1] = Ry[i + 1][curind, :] for j in range(0, nx): try: Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) except: pass Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j])) Rx[i + 1, j] = Rx[i + 1, j][curind, :] d2 = ry[d] ry[d] = 1 cry[d - 1] = np.transpose(cry[d - 1], [2, 0, 1]) # permute last_sweep = False swp = 1 dy = np.zeros((d, )) max_dy = 0 cur_order = copy.copy(block_order) order_index = 1 i = d - 1 # can't use 'dir' identifier in python dirn = int(math.copysign(1, cur_order[order_index])) # DMRG sweeps while swp <= nswp or dirn > 0: oldy = reshape(cry[i], (d2 * ry[i] * n[i] * ry[i + 1],)) if not last_sweep: # compute the X superblocks curbl = np.zeros((ry[i] * n[i] * ry[i + 1], nx), dtype=dtype) for j in range(0, nx): cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) cr = np.dot(Rx[i, j], cr) cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j])) cr = np.dot(cr, Rx[i + 1, j]) curbl[:, j] = cr.flatten('F') # call the function newy = funs(curbl) # multiply with inverted Ry newy = reshape(newy, (ry[i], n[i] * ry[i + 1] * d2)) newy = np.linalg.solve(Ry[i], newy) # y = R \ y newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2)) newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i + 1])) newy = np.transpose(np.linalg.solve( np.transpose(Ry[i + 1]), np.transpose(newy))) # y=y/R newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i + 1],)) else: newy = oldy dy[i] = np.linalg.norm(newy - oldy) / np.linalg.norm(newy) max_dy = max(max_dy, dy[i]) # truncation if dirn > 0: # left-to-right newy = reshape(newy, (d2, ry[i] * n[i] * ry[i + 1])) newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i + 1] * d2)) else: newy = reshape(newy, (d2 * ry[i], n[i] * ry[i + 1])) r = 0 # defines a variable in global scope if kickrank >= 0: u, s, v = np.linalg.svd(newy, full_matrices=False) v = np.conj(np.transpose(v)) if trunctype == "fro" or last_sweep: r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s)) else: # truncate taking into account the (r+1) overhead in the cross # (T.S.: what?) cums = abs(s * np.arange(2, len(s) + 2)) ** 2 cums = np.cumsum(cums[::-1])[::-1] cums = cums / cums[0] ff = [i for i in range(len(cums)) if cums[i] < eps ** 2 / d] if len(ff) == 0: r = len(s) else: r = np.amin(ff) r = min(r, rmax, len(s)) else: if dirn > 0: u, v = np.linalg.qr(newy) v = np.conj(np.transpose(v)) r = u.shape[1] s = np.ones((r, )) else: v, u = np.linalg.qr(np.transpose(newy)) v = np.conj(v) u = np.transpose(u) r = u.shape[1] s = np.ones((r, )) if verb > 1: print '=multifuncrs= block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy[i], r) # kicks and interfaces if dirn > 0 and i < d - 1: u = u[:, :r] v = np.dot(v[:, :r], np.diag(s[:r])) # kick radd = 0 rv = 1 if not last_sweep and kickrank > 0: uk = None if kicktype == 'amr-two': # AMR(two)-like kick. # compute the X superblocks ind2 = np.unique(np.random.randint( 0, ry[i + 2] * n[i + 1], ry[i + 1])) #ind2 = np.unique(np.floor(np.random.rand(ry[i + 1]) * (ry[i + 2] * n[i + 1]))) rkick = len(ind2) curbl = np.zeros((ry[i] * n[i] * rkick, nx), dtype=dtype) for j in range(nx): cr1 = reshape( crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) cr1 = np.dot(Rx[i, j], cr1) cr1 = reshape(cr1, (ry[i] * n[i], rx[i + 1, j])) cr2 = reshape( crx[i + 1, j], (rx[i + 1, j] * n[i + 1], rx[i + 2, j])) cr2 = np.dot(cr2, Rx[i + 2, j]) cr2 = reshape( cr2, (rx[i + 1, j], n[i + 1] * ry[i + 2])) cr2 = cr2[:, ind2] curbl[:, j] = reshape( np.dot(cr1, cr2), (ry[i] * n[i] * rkick,)) # call the function uk = funs(curbl) uk = reshape(uk, (ry[i], n[i] * rkick * d2)) uk = np.linalg.solve(Ry[i], uk) uk = reshape(uk, (ry[i] * n[i], rkick * d2)) if pcatype == 'svd': uk, sk, vk = np.linalg.svd(uk, full_matrices=False) vk = np.conj(np.transpose(vk)) uk = uk[:, :min(kickrank, uk.shape[1])] else: # uk = uchol(np.transpose(uk), kickrank + 1) # TODO uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1] else: uk = np.random.rand(ry[i] * n[i], kickrank) u, rv = np.linalg.qr(np.concatenate((u, uk), axis=1)) radd = uk.shape[1] v = np.concatenate( (v, np.zeros((ry[i + 1] * d2, radd), dtype=dtype)), axis=1) v = np.dot(rv, np.conj(np.transpose(v))) r = u.shape[1] cr2 = cry[i + 1] cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2])) v = reshape(v, (r * ry[i + 1], d2)) v = reshape(np.transpose(v), (d2 * r, ry[i + 1])) v = np.dot(v, cr2) ry[i + 1] = r u = reshape(u, (ry[i], n[i], r)) v = reshape(v, (d2, r, n[i + 1], ry[i + 2])) cry[i] = u cry[i + 1] = v Ry[i + 1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i + 1]))) Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1])) curind = maxvol(Ry[i + 1]) Ry[i + 1] = Ry[i + 1][curind, :] for j in range(nx): Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j])) Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j])) Rx[i + 1, j] = Rx[i + 1, j][curind, :] elif dirn < 0 and i > 0: u = np.dot(u[:, :r], np.diag(s[:r])) v = np.conj(v[:, :r]) radd = 0 rv = 1 if not last_sweep and kickrank > 0: if kicktype == 'amr-two': # compute the X superblocks ind2 = np.unique(np.random.randint( 0, ry[i - 1] * n[i - 1], ry[i])) rkick = len(ind2) curbl = np.zeros( (rkick * n[i] * ry[i + 1], nx), dtype=dtype) for j in range(nx): cr1 = reshape( crx[i, j], (rx[i, j] * n[i], rx[i + 1, j])) cr1 = np.dot(cr1, Rx[i + 1, j]) cr1 = reshape(cr1, (rx[i, j], n[i] * ry[i + 1])) cr2 = reshape( crx[i - 1, j], (rx[i - 1, j], n[i - 1] * rx[i, j])) cr2 = np.dot(Rx[i - 1, j], cr2) cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], rx[i, j])) cr2 = cr2[ind2, :] curbl[:, j] = reshape( np.dot(cr2, cr1), (rkick * n[i] * ry[i + 1],)) # calling the function uk = funs(curbl) uk = reshape(uk, (rkick * n[i] * ry[i + 1], d2)) uk = reshape(np.transpose( uk), (d2 * rkick * n[i], ry[i + 1])) uk = np.transpose(np.linalg.solve( np.transpose(Ry[i + 1]), np.transpose(uk))) uk = reshape(uk, (d2 * rkick, n[i] * ry[i + 1])) if pcatype == 'svd': vk, sk, uk = np.linalg.svd(uk, full_matrices=False) uk = np.conj(np.transpose(uk)) # TODO: refactor uk = uk[:, :min(kickrank, uk.shape[1])] else: # uk = uchol(uk, kickrank + 1) # TODO uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1] else: uk = np.random.rand(n[i] * ry[i + 1], kickrank) v, rv = np.linalg.qr(np.concatenate((v, uk), axis=1)) radd = uk.shape[1] u = np.concatenate( (u, np.zeros((d2 * ry[i], radd), dtype=dtype)), axis=1) u = np.dot(u, np.transpose(rv)) r = v.shape[1] cr2 = cry[i - 1] cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], ry[i])) u = reshape(u, (d2, ry[i] * r)) u = reshape(np.transpose(u), (ry[i], r * d2)) u = np.dot(cr2, u) u = reshape(u, (ry[i - 1] * n[i - 1] * r, d2)) u = reshape(np.transpose(u), (d2, ry[i - 1], n[i - 1], r)) v = reshape(np.transpose(v), (r, n[i], ry[i + 1])) ry[i] = r cry[i - 1] = u cry[i] = v Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ry[i + 1]) Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i + 1])) curind = maxvol(np.transpose(Ry[i])) Ry[i] = Ry[i][:, curind] for j in range(nx): Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j])) Rx[i, j] = np.dot(Rx[i, j], Rx[i + 1, j]) Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i + 1])) Rx[i, j] = Rx[i, j][:, curind] elif dirn > 0 and i == d - 1: newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])), np.conj(np.transpose(v[:, :r]))) newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2)) cry[i] = reshape(np.transpose(newy), (d2, ry[i], n[i], ry[i + 1])) elif dirn < 0 and i == 0: newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])), np.conj(np.transpose(v[:, :r]))) newy = reshape(newy, (d2, ry[i], n[i], ry[i + 1])) cry[i] = newy i = i + dirn cur_order[order_index] = cur_order[order_index] - dirn if cur_order[order_index] == 0: order_index = order_index + 1 if verb > 0: print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy, math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n))) if last_sweep: break if max_dy < eps and dirn < 0: last_sweep = True kickrank = 0 if order_index >= len(cur_order): cur_order = copy.copy(block_order) order_index = 0 if last_sweep: cur_order = [d - 1] max_dy = 0 swp = swp + 1 dirn = int(math.copysign(1, cur_order[order_index])) i = i + dirn cry[d - 1] = np.transpose(cry[d - 1][:, :, :, 0], [1, 2, 0]) y = tt.tensor.from_list(cry) return y
def setUp(self): self.Z = tt.rand(np.array([5, 6, 7, 8, 9]), r=10) self.Y = tt.tensor.to_list(self.Z) self.e = 1.E-14
def test_projector_splitting_add(self): for debug_mode in [False, True]: Y = tt.rand([5, 2, 3], 3, [1, 2, 3, 1]) my_res = riemannian.projector_splitting_add(Y.copy(), Y.copy(), debug=debug_mode) np.testing.assert_array_almost_equal(2 * Y.full(), my_res.full())
def ttSparseALS(cooP, shape, x0=None, ttRank=1, tol=1e-5, maxnsweeps=20, verbose=True, alpha=1e-2): ''' TT completion via Alternating Least Squares algorithm. Parameters: :dict: cooP dictionary with two records - 'indices': numpy.array of P x d shape, contains index subspace of P known elements; each string is an index of one element. - 'values': numpy array of size P, contains P known values. :list, numpy.array: shape full-format shape of tensor to be completed [dimensions] :tt.vector: x0 = None initial approximation of completed tensor If it is specified, parameters 'shape' and 'ttRank' will be ignored :int, numpy.array: ttRank = 1 assumed rank of completed tensor :float: tol = 1e-5 tolerance for functional value :int: maxnsweeps = 20 maximal number of sweeps [sequential optimization of all d cores in right or left direction] :boolean: verbose = True switcher of messages from function :float: alpha: = 1e-2 regularizer of least squares problem for each slice of current TT core. [rcond parameter for np.linalg.lstsq] Returns: :tt.vector: xNew completed TT vector :list: fit list of functional values at each sweep ''' indices = cooP['indices'] values = cooP['values'] [P, d] = indices.shape assert P == len(values) timeVal = time.clock() if x0 is None: x = tt.rand(shape, r = ttRank) x = x.round(0.) x = (1./x.norm())*x else: x = copy.deepcopy(x0) assert d == x.d # TODO: also check if cooP indices are aligned with shape normP = np.linalg.norm(values) values /= normP fitList = [] sweepTimeList = [] initTime = time.clock() - timeVal timeVal = time.clock() coreList = tt.vector.to_list(x) #coreList = orthLRFull(coreList, mu = d, splitResult = False) # orthTime = time.clock() - timeVal if verbose: print("Initialization time: %.3f seconds (proc.time)" % (initTime)) # print "Orthogonalizing time: %.3f seconds (proc.time)" % (orthTime) for sweep in xrange(maxnsweeps): sweepStart = time.clock() # list left + right [kStart, kEnd, kStep] = [0, d, 1] # select direction of sweep ''' if sweep % 2 == 0: # left to rigth [kStart, kEnd, kStep] = [0, d, 1] else: # right to left [kStart, kEnd, kStep] = [d-1, -1, -1] ''' # fix k-th core to update for k in xrange(kStart, kEnd, kStep): [r1, n, r2] = coreList[k].shape core = np.zeros([r1, n, r2]) leftU = [] rightV = [] if k > 0: leftU = coreList[:k] if k < d-1: rightV = coreList[k+1:] for i in xrange(n): thetaI = np.where(indices[:, k] == i)[0] if len(thetaI) > 0: A = np.zeros([len(thetaI), r1*r2]) for j in xrange(len(thetaI)): tmp = getRow(leftU, rightV, indices[thetaI[j], :]) A[j:j+1, :] += tmp # .flatten(order = 'F') vecCoreSlice, _, _, _ = np.linalg.lstsq(A, values[thetaI])#, rcond = alpha) # 0.5*np.linalg.norm(np.dot(A, vecCoreSlice) - values[thetaI])**2. core[:, i, :] += reshape(vecCoreSlice, [r1, r2]) #### ''' if k < (d-1): core = reshape(core, [r1*n, r2]) Q, R = np.linalg.qr(core) rnew = Q.shape[1] core = reshape(Q, [r1, n, rnew]) coreList[k+1] = np.einsum('ijk,li->ljk', coreList[k+1], R) ''' coreList[k] = core.copy() ''' else: if (k > 0): core = reshape(core, [r1, n*r2]) Q, R = np.linalg.qr(core.T) rnew = Q.shape[1] core = reshape(Q.T, [rnew, n, r2]) coreList[k-1] = np.einsum('ijk,lk->ijl', coreList[k-1], R) ''' xNew = tt.vector.from_list(coreList) fit = computeFunctional(xNew, cooP) fitList.append(fit) if fit < tol: break if sweep > 0: if abs(fit - fitList[-2]) < tol: break sweepTimeList.append(time.clock() - sweepStart) if verbose: print("sweep %d/%d\t fit value: %.5e\t time: %.3f seconds (proc.time)" % (sweep+1, maxnsweeps, fit, sweepTimeList[-1])) if verbose: print("Total sweep time: %.3f seconds (proc.time)\t Total time: %.3f seconds (proc.time)" % (sum(sweepTimeList), sum(sweepTimeList) + initTime))# + orthTime) info = {'fit': fitList, 'initTime': initTime, 'sweepTime': sweepTimeList} # 'orthTime': orthTime, xNew *= normP values *= normP return xNew, info
import timeit import numpy as np import pickle import argparse import tt from tt.riemannian import riemannian parser = argparse.ArgumentParser(description='Measure execution time of various t3f operations.') parser.add_argument('--file_path', help='Path to the file to save logs.') args = parser.parse_args() matrix = tt.matrix(tt.rand(100, 10, 10)) vec = tt.matrix(tt.rand(10, 10, 10), n=[10] * 10, m=[1] * 10) vec_100 = tt.matrix(tt.rand(10, 10, 100), n=[10] * 10, m=[1] * 10) tens = np.random.randn(10, 10, 10, 10) globals = {'matrix': matrix, 'vec': vec, 'vec_100': vec_100, 'tens': tens, 'tt': tt, 'riemannian': riemannian} logs = {'lib': 'ttpy'} # Warmup timeit.timeit("matrix * vec", globals=globals, number=10) matvec_time = timeit.timeit("matrix * vec", globals=globals, number=1000) / 1000 print('Multiplying a matrix by a vector takes %f seconds.' % matvec_time) logs['matvec_time'] = matvec_time matmul_time = timeit.timeit("matrix * matrix", globals=globals, number=100) / 100 print('Multiplying a matrix by a matrix takes %f seconds.' % matmul_time) logs['matmul_time'] = matmul_time
e = tt.matrix(e,1e-12) #Generate ssx, ssz ssp = [gen_1d(sp,e,i,d) for i in xrange(d)] ssz = [gen_1d(sz,e,i,d) for i in xrange(d)] ssm = [gen_1d(sm,e,i,d) for i in xrange(d)] A = None for i in xrange(d-1): A = A + 0.5 * (ssp[i] * ssm[i+1] + ssm[i] * ssp[i+1]) + (ssz[i] * ssz[i+1]) A = A.round(1e-8) return A if __name__ == '__main__': d = 60 #The dimension of the problem (number of spins) B = 5 # Number of eigenvalues sought eps = 1e-5 #Accuracy of the computations A = gen_heisen(d) n = A.n d = A.tt.d r = [B]*(d+1) r[0] = 1 r[d] = B x0 = tt.rand(n,d,r) t1 = time.time() print('Matrices are done') y, lam = eigb(A, x0, eps, max_full_size = 1000) t2 = time.time() print('Elapsed time: %3.1f' % (t2 - t1)) print('Eigenvalues: ', lam)
V = V.round(eps) A = 0.5*lp2 + tt.diag(0.5*harm + lm*V) A = A.round(eps) H = 1j*A #Generate the initial Gaussian, which is just shifted gs = np.exp(-0.5*(x-2)**2) gs = tt.tensor(gs,1e-8) start = None for i in xrange(f): start = tt.kron(start,gs) radd = 20 start = start+0*tt.rand(start.n,start.d,radd) y = start.copy() print 'initial value norm:', start.norm() cf = [] tf = 150.0 nit = 5000 tau = (tf/nit) i = 0 t = 0 import time t1 = time.time() while t <= tf: print '%f/%f' % (t,tf) y = ksl(H,y,tau) cf.append(tt.dot(y,start)) t += tau
import sys sys.path.append('../') import numpy as np import tt from tt.eigb import * import time """ This code computes many eigenvalus of the Laplacian operator """ d = 8 f = 8 A = tt.qlaplace_dd([d]*f) #A = (-1)*A #A = tt.eye(2,d) n = [2] *(d * f) r = [8] *(d * f + 1) r[0] = 1 r[d * f] = 8 #Number of eigenvalues sought x = tt.rand(n, d * f, r) #x = tt_ones(2,d) t = time.time() y, lam = eigb(A, x, 1e-6) t1 = time.time() print 'Eigenvalues:', lam print 'Time is:', t1-t
tt2.ps = np.cumsum(np.concatenate((np.ones(1), r2[:-1] * n2 * r2[1:]))) tt2.n[0] = tt2.n[0] / rl tt2.n[d2-1] = tt2.n[d2-1] / rr tt2.r[0] = rl tt2.r[d2] = rr if ismatrix: ttt = tt.eye(1,1) # dummy tt matrix ttt.n = sz_n ttt.m = sz_m ttt.tt = tt2 return ttt else: return tt2 if __name__ == '__main__': a = tt.rand(8, 6) sz = np.array([2, 4]*5) b = tt_reshape(a, sz, eps=1e-14, rl=2, rr=4) print np.linalg.norm(a.full().flatten(order = 'F') - b.full().flatten(order = 'F')) k = 4 c = tt.eye(8, k) sz = np.array([[2, 4]*(k), [2, 4]*(k)]).T d = tt_reshape(c, sz, eps=1e-14, rl=1, rr=1) print np.linalg.norm(c.full().flatten(order = 'F') - d.full().flatten(order = 'F'))
from __future__ import print_function, absolute_import, division import numpy as np import tt from . import rect_cross #Tested function def myfun(x): return np.sin((x.sum(axis=1))) #** 2 #return 1.0 / ((x.sum(axis=1)) + 1e-3) #return (x + 1).prod(axis=1) #return np.ones(x.shape[0]) d = 80 n = 5 r = 2 #sz = [n] * d #ind_all = np.unravel_index(np.arange(n ** d), sz) #ind_all = np.array(ind_all).T #ft = reshape(myfun(ind_all), sz) #xall = tt.tensor(ft, 1e-8) #x0 = tt.tensor(ft, 1e-8) x0 = tt.rand(n, d, r) x1 = rect_cross.cross(myfun, x0, nswp=5, kickrank=1, rf=2)
y = _np.dot(Phi1, y) y = _reshape(y, (ry1 * n * ry2, b)) return y if __name__ == '__main__': d = 12 n = 15 m = 15 ra = 30 rb = 10 eps = 1e-6 a = 0 * _tt.rand(n * m, d, r=ra) a = a + _tt.ones(n * m, d) #a = a.round(1e-12) a = _tt.vector.to_list(a) for i in xrange(d): sa = a[i].shape a[i] = _reshape(a[i], (sa[0], m, n, sa[-1])) A = _tt.matrix.from_list(a) b = _tt.rand(n, d, r=rb) c = amen_mv(A, b, eps, y=None, z=None, nswp=20, kickrank=4, kickrank2=0, verb=True, init_qr=True, renorm='gram', fkick=False) d = _tt.matvec(A, b).round(eps) print((c[0] - d).norm() / d.norm())
def ttSparseALS(cooP, shape, x0=None, ttRank=1, tol=1e-5, maxnsweeps=20, verbose=True, alpha=1e-2): ''' TT completion via Alternating Least Squares algorithm. Parameters: :dict: cooP dictionary with two records - 'indices': numpy.array of P x d shape, contains index subspace of P known elements; each string is an index of one element. - 'values': numpy array of size P, contains P known values. :list, numpy.array: shape full-format shape of tensor to be completed [dimensions] :tt.vector: x0 = None initial approximation of completed tensor If it is specified, parameters 'shape' and 'ttRank' will be ignored :int, numpy.array: ttRank = 1 assumed rank of completed tensor :float: tol = 1e-5 tolerance for functional value :int: maxnsweeps = 20 maximal number of sweeps [sequential optimization of all d cores in right or left direction] :boolean: verbose = True switcher of messages from function :float: alpha: = 1e-2 regularizer of least squares problem for each slice of current TT core. [rcond parameter for np.linalg.lstsq] Returns: :tt.vector: xNew completed TT vector :list: fit list of functional values at each sweep ''' indices = cooP['indices'] values = cooP['values'] [P, d] = indices.shape assert P == len(values) timeVal = time.clock() if x0 is None: x = tt.rand(shape, r=ttRank) x = x.round(0.) x = (1. / x.norm()) * x else: x = copy.deepcopy(x0) assert d == x.d # TODO: also check if cooP indices are aligned with shape normP = np.linalg.norm(values) values /= normP fitList = [] sweepTimeList = [] initTime = time.clock() - timeVal timeVal = time.clock() coreList = tt.vector.to_list(x) #coreList = orthLRFull(coreList, mu = d, splitResult = False) # orthTime = time.clock() - timeVal if verbose: print("Initialization time: %.3f seconds (proc.time)" % (initTime)) # print "Orthogonalizing time: %.3f seconds (proc.time)" % (orthTime) for sweep in xrange(maxnsweeps): sweepStart = time.clock() # list left + right [kStart, kEnd, kStep] = [0, d, 1] # select direction of sweep ''' if sweep % 2 == 0: # left to rigth [kStart, kEnd, kStep] = [0, d, 1] else: # right to left [kStart, kEnd, kStep] = [d-1, -1, -1] ''' # fix k-th core to update for k in xrange(kStart, kEnd, kStep): [r1, n, r2] = coreList[k].shape core = np.zeros([r1, n, r2]) leftU = [] rightV = [] if k > 0: leftU = coreList[:k] if k < d - 1: rightV = coreList[k + 1:] for i in xrange(n): thetaI = np.where(indices[:, k] == i)[0] if len(thetaI) > 0: A = np.zeros([len(thetaI), r1 * r2]) for j in xrange(len(thetaI)): tmp = getRow(leftU, rightV, indices[thetaI[j], :]) A[j:j + 1, :] += tmp # .flatten(order = 'F') vecCoreSlice, _, _, _ = np.linalg.lstsq( A, values[thetaI]) #, rcond = alpha) # 0.5*np.linalg.norm(np.dot(A, vecCoreSlice) - values[thetaI])**2. core[:, i, :] += reshape(vecCoreSlice, [r1, r2]) #### ''' if k < (d-1): core = reshape(core, [r1*n, r2]) Q, R = np.linalg.qr(core) rnew = Q.shape[1] core = reshape(Q, [r1, n, rnew]) coreList[k+1] = np.einsum('ijk,li->ljk', coreList[k+1], R) ''' coreList[k] = core.copy() ''' else: if (k > 0): core = reshape(core, [r1, n*r2]) Q, R = np.linalg.qr(core.T) rnew = Q.shape[1] core = reshape(Q.T, [rnew, n, r2]) coreList[k-1] = np.einsum('ijk,lk->ijl', coreList[k-1], R) ''' xNew = tt.vector.from_list(coreList) fit = computeFunctional(xNew, cooP) fitList.append(fit) if fit < tol: break if sweep > 0: if abs(fit - fitList[-2]) < tol: break sweepTimeList.append(time.clock() - sweepStart) if verbose: print( "sweep %d/%d\t fit value: %.5e\t time: %.3f seconds (proc.time)" % (sweep + 1, maxnsweeps, fit, sweepTimeList[-1])) if verbose: print( "Total sweep time: %.3f seconds (proc.time)\t Total time: %.3f seconds (proc.time)" % (sum(sweepTimeList), sum(sweepTimeList) + initTime)) # + orthTime) info = { 'fit': fitList, 'initTime': initTime, 'sweepTime': sweepTimeList } # 'orthTime': orthTime, xNew *= normP values *= normP return xNew, info
y = _np.dot(Phi1, y) y = _reshape(y, (ry1 * n * ry2, b)) return y if __name__ == '__main__': d = 12 n = 15 m = 15 ra = 30 rb = 10 eps = 1e-6 a = 0 * _tt.rand(n * m, d, r=ra) a = a + _tt.ones(n * m, d) #a = a.round(1e-12) a = _tt.vector.to_list(a) for i in xrange(d): sa = a[i].shape a[i] = _reshape(a[i], (sa[0], m, n, sa[-1])) A = _tt.matrix.from_list(a) b = _tt.rand(n, d, r=rb) c = amen_mv(A, b, eps, y=None, z=None,
def solver_tt(gas_params, problem, mesh, nt, nv, vx_, vx, vy, vz, \ CFL, tol, filename, init = '0'): """Solve Boltzmann equation with model collision integral gas_params -- object of class GasParams, contains gas parameters and viscosity law problem -- object of class Problem, contains list of boundary conditions, data for b.c., and function for initial condition mesh - object of class Mesh nt -- number of time steps vmax -- maximum velocity in each direction in velocity mesh nv -- number of nodes in velocity mesh CFL -- courant number filename -- name of output file for f init - name of restart file """ # Function for LU-SGS mydivide = lambda x: x[:, 0] / x[:, 1] zero_tt = 0. * tt.ones((nv, nv, nv)) ones_tt = tt.ones((nv, nv, nv)) # # Initialize main arrays and lists # vn = [None ] * mesh.nf # list of tensors of normal velocities at each mesh face vn_tmp = np.zeros((nv, nv, nv)) vnm = [None] * mesh.nf # negative part of vn: 0.5 * (vn - |vn|) vnp = [None] * mesh.nf # positive part of vn: 0.5 * (vn + |vn|) vn_abs = [None] * mesh.nf # approximations of |vn| vx_tt = tt.tensor(vx).round(tol) vy_tt = tt.tensor(vy).round(tol) vz_tt = tt.tensor(vz).round(tol) vn_error = 0. for jf in range(mesh.nf): vn_tmp = mesh.face_normals[jf, 0] * vx + mesh.face_normals[ jf, 1] * vy + mesh.face_normals[jf, 2] * vz vn[jf] = mesh.face_normals[jf, 0] * vx_tt + mesh.face_normals[ jf, 1] * vy_tt + mesh.face_normals[jf, 2] * vz_tt vnp[jf] = tt.tensor(np.where(vn_tmp > 0, vn_tmp, 0.), eps=tol) vnm[jf] = tt.tensor(np.where(vn_tmp < 0, vn_tmp, 0.), eps=tol) vn_abs[jf] = tt.tensor(np.abs(vn_tmp), rmax=4) vn_error = max( vn_error, np.linalg.norm(vn_abs[jf].full() - np.abs(vn_tmp)) / np.linalg.norm(np.abs(vn_tmp))) print('max||vn_abs_tt - vn_abs||_F/max||vn_abs||_F = ', vn_error) h = np.min(mesh.cell_diam) tau = h * CFL / (np.max(vx_) * (3.**0.5)) v2 = (vx_tt * vx_tt + vy_tt * vy_tt + vz_tt * vz_tt).round(tol) diag = [None] * mesh.nc # part of diagonal coefficient in implicit scheme # precompute diag diag_full = np.zeros( (mesh.nc, nv, nv, nv)) # part of diagonal coefficient in implicit scheme # precompute diag for ic in range(mesh.nc): for j in range(6): jf = mesh.cell_face_list[ic, j] vn_tmp = mesh.face_normals[jf, 0] * vx + mesh.face_normals[ jf, 1] * vy + mesh.face_normals[jf, 2] * vz vnp_full = np.where( mesh.cell_face_normal_direction[ic, j] * vn_tmp[:, :, :] > 0, mesh.cell_face_normal_direction[ic, j] * vn_tmp[:, :, :], 0.) diag_full[ic, :, :, :] += (mesh.face_areas[jf] / mesh.cell_volumes[ic]) * vnp_full for ic in range(mesh.nc): diag_temp = np.zeros((nv, nv, nv)) for j in range(6): jf = mesh.cell_face_list[ic, j] vn_full = (mesh.face_normals[jf, 0] * vx + mesh.face_normals[jf, 1] * vy \ + mesh.face_normals[jf, 2] * vz) * mesh.cell_face_normal_direction[ic, j] vnp_full = np.where(vn_full > 0, vn_full, 0.) vn_abs_full = np.abs(vn_full) diag_temp += (mesh.face_areas[jf] / mesh.cell_volumes[ic]) * vnp_full # diag_temp += 0.5 * (mesh.face_areas[jf] / mesh.cell_volumes[ic]) * vn_abs_full diag[ic] = tt.tensor(diag_temp) # Compute mean rank of diag diag_rank = 0. for ic in range(mesh.nc): diag_rank += 0.5 * (diag[ic].r[1] + diag[ic].r[2]) diag_rank = diag_rank / ic print('diag_rank = ', diag_rank) # diag_scal = np.zeros(mesh.nc) for ic in range(mesh.nc): for j in range(6): jf = mesh.cell_face_list[ic, j] diag_scal[ic] += 0.5 * (mesh.face_areas[jf] / mesh.cell_volumes[ic]) diag_scal *= np.max(np.abs(vx_)) * 3**0.5 # set initial condition f = [None] * mesh.nc if (init == '0'): for i in range(mesh.nc): x = mesh.cell_center_coo[i, 0] y = mesh.cell_center_coo[i, 1] z = mesh.cell_center_coo[i, 2] f[i] = problem.f_init(x, y, z, vx, vy, vz) else: # restart from distribution function # f = load_tt(init, mesh.nc, nv) # restart form macroparameters array init_data = np.loadtxt(init) for ic in range(mesh.nc): f[ic] = tt.tensor(f_maxwell(vx, vy, vz, init_data[ic, 5], \ init_data[ic, 0], init_data[ic, 1], init_data[ic, 2], init_data[ic, 3], gas_params.Rg), tol) # TODO: may be join f_plus and f_minus in one array f_plus = [None] * mesh.nf # Reconstructed values on the right f_minus = [None] * mesh.nf # reconstructed values on the left flux = [None] * mesh.nf # Flux values rhs = [None] * mesh.nc df = [None] * mesh.nc # Arrays for macroparameters n = np.zeros(mesh.nc) rho = np.zeros(mesh.nc) ux = np.zeros(mesh.nc) uy = np.zeros(mesh.nc) uz = np.zeros(mesh.nc) p = np.zeros(mesh.nc) T = np.zeros(mesh.nc) nu = np.zeros(mesh.nc) rank = np.zeros(mesh.nc) data = np.zeros((mesh.nc, 7)) # Dummy tensor with [1, 1, 1, 1] ranks F = tt.rand([nv, nv, nv], 3, [1, 1, 1, 1]) frob_norm_iter = np.array([]) it = 0 while (it < nt): it += 1 # reconstruction for inner faces # 1st order for ic in range(mesh.nc): for j in range(6): jf = mesh.cell_face_list[ic, j] if (mesh.cell_face_normal_direction[ic, j] == 1): f_minus[jf] = f[ic].copy() else: f_plus[jf] = f[ic].copy() # boundary condition # loop over all boundary faces for j in range(mesh.nbf): jf = mesh.bound_face_info[j, 0] # global face index bc_num = mesh.bound_face_info[j, 1] bc_type = problem.bc_type_list[bc_num] bc_data = problem.bc_data[bc_num] if (mesh.bound_face_info[j, 2] == 1): f_plus[jf] = set_bc_tt(gas_params, bc_type, bc_data, f_minus[jf], vx, vy, vz, vn[jf], vnp[jf], vnm[jf], tol) else: f_minus[jf] = set_bc_tt(gas_params, bc_type, bc_data, f_plus[jf], vx, vy, vz, -vn[jf], -vnm[jf], -vnp[jf], tol) # riemann solver - compute fluxes for jf in range(mesh.nf): flux[jf] = 0.5 * mesh.face_areas[jf] *\ ((f_plus[jf] + f_minus[jf]) * vn[jf] - (f_plus[jf] - f_minus[jf]) * vn_abs[jf]) flux[jf] = flux[jf].round(tol) # computation of the right-hand side for ic in range(mesh.nc): rhs[ic] = zero_tt.copy() # sum up fluxes from all faces of this cell for j in range(6): jf = mesh.cell_face_list[ic, j] rhs[ic] += -(mesh.cell_face_normal_direction[ic, j]) * ( 1. / mesh.cell_volumes[ic]) * flux[jf] rhs[ic] = rhs[ic].round(tol) # Compute macroparameters and collision integral J, n[ic], ux[ic], uy[ic], uz[ic], T[ic], nu[ic], rho[ic], p[ ic] = comp_macro_param_and_j_tt(f[ic], vx_, vx, vy, vz, vx_tt, vy_tt, vz_tt, v2, gas_params, tol, F, ones_tt) rhs[ic] += J rhs[ic] = rhs[ic].round(tol) frob_norm_iter = np.append( frob_norm_iter, np.sqrt(sum([(rhs[ic].norm())**2 for ic in range(mesh.nc)]))) # # update values, expclicit scheme # for ic in range(mesh.nc): f[ic] = (f[ic] + tau * rhs[ic]).round(tol) # save rhs norm and tec tile if ((it % 100) == 0): fig, ax = plt.subplots(figsize=(20, 10)) line, = ax.semilogy(frob_norm_iter / frob_norm_iter[0]) ax.set(title='$Steps =$' + str(it)) plt.savefig('norm_iter.png') plt.close() data[:, 0] = n[:] data[:, 1] = ux[:] data[:, 2] = uy[:] data[:, 3] = uz[:] data[:, 4] = p[:] data[:, 5] = T[:] data[:, 6] = rank[:] write_tecplot(mesh, data, 'tec_tt.dat', ('n', 'ux', 'uy', 'uz', 'p', 'T', 'rank')) save_tt(filename, f, mesh.nc, nv) Return = namedtuple( 'Return', ['f', 'n', 'ux', 'uy', 'uz', 'T', 'p', 'rank', 'frob_norm_iter']) S = Return(f, n, ux, uy, uz, T, p, rank, frob_norm_iter) return S
def amen_mv(A, x, tol, y=None, z=None, nswp=20, kickrank=4, kickrank2=0, verb=True, init_qr=True, renorm='direct', fkick=False): ''' Approximate the matrix-by-vector via the AMEn iteration [y,z]=amen_mv(A, x, tol, varargin) Attempts to approximate the y = A*x with accuracy TOL using the AMEn+ALS iteration. Matrix A has to be given in the TT-format, right-hand side x should be given in the TT-format also. Options are provided in form 'PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2 and so on. The parameters are set to default (in brackets in the following) The list of option names and default values are: o y0 - initial approximation to Ax [rand rank-2] o nswp - maximal number of sweeps [20] o verb - verbosity level, 0-silent, 1-sweep info, 2-block info [1] o kickrank - compression rank of the error, i.e. enrichment size [3] o init_qr - perform QR of the input (save some time in ts, etc) [true] o renorm - Orthog. and truncation methods: direct (svd,qr) or gram (apply svd to the gram matrix, faster for m>>n) [direct] o fkick - Perform solution enrichment during forward sweeps [false] (rather questionable yet; false makes error higher, but "better structured": it does not explode in e.g. subsequent matvecs) o z0 - initial approximation to the error Ax-y [rand rank-kickrank] ******** For description of adaptive ALS please see Sergey V. Dolgov, Dmitry V. Savostyanov, Alternating minimal energy methods for linear systems in higher dimensions. Part I: SPD systems, http://arxiv.org/abs/1301.6068, Part II: Faster algorithm and application to nonsymmetric systems, http://arxiv.org/abs/1304.1222 Use {sergey.v.dolgov, dmitry.savostyanov}@gmail.com for feedback ******** ''' if renorm is 'gram': print "Not implemented yet. Renorm is switched to 'direct'" renorm = 'direct' if isinstance(x, _tt.vector): d = x.d m = x.n rx = x.r x = _tt.vector.to_list(x) vectype = 1 # tt_tensor elif isinstance(x, list): d = len(x) m = _np.zeros(d) rx = _np.ones(d + 1) for i in xrange(d): [_, m[i], rx[i + 1]] = x[i].shape vectype = 0 # cell else: raise Exception('x: use tt.tensor or list of cores as numpy.arrays') if isinstance(A, _tt.matrix): n = A.n ra = A.tt.r A = _tt.matrix.to_list(A) # prepare A for fast ALS-mv for i in xrange(d): A[i] = _reshape(A[i], (ra[i] * n[i], m[i] * ra[i + 1])) atype = 1 # tt_matrix # Alternative: A is a cell of cell: sparse canonical format elif isinstance(A, list): n = _np.zeros(d) for i in xrange(d): n[i] = A[i][0].shape[0] ra = len(A[0]) atype = 0 # cell else: raise Exception('A: use tt.matrix or list of cores as numpy.arrays') if y is None: y = _tt.rand(n, d, 2) y = _tt.vector.to_list(y) else: if isinstance(y, _tt.vector): y = _tt.vector.to_list(y) ry = _np.ones(d + 1) for i in range(d): ry[i + 1] = y[i].shape[2] if (kickrank + kickrank2 > 0): if z is None: z = _tt.rand(n, d, kickrank + kickrank2) rz = z.r z = _tt.vector.to_list(z) else: if isinstance(z, _tt.vector): z = _tt.vector.to_list(z) rz = _np.ones(d + 1) for i in range(d): rz[i + 1] = z[i].shape[2] phizax = [None] * (d + 1) # cell(d+1,1); if (atype == 1): phizax[0] = _np.ones((1, 1, 1)) # 1 phizax[d] = _np.ones((1, 1, 1)) # 1 else: phizax[0] = _np.ones((1, ra)) # 33 phizax[d] = _np.ones((1, ra)) phizy = [None] * (d + 1) phizy[0] = _np.ones((1)) # , 1)) phizy[d] = _np.ones((1)) # , 1)) phiyax = [None] * (d + 1) if (atype == 1): phiyax[0] = _np.ones((1, 1, 1)) # 1 phiyax[d] = _np.ones((1, 1, 1)) # 1 else: phiyax[0] = _np.ones((1, ra)) # 3 phiyax[d] = _np.ones((1, ra)) nrms = _np.ones(d) # Initial ort for i in range(d - 1): if init_qr: cr = _reshape(y[i], (ry[i] * n[i], ry[i + 1])) if (renorm is 'gram') and (ry[i] * n[i] > 5 * ry[i + 1]): [cr, s, R] = _svdgram(cr) else: [cr, R] = _np.linalg.qr(cr) nrmr = _np.linalg.norm(R) # , 'fro') if (nrmr > 0): R = R / nrmr cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2])) cr2 = _np.dot(R, cr2) ry[i + 1] = cr.shape[1] y[i] = _reshape(cr, (ry[i], n[i], ry[i + 1])) y[i + 1] = _reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2])) [phiyax[i + 1], nrms[i]] = _compute_next_Phi(phiyax[i], y[i], x[i], 'lr', A[i]) if (kickrank + kickrank2 > 0): cr = _reshape(z[i], (rz[i] * n[i], rz[i + 1])) if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]): [cr, s, R] = _svdgram(cr) else: [cr, R] = _np.linalg.qr(cr) nrmr = _np.linalg.norm(R) # , 'fro') if (nrmr > 0): R = R / nrmr cr2 = _reshape(z[i + 1], (rz[i + 1], n[i + 1] * rz[i + 2])) cr2 = _np.dot(R, cr2) rz[i + 1] = cr.shape[1] z[i] = _reshape(cr, (rz[i], n[i], rz[i + 1])) z[i + 1] = _reshape(cr2, (rz[i + 1], n[i + 1], rz[i + 2])) phizax[i + 1] = _compute_next_Phi(phizax[i], z[i], x[i], 'lr', A[i], nrms[i], return_norm=False) phizy[i + 1] = _compute_next_Phi(phizy[i], z[i], y[i], 'lr', return_norm=False) i = d - 1 direct = -1 swp = 1 max_dx = 0 while swp <= nswp: # Project the MatVec generating vector crx = _reshape(x[i], (rx[i] * m[i] * rx[i + 1], 1)) cry = _bfun3(phiyax[i], A[i], phiyax[i + 1], crx) nrms[i] = _np.linalg.norm(cry) # , 'fro') # The main goal is to keep y[i] of norm 1 if (nrms[i] > 0): cry = cry / nrms[i] else: nrms[i] = 1 y[i] = _reshape(y[i], (ry[i] * n[i] * ry[i + 1], 1)) dx = _np.linalg.norm(cry - y[i]) max_dx = max(max_dx, dx) # Truncation and enrichment if ((direct > 0) and (i < d - 1)): # ?? i<d cry = _reshape(cry, (ry[i] * n[i], ry[i + 1])) if (renorm == 'gram'): [u, s, v] = _svdgram(cry, tol / d**0.5) v = v.T r = u.shape[1] else: [u, s, vt] = _np.linalg.svd(cry, full_matrices=False) #s = diag(s) r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5) u = u[:, :r] # ????? s - matrix or vector v = _np.dot(_tconj(vt[:r, :]), _np.diag(s[:r])) # Prepare enrichment, if needed if (kickrank + kickrank2 > 0): cry = _np.dot(u, v.T) cry = _reshape(cry, (ry[i] * n[i], ry[i + 1])) # For updating z crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx) crz = _reshape(crz, (rz[i] * n[i], rz[i + 1])) ys = _np.dot(cry, phizy[i + 1]) yz = _reshape(ys, (ry[i], n[i] * rz[i + 1])) yz = _np.dot(phizy[i], yz) yz = _reshape(yz, (rz[i] * n[i], rz[i + 1])) crz = crz / nrms[i] - yz nrmz = _np.linalg.norm(crz) # , 'fro') if (kickrank2 > 0): [crz, _, _] = _np.linalg.svd(crz, full_matrices=False) crz = crz[:, :min(crz.shape[1], kickrank)] crz = _np.hstack( (crz, _np.random.randn(rz[i] * n[i], kickrank2))) # For adding into solution if fkick: crs = _bfun3(phiyax[i], A[i], phizax[i + 1], crx) crs = _reshape(crs, (ry[i] * n[i], rz[i + 1])) crs = crs / nrms[i] - ys u = _np.hstack((u, crs)) if (renorm == 'gram') and (ry[i] * n[i] > 5 * (ry[i + 1] + rz[i + 1])): [u, s, R] = _svdgram(u) else: [u, R] = _np.linalg.qr(u) v = _np.hstack((v, _np.zeros((ry[i + 1], rz[i + 1])))) v = _np.dot(v, R.T) r = u.shape[1] y[i] = _reshape(u, (ry[i], n[i], r)) cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2])) v = _reshape(v, (ry[i + 1], r)) cr2 = _np.dot(v.T, cr2) y[i + 1] = _reshape(cr2, (r, n[i + 1], ry[i + 2])) ry[i + 1] = r [phiyax[i + 1], nrms[i]] = _compute_next_Phi(phiyax[i], y[i], x[i], 'lr', A[i]) if (kickrank + kickrank2 > 0): if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]): [crz, s, R] = _svdgram(crz) else: [crz, R] = _np.linalg.qr(crz) rz[i + 1] = crz.shape[1] z[i] = _reshape(crz, (rz[i], n[i], rz[i + 1])) # z[i+1] will be recomputed from scratch in the next step phizax[i + 1] = _compute_next_Phi(phizax[i], z[i], x[i], 'lr', A[i], nrms[i], return_norm=False) phizy[i + 1] = _compute_next_Phi(phizy[i], z[i], y[i], 'lr', return_norm=False) elif ((direct < 0) and (i > 0)): cry = _reshape(cry, (ry[i], n[i] * ry[i + 1])) if (renorm == 'gram'): [v, s, u] = _svdgram(cry.T, tol / d**0.5) u = u.T r = v.shape[1] else: #[v, s, u] = _np.linalg.svd(cry.T, full_matrices=False) [u, s, vt] = _np.linalg.svd(cry, full_matrices=False) #s = diag(s); r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5) v = _tconj(vt[:r, :]) #v = vt[:r, :] #v = _np.dot(v[:, :r], _np.diag(s[:r])) u = _np.dot(u[:, :r], _np.diag(s[:r])) # ?????????????????? # Prepare enrichment, if needed if (kickrank + kickrank2 > 0): cry = _np.dot(u, v.T) # .T) cry = _reshape(cry, (ry[i], n[i] * ry[i + 1])) # For updating z crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx) crz = _reshape(crz, (rz[i], n[i] * rz[i + 1])) ys = _np.dot(phizy[i], cry) yz = _reshape(ys, (rz[i] * n[i], ry[i + 1])) yz = _np.dot(yz, phizy[i + 1]) yz = _reshape(yz, (rz[i], n[i] * rz[i + 1])) crz = crz / nrms[i] - yz nrmz = _np.linalg.norm(crz) # , 'fro') if (kickrank2 > 0): [_, _, crz] = _np.linalg.svd(crz, full_matrices=False) crz = crz[:, :min(crz.shape[1], kickrank)] crz = _tconj(crz) crz = _np.vstack( (crz, _np.random.randn(kickrank2, n[i] * rz[i + 1]))) # For adding into solution crs = _bfun3(phizax[i], A[i], phiyax[i + 1], crx) crs = _reshape(crs, (rz[i], n[i] * ry[i + 1])) crs = crs / nrms[i] - ys v = _np.hstack((v, crs.T)) # .T #v = v.T if (renorm == 'gram') and (n[i] * ry[i + 1] > 5 * (ry[i] + rz[i])): [v, s, R] = _svdgram(v) else: [v, R] = _np.linalg.qr(v) u = _np.hstack((u, _np.zeros((ry[i], rz[i])))) u = _np.dot(u, R.T) r = v.shape[1] cr2 = _reshape(y[i - 1], (ry[i - 1] * n[i - 1], ry[i])) cr2 = _np.dot(cr2, u) y[i - 1] = _reshape(cr2, (ry[i - 1], n[i - 1], r)) y[i] = _reshape(v.T, (r, n[i], ry[i + 1])) ry[i] = r [phiyax[i], nrms[i]] = _compute_next_Phi(phiyax[i + 1], y[i], x[i], 'rl', A[i]) if (kickrank + kickrank2 > 0): if (renorm == 'gram') and (n[i] * rz[i + 1] > 5 * rz[i]): [crz, s, R] = _svdgram(crz.T) else: [crz, R] = _np.linalg.qr(crz.T) rz[i] = crz.shape[1] z[i] = _reshape(crz.T, (rz[i], n[i], rz[i + 1])) # don't update z[i-1], it will be recomputed from scratch phizax[i] = _compute_next_Phi(phizax[i + 1], z[i], x[i], 'rl', A[i], nrms[i], return_norm=False) phizy[i] = _compute_next_Phi(phizy[i + 1], z[i], y[i], 'rl', return_norm=False) if (verb > 1): print 'amen-mv: swp=[%d,%d], dx=%.3e, r=%d, |y|=%.3e, |z|=%.3e' % ( swp, i, dx, r, _np.linalg.norm(cry), nrmz) # Stopping or reversing if ((direct > 0) and (i == d - 1)) or ((direct < 0) and (i == 0)): if (verb > 0): print 'amen-mv: swp=%d{%d}, max_dx=%.3e, max_r=%d' % ( swp, (1 - direct) / 2, max_dx, max(ry)) if ((max_dx < tol) or (swp == nswp)) and (direct > 0): break else: # We are at the terminal block y[i] = _reshape(cry, (ry[i], n[i], ry[i + 1])) if (direct > 0): swp = swp + 1 max_dx = 0 direct = -direct else: i = i + direct # if (direct>0) y[d - 1] = _reshape(cry, (ry[d - 1], n[d - 1], ry[d])) # else # y{1} = reshape(cry, ry(1), n(1), ry(2)); # end; # Distribute norms equally... nrms = _np.exp(sum(_np.log(nrms)) / d) # ... and plug them into y for i in xrange(d): y[i] = _np.dot(y[i], nrms) if (vectype == 1): y = _tt.vector.from_list(y) if kickrank == 0: z = None else: z = _tt.vector.from_list(z) return y, z
import sys sys.path.append("../") import tt #import ctypes as ct #ct.CDLL("libblas.so.3", ct.RTLD_GLOBAL) #ct.CDLL("libcblas.so.1", ct.RTLD_GLOBAL) #ct.CDLL("liblapacke.so", ct.RTLD_GLOBAL) import numpy as np a = tt.rand([3, 5, 7, 11], 4, [1, 4, 6, 5, 1]) b = tt.rand([3, 5, 7, 11], 4, [1, 2, 4, 3, 1]) c = tt.multifuncrs2([a, b], lambda x: np.sum(x, axis=1), eps=1E-6) print "Relative error norm:", (c - (a + b)).norm() / (a + b).norm()
def prep(self): ''' Construct function values on the spatial grid. OUTPUT: FN - self type: fpcross.Func TODO If Y0 is not set, how select best random value (rank, etc.)? TODO Set more accurate algorithm for tt-round of initial guess. TODO Add catch (we should always remove log file). ''' if self.Y is not None: raise ValueError('Function values are already prepared.') if self.f is None: raise ValueError('Function is not set. Can not prepare.') if self.with_tt: def func(ind): t = tpc() X = self.SG.comp(ind) Y = self.f(X, ind) if self.opts['is_f_with_i'] else self.f(X) self.tms['func'] += tpc() - t self.res['evals'] += X.shape[1] return Y def func_v(ind): ind = ind.T.astype(int) return func(ind) def func_s(ind): ind = ind.T.astype(int) Y = np.zeros(ind.shape[1]) for j in range(ind.shape[1]): nm = '-'.join([str(i) for i in ind[:, j]]) if nm in self.Y_hst: y = self.Y_hst[nm] else: y = func(ind[:, j].reshape(-1, 1))[0] self.Y_hst[nm] = y Y[j] = y return Y f = func_s if self.opts['with_Y_hst'] else func_v log_file = './__tt-cross_tmp.txt' if self.opts['Y0'] is None: Z = tt.rand(self.SG.n, self.SG.d, 1) else: Z = self.opts['Y0'].copy() rmax = None for n, r in zip(self.SG.n, Z.r[1:]): if r > n and (rmax is None or rmax > n): rmax = n if rmax is not None: Z = Z.round(rmax=rmax) try: log = open(log_file, 'w') stdout0 = sys.stdout sys.stdout = log self.Y = cross(f, Z, eps=self.eps, nswp=self.opts['nswp'], kickrank=self.opts['kickrank'], rf=self.opts['rf'], verbose=True) finally: log.close() sys.stdout = stdout0 self.tms['func'] /= (self.res['evals'] or 1) log = open(log_file, 'r') res = log.readlines()[-1].split('swp: ')[1] self.res['iters'] = int(res.split('/')[0]) + 1 res = res.split('er_rel = ')[1] self.res['err_rel'] = float(res.split('er_abs = ')[0]) res = res.split('er_abs = ')[1] self.res['err_abs'] = float(res.split('erank = ')[0]) res = res.split('erank = ')[1] self.res['erank'] = float(res.split('fun_eval')[0]) log.close() os.remove(log_file) if self.opts['Y0'] is None: self.err0 = None else: Y1 = self.opts['Y0'] Y2 = self.Y self.err0 = (Y1 - Y2).norm() / Y2.norm() else: self.tms['func'] = tpc() if self.opts['is_f_with_i']: I = self.SG.comp(is_ind=True) X = self.SG.comp(I) Y = self.f(X, I) else: X = self.SG.comp() Y = self.f(X) self.Y = Y.reshape(self.SG.n, order='F') if self.opts['Y0'] is None: self.err0 = None else: Y1 = self.opts['Y0'] Y2 = self.Y self.err0 = np.linalg.norm(Y1 - Y2) / np.linalg.norm(Y2) self.res['evals'] = X.shape[1] self.tms['func'] = (tpc() - self.tms['func']) / self.res['evals']
def demo_completion(): d = 3 n=20 crossR=18 shape = np.array([n]*d) def func(X): return 1./(1+(X - n/2)**2).sum(axis = 1)**0.5 # tt-approximation built via cross approximation x0 = tt.rand(np.array([n]*d), r = crossR) tta = cross(func, x0) print("TT-cross ranks: ", tta.r) R = 10 gamma = 0.25 P = int(np.floor(gamma*d*n*(R**2))) Pb = 100 # random choice indices = np.random.choice(n, [P, d]) indicesB = np.random.choice(n, [Pb, d]) # making list of tupled stings [indices] indices = [tuple(indices[k, :]) for k in xrange(indices.shape[0])] indicesB = [tuple(indicesB[k, :]) for k in xrange(indicesB.shape[0])] # set naturally filters input to be unique indices = set(indices) indicesB = set(indicesB) # convert it into list indices = list(indices) indicesB = list(indicesB) # return into numpy.array form indices = np.array(indices) indicesB = np.array(indicesB) print("Unique sample points: %d/%d (%d)" % (indices.shape[0], P, n**d)) vals = func(indices) cooP = {'values': vals, 'indices': indices} cooPb = {'values': func(indicesB), 'indices': indicesB} maxR = 5 x0 = tt.rand(shape, r=1) x0 = x0 * (1./ x0.norm()) x0 = x0.round(0.) # verbose vb = True X1, f = ttSparseALS( cooP, shape, x0=None, ttRank=maxR, maxnsweeps=50, verbose=vb, tol=1e-8, alpha = 1e-3 ) # Restore original, initial and approximation into full-format (do not try it in higher dimensions!) xf1 = X1.full() # approximation ALS a = tta.full() # original b = np.zeros([n]*d) # initial for p in xrange(indices.shape[0]): b[tuple(indices[p,:])] += vals[p] # Visualize slices of original, completed and initial tensors. Colormap is standartized. plt.clf() M = [a, xf1, b] titles = ['Original', 'Completed (ALS)', 'Initial'] nRow = n nCol = 3 fig = plt.figure(figsize=(5*nCol, nRow*5)) gs = gridspec.GridSpec(nRow, nCol, wspace=0., hspace=1e-2, right=1-0.5/nCol)#top=1 - 0.5/nRow, #bottom=0.5/nRow, left=0.5/nCol, right=1 - 0.5/nCol) for k in xrange(nRow): vmin = [x[k, :, :].min() for x in M] vmax = [x[k, :, :].max() for x in M] vmin = min( vmin) vmax = max( vmax) for l in xrange(nCol): ax = plt.subplot(gs[k, l]) im = ax.imshow(M[l][k, :, :].T, vmin=vmin, vmax=vmax, interpolation='none') ax.set_axis_off() ax.set_xticklabels([]) ax.set_yticklabels([]) if k == 0: ax.set_title(titles[l], fontsize=20) if l == (nCol-1): box = ax.get_position() ax.set_position([box.x0*1.05, box.y0, box.width, box.height]) axColor = plt.axes([box.x0*1.05 + box.width * 1.05, box.y0, 0.01, box.height]) fig.colorbar(im, cax = axColor) #fig.subplots_adjust(right = 0.5) #cbar_ax = fig.add_axes([0.55, 0.45, 0.005, 0.11]) #fig.colorbar(im, cax=cbar_ax) #fig.subplots_adjust(wspace=0., hspace=0.) plt.savefig('demo_completion_gridplot.pdf', dpi=300) #fig.show() # plot functional curves plt.clf() fig = plt.figure() plt.semilogy(f['fit'], label='ALS') plt.xlabel('It.num.') plt.ylabel('ln( Fit )') plt.grid(True) plt.legend() plt.title('Funval ALS') plt.savefig('demo_completion_fitplot.pdf', dpi=300)