Exemplo n.º 1
0
def psi(time, L=0, M=1000, aperiodicity=0,kind=0):
    """Return the probability amplitude the M-site lattice at the
    given time.  The initial condition is amplitude 1 at the central site,
    zero at all other sites.
    Parameters
    ----------
    time : float
        End time of the integration.
    L : float
        Nonlinearity parameter.
    M : int
        Number of lattice sites. (Default 101.)
    aperiodicity : float
        Aperiodicity parameter, defined in terms of the hoppings as (b/a - 1).
        (Default 0, which corresponds to a periodic chain.)
    Returns
    -------
    y : float
        Amplitude at the central site, $|\psi_{M/2}|$.
    """
    integrator = complex_ode(dnls_rhs(M, L, aperiodicity,kind))

    central_site_index = (M - 1)/2
    ic = np.zeros(shape=(M,))
    ic[central_site_index] = 1
    integrator.set_initial_value(ic)
    y= integrator.integrate(time)
    integrator = complex_ode(dnls_rhs(M, L, aperiodicity,kind))
    return y
Exemplo n.º 2
0
def mod_manifold_polar(x, y, lmbda, A, s, p, m, k):
    '''
	def manifold_polar(x,y,lambda,A,s,p,m,k,mu):
	return omega, alpha
	Returns "omega", the orthogonal basis for the manifold evaluated at x(2)
	and "gamma" the radial equation evaluated at x(2).

	Input "x" is the interval on which the manifold is solved, "y" is the
	initializing vector, "lambda" is the point in the complex plane where the
	Evans function is evaluated, "A" is a function handle to the Evans
	matrix, s,p,m are structures explained in the STABLAB documentation, and k
	is the dimension of the manifold sought.'''
    def ode_f(x, y):
        return m['method'](x, y, lmbda, A, s, p, m['n'], k)

    omega = np.zeros((m['n'], k, len(x)), dtype=complex)
    alpha = np.zeros((k, k, len(x)), dtype=complex)
    omega[:, :, 0], alpha[:, :, 0] = y, np.eye(k)

    t0, y0 = x[0], y.reshape(m['n'] * k, order='F')
    y0 = np.concatenate((y0, (np.eye(k)).reshape(k * k, order='F')))

    test = complex_ode(ode_f).set_integrator('dopri5',
                                             atol=m['options']['AbsTol'],
                                             rtol=m['options']['RelTol'],
                                             nsteps=5000)
    test.set_initial_value(y0, t0)

    for j in range(1, len(x)):
        test.integrate(x[j])
        omega[:, :, j] = test.y[0:k * m['n']].reshape(m['n'], k, order='F')
        alpha[:, :, j] = test.y[k * m['n']:].reshape(k, k, order='F')
    return omega, alpha
Exemplo n.º 3
0
def psi(t,M=10,steps=1, L=0,  aperiodicity=0,kind=0):
    """
    Parameters
    ----------
    time : float
        End time of the integration.
    L : float
        Nonlinearity parameter.
    M : int
        Number of lattice sites. (Default 101.)
    aperiodicity : float
        Aperiodicity parameter, defined in terms of the hoppings as (b/a - 1).
        (Default 0, which corresponds to a periodic chain.)
    kind: 0(periodic),1 (fib),2 (TM),3 (RS)
    Returns
    -------
    y : float
    wavefn at time t
    """
    r = integrate.complex_ode(dnls_rhs(M, L, aperiodicity,kind))
    central_site_index = (M - 1)/2
    ic = np.zeros(shape=(M,))
    ic[central_site_index] = 1.0
    r.set_initial_value(ic)
    dt = float(t)/steps
    wavefn = np.ones((steps,M), dtype=np.complex)
    t_arr=np.ones((steps), dtype=np.float)
    for idx in xrange(steps): #steps are needed here
      if r.successful(): #essentially it's an saying **if True:**
		wavefn[idx,:] = r.y[:]
		t_arr[idx]=r.t
      else:
		raise ValueError("Integration failed at t = {}".format(r.t)) #i don't understand this line
      r.integrate(r.t + dt)#note that if dt is too big, then you will get an error. So, steps should at least be same as 
    return wavefn,t_arr     #time units
Exemplo n.º 4
0
    def _run_solout_break_test(self, integrator):
        # Check correct usage of stopping via solout
        ts = []
        ys = []
        t0 = 0.0
        tend = 20.0
        y0 = [0.0]

        def solout(t, y):
            ts.append(t)
            ys.append(y.copy())
            if t > tend / 2.0:
                return -1

        def rhs(t, y):
            return [1.0 / (t - 10.0 - 1j)]

        ig = complex_ode(rhs).set_integrator(integrator)
        ig.set_solout(solout)
        ig.set_initial_value(y0, t0)
        ret = ig.integrate(tend)
        assert_array_equal(ys[0], y0)
        assert_array_equal(ys[-1], ret)
        assert_equal(ts[0], t0)
        assert_(ts[-1] > tend / 2.0)
        assert_(ts[-1] < tend)
Exemplo n.º 5
0
    def update_el_state(self, state: state.State):

        self.d_old = self.d_new
        self.d_new = state.drv_coupling
        self.E_old = self.E_new
        self.E_new = state.ad_energy

        dv_ave = 0.5 * (self.d_new.dot(state.v) + self.d_old.dot(state.v))
        E_ave = 0.5 * (self.E_new + self.E_old)

        H = np.diag(E_ave) - 1j * dv_ave

        if self.using_ode:

            def liouville(t, rho):
                rho_ = rho.reshape(H.shape)
                return (-1j * (H.dot(rho_) - rho_.dot(H))).flatten()

            r = complex_ode(liouville)
            r.set_initial_value(state.rho_el.flatten())
            state.rho_el = r.integrate(self.dt).reshape(H.shape)

        else:  # Verlet integration
            drho = -1j * (H.dot(state.rho_el) - state.rho_el.dot(H))
            rho_el_old_tmp = state.rho_el
            state.rho_el = 2 * state.rho_el - self.rho_el_old + drho * dt**2
            self.rho_el_old = rho_el_old_tmp

        self.update_hopping_prob(state, dv_ave)
def psi(t,M=10,steps=1, L=0,  aperiodicity=0,kind=0):
    r = integrate.complex_ode(dnls_rhs(M, L, aperiodicity,kind))
    central_site_index = (M - 1)/2
    ic = np.zeros(shape=(M,))
    ic[central_site_index] = 1.0
    r.set_initial_value(ic)
    dt = t/steps
    wavefn = np.ones((steps,M), dtype=np.complex)
    t_arr=np.ones((steps), dtype=np.float)
    for idx in xrange(steps):
        if r.successful(): #essentially, **if True:**
                if abs(r.y[0])< 1e-8 and abs(r.y[-1])<1e-8: #to make sure the lattice is big enough so that wavefn doesn't touch the boundary.
                    wavefn[idx,:] = r.y[:]
                    t_arr[idx]=r.t
                else:  		
                    #raise ValueError("wavefunction touching the boundary at t = {}".format(r.t))
                    print ("wfn touching the boundary at t = {} for p={}, U={}".format(r.t,aperiodicity,L))
                    wave_fn_truncated=wavefn[0:idx,:]
                    t_arr_truncated=t_arr[0:idx]
                    return wave_fn_truncated, t_arr_truncated
        else:
            raise ValueError("Integration failed at t = {}".format(r.t)) 
        r.integrate(r.t + dt) 
        #print r.t
    return wavefn,t_arr     
Exemplo n.º 7
0
def _evolve_cont(i,H,T,atol=1E-9,rtol=1E-9):
	"""
	This function evolves the ith local basis state under the Hamiltonian H up to period T. 
	This is used to construct the stroboscpoic evolution operator
	"""
	
	nsteps=_np.iinfo(_np.int32).max # huge number to make sure solver is successful.
	psi0=_np.zeros((H.Ns,),dtype=_np.complex128) 
	psi0[i]=1.0

	solver=complex_ode(H._hamiltonian__SO)
	solver.set_integrator('dop853', atol=atol,rtol=rtol,nsteps=nsteps) 
	solver.set_initial_value(psi0,t=0.0)
	t_list = [0,T]
	nsteps = 1
	while True:
		for t in t_list[1:]:
			solver.integrate(t)
			if solver.successful():
				if t == T:
					return solver.y
				continue
			else:
				break

		nsteps *= 10
		t_list = _np.linspace(0,T,num=nsteps+1,endpoint=True)
Exemplo n.º 8
0
def _evolve_cont(i,H,T,atol=1E-9,rtol=1E-9):
	"""This function evolves the i-th local basis state under the Hamiltonian H up to period T. 
	It is used to construct the stroboscpoic evolution operator.
	
	"""
	
	nsteps=_np.iinfo(_np.int32).max # huge number to make sure solver is successful.
	psi0=_np.zeros((H.Ns,),dtype=_np.complex128) 
	psi0[i]=1.0

	solver=complex_ode(H._hamiltonian__SO)
	solver.set_integrator('dop853', atol=atol,rtol=rtol,nsteps=nsteps) 
	solver.set_initial_value(psi0,t=0.0)
	t_list = [0,T]
	nsteps = 1
	while True:
		for t in t_list[1:]:
			solver.integrate(t)
			if solver.successful():
				if t == T:
					return solver.y
				continue
			else:
				break

		nsteps *= 10
		t_list = _np.linspace(0,T,num=nsteps+1,endpoint=True)
Exemplo n.º 9
0
def system(n,y0,tf,f,args = []):
    """
        Integration of the differential system between t = 0 and tf :
            - n : number of step
            - y0 : initial(s) condition(s)
            - tf : endpoint
            - k : tested eigenvalue
            - f : defined differential system in scipy.integrate fashion
    """
        
    sol = complex_ode(f)
    # complex_ode doesn't accept args in set_f_params method
    sol.set_f_params(args,)
    sol.set_initial_value(y0,0)
    #sol.set_integrator('zvode', method='bdf')
    
    dt = tf/(n*1.)
    y = np.zeros((n,len(y0)))
    y[0] = y0
    
    for i in range(0,n):
        y[i] = sol.integrate(sol.t+dt)
        print("i : {}, y : {}".format(i,y))

    return y
Exemplo n.º 10
0
    def _run_solout_break_test(self, integrator):
        # Check correct usage of stopping via solout
        ts = []
        ys = []
        t0 = 0.0
        tend = 20.0
        y0 = [0.0]

        def solout(t, y):
            ts.append(t)
            ys.append(y.copy())
            if t > tend/2.0:
                return -1

        def rhs(t, y):
            return [1.0/(t - 10.0 - 1j)]

        ig = complex_ode(rhs).set_integrator(integrator)
        ig.set_solout(solout)
        ig.set_initial_value(y0, t0)
        ret = ig.integrate(tend)
        assert_array_equal(ys[0], y0)
        assert_array_equal(ys[-1], ret)
        assert_equal(ts[0], t0)
        assert_(ts[-1] > tend/2.0)
        assert_(ts[-1] < tend)
Exemplo n.º 11
0
def prepare_integrator(simparameters, inifield):
    """ 
	prepare an integration scipy can understand 
	"""
    # only pass the necessary subset of the simparameters dict to GNLSE ...
    simpsub = dict(
        (k, simparameters[k])
        for k in ('gamma', 'raman', 'linop', 'W', 'dz', 'dt', 'RW', 'fr'))

    # the line below creates a new function handle as some of the scipy integrator functions
    # seem not to wrap additional parameters (simpsub in this case) of the RHS function
    # correctly	 (as SCIPY 0.14.0.dev-a3e9c7f)
    GNLSE_RHS2 = funcpartial(GNLSE_RHS, simp=simpsub)

    integrator = complex_ode(GNLSE_RHS2)
    # available types  dop853	dopri5	 lsoda	  vode
    # zvode also available, but do not use, as complex ode handling already wrapped above

    integrator.set_integrator(simparameters['integratortype'],
                              atol=simparameters['abstol'],
                              rtol=simparameters['reltol'],
                              nsteps=simparameters['nsteps'])

    integrator.set_initial_value(np.fft.ifft(inifield))
    return integrator
