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
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
d = 6 f = 1 A = tt.qlaplace_dd([d]*f) n = [2]*(d*f) n0 = 2**d x = np.arange(1,n0+1)*1.0/(n0+1) x = np.exp(-10*(x-0.5)**2) x = tt.tensor(x.reshape([2]*d,order='F'),1e-8) #x = tt.ones(2,d) tau = 1 tau1 = 1 y = x.copy() ns_fin = 8 tau0 = 1.0 tau_ref = tau0/2**ns_fin for i in xrange(2**ns_fin): y=ksl(-1.0*A,y,tau_ref) yref = y.copy() tau = 5e-2 res = "" ns = 2 while ( ns <= ns_fin ): tau = tau0/(2**ns) y = x.copy() for i in xrange(2**ns): y = ksl(-1.0*A,y,tau) er = (y - yref).norm()/y.norm() res += 'tau=%3.1e er=%3.1e ns=%d \n' % (tau,er,2**ns) ns += 1 print res
for j in xrange(d): if j % 2: e0 = v0#np.random.rand(2) else: e0 = v1#e0 = tt.tensor(e0,1e-12) e1 = tt.kron(e1,e0) r = [1]*(d+1) r[0] = 1 r[d] = 1 x0 = tt.rand(n,d,r) tau = 1e-2 tf = 100 t = 0 start = e1 psi = start + 0 * x0 psi1 = start + 0 * x0 cf = [] while t <= tf: print '%f/%f' % (t,tf) psi = ksl(-1.0j*A,psi,tau) #psi1 = kls(-1.0j*A,psi1,tau) cf.append(tt.dot(psi,start)) #import ipdb; ipdb.set_trace() t += tau #x0 = tt.rand(n,d,r) #t1 = time.time() #print 'Matrices are done' #y, lam = eigb(A,x0,1e-3) #lm.append(d) #t2 = time.time()
#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 t2 = time.time() print("Elapsed time: %f" % (t2-t1)) zz = np.abs(fft(np.conj(cf))) lls = np.arange(zz.size)*pi/(0.5*tf)
#x = tt.ones(2,d) #x = x + 0 * tt.rand(2,d,2) tau = 1 tau1 = 1 y = x.copy() ns_fin = 8 tau0 = 1.0 tau_ref = tau0/2**ns_fin import matplotlib.pyplot as plt plt.ion() fig = plt.figure() ax = fig.add_subplot(111) #tau_ref = 0.0 line1, = ax.plot(np.real(y.full().flatten("F"))) ax.hold("True") plt.ylim([-1,1]) #The solution is the exp(i*lam*t) * sin(pi*x) x0 = x.full().flatten("F") line2, = ax.plot(np.real(x0)) B = expm(tau_ref*1j*A.full()) for i in xrange(2**ns_fin): y1=ksl(1j*A,y,tau_ref) x0 = np.dot(B,x0) #print y1.full().flatten("F")/y.full().flatten("F") y = y1.copy() line1.set_ydata(np.real(y.full().flatten("F"))) line2.set_ydata(np.real(x0)) fig.canvas.draw() raw_input()
#A = tt.eye(2,d) n = [2]*(d*f) n0 = 2**d t = np.arange(1,n0+1)*1.0/(n0+1) x = np.exp(-10*(t-0.5)**2) #x = np.sin(pi*t) x = tt.tensor(x.reshape([2]*d,order='F'),1e-8) #x = tt.ones(2,d) tau = 1 tau1 = 1 y = x.copy() ns_fin = 8 tau0 = 1.0 tau_ref = tau0/2**ns_fin for i in xrange(2**ns_fin): y=ksl(1j*A,y,tau_ref) yref = y.copy() tau = 5e-2 res = "" ns = 2 while ( ns <= ns_fin ): tau = tau0/(2**ns) y = x.copy() for i in xrange(2**ns): y = ksl(1.0j*A,y,tau) er = (y - yref).norm()/y.norm() res += 'tau=%3.1e er=%3.1e ns=%d \n' % (tau,er,2**ns) ns += 1 print res