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 add_to_final_mass_matrix(f, Ml, eps, d): rhs = tt.ones(4, d) # Впечатываем куда надо диагональные элементы if f is None: f = tt.matvec(Ml, rhs) else: f += tt.matvec(Ml, rhs) return f.round(eps)
def full_matrix(A, Qs, t0, pt, dt): support = -tt.delta(2, pt, center = 1) + tt.delta(2, pt, center = 0) G_t = tt.Toeplitz(support,kind='L').T G_t = G_t.round(1e-14) support = tt.delta(2, pt, center = 1) + tt.delta(2, pt, center = 0) M_t = tt.Toeplitz(support,kind='L').T M_t = M_t.round(1e-14) px = A.n.shape[0] Id = tt.eye(2, px) A_full = tt.kron(Id, G_t) - 0.5 * dt * tt.kron(A, M_t) A_full = A_full.round(1e-14) # collected full matrix A e1 = tt.delta(2, pt, center = 0) left = t0 + 0.5* dt * tt.matvec(A, t0) left = left.round(1e-14) left = tt.kron(left, e1) left = left.round(1e-14) right = dt * Qs Qs_full = left + right Qs_full = Qs_full.round(1e-14) return A_full, Qs_full
def windowed_mean_dimension(wst, mode='cross', eps=1e-6, verbose=False, **kwargs): """ Given a windowed Sobol TT, return a TT with the mean dimension of every window :param wst: :return: """ assert mode in ('matvec', 'cross') N = wst.tt.d if verbose: print('Computing windowed mean dimension tensor...') if mode == 'matvec': return tt.matvec(wst, tr.core.hamming_weight(N)) else: wst = wst.tt cores = tt.vector.to_list(tr.core.hamming_weight(N)) for n in range(N): cores[n] = cores[n][:, np.concatenate([np.zeros(wst.n[n]//2, dtype=np.int), np.ones(wst.n[n]//2, dtype=np.int)]), :] h = tt.vector.from_list(cores) wmd = tt.multifuncrs2([wst, h], lambda x: x[:, 0] * x[:, 1], eps=eps, verb=verbose, **kwargs) wmd = tt.vector.from_list([core[:, :core.shape[1]//2, :] + core[:, core.shape[1]//2:, :] for core in tt.vector.to_list(wmd)]) return wmd
def apply_mask(A, f, mask, eps=1e-8): """ Apply boundary mask on tt-stiffness matrix and tt-force vector :param A: :param f: :param mask: :return: """ d = A.tt.d return (mask * A + tt.eye(4, d) - mask).round(eps), tt.matvec(mask, f).round(eps)
def matvec(self, other): if not isinstance(other, Vector): raise ValueError('Incorrect input.') if self.isnone or other.isnone or self.mode != other.mode or self.d != other.d: raise ValueError('Incorrect input.') res = other.copy(copy_x=False) if self.mode == MODE_NP or self.mode == MODE_SP: res.x = self.x.dot(other.x) if self.mode == MODE_TT: res.x = tt.matvec(self.x, other.x) res = res.round([self.tau, other.tau]) return res
def parallel_worker(task_id, H, operators, guess_generator, rank, tau, n_steps, callbacks=[], **kwargs): """ Parallel worker for the calculation of the expectation value of an operator Parameters: ----------- H: tt.matrix hamiltonain matrix in the TT format operators: iterable of tt.matrix matrix of the operator in the TT format guess_generator: function initial vector generator rank: int TT rank of the initial vector tau: float time step n_steps: number of steps of the dynamics callbacks: list, default [] list of extra callbacks. The callback has to have a signature (tt.vector) -> Scalar. The callback will receive the wavefunction, and the result will be collected. The results of the callbacks are stored in the matrix along with mean values of the operators. Returns: -------- (time, evs) : (np.array, np.array) time array and array of expectation values """ # np.random.seed(seed) psi = guess_generator(H, rank) time = [] evs = [] t = 0 psi = ksl(A=-1j * H, y0=psi, tau=1e-10, **kwargs) for i in range(n_steps): ev = [] for operator in operators: ev.append(tt.dot(tt.matvec(operator, psi), psi)) for func in callbacks: ev.append(func(psi)) time.append(t) evs.append(ev) # update psi = ksl(A=-1j * H, y0=psi, tau=tau, **kwargs) t += tau evs = np.array(evs).real time = np.array(time) return time, evs
def collect_ev_sequential(H, operators, guess_generator, rank, n_samples, tau, n_steps, filename=None, append_file=True, dump_every=0, callbacks=[], **kwargs): """ Generate the expectation value of a provided operator in the dynamical process generated by the hamiltonian H. The dynamics starts from the initial vector, which is generated by the guess_generator Parameters: ----------- H: tt.matrix hamiltonain matrix in the TT format operators: iterable of tt.matrix or tt.matrix matrices of the operators in the TT format guess_generator: function initial vector generator rank: int TT rank of the initial vector n_samples: int number of sample trajectories tau: float time step n_steps: number of steps of the dynamics filename: str, default None filename to output results. The file is appended if exists append_file: bool, default True if we append to the existing file instead of replacing it dump_every: int, default 0 dump current results every n parallel rounds. Default is 0. callbacks: list, default [] list of extra callbacks. The callback has to have a signature (tt.vector) -> Scalar. The callback will receive the wavefunction, and the result will be collected. The results of the callbacks are stored in the matrix along with mean values of the operators. Returns: -------- (time, evs) : (np.array, np.array) time array and array of expectation values """ # ensure that operators is iterable if not isinstance(operators, Iterable): operators = [operators] evs_all_l = [] for s in tqdm(range(n_samples), desc="guess={}, n_steps={}".format(guess_generator.__name__, n_steps)): # np.random.seed(s) psi = guess_generator(H, rank) time_l = [] evs = [] t = 0 psi = ksl(A=-1j * H, y0=psi, tau=1e-10, **kwargs) for i in range(n_steps): ev = [] for operator in operators: ev.append(tt.dot(tt.matvec(operator, psi), psi)) for func in callbacks: ev.append(func(psi)) time_l.append(t) evs.append(ev) # update psi = ksl(A=-1j * H, y0=psi, tau=tau, **kwargs) t += tau evs_all_l.append(evs) if ((dump_every > 0) and (s // dump_every == 0) and (s != 0) and (filename is not None)): # time to dump results evs_all = np.array(evs_all_l).real time = np.array(time_l) if (s == dump_every) and (not os.path.isfile(filename) or not append_file): # rewrite old file with the first batch np.savez(filename, t=time, evs=evs_all) else: time_old = np.load(filename)['t'] evs_old = np.load(filename)['evs'] assert (np.allclose(time_old, time)) evs_updated = np.vstack((evs_old, evs_all)) np.savez(filename, t=time, evs=evs_updated) evs_all = np.array(evs_all_l).real time = np.array(time_l) if filename is not None: if not os.path.isfile(filename) or not append_file: np.savez(filename, t=time, evs=evs_all) else: time_old = np.load(filename)['t'] evs_old = np.load(filename)['evs'] assert (np.allclose(time_old, time)) evs_updated = np.vstack((evs_old, evs_all)) np.savez(filename, t=time, evs=evs_updated) return time, evs_all
import tt from tt.amen import amen_solve """ This program test two subroutines: matrix-by-vector multiplication and linear system solution via AMR scheme""" d = 12 A = tt.qlaplace_dd([d]) x = tt.ones(2,d) y = amen_solve(A,x,x,1e-6) #%% c = tt.multifuncrs2([a, b], lambda x: np.sum(x, axis=1), eps=1E-6) y = amen_solve(A,x,x,1e-6) # %% y # %% A # %% x # %% z=tt.matvec(A,x) # %% z # %% z.full().reshape(-1) # %%
#------------------building 3d lf matrix in TT-format with TT-kronecker product Lf_qtt = tt.kron(tt.kron(Lf_qtt,Identity_qtt),Identity_qtt)+tt.kron(tt.kron(Identity_qtt,Lf_qtt),Identity_qtt)+tt.kron(tt.kron(Identity_qtt,Identity_qtt),Lf_qtt) #------------------building 3d laplacian matrix in TT-format with TT-kronecker product------------------ L_qtt = tt.kron(tt.kron(L_qtt,Identity_qtt),Identity_qtt)+tt.kron(tt.kron(Identity_qtt,L_qtt),Identity_qtt)+tt.kron(tt.kron(Identity_qtt,Identity_qtt),L_qtt) # #adding boundary matrix to laplacian matrix L_qtt = L_qtt+Lbd_qtt # #matrix-vector multiplication to maintain f and g and sum both to get the complete righside b b1_qtt = tt.matvec(Lf_qtt,f1_qtt) + tt.matvec(Lbd_qtt,g1_qtt) b2_qtt = tt.matvec(Lf_qtt,f2_qtt) + tt.matvec(Lbd_qtt,g2_qtt) #------------------solving higher order linear system in TT-format------------------ #defining initial guess vector x_qtt= tt.ones(2,int(np.log2(n+1)*(d))) #solving the higher order linear system with AMEN print("") print("Solving Problem 1 with AMEN") print("") u1_qtt=amen_solve(L_qtt,b1_qtt,x_qtt,1e-10,nswp=100) time.sleep(0.01)
#consts I0 = 1 rho = 1 tau = 1 r02 = 1 k_sc = 1 k_abs = 1 k_t = 1 Cv = 1 T0 = 1 #tensor dim dx = 50 pt = 50 dt = 1e-10 #initialisation' t1 = time.time() A = matrix(dx, rho, Cv, k_t) Qs = vector(dx, pt, tau, I0, r02, k_sc, k_abs, rho, Cv, T0) t0 = initial_cond(T0, dx) A, Qs = full_matrix(A, Qs, t0, pt, dt) y = amen_solve(A, Qs, Qs, 1e-14) t2 = time.time() print('error:', (tt.matvec(A, y) - Qs).norm() / Qs.norm()) print('time:', (t2-t1))
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())
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()