Exemplo n.º 12
0
    def k_int(mani,k_radii,k_powers,p,m,e):

        # time interval
        tspan = [0,2*np.pi]
        # initial condition
        ynot = np.array([0,0])

        out = np.zeros((len(k_powers)),dtype=np.complex)

        for j in range(len(k_powers)): # 1:length(k_powers)

            pre_k_ode = lambda t,y: k_ode(t,y,mani,k_radii[j],k_powers[j],p,e)
            # solve ode
            integrator = complex_ode(pre_k_ode).set_integrator('dopri5',
                            atol=m['k_int_options']['AbsTol'],
                            rtol=m['k_int_options']['RelTol'])
            integrator.set_initial_value(ynot,tspan[0])
            integrator.integrate(tspan[-1])
            Y = integrator.y
            Y = np.array([Y.T]).T

            # gather output
            out[j] = Y[0,-1]+Y[1,-1]*1j

        return out
Exemplo n.º 13
0
def manifold_polar(x,y,lamda,A,s,p,m,k,mu):
    """
     Returns "Omega", the orthogonal basis for the manifold evaluated at x[-1]
     and "gamma" the radial equation evaluated at x[-1].

     Input "x" is the interval on which the manifold is solved, "y" is the
     initializing vector, "lambda" is the point in the complex plane where the
     Evans function is evaluated, "A" is a function handle to the Evans
     matrix, s, p,and m are structures explained in the STABLAB documentation,
     and k is the dimension of the manifold sought.
    """

    def ode_f(x,y):
        return m['method'](x,y,lamda,A,s,p,m['n'],k,mu,m['damping'])

    t0 = x[0]
    y0 = y.reshape(m['n']*k,1,order='F')
    y0 = np.concatenate((y0,np.array([[0.0]],dtype=np.complex)),axis=0)
    y0 = y0.T[0]

    #initiate integrator object
    if 'options' in m:
        try:
            integrator = complex_ode(ode_f).set_integrator('dopri5',
                         atol=m['options']['AbsTol'],
                         rtol=m['options']['RelTol'],
                         nsteps=m['options']['nsteps'])
        except KeyError:
            integrator = complex_ode(ode_f).set_integrator('dopri5',atol=1e-6,
                                                            rtol=1e-5,
                                                            nsteps=10000)
    else:
        integrator = complex_ode(ode_f).set_integrator('dopri5',atol=1e-6,
                                                                rtol=1e-5,
                                                                nsteps=10000)

    integrator.set_initial_value(y0,t0) # set initial time and initial value
    integrator.integrate(x[-1])
    Y = integrator.y
    Y = np.array([Y.T]).T

    omega = Y[0:k*m['n'],-1].reshape(m['n'],k,order = 'F')
    gamma = np.exp(Y[m['n']*k,-1])

    return omega, gamma
Exemplo n.º 14
0
def manifold_compound(x, z, lamda, s, p, m, A, k, pmMU):
    """
    manifold_compound(x,z,lambda,s,p,m,A,k,pmMU)

    Returns the vector representing the manifold evaluated at x(2).

    Input "x" is the interval the manifold is computed on, "z" is the
    initializing vector for the ode solver, "lambda" is the point on the
    complex plane where the Evans function is computed, s,p,m are structures
    explained in the STABLAB documentation, "A" is the function handle to the
    desired Evans matrix, "k" is the dimension of the manifold sought, and
    "pmMU" is 1 or -1 depending on if respectively the growth or decay
    manifold is sought.
    """

    eigenVals,eigenVects = np.linalg.eig(A(x[0],lamda,s,p))

    ind = np.argmax(np.real(pmMU*eigenVals))
    MU = eigenVals[ind]

    # Solve the ODE
    def ode_f(x,y):
        return capa(x,y,lamda,s,p,A,m['n'],k,MU)
    if 'options' in m:
        try:
            integrator = complex_ode(ode_f).set_integrator('dopri5',
                         atol=m['options']['AbsTol'],
                         rtol=m['options']['RelTol'],
                         nsteps=m['options']['nsteps'])
        except KeyError:
            integrator = complex_ode(ode_f).set_integrator('dopri5',atol=1e-6,
                                                            rtol=1e-5,
                                                            nsteps=10000)
    else:
        integrator = complex_ode(ode_f).set_integrator('dopri5',atol=1e-6,
                                                                rtol=1e-5,
                                                                nsteps=10000)
    x0 = x[0]
    z0 = z.T[0]
    integrator.set_initial_value(z0,x0)
    integrator.integrate(x[-1])
    Z = integrator.y

    out = Z
    return out
Exemplo n.º 15
0
def _testcase_one_mode(h_sys, rho0, g, w, L, timesteps):
    """Integration of the single environment-mode case for debugging. The exact
    reduced dynamics is described by the reduced density operator p00 as well
    as three auxiliary states (p01, p10, p11). Their equations of motion read


    :param h_sys: @todo
    :param rho0: @todo
    :param g: @todo
    :param w: @todo
    :param L: @todo
    :param timesteps: @todo
    :returns: @todo

    """
    from numpy import dot
    from scipy.integrate import complex_ode

    dim = h_sys.shape[0]
    adj = lambda A: np.conj(np.transpose(A))

    prop = sp.lil_matrix((dim**2 * 4, dim**2 * 4), dtype=complex)
    i = [[(slice(m*dim**2, (m+1)*dim**2), slice(n*dim**2, (n+1)*dim**2))
          for n in range(4)] for m in range(4)]

    prop[i[0][0]] += -1.j * commutator(h_sys)
    prop[i[0][2]] += -multiply_raveled(adj(L), 'l') + multiply_raveled(adj(L), 'r')
    prop[i[0][1]] += multiply_raveled(L, 'l') - multiply_raveled(L, 'r')

    prop[i[1][1]] += -1.j * commutator(h_sys) - np.conj(w) * np.identity(dim**2)
    prop[i[1][0]] += np.conj(g) * multiply_raveled(adj(L), 'r')
    prop[i[1][3]] += -multiply_raveled(adj(L), 'l') - multiply_raveled(adj(L), 'r')

    prop[i[2][2]] += -1.j * commutator(h_sys) - w * np.identity(dim**2)
    prop[i[2][0]] += g * multiply_raveled(L, 'l')
    prop[i[2][3]] += -multiply_raveled(L, 'l') - multiply_raveled(L, 'r')

    prop[i[3][3]] += -1.j * commutator(h_sys) - (w + np.conj(w)) * np.identity(dim**2)
    prop[i[3][1]] += g * multiply_raveled(L, 'l')
    prop[i[3][2]] += np.conj(g) * multiply_raveled(adj(L), 'r')

    print('CORRECT')
    print(prop)

    y0 = np.zeros((4, dim, dim), dtype=complex)
    y0[0] = rho0
    rho = np.empty((len(timesteps), dim, dim), dtype=complex)
    rho[0] = rho0

    r = complex_ode(lambda t, y: prop.dot(y))\
        .set_integrator('vode', atol=1e-10, rtol=1e-10, nsteps=100) \
        .set_initial_value(y0.ravel())
    for i, t in enumerate(timesteps[1:]):
        r.integrate(t)
        rho[i + 1] = r.y.reshape((4, dim, dim))[0]

    return timesteps, rho
Exemplo n.º 16
0
def test_evolve():
    def ifunc(t, y):
        return -1j * np.cos(t) * M.dot(y)

    def func(t, y):
        return -np.cos(t) * M.dot(y)

    M = np.random.uniform(
        -1, 1, size=(4, 4)) + 1j * np.random.uniform(-1, 1, size=(4, 4))
    M = (M.T.conj() + M) / 2.0
    M = np.asarray(M)

    H = hamiltonian([], [[M, np.cos, ()]])

    psi0 = np.random.uniform(
        -1, 1, size=(4, )) + 1j * np.random.uniform(-1, 1, size=(4, ))
    psi0 /= np.linalg.norm(psi0)

    isolver = complex_ode(ifunc)
    isolver.set_integrator("dop853",
                           atol=1e-9,
                           rtol=1e-9,
                           nsteps=np.iinfo(np.int32).max)
    isolver.set_initial_value(psi0, 0)

    solver = complex_ode(func)
    solver.set_integrator("dop853",
                          atol=1e-9,
                          rtol=1e-9,
                          nsteps=np.iinfo(np.int32).max)
    solver.set_initial_value(psi0, 0)

    times = np.arange(0, 100.1, 10)

    ipsi_t = H.evolve(psi0, 0, times, iterate=True)
    psi_t = H.evolve(psi0, 0, times, iterate=True, imag_time=True)

    for i, (ipsi, psi) in enumerate(zip(ipsi_t, psi_t)):
        solver.integrate(times[i])
        solver._y /= np.linalg.norm(solver.y)
        np.testing.assert_allclose(psi - solver.y, 0, atol=1e-10)

        isolver.integrate(times[i])
        np.testing.assert_allclose(ipsi - isolver.y, 0, atol=1e-10)
Exemplo n.º 17
0
    def solve_ODE(self, H=None):
        """Iteratively solve the ODE dy/dt = f(t,y) on a discretized time-grid.

            Returns:
            --------
                    t:  (N,)  ndarray
                        Time array.
                phi_a:  (N,2) ndarray
                        Overlap <phi_a|psi>.
                phi_b:  (N,2) ndarray
                        Overlap <phi_b|psi>.
        """

        if H is None:
            H = self.H

        # set initial conditions
        self.get_c_eigensystem()        # calculate eigensystem for all times
        if self.init_state_method == 'gain':
            self._find_gain_state()
        elif self.init_state_method == 'energy':
            self._find_lower_energy_state()
        self.eVec0 = self._get_init_state()

        # create ode object to solve Schroedinger equation (SE)
        ode_kwargs = {'rtol': 1e-9,
                      'atol': 1e-9}
        SE = complex_ode(lambda t, phi: -1j*H(t).dot(phi))
        SE.set_integrator('dopri5', **ode_kwargs)
        SE.set_initial_value(self.eVec0, t=0.0)

        # iterate SE
        for n, tn in enumerate(self.t):
            if SE.successful():
                self.Psi[n,:] = SE.y
                SE.integrate(SE.t + self.dt)
            else:
                raise Exception("ODE convergence error!")

        if self.calc_adiabatic_state:
            self._get_adiabatic_state()

        # replace projection of states by dot product via Einstein sum
        projection = np.einsum('ijk,ij -> ik',
                               self.eVecs_l, self.Psi)
        # use alternative means to obtain coefficients:
        #  (c1, c2) = X^-1^T psi
        # from scipy.linalg import inv
        # projection = [np.einsum('jk,j -> k', inv(self.eVecs_r[n,:]).T, self.Psi[n,:])
        #                for n, _ in enumerate(self.t)]
        # projection = np.asarray(projection)

        self.phi_a, self.phi_b = [projection[:,n] for n in (0,1)]

        return self.t, self.phi_a, self.phi_b
Exemplo n.º 18
0
Arquivo: evo.py Projeto: jcmgray/quimb
 def _start_integrator(self, ham, small_step):
     """ Initialize a stepping integrator. """
     self.sparse_ham = issparse(ham)
     evo_eq = calc_evo_eq(self.isdop, self.sparse_ham)
     self.stepper = complex_ode(evo_eq(ham))
     int_mthd, step_fct = ('dopri5', 150) if small_step else ('dop853', 50)
     first_step = norm(ham, 'f') / step_fct
     self.stepper.set_integrator(int_mthd, nsteps=0, first_step=first_step)
     self.stepper.set_initial_value(self.p0.A.reshape(-1), self.t0)
     self.update_to = self._update_to_integrate
     self.solved = False
def adiabatic(n, T, M, H_driver, H_problem, ground_state_prob, normalise=True, sprs=True):
    N = 2**n
    psi0 = np.ones(N) * (1 / np.sqrt(N))
    newschro = lambda t, y: schrodinger(t, y, T, H_driver, H_problem)
    r = complex_ode(newschro)
    r.set_integrator("dop853")
    r.set_initial_value(psi0, 0)
    # r.set_f_params(T, H_driver, H_problem)
    # print(r.f_params)
    psiN = r.integrate(T)
    return np.abs(np.dot(np.conjugate(ground_state_prob), psiN)) ** 2
Exemplo n.º 20
0
def sol(kx, ky):
	def ham_k(t):
		return ham(kx, ky, t)
	def f(y_vec, t):
		y_1, y_2 = y_vec
		fun = -1j * np.dot( ham_k(t), np.array([ [y_1],[y_2] ]) )
		return [fun[0,0], fun[1,0]]

	y_result = complex_ode(f, y0, t_output)
	
	return np.array([y_result.real, y_result.imag])
