def integrate(): psi_init = np.array([[1.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], dtype=np.complex128) t = np.linspace(0, 45 * 10 ** -7, 2001) sol = odeintw(right_part, psi_init, t) return t, sol
def EtaB(self): #Define fixed quantities for BEs _HT = [ np.real(self.hterm(2,0)), np.real(self.hterm(1,0)), np.real(self.hterm(0,0)), np.real(self.hterm(2,1)), np.real(self.hterm(1,1)), np.real(self.hterm(0,1)) ] _K = [np.real(self.k1), np.real(self.k2)] y0 = np.array([0+0j,0+0j,0+0j], dtype=np.complex128) _ETA = [ np.real(self.epsilon1ab(2,2)), np.real(self.epsilon1ab(1,1)), np.real(self.epsilon1ab(0,0)), self.epsilon1ab(2,1) , self.epsilon1ab(2,0) , self.epsilon1ab(1,0), np.real(self.epsilon2ab(2,2)), np.real(self.epsilon2ab(1,1)), np.real(self.epsilon2ab(0,0)), self.epsilon2ab(2,1) , self.epsilon2ab(2,0) , self.epsilon2ab(1,0), ] _K = [np.real(self.k1), np.real(self.k2)] ys = odeintw(self.RHS, y0, self.zs, args = tuple([_ETA, _K])) self.setEvolData(ys) return self.ys[-1][-1]
def get_solution(t, k, kg, M, beta, init_cond=[20, 0, 0, 0]): omega = np.sqrt((k + kg) / M) #differential equations system def func(y, t, k, kg, M, beta): a1, a2 = y return [(a2 * 1j * kg) / (2 * np.sqrt(M * (k + kg))), (a1 * 1j * kg) / (2 * np.sqrt(M * (k + kg))) - (beta / 2) * a2] #a1', a2' #parse initial conditions - convert x and v to a x1_0, x2_0, v1_0, v2_0 = init_cond p1_0, p2_0 = M * v1_0, M * v2_0 a1_0 = x1_0 * np.sqrt(M * omega / 2) + p1_0 / (1j * np.sqrt(2 * M * omega)) a2_0 = x2_0 * np.sqrt(M * omega / 2) + p2_0 / (1j * np.sqrt(2 * M * omega)) y0 = [a1_0, a2_0] #get solution res = odeintw(func, y0, t, args=(k, kg, M, beta)) a1, a2 = res[:, 0], res[:, 1] #Multiply by exponents (as was in ansatz) for i, t in enumerate(t): a1[i] = a1[i] * np.exp(-1j * omega * t) a2[i] = a2[i] * np.exp(-1j * omega * t) #Complex conjugated operators (annihilation operators) a1_dag = np.conjugate(a1) a2_dag = np.conjugate(a2) #Now restore x_1 and x_2 x1 = np.sqrt(1 / (2 * M * omega)) * (a1 + a1_dag) x2 = np.sqrt(1 / (2 * M * omega)) * (a2 + a2_dag) return np.hstack((np.reshape(x1, (-1, 1)), np.reshape(x2, (-1, 1))))
def get_solution(t, k, kg, M, F, beta, init_cond=[0, 0, 0, 0]): omega = np.sqrt((k + kg) / M) #differential equations system @jit(nopython=True) def func(y, t, k, kg, M, beta, F, omega_d): a1, a2 = y force = 1j * np.sqrt(1 / (2 * M * omega)) * (F / 2) g = kg / (2 * np.sqrt(M * (k + kg))) return [ a1 * 1j * (omega_d - omega) + 1j * g * a2 - force, a2 * 1j * (omega_d - omega) + 1j * g * a1 - (beta / 2) * a2 ] #return [(a2*1j*g) + force, (a1*1j*g) - (beta/2)*a2] #a1', a2' #parse initial conditions - convert x and v to a x1_0, x2_0, v1_0, v2_0 = init_cond p1_0, p2_0 = M * v1_0, M * v2_0 a1_0 = x1_0 * np.sqrt(M * omega / 2) + p1_0 / (1j * np.sqrt(2 * M * omega)) a2_0 = x2_0 * np.sqrt(M * omega / 2) + p2_0 / (1j * np.sqrt(2 * M * omega)) y0 = [a1_0, a2_0] #get solution res = odeintw(func, y0, t, args=(k, kg, M, beta, F, omega_d)) a1, a2 = res[:, 0], res[:, 1] for i, t in enumerate(t): a1[i] = a1[i] * np.exp(-1j * omega_d * t) a2[i] = a2[i] * np.exp(-1j * omega_d * t) a1_dag = np.conjugate(a1) a2_dag = np.conjugate(a2) x1 = np.sqrt(1 / (2 * M * omega)) * (a1 + a1_dag) x2 = np.sqrt(1 / (2 * M * omega)) * (a2 + a2_dag) return np.hstack((np.reshape(x1, (-1, 1)), np.reshape(x2, (-1, 1))))
def main(): flowparams=np.linspace(0,100,2) gspace=linspace(-100,100,101) alpha=1.0 g=1.0 delta=1.0 while alpha <=1.0: solution_set=[] eigenvalue_set=[] for h in gspace: #initial pairing matrix H0=H_Pairing_n4_p4(delta,h,alpha) #eigenvalues y standard diagonalization eigenvalue_set.append(eigvals(H0)) # just reshapes the initial matrix into an array, honestly having a # function for this is over kill y0=HtoY0(H0) # generates an array of srg evoled matrix elements # while I did make another version that didn't use odeintw, I ended # up using it again as effective shorthand since it seemed consistent # with results of my other version. solution_set.append(odeintw(derivative, y0, flowparams, args=(H0.shape[0],1.0,0.0,1.0,1.0))[-1]) linear_ploter(array(solution_set).real,array(eigenvalue_set).real,gspace,True,alpha) linear_ploter(array(solution_set).imag,array(eigenvalue_set).imag,gspace,False,alpha) alpha=alpha+1.0 print 'end'
def EtaB(self): #Define fixed quantities for BEs _ETA = [ np.real(self.epsilon1ab(2,2)), np.real(self.epsilon1ab(1,1)), np.real(self.epsilon1ab(0,0)), self.epsilon1ab(2,1) , self.epsilon1ab(2,0) , self.epsilon1ab(1,0), np.real(self.epsilon2ab(2,2)), np.real(self.epsilon2ab(1,1)), np.real(self.epsilon2ab(0,0)), self.epsilon2ab(2,1) , self.epsilon2ab(2,0) , self.epsilon2ab(1,0), ] _C = [ self.c1a(2), self.c1a(1), self.c1a(0), self.c2a(2), self.c2a(1), self.c2a(0)] _K = [np.real(self.k1), np.real(self.k2)] _W = [ 485e-10*self.MP/self.M1, 1.7e-10*self.MP/self.M1] y0 = np.array([0+0j,0+0j,0+0j,0+0j,0+0j,0+0j,0+0j,0+0j], dtype=np.complex128) ys, _ = odeintw(self.RHS, y0, self.zs, args = tuple([_ETA, _C , _K, _W]), full_output=1) self.setEvolData(ys) return self.ys[-1][-1]
def EtaB(self): #Define fixed quantities for BEs epstt = np.real(self.epsilon1ab(2, 2)) epsmm = np.real(self.epsilon1ab(1, 1)) epsee = np.real(self.epsilon1ab(0, 0)) epstm = self.epsilon1ab(2, 1) epste = self.epsilon1ab(2, 0) epsme = self.epsilon1ab(1, 0) c1t = self.c1a(2) c1m = self.c1a(1) c1e = self.c1a(0) k = np.real(self.k1) y0 = np.array([0 + 0j, 0 + 0j, 0 + 0j], dtype=np.complex128) params = np.array( [epstt, epsmm, epsee, epstm, epste, epsme, c1t, c1m, c1e, k], dtype=np.complex128) ys, _ = odeintw(self.RHS, y0, self.zs, args=tuple(params), full_output=True) self.setEvolData(ys) return self.ys[-1][-1]
def getEtaB_1DS_DM(self): #Define fixed quantities for BEs epstt = np.real(self.epsilonab(2,2)) epsmm = np.real(self.epsilonab(1,1)) epsee = np.real(self.epsilonab(0,0)) epstm = self.epsilonab(2,1) epste = self.epsilonab(2,0) epsme = self.epsilonab(1,0) c1t = self.c1a(2) c1m = self.c1a(1) c1e = self.c1a(0) xs = np.linspace(self.xmin, self.xmax, self.xsteps) k = np.real(self.k1) y0 = np.array([0+0j,0+0j,0+0j,0+0j,0+0j,0+0j,0+0j], dtype=np.complex128) params = np.array([epstt,epsmm,epsee,epstm,epste,epsme,c1t,c1m,c1e,k], dtype=np.complex128) ys, _ = odeintw(self.RHS_1DS_DM, y0, self.xs, args = tuple(params), full_output=1) nb = 0.013*(ys[-1,1]+ys[-1,2]+ys[-1,3]).real X=_["tcur"] # ys=np.absolute(ys) N1 =ys[:,0][0:-1] Nee =ys[:,1][0:-1] Nmumu =ys[:,2][0:-1] Ntautau=ys[:,3][0:-1] import pylab fig, ax = pylab.subplots() pylab.plot(X, np.absolute(Nee), label="|Nee|" , color="r") pylab.plot(X, np.absolute(Nmumu), label="|Nmumu|" , color="g") pylab.plot(X, np.absolute(Ntautau), label="|Ntautau|", color="b") pylab.legend() pylab.xlabel("z") pylab.ylabel("|N|") pylab.xscale("log") pylab.yscale("log") pylab.xlim((self.xmin,self.xmax)) pylab.show() pylab.clf() pylab.plot(X.real, Nee.real+Nmumu.real+Ntautau.real, label="1 dec. st. (DM) eta=%e"%nb, color="b") pylab.legend() pylab.xlabel("z") pylab.ylabel("eta") pylab.xscale("log") pylab.yscale("log") pylab.xlim((self.xmin,self.xmax)) pylab.show() return nb
def integrate(): rho_init = array([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], dtype=complex128) t = linspace(0, 2 * 10 ** -2, 2000) sol = odeintw(right_part, rho_init, t) return t, sol
def integrator(sys, t, H, dH): U0 = [] shape = H(0).shape U0.append(np.eye(shape[0], dtype='complex128')) for i in range(len(dH)): U0.append(1j * np.zeros(shape)) sol = odeintw(sys, U0, t, args=(H, dH), atol=1e-12, rtol=1e-12) U_f = sol[-1] print('Integration Complete...') return U_f
def EtaB(self): #Define fixed quantities for BEs epstt = np.real(self.epsilon1ab(2, 2)) epsmm = np.real(self.epsilon1ab(1, 1)) epsee = np.real(self.epsilon1ab(0, 0)) k = np.real(self.k1) y0 = np.array([0 + 0j, 0 + 0j], dtype=np.complex128) params = np.array([epstt, epsmm, epsee, k], dtype=np.complex128) ys = odeintw(self.RHS, y0, self.zs, args=tuple(params)) self.setEvolData(ys) return self.ys[-1][-1]
def run_n_steps(self, current_state=None, n=1, labelled_states=False): """ Runs the model for n steps Parameters ---------- current_state: 1D nd.array Current model state. n: int Number of steps the model should be run for. labelled_states: bool Whether the result should be a dict with state labels or a nd array. Returns ------- dict or 2D nd.array Returns a dict if labelled_states is True, where keys are state labels. Returns an array of size (n, n_states) of the last n model states. """ if current_state is None: current_state = np.array(self._get_current_state()) for f in range(16): self.dCV1[f] = sum([self.current_state[self._age_groups[f]]['{}'.format(s)] for s in ['CV11', 'CV21', 'CV31', 'CV41']]) self.dCV2[f] = sum([self.current_state[self._age_groups[f]]['{}'.format(s)] for s in ['CV12', 'CV22', 'CV32', 'CV42']]) if(self.t == self.step_list[self.step]): self.k = k_value(self.t) A_c = calculate_A_and_c(self.step, self.k, self.contact_modifiers, self.perturbations_matrices, self.transition_matrices) self.current_internal_params['A'], self.current_internal_params['c'] = np.array(A_c[0]), A_c[1] self.current_internal_params['nu'] = nu_value(self.t) if self.t > 369: sigma = self.compute_sigma() self.current_internal_params['sigma'] = np.array(sigma) self.current_internal_params['sigma2'] = np.array(duplicate_data(1/28, 16)) self.vacStep += 1 self.step += 1 # Use the odeint library to run the ODE model z = odeintw(self.internal_model, current_state, np.linspace(0, n, n + 1), args=(self._get_model_params())) self._set_current_state(current_state=z[-1].copy()) # save new current state self.t += 1 self.current_state = self.convert_states(self.current_state) # format results if labelled_states: return self._convert_to_labelled_states(np.atleast_2d(z[1:])) else: return np.atleast_2d(z[1:])
def getEtaB_2DS_Approx(self): #Define fixed quantities for BEs _ETA = [ np.real(self.epsilon(0,1,2,2)), np.real(self.epsilon(0,1,2,1)), np.real(self.epsilon(0,1,2,0)), np.real(self.epsilon(1,0,2,2)), np.real(self.epsilon(1,0,2,1)), np.real(self.epsilon(1,0,2,0)) ] _HT = [ np.real(self.hterm(2,0)), np.real(self.hterm(1,0)), np.real(self.hterm(0,0)), np.real(self.hterm(2,1)), np.real(self.hterm(1,1)), np.real(self.hterm(0,1)) ] _K = [np.real(self.k1), np.real(self.k2)] y0 = np.array([0+0j,0+0j,0+0j,0+0j,0+0j], dtype=np.complex128) # KKK _ETA = [ np.real(self.epsilon1ab(2,2)), np.real(self.epsilon1ab(1,1)), np.real(self.epsilon1ab(0,0)), self.epsilon1ab(2,1) , self.epsilon1ab(2,0) , self.epsilon1ab(1,0), np.real(self.epsilon2ab(2,2)), np.real(self.epsilon2ab(1,1)), np.real(self.epsilon2ab(0,0)), self.epsilon2ab(2,1) , self.epsilon2ab(2,0) , self.epsilon2ab(1,0), ] _C = [ self.c1a(2), self.c1a(1), self.c1a(0), self.c2a(2), self.c2a(1), self.c2a(0)] _K = [np.real(self.k1), np.real(self.k2)] ys = odeintw(self.RHS_2DS_Approx, y0, self.xs, args = tuple([_ETA, _C, _K])) nb = 0.013*(ys[-1,2]+ys[-1,3]+ys[-1,4]) return nb
def compute_first_order_beta(rho, eq, theta, schedule): # Change the basis of the jump operators num = 100 times = np.linspace(0, 1, num) dim = eq.hamiltonians[0].hamiltonian.shape[0] times = times[5:-5] def evolve(rho, t): # Generate a mapping from a time to an index schedule(t, 1) eigenenergies, eigenbasis = np.linalg.eigh( eq.hamiltonians[0].hamiltonian) eigenenergies = np.flip(eigenenergies) eigenbasis = np.flip(eigenbasis, axis=1) # Compute theta def compute_eigenenergies(t, y): schedule(t, 1) # Compute the Hamiltonian basis vectors eigval, eigvec = np.linalg.eigh(eq.hamiltonians[0].hamiltonian) return eigval theta = \ scipy.integrate.solve_ivp(compute_eigenenergies, (0, t), np.zeros(dim), atol=1e-8, rtol=1e-6, method='DOP853')['y'].T[-1] theta = np.flip(theta) schedule(t, 1) # Generate matrix of energy denominators energy_denom = np.reshape(np.repeat(eigenenergies, dim), (dim, dim)) energy_denom = energy_denom.T - energy_denom np.fill_diagonal(energy_denom, np.ones(dim)) energy_denom = 1 / energy_denom rho = rho @ (hamiltonian_time_derivative_term(t, eq, eigenbasis, eigenbasis) * energy_denom) \ - (hamiltonian_time_derivative_term(t, eq, eigenbasis, eigenbasis) * energy_denom) @ rho rho = rho * np.exp(-1j * (theta)) * np.exp(1j * (theta)).T return rho psi0 = np.zeros((dim, dim), dtype=np.complex128) psi0[-1, -1] = 1 s = odeintw(evolve, psi0, times, full_output=True)[0][-1, :, :] print(s, np.linalg.eigh(s), tools.is_hermitian(s))
def getEtaB_1DS_Approx(self): #Define fixed quantities for BEs epstt = np.real(self.epsilonab(2,2)) epsmm = np.real(self.epsilonab(1,1)) epsee = np.real(self.epsilonab(0,0)) c1t = self.c1a(2) c1m = self.c1a(1) c1e = self.c1a(0) xs = np.linspace(self.xmin, self.xmax, self.xsteps) k = np.real(self.k1) y0 = np.array([0+0j,0+0j,0+0j,0+0j], dtype=np.complex128) params = np.array([epstt,epsmm,epsee,c1t,c1m,c1e,k], dtype=np.complex128) ys = odeintw(self.RHS_1DS_Approx, y0, self.xs, args = tuple(params)) nb = 0.013*(ys[-1,1]+ys[-1,2]+ys[-1,3]) return nb
def EtaB(self): _HT = [ np.real(self.hterm(2, 0)), np.real(self.hterm(1, 0)), np.real(self.hterm(0, 0)), np.real(self.hterm(2, 1)), np.real(self.hterm(1, 1)), np.real(self.hterm(0, 1)) ] _K = [np.real(self.k1), np.real(self.k2)] y0 = np.array([0 + 0j, 0 + 0j, 0 + 0j, 0 + 0j, 0 + 0j], dtype=np.complex128) _ETA = [ self.epsiloniaaRESmix(2, 1, 0), self.epsiloniaaRESmix(1, 1, 0), self.epsiloniaaRESmix(0, 1, 0), self.epsiloniaaRESmix(2, 0, 1), self.epsiloniaaRESmix(1, 0, 1), self.epsiloniaaRESmix(0, 0, 1) ] _C = [ self.c1a(2), self.c1a(1), self.c1a(0), self.c2a(2), self.c2a(1), self.c2a(0) ] _K = [np.real(self.k1), np.real(self.k2)] ys = odeintw(self.RHS, y0, self.zs, args=tuple([_ETA, _C, _K]), atol=1e-10) self.setEvolData(ys) return self.ys[-1][-1]
def run_ode_solver(self, state: State, t0, tf, num=50, schedule=lambda t: None, times=None, method='RK45', full_output=True, verbose=False): """Numerically integrates the Schrodinger equation""" assert state.is_ket # Save s properties is_ket = state.is_ket code = state.code IS_subspace = state.IS_subspace graph = state.graph def f(t, s): global state if method == 'odeint': t, s = s, t if method != 'odeint': s = np.reshape(np.expand_dims(s, axis=0), state_shape) schedule(t) s = State(s, is_ket=is_ket, code=code, IS_subspace=IS_subspace, graph=graph) return np.asarray(self.evolution_generator(s)).flatten() # s is a ket specifying the initial codes # tf is the total simulation time state_asarray = np.asarray(state) if method == 'odeint': if full_output: if times is None: times = np.linspace(t0, tf, num=num) z, infodict = odeintw(f, state_asarray, times, full_output=True) infodict['t'] = times norms = np.linalg.norm(z, axis=(-2, -1)) if verbose: print('Fraction of integrator results normalized:', len(np.argwhere(np.isclose(norms, np.ones(norms.shape)) == 1)) / len(norms)) print('Final state norm - 1:', norms[-1] - 1) norms = norms[:, np.newaxis, np.newaxis] z = z / norms return z, infodict else: if times is None: times = np.linspace(int(t0), int(tf), num=int(num)) norms = np.zeros(len(times)) s = state_asarray.copy() for (i, t) in zip(range(len(times)), times): if i == 0: norms[i] = 1 else: s = odeintw(f, s, [times[i - 1], times[i]], full_output=False)[-1] # Normalize output? norms[i] = np.linalg.norm(s) infodict = {'t': times} if verbose: print('Fraction of integrator results normalized:', len(np.argwhere(np.isclose(norms, np.ones(norms.shape)) == 1)) / len(norms)) print('Final state norm - 1:', norms[-1] - 1) s = np.array([s/norms[-1]]) return s, infodict else: # You need to flatten the array state_shape = state.shape state_asarray = state_asarray.flatten() if full_output: res = scipy.integrate.solve_ivp(f, (t0, tf), state_asarray, t_eval=times, method=method) else: res = scipy.integrate.solve_ivp(f, (t0, tf), state_asarray, t_eval=[tf], method=method) res.y = np.swapaxes(res.y, 0, 1) res.y = np.reshape(res.y, (-1, state_shape[0], state_shape[1])) norms = np.linalg.norm(res.y, axis=(-2, -1)) if verbose: print('Fraction of integrator results normalized:', len(np.argwhere(np.isclose(norms, np.ones(norms.shape)) == 1)) / len(norms)) print('Final state norm - 1:', norms[-1] - 1) norms = norms[:, np.newaxis, np.newaxis] res.y = res.y / norms return res.y, res
c = np.array([[-20 + 1j, 5 - 1j, 0, 0], [0, -0.1, 1 + 2.5j, 0], [0, 0, -1, 0.5], [0, 0, 0, -5 + 10j]]) print(c) print() z0 = np.arange(1, 5.0) + 0.5j t = np.linspace(0, 250, 11) common_kwargs = dict(args=(c, ), full_output=True, atol=1e-12, rtol=1e-10, mxstep=1000) sol0, info0 = odeintw(funcz, z0, t, Dfun=jac, **common_kwargs) print(info0['nje']) rargs = common_kwargs.copy() rargs.pop('args') x0 = z0.view(np.float64) solr, infor = odeint(func, x0, t, Dfun=jac, args=(_complex_to_real_jac(c), ), **rargs) print(infor['nje']) print("-----")
def cts_time_extinction_prob(beta, gamma, T=None, intermediate_values=False, numvals=11): r''' Gives probability of eventual extinction, extinction by time T, or at times in interval [0,T] for continuous-time model. **Arguments** : beta (float) transmission rate gamma (float) recovery rate T (float [default None]) stop time (if None, then just gives final extinction probability) intermediate_values (boolean [default False]) irrelevant if T is None tells whether to return intermediate values in [0,T] numvals (int [default 11]) number of values in [0, T] inclusive to return. **Returns** : if T is None, returns alpha (a float) the probability of extinction by time infinity if T is not None and intermediate_values is False : alpha(T) (a float) the probability of extinction by time T if T is not None and intermediate_values is True : tuple of numpy arrays (times, alphas) each of length numvals times =[0,T/numvals, ..., T] is times at which results are reported alphas is [alpha(0), alpha(T/numvals), alpha(2T/numvals), ..., alpha(T)] :SAMPLE USE: :: import Invasion_PGF as pgf beta = 2 gamma = 1 alpha = pgf.cts_time_extinction_prob(beta, gamma) #The probability it eventually goes extinct. alpha > 0.5 times, alphas = pgf.cts_time_extinction_prob(beta, gamma, 5, intermediate_values = True, numvals=11) #The optional argument intermediate_values means that it gives everything #from time 0 to 5 (inclusive) in intervals of 0.5 times > array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ]) alphas > array([[ 0. , 0.2823667 , 0.38730017, 0.43721259, 0.46371057, 0.47860048, 0.48723549, 0.49233493, 0.49537878, 0.49720725, 0.49830983]]) ''' if T is None: return min(1, gamma / float(beta)) else: times = numpy.linspace(0, T, numvals) alpha0 = [0j] alphas = odeintw(_dalpha_dt_, alpha0, times, args=(beta, gamma)) alphas = numpy.real( alphas) #removes numerical noise from imaginary part alphas = numpy.transpose(alphas) if intermediate_values: return (times, alphas) else: return alphas[-1]
def run_ode_solver(self, state: State, t0, tf, num=50, schedule=lambda t: None, times=None, method='RK45', full_output=True, verbose=False, make_valid_state=False): """ :param verbose: :param method: :param times: :param full_output: :param num: :param schedule: :param state: :param t0: :param tf: :return: """ assert not state.is_ket # Save s properties is_ket = state.is_ket code = state.code IS_subspace = state.IS_subspace graph = state.graph def f(t, s): if method == 'odeint': t, s = s, t if method != 'odeint': s = np.reshape(np.expand_dims(s, axis=0), state_shape) schedule(t) s = State(s, is_ket=is_ket, code=code, IS_subspace=IS_subspace, graph=graph) return np.asarray(self.evolution_generator(s)).flatten() # s is a ket or density matrix # tf is the total simulation time state_asarray = np.asarray(state) if method == 'odeint': # Use the odeint wrapper if full_output: if times is None: times = np.linspace(0, 1, num=int(num)) * (tf - t0) + t0 z, infodict = odeintw(f, state_asarray, times, full_output=True) infodict['t'] = times norms = np.trace(z, axis1=-2, axis2=-1) if verbose: print( 'Fraction of integrator results normalized:', len( np.argwhere( np.isclose(norms, np.ones(norms.shape)) == 1)) / len(norms)) print('Final state norm - 1:', norms[-1] - 1) for i in range(z.shape[0]): z[i, ...] = tools.make_valid_state(z[i, ...], is_ket=False) return z, infodict else: if times is None: times = np.linspace(0, 1, num=int(num)) * (tf - t0) + t0 norms = np.zeros(len(times)) s = state_asarray.copy() for (i, t) in zip(range(len(times)), times): if i == 0: norms[i] = 1 else: s = odeintw(f, s, [times[i - 1], times[i]], full_output=False)[-1] # Normalize output? norms[i] = np.trace(s).real infodict = {'t': times} if verbose: print( 'Fraction of integrator results normalized:', len( np.argwhere( np.isclose(norms, np.ones(norms.shape)) == 1)) / len(norms)) print('Final state norm - 1:', norms[-1] - 1) s = np.array([tools.make_valid_state(s, is_ket=False)]) return s, infodict else: state_shape = state_asarray.shape state_asarray = state_asarray.flatten() if full_output: res = scipy.integrate.solve_ivp(f, (t0, tf), state_asarray, t_eval=times, method=method, vectorized=True) else: res = scipy.integrate.solve_ivp(f, (t0, tf), state_asarray, t_eval=[tf], method=method, vectorized=True) res.y = np.swapaxes(res.y, 0, 1) res.y = np.reshape(res.y, (-1, state_shape[0], state_shape[1])) norms = np.trace(res.y, axis1=-2, axis2=-1) if verbose: print( 'Fraction of integrator results normalized:', len( np.argwhere( np.isclose(norms, np.ones(norms.shape)) == 1)) / len(norms)) print('Final state norm - 1:', norms[-1] - 1) if make_valid_state: for i in range(res.y.shape[0]): res.y[i, ...] = tools.make_valid_state(res.y[i, ...], is_ket=False) return res.y, res
def integrate(self, z0, t0, tf=None, dt=0.1): """ Class method to calculate the system's time evolution through numerical integration Parameters: ---------- z0 : complex ndarray of shape (N) State of system at initial time t0 t0 : float or ndarray Initial time (float) or time array on which to evolve the system tf : float Final time value dt : float Size of steps in the time interval Returns ---------- z : ndarray of shape (N, Nt) z[i] gives time evolution array for the ith oscillator t : ndarray of shape (Nt) Time values for which we evaluated the integral """ if tf==None: t = t0 else: t = np.arange(t0,tf,dt) # If the system is in its compex form, we use the special numerical integration # function odeintw, which extends scipy's odeint to accept complex ODE's # Obs: the initial condition z0 must be of type complex for this solver to work if self.systype =='complex': z = odeintw(self, z0, t).T if self.systype =='polar': # Jacobian for polar coordinates def pJac(z, t=0): z = np.reshape(z, (2,self.N)) rho = z[0] theta = z[1] jac = np.zeros((2*self.N, 2*self.N)) # Diagonal terms for i in range(self.N): jac[i,i] = self.alpha**2 - 3 * rho[i]**2 # Forced terms (off-diagonal) if self.F is not None: for i in self.forced_osc: jac[i,(i+self.N)] += - self.F[i] * np.sin(t*self.Omega - theta[i]) jac[(i+self.N),(i+self.N)] += self.F[i] * np.cos(t*self.Omega - theta[i]) # Coupling terms (off-diagonal when assuming there are no self-edges) for k in range(self.Ne): [i, j] = self.edges[k] jac[i, j] += self.K * self.A[i,j] * np.cos(theta[j] - theta[i]) jac[i,(j+self.N)] = - self.K * self.A[i,j] * rho[j] * np.sin(theta[j] - theta[i]) jac[(i+self.N),j] = (self.K/rho[i]) * self.A[i,j] * np.sin(theta[j] - theta[i]) jac[(i+self.N),(j+self.N)] = self.K * self.A[i,j] * (rho[j]/rho[i]) * np.cos(theta[j] - theta[i]) return jac rho0 = np.absolute(z0) theta0 = np.angle(z0) z0 = np.concatenate((rho0,theta0), axis=0) z = odeint(self, z0, t, Dfun=pJac).T rho = z[:self.N] theta = z[self.N:] z = rho*np.exp(1j*theta) if self.systype =='rectangular': # Jacobian for rectangular coordinates def rJac(z, t=0): z = np.reshape(z, (2,self.N)) x = z[0] y = z[1] jac = np.zeros((2*self.N, 2*self.N)) # Individual oscillator dynamics for i in range(self.N): jac[i,i] = self.alpha**2 - y[i]**2 - 3*x[i]**2 jac[i,(i+self.N)] = - 2*x[i]*y[i] - self.w[i] jac[(i+self.N),i] = - 2*x[i]*y[i] + self.w[i] jac[(i+self.N),(i+self.N)] = self.alpha**2 - x[i]**2 - 3*y[i]**2 # Coupling terms for k in range(self.Ne): [i,j] = self.edges[k] jac[i,j] += self.K*self.A[i,j] jac[i+self.N,j+self.N] += self.K*self.A[i,j] return jac x0 = np.real(z0) y0 = np.imag(z0) z0 = np.concatenate((x0,y0), axis=0) z = odeint(self, z0, t, Dfun=rJac).T x = z[:self.N] y = z[self.N:] z = x + 1j*y return z, t
n = np.size(A, 0) A = np.column_stack((A, np.zeros(n))) A = np.vstack((A, np.zeros(n + 1))) H = h_bar * A n_bra = np.zeros(n) n_bra[n - 1] = 1 n_1_ket = np.zeros(n + 1).T n_1_ket[n] = 1 print(n_bra, n_1_ket) L = np.matrix(np.outer(n_1_ket, n_bra)) print(L.getH()) L_dag_L = np.matmul(L.getH(), L) drho_dt = -(1j / h_bar) * ( np.matmul(H, rho) - np.matmul(rho, H)) + gamma * ( np.matmul(L, np.matmul(rho, L.getH())) - 0.5 * (np.matmul(L_dag_L, rho) + np.matmul(rho, L_dag_L))) return drho_dt p_th = 1 / np.log(np.size(A, 0)) rho = odeintw(GKSL, rho0, t, args=(A, )) plt.plot(t, rho, 'b', t, p_th, 'g--') plt.xlabel('time') plt.ylabel('rho(t)') plt.savefig("mygraph.png")
def cts_time_completed_infections(beta, gamma, T, M=100, radius=1., numpts=1000, intermediate_values=False, numvals=11): r''' Gives probability of having 0, ...., M-1 completed infections at time T. **Arguments** : beta (float) transmission rate gamma (float) recovery rate T (float) stop time M (integer [default 100]) consider 0, ..., M-1 current infecteds radius (positive integer [default 1]) radius to use for the integral. numpts (positive integer [default 1000]) number of points on circle to use in calculating approximate coefficient threshold (float [default 10**(-10)]) any value below threshold is reported as 0. Assumes that calculation cannot be trusted at that size. intermediate_values (boolean [default False]) irrelevant if T is None tells whether to return intermediate values in [0,T] numvals (int [default 11]) number of values in [0, T] inclusive to return. **Returns** : if intermediate_values is False : numpy array omega, where omega[n] is probability of n completed infections at time T. if intermediate_values is True : (ts, numvals x M numpy array) ts[i] is ith time and where Omega[i, n] is probability of n completed infections at ith time. :SAMPLE USE: :: import Invasion_PGF as pgf beta = 2 gamma = 1 omega = pgf.cts_time_completed_infections(beta, gamma, 5, M=10) omega > array([ 5.52508654e-05, 3.33393489e-01, 7.41491401e-02, 3.30285036e-02, 1.84500461e-02, 1.16175539e-02, 7.92268199e-03, 5.74983465e-03, 4.40353976e-03, 3.54079245e-03]) omega = pgf.cts_time_completed_infections(beta, gamma, 5, M=10, numpts = 100000) > array([ 9.17704321e-07, 3.33339349e-01, 7.40951926e-02, 3.29747479e-02, 1.83964816e-02, 1.15641798e-02, 7.86949766e-03, 5.69683942e-03, 4.35073295e-03, 3.48817339e-03]) ''' if numpts <= M: print("warning numpts should be larger than M") times = numpy.linspace(0, T, numvals) zs = _get_pts_(numpts, radius) Omega0 = numpy.ones(numpts) + 0j #array of ones (but complex) Omegas = odeintw(_dOmega_dt_, Omega0, times, args=(beta, gamma, zs)) if intermediate_values: omegas = [] for fxn_values in Omegas: coeffs = [] for n in range(M): integral = _get_coeff_(fxn_values, n, radius) coeffs.append(integral) omegas.append(coeffs) omegas = numpy.array(omegas) omegas = numpy.real(omegas) return (times, omegas) else: fxn_values = Omegas[-1] coeffs = [] for n in range(M): integral = _get_coeff_(fxn_values, n, radius) coeffs.append(integral) coeffs = numpy.array(coeffs) coeffs = numpy.real(coeffs) return coeffs
def getEtaB_2DS_DM(self): #Define fixed quantities for BEs _ETA = [ np.real(self.epsilon1ab(2,2)), np.real(self.epsilon1ab(1,1)), np.real(self.epsilon1ab(0,0)), self.epsilon1ab(2,1) , self.epsilon1ab(2,0) , self.epsilon1ab(1,0), np.real(self.epsilon2ab(2,2)), np.real(self.epsilon2ab(1,1)), np.real(self.epsilon2ab(0,0)), self.epsilon2ab(2,1) , self.epsilon2ab(2,0) , self.epsilon2ab(1,0), ] _C = [ self.c1a(2), self.c1a(1), self.c1a(0), self.c2a(2), self.c2a(1), self.c2a(0)] _K = [np.real(self.k1), np.real(self.k2)] _W = [ 485e-10*self.MP/self.M1, 1.7e-10*self.MP/self.M1] y0 = np.array([0+0j,0+0j,0+0j,0+0j,0+0j,0+0j,0+0j,0+0j], dtype=np.complex128) zcrit = 1e100 ys, _ = odeintw(self.RHS_2DS_DM, y0, self.xs, args = tuple([_ETA, _C , _K, _W]), full_output=1) nb = np.real(0.013*(ys[-1,2]+ys[-1,3]+ys[-1,4])) X=_["tcur"] N1 =ys[:,0][0:-1] N2 =ys[:,1][0:-1] Nee =ys[:,2][0:-1] Nmumu =ys[:,3][0:-1] Ntautau=ys[:,4][0:-1] import pylab pylab.plot(X, np.absolute(Nee), label="|Nee|" , color="r") pylab.plot(X, np.absolute(Nmumu), label="|Nmumu|" , color="g") pylab.plot(X, np.absolute(Ntautau), label="|Ntautau|", color="b") pylab.legend() pylab.ylabel("|N|") pylab.xlabel("z") pylab.xscale("log") pylab.yscale("log") pylab.xlim((self.xmin,self.xmax)) pylab.show() pylab.plot(X, np.absolute(Nee+Nmumu+Ntautau), label="2 dec. st. (DM) eta=%e"%nb, color="b") pylab.legend() pylab.ylabel("eta") pylab.xlabel("z") pylab.xscale("log") pylab.yscale("log") pylab.xlim((self.xmin,self.xmax)) pylab.show() return nb
def cts_time_active_and_completed(beta, gamma, T, M1=100, M2=100, radius=1, numpts=1000, threshold=10**(-10), intermediate_values=False, numvals=11): r''' Gives probability of having 0, ...., M1-1 active infections and 0,..., M2-1 completed infections at time T. (joint distribution) **Arguments** : beta (float) transmission rate gamma (float) recovery rate T (float) stop time M1 (integer [default 100]) consider 0, ..., M1-1 current infecteds M2 (integer [default 100]) consider 0, ..., M2-1 completed infections radius (positive integer [default 1]) radius to use for the integral. numpts (positive integer [default 1000]) number of points on circle to use in calculating approximate coefficient threshold (float [default 10**(-10)]) any value below threshold is reported as 0. Assumes that calculation cannot be trusted at that size. intermediate_values (boolean [default False]) irrelevant if T is None tells whether to return intermediate values in [0,T] numvals (int [default 11]) number of values in [0, T] inclusive to return. **Returns** : if intermediate_values is False : numpy array pi, where pi[n1,n2] is probability of n1 active and n2 completed infections at time T. if intermediate_values is True : (ts, numvals x M1xM2 numpy array) ts[i] is ith time and where pi[i, n1,n2] is probability of n1 active infections and n2 completed at ith time. :SAMPLE USE: :: import Invasion_PGF as pgf beta = 2 gamma = 1 Pi = pgf.cts_time_active_and_completed(beta, gamma, 5, M1=3, M2=5, numpts=1000) Pi > array([[ 2.63687494e-07, 3.33333492e-01, 7.40736527e-02, 3.29196545e-02, 1.82840763e-02], [ 5.71064881e-07, 2.16597225e-06, 6.55929588e-06, 1.50413677e-05, 2.79279374e-05], [ 4.70531265e-07, 1.57829529e-06, 4.76314546e-06, 1.11846210e-05, 2.13865892e-05]]) ''' if numpts <= M1 or numpts <= M2: print("warning numpts should be (quite a bit) larger than M1 and M2") times = numpy.linspace(0, T, numvals) ys = _get_pts_(numpts, radius) + 0j zs = _get_pts_(numpts, radius) + 0j Z = numpy.transpose(numpy.array([zs for y in ys])) Pis0 = numpy.array([ys for z in zs]) Pis = odeintw(_dPi_dt_, Pis0, times, args=(beta, gamma, Z)) pis = _get_pis_(Pis, M1, M2, intermediate_values, radius, threshold) pis = numpy.real(pis) if intermediate_values: return (times, pis) else: return pis[-1]
return [-z1 * (K - z2), L - M*z2] def zjac(z, t, K, L, M): z1, z2 = z jac = np.array([[z2 - K, z1], [0, -M]]) return jac # Set up the inputs and call odeintw to solve the system. z0 = np.array([1+2j, 3+4j]) t = np.linspace(0, 5, 101) K = 2 L = 4 - 2j M = 2.5 z, infodict = odeintw(zfunc, z0, t, args=(K, L, M), Dfun=zjac, full_output=True) plt.figure(1) plt.clf() color1 = (0.5, 0.4, 0.3) color2 = (0.2, 0.2, 1.0) plt.plot(t, z[:, 0].real, color=color1, label='z1.real', linewidth=1.5) plt.plot(t, z[:, 0].imag, '--', color=color1, label='z1.imag', linewidth=2) plt.plot(t, z[:, 1].real, color=color2, label='z2.real', linewidth=1.5) plt.plot(t, z[:, 1].imag, '--', color=color2, label='z2.imag', linewidth=2) plt.xlabel('t') plt.grid(True) plt.legend(loc='best') plt.show()
def zjac(z, t, K, L, M): z1, z2 = z jac = np.array([[z2 - K, z1], [0, -M]]) return jac # Set up the inputs and call odeintw to solve the system. z0 = np.array([1 + 2j, 3 + 4j]) t = np.linspace(0, 5, 101) K = 2 L = 4 - 2j M = 2.5 z, infodict = odeintw(zfunc, z0, t, args=(K, L, M), Dfun=zjac, full_output=True) plt.figure(1) plt.clf() color1 = (0.5, 0.4, 0.3) color2 = (0.2, 0.2, 1.0) plt.plot(t, z[:, 0].real, color=color1, label='z1.real', linewidth=1.5) plt.plot(t, z[:, 0].imag, '--', color=color1, label='z1.imag', linewidth=2) plt.plot(t, z[:, 1].real, color=color2, label='z2.real', linewidth=1.5) plt.plot(t, z[:, 1].imag, '--', color=color2, label='z2.imag', linewidth=2) plt.xlabel('t') plt.grid(True) plt.legend(loc='best')
c = np.array([[-20+1j, 5-1j, 0, 0], [ 0, -0.1, 1+2.5j, 0], [ 0, 0, -1, 0.5], [ 0, 0, 0, -5+10j]]) print(c) print() z0 = np.arange(1,5.0) + 0.5j t = np.linspace(0, 250, 11) common_kwargs = dict(args=(c,), full_output=True, atol=1e-12, rtol=1e-10, mxstep=1000) sol0, info0 = odeintw(funcz, z0, t, Dfun=jac, **common_kwargs) print(info0['nje']) rargs = common_kwargs.copy() rargs.pop('args') x0 = z0.view(np.float64) solr, infor = odeint(func, x0, t, Dfun=jac, args=(_complex_to_real_jac(c),), **rargs) print(infor['nje']) print("-----") solbnj, infobnj = odeintw(func, z0, t, ml=0, mu=1, **common_kwargs) print(infobnj['nje']) sol2, info2 = odeint(func, x0, t, ml=1, mu=3, args=(_complex_to_real_jac(c),), **rargs)
def factor(N, T=100000): # Integer to factor assert N > 0 #Must be a positive one print("Factoring N={}".format(N)) n = int(np.log2(N)) + 1 #Bits needed to represent N in binary dim = 2 * n #Dimensions for the complex Hilbert space in which the evolution will take place print("Dimensions for the Hilbert space: 2^{}={}".format(dim, 2**dim)) v0 = np.full(2**dim, 1 / 2**(dim // 2)).astype( np.complex128 ) #Initial ground state, which is a uniform superposition H^(2^dim)|0> #Let's create the hadamard 2^dim-dimensional gate with the scipy library Had = hadamard(2**dim, dtype=complex) / 2**dim reg = regularizationConstant # The function computes the value for the initial hamiltonian H_0 over a input vector v def H0_mult(v): h = lambda n: 0 if n == 0 else 1 #Let's define the h function just as done in the project report ret = np.full(2**dim, 0. + 0.j) #We start with a vector of all zeros for i in range( 2**dim ): # and we iterate as showed in the equation 4.4.2 <z|H^(2dim)|v>|z> vi = np.full(2**dim, 0. + 0.j) vi[i] = 1. + 0.j #We create |z> Hvi = np.dot(Had, vi) # Then we calculate |H^(2dim)|v> ret += h(i) * np.vdot( Hvi, v) * Hvi # And least we add <z|H^(2dim)|v>|z> return ret # The function computes the value for the final hamiltonian H_f over a input vector v def Hf_mult(v): Q = lambda x, y: N**2 * (N - x * y)**2 + x * ( x - y)**2 # Integer function from the paper by Kieu ret = np.array(v) for i in range(2**(dim // 2)): for j in range( 2** (dim // 2)): # We iterate over all pair (i,j)~2^dim*i+j in the range ind = 2**(dim // 2) * i + j ret[ind] *= Q(i, j) #return ret/np.linalg.norm(ret) return ret * reg #The hamiltonian we are looking for is the interpolation over time of them both. def H(v, t): ret = (1 - t / T) * H0_mult(v) + t / T * Hf_mult(v) #If the result of applying the hamiltonian over the vector is too small, then we normalize it return ret * (-1j) / (1 if np.linalg.norm(ret) < 0.0001 else np.linalg.norm(ret)) # We keep the interpolated hamiltonian without regularization for testing. def Hnoreg(v, t): ret = (1 - t / T) * H0_mult(v) + t / T * Hf_mult(v) / reg return ret * (-1j) # And finally, our computation begins steps = stepsConstant #How many steps will our integration consists of t = np.linspace( 0, T, num=steps) #So we subdivide the inverval into *steps* pieces res = odeintw( H, v0, t) # And we integrate the differential multi-dimensional equation. #print(res[0]) #print(np.linalg.norm(res[0])) pos = np.argmax(np.array([np.linalg.norm(ress) for ress in res[-1]])) x, y = pos // 2**(dim // 2), pos % 2**( dim // 2) #We calculate the divisors from the found eigenstate. #Auxiliary functions to print stuff. def plotEnergy(res, t): energies = [ np.linalg.norm(Hnoreg(res[i], t[i])) for i in range(len(res)) ] plt.plot(t, energies) plt.savefig("N={},T={}_energies.eps".format(N, T)) plt.show() print(energies[-1]) def plotThings(res, t): my_xticks = [ "({},{})".format(i // 2**(dim // 2), i % 2**(dim // 2)) for i in range(2**dim) ] plt.xticks(range(2**dim), my_xticks) plt.plot(range(2**dim), [np.abs(x) for x in res], 'bo') plt.savefig("N={},T={}.eps".format(N, T)) plt.show() def plotNorm(res): norms = [np.linalg.norm(i) for i in res] #print(norms) plt.plot(t, norms) plt.show() plotEnergy(res, t) plotThings(res[-1], t) #plotNorm(res) return x, y #We return both divisors.
jac[0, 0, 1, 0] = c[0, 1] jac[0, 1, 0, 1] = c[0, 0] jac[0, 1, 1, 1] = c[0, 1] jac[1, 0, 0, 0] = c[1, 0] jac[1, 0, 1, 0] = c[1, 1] jac[1, 1, 0, 1] = c[1, 0] jac[1, 1, 1, 1] = c[1, 1] return jac c = np.array([[-0.5, -1.25], [0.5, -0.25]]) t = np.linspace(0, 10, 201) # a0 is the initial condition. a0 = np.array([[0.0, 1.0], [2.0, 3.0]]) sol = odeintw(asys, a0, t, Dfun=ajac, args=(c, )) plt.figure(1) plt.clf() color1 = (0.5, 0.4, 0.3) color2 = (0.2, 0.2, 1.0) plt.plot(t, sol[:, 0, 0], color=color1, label='a[0,0]') plt.plot(t, sol[:, 0, 1], color=color2, label='a[0,1]') plt.plot(t, sol[:, 1, 0], '--', color=color1, linewidth=1.5, label='a[1,0]') plt.plot(t, sol[:, 1, 1], '--', color=color2, linewidth=1.5, label='a[1,1]') plt.legend(loc='best') plt.grid(True) plt.show()
def cts_time_active_infections(beta, gamma, T, M=100, radius=1, numpts=10000, intermediate_values=False, numvals=11): r''' Gives probability of having 0, ..., M-1 active infections at time T or at times in interval [0,T] for continuous-time model. **Arguments** : beta (float) transmission rate gamma (float) recovery rate T (float) stop time M (integer [default 100]) returns probababilities of sizes from 0 to M-1 radius (positive integer [default 1]) radius to use for the integral. numpts (positive integer [default 10000]) number of points on circle to use in calculating approximate coefficient intermediate_values (boolean [default False]) irrelevant if T is None tells whether to return intermediate values in [0,T] numvals (int [default 11]) number of values in [0, T] inclusive to return. **Returns** : if intermediate_values is False : numpy array phi, where phi[n] is probability of n infections at time T. if intermediate_values is True : (ts, numvals x M numpy array) ts[i] is ith time and where phi[i, n] is probability of n active infections at ith time. :SAMPLE USE: :: import Invasion_PGF as pgf beta = 2 gamma = 1 #This shows some dependence on numpts. phi = pgf.cts_time_active_infections(beta, gamma, 10, M=5, numpts = 1000) phi > array([ 0.50048301, 0.0005057 , 0.00050569, 0.00050568, 0.00050567]) phi = pgf.cts_time_active_infections(beta, gamma, 10, M=5, numpts = 100000) phi > array([ 4.99989957e-01, 1.26581393e-05, 1.26578554e-05, 1.26575673e-05, 1.26572795e-05]) ''' if numpts <= M: print("warning numpts should be larger than M") times = numpy.linspace(0, T, numvals) ys = _get_pts_(numpts, radius) Phis0 = ys + 0j #just to make sure complex Phis = odeintw(_dPhi_dt_, Phis0, times, args=(beta, gamma)) if intermediate_values: phis = [] for fxn_values in Phis: coeffs = [] for n in range(M): coeffs.append(_get_coeff_(fxn_values, n, radius)) phis.append(numpy.array(coeffs)) phis = numpy.array(phis) phis = numpy.real(phis) #remove numerical noise return (times, phis) else: fxn_values = Phis[-1] coeffs = [] for n in range(M): coeffs.append(_get_coeff_(fxn_values, n, radius)) coeffs = numpy.array(coeffs) coeffs = numpy.real(coeffs) #remove numerical noise return coeffs
jac[0, 1, 0, 1] = c[0, 0] jac[0, 1, 1, 1] = c[0, 1] jac[1, 0, 0, 0] = c[1, 0] jac[1, 0, 1, 0] = c[1, 1] jac[1, 1, 0, 1] = c[1, 0] jac[1, 1, 1, 1] = c[1, 1] return jac c = np.array([[-0.5, -1.25], [ 0.5, -0.25]]) t = np.linspace(0, 10, 201) # a0 is the initial condition. a0 = np.array([[0.0, 1.0], [2.0, 3.0]]) sol = odeintw(asys, a0, t, Dfun=ajac, args=(c,)) plt.figure(1) plt.clf() color1 = (0.5, 0.4, 0.3) color2 = (0.2, 0.2, 1.0) plt.plot(t, sol[:, 0, 0], color=color1, label='a[0,0]') plt.plot(t, sol[:, 0, 1], color=color2, label='a[0,1]') plt.plot(t, sol[:, 1, 0], '--', color=color1, linewidth=1.5, label='a[1,0]') plt.plot(t, sol[:, 1, 1], '--', color=color2, linewidth=1.5, label='a[1,1]') plt.legend(loc='best') plt.grid(True) plt.show()
def run_stochastic_wavefunction_solver(self, s, t0, tf, num=50, schedule=lambda t: None, times=None, full_output=True, method='trotterize', verbose=False, iterations=None): if iterations is None: iterations = 1 # Compute probability that we have a jump # For the stochastic solver, we have to return a times dictionary assert s.is_ket # Save state properties is_ket = s.is_ket code = s.code IS_subspace = s.IS_subspace state_shape = s.shape graph = s.graph num_jumps = [] jump_times = [] jump_indices = [] if times is None and (method == 'odeint' or method == 'trotterize'): times = np.linspace(0, 1, num=int(num)) * (tf - t0) + t0 if not (method == 'odeint' or method == 'trotterize'): raise NotImplementedError schrodinger_equation = SchrodingerEquation( hamiltonians=self.hamiltonians + self.jump_operators) def f(t, state): if method == 'odeint': t, state = state, t if method != 'odeint': state = np.reshape(np.expand_dims(state, axis=0), state_shape) state = State(state, is_ket=is_ket, code=code, IS_subspace=IS_subspace) return np.asarray( schrodinger_equation.evolution_generator(state)).flatten() assert len(times) > 1 if full_output: outputs = np.zeros( (iterations, len(times), s.shape[0], s.shape[1]), dtype=np.complex128) else: outputs = np.zeros((iterations, s.shape[0], s.shape[1]), dtype=np.complex128) dt = times[1] - times[0] for k in range(iterations): jump_time = [] jump_indices_iter = [] num_jump = 0 out = s.copy() if verbose: print('Iteration', k) for (j, time) in zip(range(times.shape[0]), times): # Update energies schedule(time) for i in range(len(self.jump_operators)): if i == 0: jumped_states, jump_probabilities = self.jump_operators[ i].jump_rate( out, list(range(out.number_physical_qudits))) jump_probabilities = jump_probabilities * dt elif i > 0: js, jp = self.jump_operators[i].jump_rate( out, list(range(out.number_physical_qudits))) jump_probabilities = np.concatenate( [jump_probabilities, jp * dt]) jumped_states = np.concatenate([jumped_states, js]) if len(self.jump_operators) == 0: jump_probability = 0 else: jump_probability = np.sum(jump_probabilities) if np.random.uniform() < jump_probability and len( self.jump_operators) != 0: # Then we should do a jump num_jump += 1 jump_time.append(time) if verbose: print('Jumped with probability', jump_probability, 'at time', time) jump_index = np.random.choice( list(range(len(jump_probabilities))), p=jump_probabilities / np.sum(jump_probabilities)) jump_indices_iter.append(jump_index) out = State(jumped_states[jump_index, ...] * np.sqrt(dt / jump_probabilities[jump_index]), is_ket=is_ket, code=code, IS_subspace=IS_subspace, graph=graph) # Normalization factor else: state_asarray = np.asarray(out) if method == 'odeint': z = odeintw(f, state_asarray, [0, dt], full_output=False) out = State(z[-1], code=code, IS_subspace=IS_subspace, is_ket=is_ket, graph=graph) else: for hamiltonian in self.hamiltonians: out = hamiltonian.evolve(out, dt) for jump_operator in self.jump_operators: if isinstance(jump_operator, LindbladJumpOperator): # Non-hermitian evolve out = jump_operator.nh_evolve(out, dt) elif isinstance(jump_operator, QuantumChannel): out = jump_operator.evolve(out, dt) out = State(out, code=code, IS_subspace=IS_subspace, is_ket=is_ket, graph=graph) # Normalize the output out = out / np.linalg.norm(out) # We don't do np.sqrt(1 - jump_probability) because it is only a first order expansion, # and is often inaccurate. Things will quickly diverge if the state is not normalized if full_output: outputs[k, j, ...] = out jump_times.append(jump_time) jump_indices.append(jump_indices_iter) num_jumps.append(num_jump) if not full_output: outputs[k, ...] = out return outputs, { 't': times, 'jump_times': jump_times, 'num_jumps': num_jumps, 'jump_indices': jump_indices }
#solving for steady state detuning del_om_0 = -kappa * np.sqrt(1 + alpha**2) * A_fr * np.sin( phi + np.arctan(alpha)) / A0 / 2 / np.pi #defining the function to be solved def f(y, t): #Complex amplitude differential equation dyA = 0.5 * g * (y[1] - N_th) * ( 1 + 1j * alpha) * y[0] + kappa * A_fr - 1j * del_om_0 * 2 * np.pi * y[0] #Carrier density equation dyN = J - gamma_n * y[1] - (gamma_p + g * (y[1] - N_th)) * abs(y[0])**2 return np.asarray([dyA, dyN]) # Declaring initial conditions ini_cond = np.array([A_fr, N_th], dtype=complex128) t_fin = 3.e-9 t_step = 0.05e-10 t = np.arange(0., t_fin, t_step) psol = odeintw(f, ini_cond, t, rtol=1.e-4) print("------Total Solver Time = %s seconds-----" % (time.time() - start_time)) #plotting the solution plt.plot(t / 1.e-9, abs(psol[:, 0]), 'rx-') plt.xlabel('time(ns)') plt.ylabel('amplitude(arbitrary units)') plt.title('solution') show()
def EtaB(self): #Define fixed quantities for BEs epstt = np.real(self.epsilon1ab(2, 2)) epsmm = np.real(self.epsilon1ab(1, 1)) epsee = np.real(self.epsilon1ab(0, 0)) epstm = self.epsilon1ab(2, 1) epste = self.epsilon1ab(2, 0) epsme = self.epsilon1ab(1, 0) # Yukawa couplings c1t = self.c1a(2) c1m = self.c1a(1) c1e = self.c1a(0) Mi = 10**(self.MPBHi) # PBH initial Mass in grams bi = 10**(self.bPBHi) # Initial PBH fraction Ti = ((45. / (16. * 106.75 * (np.pi * GCF)**3.))**0.25) * np.sqrt( gamma * GeV_in_g / Mi) # Initial Universe temperature rRadi = (np.pi**2. / 30.) * gstar( Ti ) * Ti**4 # Initial radiation energy density -- assuming a radiation dominated Universe rPBHi = (bi / (np.sqrt(gamma) - bi)) * rRadi # Initial PBH energy density nphi = (2. * zeta(3) / np.pi**2) * Ti**3 # Initial photon number density N1Ri = 0. # Initial RH neutrino number density Ntti = 0. # Initial B-L number densities Nmmi = 0. Neei = 0. Ntmi = 0. Ntei = 0. Nmei = 0. parms1 = np.array([ epstt, epsmm, epsee, epstm, epste, epsme, c1t, c1m, c1e, np.real(rRadi), np.real(rPBHi), np.real(nphi) ], dtype=np.complex128) v0 = [Mi, rRadi, rPBHi, N1Ri, Ti, Ntti, Nmmi, Neei, Ntmi, Ntei, Nmei] tau = integrate.quad(Itau, GeV_in_g * mPL, Mi, args=(self.M1, self.M2, self.M3)) # PBH lifetime in s af = root(afin, [20.], args=(rPBHi, rRadi, tau[0]), method='hybr') # Scale factor in which BHs evaporate aflog10 = 0.995 * af.x[0] #------------------------------------------------------------# # # # Before BH evaporation # # # #------------------------------------------------------------# # time points t1 = np.linspace(0., aflog10, num=1000, endpoint=True) # solve ODE solFBE = odeintw(self.RHS, v0, t1, args=tuple(parms1), rtol=1.e-13, atol=1.e-13) #------------------------------------------------------------# # # # After BH evaporation # # # #------------------------------------------------------------# # time points npaf = 500 azmax = aflog10 + 2. * np.log10( 25. * solFBE[-1, 4] / self.M1) # Determining the z=M1/T at which PBH evaporate afmax = max(aflog10, azmax) t2 = np.linspace(aflog10, afmax, num=npaf) v0aBE = [ solFBE[-1, 1], solFBE[-1, 3], solFBE[-1, 4], solFBE[-1, 5], solFBE[-1, 6], solFBE[-1, 7], solFBE[-1, 8], solFBE[-1, 9], solFBE[-1, 10] ] parms2 = np.array([ epstt, epsmm, epsee, epstm, epste, epsme, c1t, c1m, c1e, np.real(solFBE[-1, 1]), np.real(nphi) ], dtype=np.complex128) # solve ODE solFBE_aBE = odeintw(self.RHS_aBE, v0aBE, t2, args=tuple(parms2), rtol=1.e-13, atol=1.e-13) #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++# # Joining the solutions before and after evaporation # #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++# t = np.concatenate((t1, t2), axis=None) MBH = np.concatenate((solFBE[:, 0], np.zeros(npaf)), axis=None) Rad = np.concatenate((solFBE[:, 1], solFBE_aBE[:, 0]), axis=None) PBH = np.concatenate((solFBE[:, 2], np.zeros(npaf)), axis=None) T = np.concatenate((solFBE[:, 4], solFBE_aBE[:, 2]), axis=None) NRH = np.concatenate((solFBE[:, 3], solFBE_aBE[:, 1]), axis=None) NBLtt = np.concatenate((solFBE[:, 5], solFBE_aBE[:, 3]), axis=None) NBLmm = np.concatenate((solFBE[:, 6], solFBE_aBE[:, 4]), axis=None) NBLee = np.concatenate((solFBE[:, 7], solFBE_aBE[:, 5]), axis=None) #------------------------------------------------------------# # # # Conversion to eta_B # # # #------------------------------------------------------------# gstarSrec = gstarS(0.3e-9) # d.o.f. at recombination gstarSoff = gstarS(T[-1]) # d.o.f. at the end of leptogenesis SMspl = 28. / 79. zeta3 = zeta(3) ggamma = 2. coeffNgamma = ggamma * zeta3 / np.pi**2 Ngamma = coeffNgamma * (10**t * T)**3 coeffsph = (SMspl * gstarSrec) / (gstarSoff * Ngamma) nb = coeffsph * (NBLtt + NBLmm + NBLee) * nphi return np.real(nb[-1])