Exemplo n.º 21
0
    def _integrator(self, f, **kwargs):
        from scipy.integrate import complex_ode

        defaults = {
            'nsteps': 1e9,
            'with_jacobian': False,
            'method': 'bdf',
        }
        defaults.update(kwargs)

        r = complex_ode(f).set_integrator('vode', atol=self.error_abs, rtol=self.error_rel, **defaults)
        return r
Exemplo n.º 22
0
    def Propagate_SAM(self, L, betta2=-1, gamma=1, Tr=0, n=50, abtol=1e-10, reltol=1e-9, param='fin_res'):
        """Propagate Using the Step Adaptative  Method"""
        def deriv_2(dt, field_in):
        # computes the second-order derivative of field_in
            field_fft = np.fft.fft(field_in)
            freq = 1./dt*np.fft.fftfreq(len(field_in))
            # print freq
            omega = 2.*np.pi*freq
            # field_fft*=np.exp(1j*0.5*beta2z*omega**2)
            field_fft *= -omega**2
            out_field = np.fft.ifft(field_fft)
            return out_field 
            
        def deriv_1(dt, field_in):
        # computes the second-order derivative of field_in
            field_fft = np.fft.fft(field_in)
            freq = 1./dt*np.fft.fftfreq(len(field_in))
            # print freq
            omega = 2.*np.pi*freq
            # field_fft*=np.exp(1j*0.5*beta2z*omega**2)
            field_fft *= 1j*omega
            out_field = np.fft.ifft(field_fft)
            return out_field
        if Tr==0:
            def NLS_1d(Z, A):
                # time second order derivative
                dAdT2 = deriv_2(self.TimeStep, A)
#                dAAdT = deriv_1(self.TimeStep,abs(A)**2)
                dAdz = -1j*betta2/2*dAdT2+1j*gamma*abs(A)**2*A#-1j*gamma*Tr*dAAdT
                return dAdz        
        else:
            def NLS_1d(Z, A):
                # time second order derivative
                dAdT2 = deriv_2(self.TimeStep, A)
                dAAdT = deriv_1(self.TimeStep,abs(A)**2)
                dAdz = -1j*betta2/2*dAdT2+1j*gamma*abs(A)**2*A-1j*gamma*Tr*dAAdT*A
                return dAdz

        dz =float(L)/n
#        r = complex_ode(NLS_1d).set_integrator('zvode', method='bdf', with_jacobian=False, atol=abtol, rtol=reltol)
        r = complex_ode(NLS_1d).set_integrator('dopri5', atol=abtol, rtol=reltol)
#        r = complex_ode(NLS_1d).set_integrator('lsoda', method='BDF', atol=abtol, rtol=reltol, with_jacobian=False)
        r.set_initial_value(self.Sig, 0)
        sol=np.ndarray(shape=(n+1, len(self.Sig)), dtype=complex)
        sol[0] = self.Sig
        for it in range(1, n+1):
            sol[it] = r.integrate(r.t+dz)
        if param == 'map':
            return sol
        elif param == 'fin_res':
            return sol[-2, :]
        else:
            print ('wrong parameter')
Exemplo n.º 23
0
def central_amplitude(time, L, M=101, aperiodicity=0):


integrator = complex_ode(dnls_rhs(M, L, aperiodicity))

    central_site_index = (M - 1)/2
    ic = np.zeros(shape=(M,))
    ic[central_site_index] = 1
    integrator.set_initial_value(ic)

    y = integrator.integrate(time)
    return np.abs(y[central_site_index])
def f(df, u, h, theta):
    dt = h / 1e1
    df_args = functools.partial(df, theta = theta)
    r = si.complex_ode(df_args)
    sol = []
    for v in u:
        x0 = [0., v * 1j]
        r.set_initial_value(x0, 0)
        while r.successful() and r.t < h:
            r.integrate(r.t + dt)
        sol.append(r.y)
    return np.array(sol).T
def compare_performance(func, y0, t0, tf, y_ref, problem_name, tol_boundary=(0,6), is_complex=False, nsteps=10e5, solout=(lambda t: t)):
    print 'RUNNING COMPARISON TEST FOR ' + problem_name
    tol = [1.e-3,1.e-5,1.e-7,1.e-9,1.e-11,1.e-13]
    a, b = tol_boundary
    tol = tol[a:b]

    extrap = {}
    dopri5 = {}
    dop853 = {}

    for method in [extrap, dopri5, dop853]:
        for diagnostic in ['runtime','fe_seq','fe_tot','yerr','nstp']:
            method[diagnostic] = np.zeros(len(tol))

    def func2(t,y):
        return func(y,t)

    for i in range(len(tol)):
        print 'Tolerance: ', tol[i]

        for method, name in [(extrap,'ParEx'), (dopri5,'DOPRI5'), (dop853,'DOP853')]:
            print 'running ' + name
            start_time = time.time()
            if name == 'ParEx':
                y, infodict = parex.solve(func, [t0, tf], y0, solver=parex.Solvers.EXPLICIT_MIDPOINT, atol=tol[i], rtol=tol[i], max_steps=nsteps, adaptive=True, diagnostics=True)
                y[-1] = solout(y[-1])
                method['yerr'][i] = relative_error(y[-1], y_ref)
            else: # scipy solvers DOPRI5 and DOP853
                if is_complex:
                    r = complex_ode(func2, jac=None).set_integrator(name.lower(), atol=tol[i], rtol=tol[i], verbosity=10, nsteps=nsteps)
                else:
                    r = ode(func2, jac=None).set_integrator(name.lower(), atol=tol[i], rtol=tol[i], verbosity=10, nsteps=nsteps)
                r.set_initial_value(y0, t0)
                r.integrate(r.t+(tf-t0))
                assert r.t == tf, "Integration did not converge. Try increasing the max number of steps"
                y = solout(r.y)
                method['yerr'][i] = relative_error(y, y_ref)

            method['runtime'][i] = time.time() - start_time
            method['fe_seq'][i], method['fe_tot'][i], method['nstp'][i] = infodict['fe_seq'], infodict['nfe'], infodict['nst']
            print 'Runtime: ', method['runtime'][i], ' s   Error: ', method['yerr'][i], '   fe_seq: ', method['fe_seq'][i], '   fe_tot: ', method['fe_tot'][i], '   nstp: ', method['nstp'][i]
            print ''
        
        print ''

    for method, name in [(extrap,'ParEx'), (dopri5,'DOPRI5'), (dop853,'DOP853')]:
        print "Final data: " + name
        print method['runtime'], method['fe_seq'], method['fe_tot'], method['yerr'], method['nstp']
    print ''
    print ''

    return (extrap, dopri5, dop853)
Exemplo n.º 26
0
    def _setup_integrator(self, t0, name, **params):
        if (self.is_ensemble):
            func = vonNeumann
        else:
            func = schroedinger

        if (name == 'zvode'):
            I = ode(_wrap(func, self.H))
        else:
            I = complex_ode(_wrap(func, self.H))

        I.set_integrator(name, **params)
        I.set_initial_value(self.state.as_vector(), t0)
        return I
Exemplo n.º 27
0
    def _integrator(self, f, **kwargs):
        from scipy.integrate import complex_ode

        defaults = {
            'nsteps': 1e9,
            'with_jacobian': False,
            'method': 'bdf',
        }
        defaults.update(kwargs)

        r = complex_ode(f).set_integrator('vode',
                                          atol=self.error_abs,
                                          rtol=self.error_rel,
                                          **defaults)
        return r
Exemplo n.º 28
0
    def integrate(self, end_z, dz):
        steps = int(end_z / dz)
        self.z = np.arange(0, stop=end_z, step=dz)
        self._allocate_storage(steps)
        f = complex_ode(self.qpm_coupled_system)
        f.set_initial_value(self.A)
        i = 0

        while f.successful() and f.t <= end_z:
            self.solution[i] = f.integrate(f.t + dz)
            i += 1

        self.A_1_solution = np.transpose(self.solution)[0]
        self.A_2_solution = np.transpose(self.solution)[1]
        return [self.A_1_solution, self.A_2_solution, self.z]
Exemplo n.º 29
0
    def plot_this(ynot,tspan,ode,rp):
        sol = stablab.Struct()
        sol.t = []
        sol.y = []
        def updateSol(tVal,yVals):
            sol.t.append(tVal)
            sol.y.append(yVals)
            return None

        integrator = complex_ode(ode)
        integrator.set_integrator('dopri5',atol=1e-10,rtol=1e-10)
        integrator.set_solout(updateSol)
        integrator.set_initial_value(ynot,tspan[0])
        integrator.integrate(tspan[-1])
        sol.t, sol.y = np.array(sol.t), np.array(sol.y)
        return sol
Exemplo n.º 30
0
    def _do_problem(self, problem, integrator, method='adams'):

        # ode has callback arguments in different order than odeint
        f = lambda t, z: problem.f(z, t)
        jac = None
        if hasattr(problem, 'jac'):
            jac = lambda t, z: problem.jac(z, t)
        ig = complex_ode(f, jac)
        ig.set_integrator(integrator,
                          atol=problem.atol/10,
                          rtol=problem.rtol/10,
                          method=method)
        ig.set_initial_value(problem.z0, t=0.0)
        z = ig.integrate(problem.stop_t)

        assert_(ig.successful(), (problem, method))
        assert_(problem.verify(array([z]), problem.stop_t), (problem, method))
Exemplo n.º 31
0
    def solve_equations(self):
        time_stamps = np.concatenate((np.linspace(0,
                                                  time_limit / 100,
                                                  num=10**3),
                                      np.linspace(time_limit / 100,
                                                  time_limit,
                                                  num=10**3)))

        self.initial_conditions()
        ode = complex_ode(self.ode_sys()).set_integrator('dopri5',
                                                         method='bdf')
        ode.set_initial_value(self.ode_init)
        for t in tqdm(time_stamps[1:]):
            dt = t - ode.t
            solution = ode.integrate(ode.t + dt)
            self.decompose_ode_sol(sol=solution)
            self.append_quantities(t)
Exemplo n.º 32
0
    def _do_problem(self, problem, integrator, method='adams'):

        # ode has callback arguments in different order than odeint
        f = lambda t, z: problem.f(z, t)
        jac = None
        if hasattr(problem, 'jac'):
            jac = lambda t, z: problem.jac(z, t)
        ig = complex_ode(f, jac)
        ig.set_integrator(integrator,
                          atol=problem.atol / 10,
                          rtol=problem.rtol / 10,
                          method=method)
        ig.set_initial_value(problem.z0, t=0.0)
        z = ig.integrate(problem.stop_t)

        assert_(ig.successful(), (problem, method))
        assert_(problem.verify(array([z]), problem.stop_t), (problem, method))
Exemplo n.º 33
0
	def __init__(self,myhamgen,param):
		self.hamgen = myhamgen
		self.param=param

		#Set up the solver
		self.norm=0
		#self.r=ode(self.func).set_integrator('zvode', method='bdf',rtol=1e-6)
		#self.r=complex_ode(self.func).set_integrator('dopri5',rtol=1e-6)
		self.r=complex_ode(self.func).set_integrator('dopri5',rtol=1e-6,nsteps=100000)


		#Generate basis vectors
		self.b=[]
		for x in range(0,param.numneu):
			self.b.append(np.zeros(param.numneu))
			self.b[x][x]=1.0

		self.splines=Splines.Spline()
Exemplo n.º 34
0
def adiabatic(n,
              T,
              H_driver,
              H_problem,
              ground_state_prob,
              normalise=True,
              sprs=True,
              n_steps=16384):
    # print(T)
    N = 2**n
    psi0 = np.ones(N) * (1 / np.sqrt(N))
    newschro = lambda t, y: schrodinger(t, y, T, H_driver, H_problem)
    r = complex_ode(newschro)
    r.set_integrator("dop853", nsteps=n_steps)
    r.set_initial_value(psi0, 0)
    # r.set_f_params(T, H_driver, H_problem)
    psiN = r.integrate(T)
    # print(np.abs(np.conjugate(ground_state_prob).dot(psiN)) ** 2)
    return np.abs(np.conjugate(ground_state_prob).dot(psiN))**2, r.successful()
Exemplo n.º 35
0
def psi_old(t,M=10,steps=1, L=0,  aperiodicity=0,kind=0):
    """
    Parameters
    ----------
    time : float
        End time of the integration.
    L : float
        Nonlinearity parameter.
    M : int
        Number of lattice sites. (Default 101.)
    aperiodicity : float
        Aperiodicity parameter, defined in terms of the hoppings as (b/a - 1).
        (Default 0, which corresponds to a periodic chain.)
    kind: 0(periodic),fib,tm,rs
    Returns
    -------
    y : float
    wavefn at time t
    """
    r = integrate.complex_ode(dnls_rhs(M, L, aperiodicity,kind))
    central_site_index = (M - 1)/2
    ic = np.zeros(shape=(M,))
    ic[central_site_index] = 1.0
    r.set_initial_value(ic)
    dt = float(t)/steps
    wavefn = np.zeros((steps,M), dtype=np.complex)
    t_arr=np.zeros((steps), dtype=np.float)
    for idx in xrange(steps):
      if r.successful(): #essentially, **if True:**
		if abs(r.y[0])< 1e-10 and abs(r.y[-1])<1e-10: #to make sure the lattice is big enough so that wavefn doesn't touch the boundary.
		    wavefn[idx,:] = r.y[:]
		    t_arr[idx]=r.t
		    #print "y"
		else:
		    print ("wfn touching the boundary at t = {} for p={}".format(r.t,aperiodicity))
		    wave_fn_truncated=wavefn[0:idx,:]
		    t_arr_truncated=t_arr[0:idx]
		    return wave_fn_truncated, t_arr_truncated
      else:
		raise ValueError("Integration failed at t = {}".format(r.t)) 
      r.integrate(r.t + dt)#note that if dt is too big, then you will get an error. So, steps should at least be same as 
    return wavefn,t_arr     #time units
Exemplo n.º 36
0
def manifold_polar(x, y, lmbda, A, s, p, m, k, mu):
    def ode_f(x, y):
        return m['method'](x, y, lmbda, A, s, p, m['n'], k, mu, m['damping'])

    t0 = x[0]
    y0 = y.reshape(m['n'] * k, 1, order='F')
    y0 = np.concatenate((y0, np.array([[1.0]])), axis=0)
    y0 = y0.T[0]

    #initiate integrator object
    test = complex_ode(ode_f).set_integrator('dopri5', atol=1e-5)

    test.set_initial_value(y0, t0)  # set initial time and initial value
    test.integrate(0)
    Y = test.y
    Y = np.array([Y.T]).T

    omega = Y[0:k * m['n'], 0].reshape(m['n'], k, order='F')
    gamma = Y[-1, 0]
    gamma = np.exp(gamma)

    return omega, gamma
Exemplo n.º 37
0
def solve(x, t, A0, fvec, callbackFunc):
    """ solve

    implements numerical integration scheme for complex field based on the
    explicit higher-order Runge-Kutta method "DOP853" (hard-coded).

    Args:
        x (numpy-array): discrete x-domain
        t (numpy-array): discrete t-domain
        A0 (numpy-array): initial condition
        fvec (object): right-hand-side of first order propagation equation
        callbaclFunc (object): callback function facilitating the measurement
            at distinct values of t. It takes 4 paramters in the form
            callbackFunc(n, tCurr, x, Ax), where:

            n (int): current propagation step
            t_curr (float): current time coordinate
            x (numpy-array): discrete x-domain
            Ax (numpy-array): field configuration at t_curr

    Returns: (t_fin,A_fin)
        t_fin (float): final time coordinate
        A_fin (numpy-array): final field configuration
    """

    dt = t[1]-t[0]
    it = 0

    solver = complex_ode(lambda t, A: fvec(A))
    solver.set_integrator('dop853')
    solver.set_initial_value(A0, t.min())

    while solver.successful() and solver.t < t.max():
        solver.integrate(solver.t+dt,step=1)
        callbackFunc(it, solver.t, x, solver.y)
        it += 1

    return solver.t, solver.y
Exemplo n.º 38
0
def prepare_integrator(simparameters, inifield):
    """ 
    prepare an integration scipy can understand 
    """
        # only pass the necessary subset of the simparameters dict to GNLSE ...
    simpsub = dict( (k, simparameters[k]) for k in ('gamma','raman','linop','W','dz','dt','RW','fr'))

        # the line below creates a new function handle as some of the scipy integrator functions
        # seem not to wrap additional parameters (simpsub in this case) of the RHS function 
        # correctly  (as SCIPY 0.14.0.dev-a3e9c7f)
    GNLSE_RHS2 = funcpartial( GNLSE_RHS, simp=simpsub)    
 
    integrator = complex_ode(GNLSE_RHS2)
        # available types  dop853   dopri5   lsoda    vode
        # zvode also available, but do not use, as complex ode handling already wrapped above

    integrator.set_integrator(simparameters['integratortype'], 
                              atol=simparameters['abstol'],
                              rtol=simparameters['reltol'],
                              nsteps=simparameters['nsteps'])

    integrator.set_initial_value(np.fft.ifft( inifield))
    return integrator
Exemplo n.º 39
0
def DGLloesen(A_0, w, v0, t0, t1, N):

    # Startwerte:
    x = np.zeros((36,N))*1j # für RK5
    y0 = np.array(v0)

    x[:,0] = y0 # Imaginärteil ist 0
    # x ist complexes 36xN array

    #Integration mit Runge-Kutta 5:
    t = np.linspace(t0,t1,N)
    r = complex_ode(f).set_integrator('dopri5')
    r.set_initial_value(y0, t0)

    i = 1
    print('Runge-Kutta(5) für',N-1,'Werte:')
    with tqdm(total=N-1) as pbar:
        while r.successful() and r.t < t[N-1]:
            r.integrate(t[i])
            pbar.update(1)
            x[:,i] = r.y
            i += 1
    return x
Exemplo n.º 40
0
    def _start_integrator(self, ham, small_step):
        """Initialize a stepping integrator.
        """
        if self._timedep:
            H0 = ham(0.0)
        else:
            H0 = ham

        # set complex ode with governing equation
        evo_eq = _calc_evo_eq(self._isdop, issparse(H0), False, self._timedep)

        self._stepper = complex_ode(evo_eq(ham))

        # 5th order stpper or 8th order stepper
        int_mthd, step_fct = ('dopri5', 150) if small_step else ('dop853', 50)
        if isinstance(H0, LinearOperator):
            # approx norm doesn't need to be very accurate
            nrm0 = norm_fro_approx(H0, tol=0.1)
        else:
            nrm0 = norm(H0, 'f')
        first_step = nrm0 / step_fct

        self._stepper.set_integrator(int_mthd, nsteps=0, first_step=first_step)

        # Set step_callback to be evaluated with args (t, y) at each step
        if self._int_step_callback is not None:

            def solout(t, y):
                self._int_step_callback(t, y, self._ham)

            self._stepper.set_solout(solout)

        self._stepper.set_initial_value(self._p0.A.reshape(-1), self.t0)

        # assign the correct update_to method
        self._update_method = self._update_to_integrate
Exemplo n.º 41
0
    def _start_integrator(self, ham, small_step):
        """Initialize a stepping integrator.
        """
        self._sparse_ham = issparse(ham)

        # set complex ode with governing equation
        evo_eq = _calc_evo_eq(self._isdop, self._sparse_ham)
        self._stepper = complex_ode(evo_eq(ham))

        # 5th order stpper or 8th order stepper
        int_mthd, step_fct = ('dopri5', 150) if small_step else ('dop853', 50)
        first_step = norm(ham, 'f') / step_fct

        self._stepper.set_integrator(int_mthd, nsteps=0, first_step=first_step)

        # Set step_callback to be evaluated with args (t, y) at each step
        if self._int_step_callback is not None:
            self._stepper.set_solout(self._int_step_callback)

        self._stepper.set_initial_value(self._p0.A.reshape(-1), self.t0)

        # assign the correct update_to method
        self._update_method = self._update_to_integrate
        self._solved = False
Exemplo n.º 42
0
def power_expansion2(R_lambda,k_radii,lambda_powers,k_powers,s,p,m,c,e):
    """
    # function out = power_expansion2(R_lambda,k_radii,lambda_powers,k_powers,s,p,m,c,e)
    #
    # Returns the double contour integral of $D(lambda,kappa)/(lambda^r
    # kappa^s)$ evaluated on a contour in lambda of radius R_lambda and in
    # kappa of radius k_radii(j) for the jth power in kappa, s = k_powers(j).
    #
    #
    # Example: St. Venant's equation
    #
    # [s,e,m,c] = emcset(s,'periodic',[2,1],'balanced_polar_periodic','Aper');
    #
    # m.k_int_options = odeset('AbsTol',10^(-10), 'RelTol',10^(-8));
    # m.lambda_int_options = odeset('AbsTol',10^(-8), 'RelTol',10^(-6));
    #
    # st.k_int_options = m.k_int_options;
    # st.lambda_int_options = m.lambda_int_options;
    #
    # R_lambda = 0.01;
    # k_radii = 9*[0.001, 0.001, 0.001 0.001];
    # k_powers = [0 1 2 3 ];
    # lambda_powers = [0 1 2 3];
    #
    # st.R_lambda = R_lambda;
    # st.k_radii = k_radii;
    #
    # s_time = tic;
    # out = power_expansion2(R_lambda,k_radii,lambda_powers,k_powers,s,p,m,c,e);
    # st.time = toc(s_time);
    #
    # coef = out.';
    #
    # aa=coef(3,1);
    # bb=coef(2,2);
    # cc=coef(1,3);
    # dd=coef(4,1);
    # ee=coef(3,2);
    # ff = coef(2,3);
    # gg = coef(1,4);
    #
    # alpha1=(-bb+sqrt(bb^2-4*aa*cc))/(2*aa);
    # alpha2=(-bb-sqrt(bb^2-4*aa*cc))/(2*aa);
    # beta1=-(dd*alpha1^3+alpha1^2*ee+alpha1*ff+gg)/(2*aa*alpha1+bb);
    # beta2=-(dd*alpha2^3+alpha2^2*ee+alpha2*ff+gg)/(2*aa*alpha2+bb);
    """
    # input error checking
    if len(k_radii) != len(k_powers):
       raise ValueError("Input k_radii must have the same number of entries as k_powers")

    # HELPER FUNCTIONS:

    #--------------------------------------------------------------------------
    # lambda_ode
    #--------------------------------------------------------------------------
    def lambda_ode(t,y,k_radii,k_powers,lambda_powers,R_lambda,p,s,e,m,c):

        lamda = R_lambda*np.exp(1j*t)

        # get manifolds from Evans solver
        e.evans = 'bpspm'
        mani = c.evans(1,0,lamda,s,p,m,e)

        # $\int_{|z| = R_k}D(lamda,k)/k^{r+1} dk$, r = k_powers
        temp = k_int(mani,k_radii,k_powers,p,m,e)

        len_lambda_powers = len(lambda_powers)
        totlen = len_lambda_powers*len(k_powers)

        mat = np.zeros((len(k_powers),len_lambda_powers),dtype=np.complex)

        for j in range(len_lambda_powers): # 1:len
            mat[:,j] = (1j*temp*lamda**(-lambda_powers[j]))/(2*np.pi*1j)

        pre_out = np.reshape(mat,(totlen))

        out = np.zeros((2*totlen),dtype=np.complex)
        out[:totlen] = np.real(pre_out)
        out[totlen:2*totlen] = np.imag(pre_out)
        return out

    #--------------------------------------------------------------------------
    # k_int
    #--------------------------------------------------------------------------
    def k_int(mani,k_radii,k_powers,p,m,e):

        # time interval
        tspan = [0,2*np.pi]
        # initial condition
        ynot = np.array([0,0])

        out = np.zeros((len(k_powers)),dtype=np.complex)

        for j in range(len(k_powers)): # 1:length(k_powers)

            pre_k_ode = lambda t,y: k_ode(t,y,mani,k_radii[j],k_powers[j],p,e)
            # solve ode
            integrator = complex_ode(pre_k_ode).set_integrator('dopri5',
                            atol=m['k_int_options']['AbsTol'],
                            rtol=m['k_int_options']['RelTol'])
            integrator.set_initial_value(ynot,tspan[0])
            integrator.integrate(tspan[-1])
            Y = integrator.y
            Y = np.array([Y.T]).T

            # gather output
            out[j] = Y[0,-1]+Y[1,-1]*1j

        return out

    #--------------------------------------------------------------------------
    # k_ode
    #--------------------------------------------------------------------------
    def k_ode(t,y,mani,R_k,kpow,p,e):

        # Floquet parameter
        kappa = R_k*np.exp(1j*t)

        # Evans function
        D = np.linalg.det(np.vstack([
            np.hstack([mani.sigh[:e.kl,:e.kl], np.exp(1j*kappa*p.X)*mani.phi[:e.kl,:e.kr]]),
            np.hstack([mani.sigh[e.kl:2*e.kl,:e.kl], mani.phi[e.kl:2*e.kl,:e.kl]])
            ]))

        # integrand
        temp = (1j*D*np.exp(-1j*kpow*t)/R_k**kpow)/(2*np.pi*1j)
        out = np.zeros((2))
        # split into real and imaginary parts
        out[0] = np.real(temp)
        out[1] = np.imag(temp)
        return out

    # Begin power_expansion2

    len_lambda_powers = len(lambda_powers)
    totlen = len_lambda_powers*len(k_powers)

    # time interval
    tspan = [0,2*np.pi]

    # initial condition
    ynot = np.zeros((2*totlen),dtype=np.complex)

    pre_lambda_ode = lambda t,y: lambda_ode(t,y,k_radii,k_powers,lambda_powers,
                                            R_lambda,p,s,e,m,c)

    integrator = complex_ode(pre_lambda_ode).set_integrator('dopri5',
                    atol=m['lambda_int_options']['AbsTol'],
                    rtol=m['lambda_int_options']['RelTol'])
    integrator.set_initial_value(ynot,tspan[0])
    integrator.integrate(tspan[-1])
    Y = integrator.y
    Y = np.array([Y.T]).T

    out = np.reshape(Y[:totlen,-1]+1j*Y[totlen:2*totlen,-1],(len(k_powers),
                                                            len_lambda_powers))
    return out
Exemplo n.º 43
0
for problem in problems:
    results[problem.name] = {}
    reference_file = "./reference_data/" + problem.name + ".txt"
    y_ref = np.loadtxt(reference_file)
    for solver in solvers:
        results[problem.name][solver] = {}
        for tol in tols:
            print(problem.name, solver, tol)
            results[problem.name][solver][tol] = {}
            start = time.time()
            if 'scipy' in solver:
                solver_name = solver.split()[-1].lower()
                if problem in [kdv, burgers]:
                    r = integrate.complex_ode(problem.rhs_reversed).set_integrator(solver_name, atol=tol, 
                                                                          rtol=tol, verbosity=10, 
                                                                          nsteps=1e6)
                else:
                    r = integrate.ode(problem.rhs_reversed).set_integrator(solver_name, atol=tol, rtol=tol, 
                                                                  verbosity=10, nsteps=1e7)
                t0 = problem.output_times[0]
                tf = problem.output_times[-1]
                r.set_initial_value(problem.y0, t0)
                r.integrate(r.t+(tf-t0))
                assert r.t == tf, "Integration failed. Try increasing the maximum allowed steps."
                y = r.y


                results[problem.name][solver][tol]['fe_seq'] = None
                results[problem.name][solver][tol]['mean_order'] = None
            else:
Exemplo n.º 44
0
    def Propagate_SAM(self,
                      simulation_parameters,
                      Pump,
                      Seed=[0],
                      Normalized_Units=False):
        start_time = time.time()

        T = simulation_parameters['slow_time']
        abtol = simulation_parameters['absolute_tolerance']
        reltol = simulation_parameters['relative_tolerance']
        out_param = simulation_parameters['output']
        nmax = simulation_parameters['max_internal_steps']
        detuning = simulation_parameters['detuning_array']
        eps = simulation_parameters['noise_level']
        J = simulation_parameters['electro-optical coupling']

        if Normalized_Units == False:
            pump = Pump * np.sqrt(1. / (hbar * self.w0))
            if Seed[0] == 0:
                seed = self.seed_level(Pump, detuning[0]) * np.sqrt(
                    2 * self.g0 / self.kappa)
            else:
                seed = Seed * np.sqrt(2 * self.g0 / self.kappa)
            ### renormalization
            T_rn = (self.kappa / 2) * T
            f0 = pump * np.sqrt(8 * self.g0 * self.kappa_ex / self.kappa**3)
            J *= 2 / self.kappa
            print('f0^2 = ' + str(np.round(max(abs(f0)**2), 2)))
            print('xi [' + str(detuning[0] * 2 / self.kappa) + ',' +
                  str(detuning[-1] * 2 / self.kappa) + ']')
        else:
            pump = Pump
            if Seed[0] == 0:
                seed = self.seed_level(Pump, detuning[0], Normalized_Units)
            else:
                seed = Seed
            T_rn = T
            f0 = pump
            print('f0^2 = ' + str(np.round(max(abs(f0)**2), 2)))
            print('xi [' + str(detuning[0]) + ',' + str(detuning[-1]) + ']')
            detuning *= self.kappa / 2
        noise_const = self.noise(eps)  # set the noise level
        nn = len(detuning)

        ### define the rhs function
        def LLE_1d(Time, A):
            A = A - noise_const  #self.noise(eps)
            A_dir = np.fft.ifft(A) * len(A)  ## in the direct space
            dAdT = -1 * (
                1 + 1j *
                (self.Dint + dOm_curr) * 2 / self.kappa) * A + 1j * np.fft.fft(
                    A_dir * np.abs(A_dir)**2) / len(A) + 1j * np.fft.fft(
                        J * 2 / self.kappa * np.cos(self.phi) * A_dir /
                        self.N_points) + f0  #*len(A)
            return dAdT

        t_st = float(T_rn) / len(detuning)
        r = complex_ode(LLE_1d).set_integrator('dop853',
                                               atol=abtol,
                                               rtol=reltol,
                                               nsteps=nmax)  # set the solver
        #r = ode(LLE_1d).set_integrator('zvode', atol=abtol, rtol=reltol,nsteps=nmax)# set the solver
        r.set_initial_value(seed, 0)  # seed the cavity
        sol = np.ndarray(shape=(len(detuning), self.N_points),
                         dtype='complex')  # define an array to store the data
        sol[0, :] = seed
        #printProgressBar(0, nn, prefix = 'Progress:', suffix = 'Complete', length = 50, fill='elapsed time = ' + str((time.time() - start_time)) + ' s')
        for it in range(1, len(detuning)):
            self.printProgressBar(it + 1,
                                  nn,
                                  prefix='Progress:',
                                  suffix='Complete,',
                                  time='elapsed time = ' +
                                  '{:04.1f}'.format(time.time() - start_time) +
                                  ' s',
                                  length=50)
            #self.print('elapsed time = ', (time.time() - start_time))
            dOm_curr = detuning[it]  # detuning value
            sol[it] = r.integrate(r.t + t_st)

        if out_param == 'map':
            if Normalized_Units == False:
                return sol / np.sqrt(2 * self.g0 / self.kappa)
            else:
                detuning /= self.kappa / 2
                return sol
        elif out_param == 'fin_res':
            return sol[-1, :] / np.sqrt(2 * self.g0 / self.kappa)
        else:
            print('wrong parameter')
Exemplo n.º 45
0
    def NeverStopSAM(self,
                     T_step,
                     detuning_0=-1,
                     Pump_P=2.,
                     nmax=1000,
                     abtol=1e-10,
                     reltol=1e-9,
                     out_param='fin_res'):
        self.Pump = self.Pump / abs(self.Pump)

        def deriv_1(dt, field_in):
            # computes the first-order derivative of field_in
            field_fft = np.fft.fft(field_in)
            omega = 2. * np.pi * np.fft.fftfreq(len(field_in), dt)
            out_field = np.fft.ifft(-1j * omega * field_fft)
            return out_field

        def deriv_2(dt, field_in):
            # computes the second-order derivative of field_in
            field_fft = np.fft.fft(field_in)
            omega = 2. * np.pi * np.fft.fftfreq(len(field_in), dt)
            field_fft *= -omega**2
            out_field = np.fft.ifft(field_fft)
            return out_field

        def disp(field_in, Dint_in):
            # computes the dispersion term in Fourier space
            field_fft = np.fft.fft(field_in)
            out_field = np.fft.ifft(Dint_in * field_fft)
            return out_field

        ### define the rhs function
        def LLE_1d(Z, A):
            # for nomalized
            if np.size(self.Dint) == 1 and self.Dint == 1:
                dAdt2 = deriv_2(self.TimeStep, A)
                dAdT = 1j * dAdt2 / 2 + 1j * self.gamma * self.L / self.Tr * np.abs(
                    A)**2 * A - (self.kappa / 2 + 1j * dOm_curr) * A + np.sqrt(
                        self.kappa / 2 / self.Tr) * self.Pump * Pump_P**.5
            elif np.size(self.Dint) == 1 and self.Dint == -1:
                dAdt2 = deriv_2(self.TimeStep, A)
                dAdT = -1j * dAdt2 / 2 + 1j * self.gamma * self.L / self.Tr * np.abs(
                    A)**2 * A - (self.kappa / 2 + 1j * dOm_curr) * A + np.sqrt(
                        self.kappa / 2 / self.Tr) * self.Pump * Pump_P**.5
            else:
                # with out raman
                Disp_int = disp(A, self.Dint)
                if self.Traman == 0:
                    dAdT = -1j * Disp_int + 1j * self.gamma * self.L / self.Tr * np.abs(
                        A
                    )**2 * A - (self.kappa / 2 + 1j * dOm_curr) * A + np.sqrt(
                        self.kappa / 2 / self.Tr) * self.Pump * Pump_P**.5
                else:
                    # with raman
                    dAAdt = deriv_1(self.TimeStep, abs(A)**2)
                    dAdT = -1j * Disp_int + 1j * self.gamma * self.L / self.Tr * np.abs(
                        A
                    )**2 * A - (
                        self.kappa / 2 + 1j * dOm_curr
                    ) * A - 1j * self.gamma * self.Traman * dAAdt * A + np.sqrt(
                        self.kappa / 2 / self.Tr) * self.Pump * Pump_P**.5
            return dAdT

        r = complex_ode(LLE_1d).set_integrator('dopri5',
                                               atol=abtol,
                                               rtol=reltol,
                                               nsteps=nmax)  # set the solver
        r.set_initial_value(self.seed, 0)  # seed the cavity

        img = mpimg.imread('phase_space.png')
        xx = np.linspace(-1, 5, np.size(img, axis=1))
        yy = np.linspace(11, 0, np.size(img, axis=0))
        XX, YY = np.meshgrid(xx, yy)

        fig = plt.figure(figsize=(11, 7))
        plt.subplots_adjust(top=0.95,
                            bottom=0.1,
                            left=0.06,
                            right=0.986,
                            hspace=0.2,
                            wspace=0.16)

        ax1 = plt.subplot(221)
        ax1.pcolormesh(XX, YY, img[:, :, 1])
        plt.xlabel('Detuning')
        plt.ylabel('f^2')
        plt.title('Choose the region')
        plt.xlim(min(xx), max(xx))
        dot = plt.plot(detuning_0, Pump_P, 'rx')

        ax2 = plt.subplot(222)
        line, = plt.plot(abs(self.seed)**2)
        plt.ylim(0, 1.1)
        plt.ylabel('$|\Psi|^2$')

        ax3 = plt.subplot(224)
        line2, = plt.semilogy(self.mu, np.abs(np.fft.fft(self.seed))**2)
        plt.ylabel('PSD')
        plt.xlabel('mode number')
        ### widjets
        axcolor = 'lightgoldenrodyellow'

        resetax = plt.axes([0.4, 0.025, 0.1, 0.04])
        button = Button(resetax, 'Stop', color=axcolor, hovercolor='0.975')

        axboxf = plt.axes([0.1, 0.35, 0.1, 0.075])
        text_box_f = TextBox(axboxf, 'f^2', initial=str(Pump_P))

        axboxd = plt.axes([0.1, 0.25, 0.1, 0.075])
        text_box_d = TextBox(axboxd, 'Detuning', initial=str(detuning_0))

        Run = True

        def setup(event):
            global Run
            Run = False

        button.on_clicked(setup)

        def onclick(event):
            if event.inaxes == ax1:
                ix, iy = event.xdata, event.ydata
                text_box_d.set_val(np.round(ix, 4))
                text_box_f.set_val(np.round(iy, 4))
                ax1.plot([ix], [iy], 'rx')

        fig.canvas.mpl_connect('button_press_event', onclick)

        while Run:
            dOm_curr = float(text_box_d.text)  # get the detuning value
            Pump_P = float(text_box_f.text)
            Field = r.integrate(r.t + T_step)
            F_mod_sq = np.abs(Field)**2
            F_sp = np.abs(np.fft.fft(Field))**2
            line.set_ydata(F_mod_sq)
            line2.set_ydata(F_sp)
            ax2.set_ylim(0, max(F_mod_sq))
            ax3.set_ylim(min(F_sp), max(F_sp))
            plt.pause(1e-10)
Exemplo n.º 46
0
t = np.array([], dtype=np.complex64)
x = np.arange(-dom, dom, grid)
L = len(x)

mu = 0
sigma = 0.1

#A_0 = 0.2*np.sin(2*np.pi*x) + 0.1*1j*np.cos(2*np.pi*x+np.pi/6) + 0.1*np.random.random()
#A_0 = np.random.normal(mu, sigma, dom*2)
#A_0 = 1/np.cos((2*np.pi*x/L)**2) + 0.8/np.cos((2*np.pi*x/L)**2) + 0.01*np.random.random()
#A_0 = np.cos(2*np.pi*x/L) + 0.1*np.random.normal(mu, sigma, dom*2)
A_0 = np.sqrt(1 - (20 * np.pi / L)**2) * np.exp(
    1j * 20 * np.pi * x / L) + 0.1 * np.random.normal(mu, sigma, dom * 2)
L = len(A_0)

r = complex_ode(dAdt)
r.set_initial_value(A_0, t0)

while r.successful() and r.t < t1:
    t = np.append(t, r.t + dt)
    sol.append(r.integrate(r.t + dt))

sol = np.array(sol)

#abs_sol = sol[:,0:L/2]**2 + sol[:,L/2:L]**2
#abs_sol = np.array([abs_sol,abs_sol])
#abs_sol = abs_A2.flatten()

X, T = np.meshgrid(x, t)

fig = plt.figure(figsize=(15, 6))
Exemplo n.º 47
0
def NLSE(pulse,
         fiber,
         nsaves=200,
         atol=1e-4,
         rtol=1e-4,
         reload_fiber=False,
         raman=False,
         shock=True,
         integrator='lsoda',
         print_status=True):
    """Propagate an laser pulse through a fiber according to the NLSE.

    This function propagates an optical input field (often a laser pulse)
    through a nonlinear material using the generalized nonlinear
    Schrodinger equation, which takes into account dispersion and
    nonlinearity. It is a "one dimensional" calculation, in that it doesn't
    capture things like self focusing and other geometric effects. It's most
    appropriate for analyzing light propagating through optical fibers.

    This code is based on the Matlab code found at www.scgbook.info,
    which is based on Eqs. (3.13), (3.16) and (3.17) of the book
    "Supercontinuum Generation in Optical Fibers" Edited by J. M. Dudley and
    J. R. Taylor (Cambridge 2010). The original Matlab code was written by
    J.C. Travers, M.H. Frosz and J.M. Dudley (2009). They ask that you cite
    the book in publications using their code.

    Parameters
    ----------
    pulse : pulse object
        This is the input pulse.
    fiber : fiber object
        This defines the media ("fiber") through which the pulse propagates.
    nsaves : int
        The number of equidistant grid points along the fiber to return
        the field. Note that the integrator usually takes finer steps than
        this, the nsaves parameters simply determines what is returned by this
        function.
    atol : float
        Absolute tolerance for the integrator. Smaller values produce more
        accurate results but require longer integration times. 1e-4 works well.
    rtol : float
        Relative tolerance for the integrator. 1e-4 work well.
    reload_fiber : boolean
        This determines if the fiber information is reloaded at each step. This
        should be set to True if the fiber properties (gamma, dispersion) vary
        as a function of length.
    raman : boolean
        Determines if the Raman effect will be included. Default is False.
    shock : boolean
        Determines if the self-steepening (shock) term will be taken into
        account. This is especially important for situations where the
        slowly varying envelope approximation starts to break down, which
        can occur for large bandwidths (short pulses).
    integrator : string
        Selects the integrator that will be passes to scipy.integrate.ode.
        options are 'lsoda' (default), 'vode', 'dopri5', 'dopri853'.
        'lsoda' is a good option, and seemed fastest in early tests.
        I think 'dopri5' and 'dopri853' are simpler Runge-Kutta methods,
        and they seem to take longer for the same result.
        'vode' didn't seem to produce good results with "method='adams'", but
        things werereasonable with "method='bdf'"
        For more information, see:
        docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html
    print_status : boolean
         This determines if the propagation status will be printed. Default
         is True.

    Returns
    -------
    results : PulseData object
        This object contains all of the results. Use
        ``z, f, t, AW, AT = results.get_results()``
        to unpack the z-coordinates, frequency grid, time grid, amplitude at
        each z-position in the freuqency domain, and amplitude at each
        z-position in the time domain.
    """
    # get the pulse info from the pulse object:
    t = pulse.t_ps  # time array in picoseconds
    at = pulse.at  # amplitude for those times in sqrt(W)
    w0 = pulse.centerfrequency_THz * 2 * pi  # center freq (angular!)

    n = t.size  # number of time/frequency points
    dt = t[1] - t[0]  # time step
    v = 2 * pi * linspace(-0.5 / dt, 0.5 / dt, n)  # *angular* frequency grid

    flength = fiber.length  # get length of fiber

    def load_fiber(fiber, z=0):
        # gets the fiber info from the fiber object
        gamma = fiber.get_gamma(z)  # gamma should be in 1/(W m), not 1/(W km)
        b = fiber.get_B(pulse, z)

        loss = np.log(10**(fiber.get_alpha(z) * 0.1))  # convert from dB/m

        lin_operator = 1j * b - loss * 0.5  # linear operator

        if w0 > 0 and shock:  # if w0>0 then include shock
            gamma = gamma / w0
            w = v + w0  # for shock w is true freq
        else:
            w = 1 + v * 0  # set w to 1 when no shock

        # some fft shifts to things line up later:
        lin_operator = fftshift(lin_operator)
        w = fftshift(w)
        return lin_operator, w, gamma

    lin_operator, w, gamma = load_fiber(fiber)  # load fiber info

    # Raman response:
    if raman == 'dudley' or raman:
        fr = 0.18
        t1 = 0.0122
        t2 = 0.032
        rt = (t1**2 + t2**2) / t1 / t2**2 * exp(-t / t2) * sin(t / t1)
        rt[t < 0] = 0  # heaviside step function
        rw = n * ifft(fftshift(rt))  # frequency domain Raman
    elif not raman:
        fr = 0
    else:
        raise ValueError('Raman method not supported')

    # define function to return the RHS of Eq. (3.13):
    def rhs(z, aw):
        nonlocal lin_operator, w, gamma

        if reload_fiber:
            lin_operator, w, gamma = load_fiber(fiber, z)

        at = fft(aw * exp(lin_operator * z))  # time domain field
        it = np.abs(at)**2  # time domain intensity

        if np.isclose(fr, 0):  # no Raman case
            m = ifft(at * it)  # response function
        else:
            rs = dt * fr * fft(ifft(it) * rw)  # Raman convolution
            m = ifft(at * ((1 - fr) * it + rs))  # response function

        r = 1j * gamma * w * m * exp(
            -lin_operator * z)  # full RHS of Eq. (3.13)
        return r

    z = linspace(0, flength, nsaves)  # select output z points
    aw = ifft(at.astype('complex128'))  # ensure integrator knows it's complex

    # set up the integrator:
    r = complex_ode(rhs).set_integrator(integrator, atol=atol, rtol=rtol)
    r.set_initial_value(aw, z[0])

    # intialize array for results:
    AW = np.zeros((z.size, aw.size), dtype='complex128')
    AW[0] = aw  # store initial pulse as first row

    start_time = time.time()  # start the timer

    for count, zi in enumerate(z[1:]):

        if print_status:
            print('% 6.1f%% - %.3e m - %.1f seconds' %
                  ((zi / z[-1]) * 100, zi, time.time() - start_time))
        if not r.successful():
            raise Exception('Integrator failed! Check the input parameters.')

        AW[count + 1] = r.integrate(zi)

    # process the output:
    AT = np.zeros_like(AW)
    for i in range(len(z)):
        AW[i] = AW[i] * exp(
            lin_operator.transpose() * z[i])  # change variables
        AT[i, :] = fft(AW[i])  # time domain output
        AW[i, :] = fftshift(AW[i])

        # Below is the original dudley scaling factor that I think gives units
        # of sqrt(J/Hz) for the AW array. Removing this gives units that agree
        # with PyNLO, that seem to be sqrt(J*Hz) = sqrt(Watts) -DH 2021-12-15
        # AW[i, :] = AW[i, :] * dt * n

    pulse_out = pulse.create_cloned_pulse()
    pulse_out.at = AT[-1]

    results = PulseData(z, AW, AT, pulse, pulse_out, fiber)

    return results
def psi(tf,M=10, L=0,  aperiodicity=0,kind=0):
    """
    Parameters
    ----------
    time : float
        End time of the integration.
    L : float
        Nonlinearity parameter.
    M : int
        Number of lattice sites. (Default 101.)
    aperiodicity : float
        Aperiodicity parameter, defined in terms of the hoppings as (b/a - 1).
        (Default 0, which corresponds to a periodic chain.)
    kind: 0(periodic),fib,tm,rs
    Returns
    -------
    y : float
    wavefn at time t
    """
    def delta(t):
        if -0.1<t<1:
            return 1e0
        elif 1<=t<=10:
            return 1e-1
        elif 1e1<t<=1e2:
            return 1e0
        elif 1e2<t<=1e3:
            return 1e1
        elif 1e3<t<=1e4:
            return 1e2
        elif 1e4<t<=1e5:
            return 1e3
        else:
            return 1e4
    
    r = integrate.complex_ode(dnls_rhs(M, L, aperiodicity,kind)).set_integrator('dopri5', nsteps=10000)    
    central_site_index = (M - 1)/2
    ic = np.zeros(shape=(M,))
    ic[central_site_index] = 1.0
    r.set_initial_value(ic)
    steps=int(np.ceil(90 * (np.log(tf)/np.log(10.0)))+2)#+ int(1e3) 
    #dt = float(tf)/steps
    wavefn = np.zeros((steps,M), dtype=np.complex)
    t_arr=np.zeros((steps), dtype=np.float)
    idx=0
    #for idx in xrange(steps):
    while r.t<tf:
      if r.successful(): #essentially, **if True:**
		if abs(r.y[0])< 1e-10 and abs(r.y[-1])<1e-10: #to make sure the lattice is big enough so that wavefn doesn't touch the boundary.
		    wavefn[idx,:] = r.y[:]
		    t_arr[idx]=r.t
		    
		else:
		    print ("wfn touching the boundary at t = {} for p={}".format(r.t,aperiodicity))
		    wave_fn_truncated=wavefn[0:idx,:]
		    t_arr_truncated=t_arr[0:idx]
		    return wave_fn_truncated, t_arr_truncated
      else:
		raise ValueError("Integration failed at t = {}".format(r.t))	
      r.integrate(r.t + delta(r.t))
      idx+=1
    return wavefn,t_arr    
def compare_performance_dense(func, y0, t, y_ref, problem_name, tol_boundary=(0,6), is_complex=False, nsteps=10e5, solout=(lambda y,t: y)):
    print 'RUNNING COMPARISON TEST FOR ' + problem_name
    tol = [1.e-3,1.e-5,1.e-7,1.e-9,1.e-11,1.e-13]
    a, b = tol_boundary
    tol = tol[a:b]
    t0, tf = t[0], t[-1]

    py_runtime = np.zeros(len(tol))
    py_fe_seq = np.zeros(len(tol))
    py_fe_tot = np.zeros(len(tol))
    py_yerr = np.zeros(len(tol))
    py_nstp = np.zeros(len(tol))

    dopri5_runtime = np.zeros(len(tol))
    dopri5_fe_seq = np.zeros(len(tol))
    dopri5_fe_tot = np.zeros(len(tol))
    dopri5_yerr = np.zeros(len(tol))
    dopri5_nstp = np.zeros(len(tol))

    dop853_runtime = np.zeros(len(tol))
    dop853_fe_seq = np.zeros(len(tol))
    dop853_fe_tot = np.zeros(len(tol))
    dop853_yerr = np.zeros(len(tol))
    dop853_nstp = np.zeros(len(tol))
    
    # This is necessary because multiprocessing uses pickle, which can't handle
    # Fortran function pointers
    def func2(t,y):
        return func(y,t)

    for i in range(len(tol)):
        print 'Tolerance: ', tol[i]

        # run Python extrapolation code 
        print 'running ParEx'
        start_time = time.time()
        y, infodict = ex_p.ex_midpoint_explicit_parallel(func, None, y0, t, atol=tol[i], rtol=tol[i], mxstep=nsteps, adaptive="order", full_output=True)
        py_runtime[i] = time.time() - start_time
        py_fe_seq[i], py_fe_tot[i], py_nstp[i] = infodict['fe_seq'], infodict['nfe'], infodict['nst']
        y[1:] = solout(y[1:],t[1:])
        py_yerr[i] = relative_error(y[1:], y_ref)
        print 'Runtime: ', py_runtime[i], ' s   Error: ', py_yerr[i], '   fe_seq: ', py_fe_seq[i], '   fe_tot: ', py_fe_tot[i], '   nstp: ', py_nstp[i]
        print ''
        
        # run DOPRI5 (scipy)
        print 'running DOPRI5 (scipy)'
        dopri5_d_solout = DenseSolout(t)
        start_time = time.time()
        if is_complex:
            r = complex_ode(func2).set_integrator('dopri5', atol=tol[i], rtol=tol[i], verbosity=10, nsteps=nsteps)
        else:
            r = ode(func2).set_integrator('dopri5', atol=tol[i], rtol=tol[i], verbosity=10, nsteps=nsteps)
        r.set_solout(dopri5_d_solout.solout, dense_components=tuple(range(len(y0))))
        r.set_initial_value(y0, t0)
        r.integrate(r.t+(tf-t0))
        assert r.t == tf, "Integration did not converge. Try increasing the max number of steps"
        dopri5_runtime[i] = time.time() - start_time
        y = np.array(dopri5_d_solout.dense_output)
        y[1:] = solout(y[1:],t[1:])
        dopri5_yerr[i] = relative_error(y[1:], y_ref)
        print 'Runtime: ', dopri5_runtime[i], ' s   Error: ', dopri5_yerr[i], '   fe_seq: ', dopri5_fe_seq[i], '   fe_tot: ', dopri5_fe_tot[i], '   nstp: ', dopri5_nstp[i]
        print ''

        # run DOP853 (scipy)
        print 'running DOP853 (scipy)'
        dop853_d_solout = DenseSolout(t)
        start_time = time.time()
        if is_complex:
            r = complex_ode(func2, jac=None).set_integrator('dop853', atol=tol[i], rtol=tol[i], verbosity=10, nsteps=nsteps)
        else:
            r = ode(func2, jac=None).set_integrator('dop853', atol=tol[i], rtol=tol[i], verbosity=10, nsteps=nsteps)
        r.set_solout(dop853_d_solout.solout, dense_components=tuple(range(len(y0))))
        r.set_initial_value(y0, t0)
        r.integrate(r.t+(tf-t0))
        assert r.t == tf, "Integration did not converge. Try increasing the max number of steps"
        dop853_runtime[i] = time.time() - start_time
        y = np.array(dop853_d_solout.dense_output)
        y[1:] = solout(y[1:],t[1:])
        dop853_yerr[i] = relative_error(y[1:], y_ref)
        print 'Runtime: ', dop853_runtime[i], ' s   Error: ', dop853_yerr[i], '   fe_seq: ', dop853_fe_seq[i], '   fe_tot: ', dop853_fe_tot[i], '   nstp: ', dop853_nstp[i]
        print ''

        print ''
        
    print "Final data: ParEx"
    print py_runtime, py_fe_seq, py_fe_tot, py_yerr, py_nstp
    print "Final data: DOPRI5 (scipy)"
    print dopri5_runtime, dopri5_fe_seq, dopri5_fe_tot, dopri5_yerr, dopri5_nstp
    print "Final data: DOP853 (scipy)"
    print dop853_runtime, dop853_fe_seq, dop853_fe_tot, dop853_yerr, dop853_nstp
    print ''
    print ''

    # plot performance graphs
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    plt.hold('true')

    py_line,   = plt.loglog(py_yerr, py_runtime, "s-")
    dopri5_line, = plt.loglog(dopri5_yerr, dopri5_runtime, "s-")
    dop853_line, = plt.loglog(dop853_yerr, dop853_runtime, "s-")
    plt.legend([py_line, dopri5_line, dop853_line], ["ParEx", "DOPRI5 (scipy)", "DOP853 (scipy)"], loc=1)
    plt.xlabel('Error')
    plt.ylabel('Wall clock time (seconds)')
    plt.title(problem_name)
    plt.show()
    plt.savefig('images/' + problem_name + '_err_vs_time.png')
    plt.close()
Exemplo n.º 50
0
def laser_simulation(uvt, alpha1, alpha2, alpha3, alphap,K):
    # parameters of the Maxwell equation
    """
    D = 1
    K = 0.1
    E0 = 1
    tau = 0.1
    g0 = 0.3
    Gamma = 0.2
    """
    D = -0.4
    E0 = 4.23
    tau = 0.1
    g0 = 1.73
    Gamma = 0.1
    
    Z = 1.5         # cavity length
    T = 60
    n = 256       # t slices
    Rnd = 500     # round trips
    t2 = np.linspace(-T/2,T/2,n+1)
    t_dis = t2[0:n].reshape([1,n])   # time discretization
    new = np.concatenate((np.linspace(0,n//2-1,n//2),
                          np.linspace(-n//2,-1,n//2)),0)
    k = (2*np.pi/T)*new
    ts=[]
    ys=[]
    t0=0.0
    tend=1
    
    # waveplates & polarizer
    W4 = np.array([[np.exp(-1j*np.pi/4), 0],[0, np.exp(1j*np.pi/4)]]); # quarter waveplate
    W2 = np.array([[-1j, 0],[0, 1j]]);  # half waveplate
    WP = np.array([[1, 0], [0, 0]]);  # polarizer
    
    # waveplate settings
    R1 = np.array([[np.cos(alpha1), -np.sin(alpha1)], 
                   [np.sin(alpha1), np.cos(alpha1)]])
    R2 = np.array([[np.cos(alpha2), -np.sin(alpha2)], 
                   [np.sin(alpha2), np.cos(alpha2)]])
    R3 = np.array([[np.cos(alpha3), -np.sin(alpha3)], 
                   [np.sin(alpha3), np.cos(alpha3)]])
    RP = np.array([[np.cos(alphap), -np.sin(alphap)], 
                   [np.sin(alphap), np.cos(alphap)]])
    J1 = np.matmul(np.matmul(R1,W4),np.transpose(R1))
    J2 = np.matmul(np.matmul(R2,W4),np.transpose(R2))
    J3 = np.matmul(np.matmul(R3,W2),np.transpose(R3))
    JP = np.matmul(np.matmul(RP,WP),np.transpose(RP))
    
    # transfer function
    Transf = np.matmul(np.matmul(np.matmul(J1,JP),J2),J3)
    
    urnd=np.zeros([Rnd, n], dtype=complex)
    vrnd=np.zeros([Rnd, n], dtype=complex)
    t_dis=t_dis.reshape(n,)
    energy=np.zeros([1,Rnd])
    
    # definition of the rhs of the ode
    def mlock_CNLS_rhs(ts, uvt):
        [ut_rhs,vt_rhs] = np.split(uvt,2)
        u = np.fft.ifft(ut_rhs)
        v = np.fft.ifft(vt_rhs)
        # calculation of the energy function
        E = np.trapz(np.conj(u)*u+np.conj(v)*v,t_dis)
        
        # u of the rhs
        urhs = -1j*0.5*D*(k**2)*ut_rhs - 1j*K*ut_rhs + \
                1j*np.fft.fft((np.conj(u)*u+ (2/3)*np.conj(v)*v)*u + \
                              (1/3)*(v**2)*np.conj(u)) + \
                2*g0/(1+E/E0)*(1-tau*(k**2))*ut_rhs - Gamma*ut_rhs
        
        # v of the rhs
        vrhs = -1j*0.5*D*(k**2)*vt_rhs + 1j*K*vt_rhs + \
                1j*np.fft.fft((np.conj(v)*v+(2/3)*np.conj(u)*u)*v + \
                              (1/3)*(u**2)*np.conj(v) ) + \
                2*g0/(1+E/E0)*(1-tau*(k**2))*vt_rhs - Gamma*vt_rhs
         
        return np.concatenate((urhs, vrhs),axis=0)
    
    # definition of the solution output for the ode integration
    def solout(t,y):
        ts.append(t)
        ys.append(y.copy())
        
    start = time.time()
    
    uv_list = []
    norms = []
    change_norm = 100
    jrnd = 0
    # solving the ode for Rnd rounds
    while(jrnd < Rnd and change_norm > 1e-6):
        ts = []
        ys = []
        
        t0 = Z*jrnd
        tend = Z*(jrnd+1)
        
        uvtsol = complex_ode(mlock_CNLS_rhs)
        uvtsol.set_integrator(method='adams', name='dop853') # alternative 'dopri5'
        uvtsol.set_solout(solout)
        uvtsol.set_initial_value(uvt, t0)
        sol = uvtsol.integrate(tend)
        assert_equal(ts[0], t0)
        assert_equal(ts[-1], tend)
        
        u=np.fft.ifft(sol[0:n])
        v=np.fft.ifft(sol[n:2*n])
        
        urnd[jrnd,:]=u
        vrnd[jrnd,:]=v
        energy[0, jrnd]=np.trapz(np.abs(u)**2+np.abs(v)**2,t_dis)
        
        uvplus=np.matmul(Transf,np.transpose(np.concatenate((u.reshape(n,1),
                                                              v.reshape(n,1)),axis=1)))
        uv_list.append(np.concatenate((uvplus[0,:],
                                       uvplus[1,:]), axis=0))
        
        uvt=np.concatenate((np.fft.fft(uvplus[0,:]),
                                       np.fft.fft(uvplus[1,:])), axis=0)
        
        if jrnd > 0:
            phi=np.sqrt(np.abs(np.vstack(uv_list)[:,:n])**2 + \
                        np.abs(np.vstack(uv_list)[:,n:2*n])**2)
            change_norm=np.linalg.norm((phi[-1,:]-phi[len(phi)-2,:]))/ \
            np.linalg.norm(phi[len(phi)-2,:])
            norms.append(change_norm) 
            
        jrnd += 1
    
    
    kur = np.abs(np.fft.fftshift(np.fft.fft(phi[-1,:])))
    #M4 = kurtosis(kur)
    M4 = moment(kur,4)/np.std(kur)**4
    
    end = time.time()
    print(end-start)
    
    E = np.sqrt(np.trapz(phi[-1,:]**2, t_dis))
    
    states = np.array([E, M4, alpha1, alpha2, alpha3, alphap])
    
    """ surface plot 
    # create meshgrid
    X, Y = np.meshgrid(t_dis,np.arange(0,len(norms)))
    
    # figure urnd
    fig_urand = plt.figure()
    ax = fig_urand.gca(projection='3d')
    
    # plot the surface
    surf = ax.plot_surface(X, Y, np.abs(urnd[:len(norms),:]), cmap=cm.coolwarm,
                           linewidth=0, antialiased=False)
    
    # Add a color bar which maps values to colors.
    fig_urand.colorbar(surf, shrink=0.5, aspect=5)
    
    
    # figure vrnd
    fig_vrand = plt.figure()
    ax = fig_vrand.gca(projection='3d')
    
    # plot the surface
    surf = ax.plot_surface(X, Y, np.abs(vrnd[:len(norms),:]), cmap=cm.coolwarm,
                           linewidth=0, antialiased=False)
    
    # Add a color bar which maps values to colors.
    fig_vrand.colorbar(surf, shrink=0.5, aspect=5)
    
    plt.show()
    """
    return (uvt,states)
Exemplo n.º 51
0
x = np.zeros((6,N))*1j # für RK5
y0 = np.array(psi_0)
x[:,0] = y0 # Imaginärteil ist 0
# x ist complexes 36xN array

t0 = 0
t1 = 30*np.pi
t = np.linspace(t0,t1,N)

#Ausgabe:
print('E_0*a:', E_0_n, '// w:', w,
'// Intervall für t: [',t0,';',t1,']'
)

#Integration mit Runge-Kutta 5:
r = complex_ode(f).set_integrator('dopri5')
r.set_initial_value(y0, t0)

i = 1
print('Runge-Kutta(5) für',N-1,'Werte:')
with tqdm(total=N-1) as pbar:
    while r.successful() and r.t < t1:
        r.integrate(t[i])
        pbar.update(1)
        x[:,i] = r.y
        i += 1

# Stromoperator Erwartungswert:
J = np.zeros((6,6))
for i in range(0,6): # Alle Zeilen (jede i-te Zeile bestimmt alpha des i-ten End-Zustandes)
    for j in range(0,6): # Alle Spalten (Multiplikation von J mit |j>)
Exemplo n.º 52
0
def BS_mc_evolution( p0, gamma, length, dispersion,
                     s_wl, p1_wl, p2_wl,
                     s_0 = np.array([0,1,0], dtype=np.complex64),
                     a_p = r_[1,1],
                    
                     ## Losses terms (for completeness)
                     alpha_l  = Q_('0 1/m'), # Loss
                     alpha_2p = Q_('0 1/(W m)'), # NL loss
                     s_fca    = Q_('0 m**2'), t_fca = Q_(1, 'as'), # TPA
                     w0_wl = 1550 * nm,    ## FCA defined at 1550 nn
                     
                     vary_pump = False,
                     grid_size = 100):
    
    """ Bragg Scattering MultiChannel Simulation 

    requires Units and Dispersion

    wl1, wl2: define the pump frequency comb (i.e. p_w and dw)
    s_wl: is the input signal wavelength.
    dispersion: is the dispersion (Dispersion)

    s_0: input fields. Size of the array determines the channels
    a_p: are the pump fields amplitudes normalized to p0
    
    """

    # Simulation units
    u_l = Q_('mm')
    u_p = Q_('W')

    # Obtain angular frequency
    p_w = 2*pi*c_light*(1/p1_wl + 1/p2_wl)/2
    s_w = 2*pi*c_light/s_wl
    dw = (1/p1_wl - 1/p2_wl)*2*pi*c_light  # Channel separation

    z = length.to(u_l).magnitude
    dz = z/grid_size
    
    # signal is centered at len(s_0)/2
    n_ch = len(s_0)
    n_order = np.floor(n_ch / 2)
    a_s = s_0
    
    # Generate a dimensionless phasematching function.
    phasematching = generatePhasematching(p_w, s_w, dw,
                                          dispersion, k_unit = 1/u_l)
    
    # Effective nonlinearity
    nl_eff = gamma * p0
    a_p = a_p * sqrt(nl_eff.to(1/u_l).magnitude)
    
    p_out = np.zeros((gridsize + 1, len(a_p)), dtype= np.complex64)
    
    if varying_pump:
        ## Simulate pumps
        ode_pump = complex_ode(f)
        ode.set_initial_value(a_p)
        i = 1
        for zi in np.arange(dz, z, dz):
            output [i,:] = ode.integrate(zi)
            i += 1
            if not ode.successful():
                raise Exception()
    
    # Use it to generate the coupling matrix coefficients
    k_dict = generateCoefficients(a_p = a_p, phasematching = phasematching, 
                                  n_order= n_order, kappa_limit = 1e3/dz)
    
    
    
    
    # Losses
    #a2p_eff = alpha_2p * p0
    
    #h_nup = Q_('h*c')/w0_wl
    #fca = [alpha_2p*t_fca/(2*h_nup)*s_fca*(wl/w0_wl)**2 * p0**2 \
    #                      for wl in [s_wl, i_wl, p1_wl, p2_wl]]
    
    #fca = zeros(4) * Q_('1/m') # FCA formula may be wrong
    
    ## There is a BUG in scipy for functions accepting external arguments in complex_ode.
    ## I just make them global and unitless
    #args =          ( dk.to(1/u_l).magnitude,
    #              nl_eff.to(1/u_l).magnitude,
    #             alpha_l.to(1/u_l).magnitude,
    #             a2p_eff.to(1/u_l).magnitude,
    #              r_[ [f.to(1/u_l).magnitude for f in fca] ] )

    
    ## Compute simulation parameters ###
    print(k_dict)

    # Define a f(z, x) = dx/dz
    f = lambda z, x: np.dot(x, interactionMatrixZ(k_dict, z, n_ch))
    
    # Build the output array
    output = np.zeros((grid_size+1, n_ch), dtype= np.complex64)
    output[0,:] = a_s

    # Finally, simulate
    ode = complex_ode(f)
    ode.set_initial_value(a_s)
    i = 1
    for zi in np.arange(dz, z, dz):
        output [i,:] = ode.integrate(zi)
        i += 1
        if not ode.successful():
            raise Exception()

    return (output, dz)
Exemplo n.º 53
0
Arquivo: fmo.py Projeto: TanMath/fmo
# ## Starting state and times

# In[207]:

rho0= ls[0]
ti = 0
tf = 1
dt = 101
ts = np.linspace(ti, tf, dt)


# ## Initiate scipy integrator and evolve

# In[208]:

stepper = complex_ode(leq)
stepper.set_integrator('dop853', nsteps=0, first_step=0.01)
stepper.set_initial_value(np.asarray(rho0).reshape(-1), ti)

# array for population values
xs = np.empty((d, len(ts)), dtype=float)

for i, t in enumerate(ts):
    stepper.integrate(t)
    rhot = np.asmatrix(stepper.y.reshape(d, d))
    xs[:, i] = np.diag(rhot).real


# In[209]:

plt.plot(ts, xs[0, :], label='1')
Exemplo n.º 54
0
def gnlse(t,
          at,
          w0,
          gamma,
          betas,
          loss,
          fr,
          rt,
          flength,
          nsaves=200,
          atol=1e-4,
          rtol=1e-4,
          integrator='lsoda'):
    """
    This function propagates an optical input field (often a laser pulse)
    through a nonlinear material using the generalized nonlinear
    Schrodinger equation, which takes into account dispersion and
    nonlinearity. It is a "one dimensional" calculation, in that it doesn't
    capture things like self focusing and other geometric effects. It's most
    appropriate for analyzing light propagating through optical fibers.

    This code is based on the Matlab code found at www.scgbook.info,
    which is based on Eqs. (3.13), (3.16) and (3.17) of the book
    "Supercontinuum Generation in Optical Fibers" Edited by J. M. Dudley and
    J. R. Taylor (Cambridge 2010).
    The original Matlab code was written by J.C. Travers, M.H. Frosz and J.M.
    Dudley (2009). They ask that you please cite this chapter in any
    publication using this code.

    2018-02-01 - First Python port by Dan Hickstein ([email protected])
    2020-01-11 - General clean up and PEP8

    Parameters
    ----------
    t : 1D numpy array of length n
        The time grid. Should be evenly spaced.
    at : 1D numpy array of length n
        The temporal pulse envelope. Matches the time grid T. Can be complex.
    w0 : float
        The "carrier frequency" for the moving reference frame
    gamma : float
        The effective nonlinearity, in units of [1/(W m)].
        note that the gammas for fibers are often described
        in units of 1/(W km) (per kilometer rather than per meter).
    betas : list of floats
        the coefficients of the dispersion expansion.
        Given as betas = [beta2, beta3, beta4, ...]
        In units of [ps^2/m, ps^3/m, ps^4/m ...]
        Note that this betas array is used to generate the b array.
        Those who want to include an aibitrary dispersion could hack this
        function and supply the b array. b is to so-called wavenumber
        (often written as k) and is equal to
        (refractive index)*2*pi/wavelength.
    rt : numpy array
        The time domain Raman response. Matches the time grid T.
    flength : float
        the fiber length [meters]
    nsaves : int
        the number of equidistant grid points along the fiber to return
        the field. Note that the integrator usually takes finer steps than
        this, the nsaves parameters simply determines what is returned by this
        function
    integrator : string
        Selects the integrator that will be passes to scipy.integrate.ode.
        options are 'lsoda' (default), 'vode', 'dopri5', 'dopri853'.
        'lsoda' is a good option, and seemed fastest in early tests.
        I think 'dopri5' and 'dopri853' are simpler Runge-Kutta methods,
        and they seem to take longer for the same result.
        'vode' didn't seem to produce good results with "method='adams'", but
        things werereasonable with "method='bdf'"
        For more information, see:
        docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html

    Returns
    -------
    z : 1D numpy array of length nsaves
        an array of the z-coordinate along the fiber where the results are
        returned
    AT : 2D numpy array, with dimensions nsaves x n
        The time domain field at every step. Complex.
    AW : 2D numpy array, with dimensions nsaves x n
        The frequency domain field at every step. Complex.
    v : 1D numpy array of length n
        The frequency grid.
    """

    n = t.size  # number of time/frequency points
    dt = t[1] - t[0]  # time step
    v = 2 * pi * linspace(-0.5 / dt, 0.5 / dt, n)  # *angular* frequency grid
    alpha = log10(10**(loss / 10.))  # attenuation coefficient

    b = np.zeros_like(v)
    for i in range(len(betas)):  # Taylor expansion of GVD
        b += betas[i] / factorial(i + 2) * v**(i + 2)

    lin_operator = 1j * b - alpha * 0.5  # linear operator

    if np.nonzero(w0):  # if w0>0 then include shock
        gamma = gamma / w0
        w = v + w0  # for shock w is true freq
    else:
        w = 1  # set w to 1 when no shock

    rw = n * ifft(fftshift(rt))  # frequency domain Raman

    # shift to fft space  -- Back to time domain, right?
    lin_operator = fftshift(lin_operator)
    w = fftshift(w)

    # define function to return the RHS of Eq. (3.13):
    def rhs(z, aw):
        at = fft(aw * exp(lin_operator * z))  # time domain field
        it = np.abs(at)**2  # time domain intensity

        if rt.size == 1 or np.isclose(fr, 0):  # no Raman case
            m = ifft(at * it)  # response function
        else:
            rs = dt * fr * fft(ifft(it) * rw)  # Raman convolution
            m = ifft(at * ((1 - fr) * it + rs))  # response function

        r = 1j * gamma * w * m * exp(
            -lin_operator * z)  # full RHS of Eq. (3.13)
        return r

    z = linspace(0, flength, nsaves)  # select output z points

    aw = ifft(at.astype('complex128'))  # ensure integrator knows it's complex

    r = complex_ode(rhs).set_integrator(integrator, atol=atol, rtol=rtol)
    r.set_initial_value(aw, z[0])  # set up the integrator

    # intialize array for results:
    AW = np.zeros((z.size, aw.size), dtype='complex128')
    AW[0] = aw  # store initial pulse as first row

    start_time = time.time()  # start the timer

    for count, zi in enumerate(z[1:]):
        print('% 6.1f%% complete - %.1f seconds' %
              ((zi / z[-1]) * 100, time.time() - start_time))
        if not r.successful():
            print('integrator failed!')
            break

        AW[count + 1] = r.integrate(zi)

    # process the output:
    AT = np.zeros_like(AW)
    for i in range(len(z)):
        AW[i] = AW[i] * exp(
            lin_operator.transpose() * z[i])  # change variables
        AT[i, :] = fft(AW[i])  # time domain output
        AW[i, :] = fftshift(AW[i]) / dt  # scale

    AT = fft(AW, axis=1)
    return z, AT, AW, v + w0
Exemplo n.º 55
0
psi_t = np.zeros((N_TIMES, 2)).astype(np.complex)
psi_t[0] = psi_0
one = np.eye(psi_0.shape[0])
for t in range(1, np.shape(times)[0]):
    time = times[t]
    delta_t = times[t] - times[t-1]
    propagator = np.linalg.inv(one + 1j * delta_t / 2 * hamiltonian(time - delta_t / 2.0))
    propagator = propagator.dot(one - 1j * delta_t / 2 * hamiltonian(time - delta_t / 2.0))
    psi_t[t] = propagator.dot(psi_t[t-1])

plot_evolution(times, psi_t)


# Create a complex_ode instance to solve the system of differential
# equations defined by `hamiltonian`, and set the solver method to dopri5 (an alternative more precise RK-8 is dop853)
solver = complex_ode(rhs)
solver.set_integrator('dopri5')
solver.set_initial_value(psi_0, t0)

psi_t = np.zeros((N_TIMES, 2)).astype(np.complex)
psi_t[0] = psi_0

# Repeatedly call the `integrate` method to advance the
# solution to time t[k], and save the solution in sol[k].
for i in range(1, times.shape[0]):
    time = times[i]
    if not solver.successful():
        break
    psi_t[i] = solver.integrate(time)