def ssft(self, 
             potential, 
             dt=-.1j*50e-6,
             max_its = 10000, 
             start_psi = None, 
             precision= 1e-8):
        self.dt = dt
        ## kinetic energy part
        self.T = hbar**2*self.k**2/(2*self.p.m)
        self.exp_T =  scipy.exp(-1j*self.dt/(2.*hbar)*self.T)
        self.exp_2T =  scipy.exp(-1j*self.dt/(hbar)*self.T)

        if start_psi == None:
        ## Initialize psi to TF-solution
            psi = self.rand_psi()
        else:
            psi = self.Normalize(start_psi)
        
        psi_old = scipy.array(psi)
        exp_prefactor = -1j*self.dt/hbar
        

        psik = scipy.fftpack.fft(psi)
        psik *= self.exp_T
        psi = scipy.fftpack.ifft(psik)
        for i in scipy.arange(max_its):
#            print i
            if scipy.iscomplex(self.dt):
                psi = self.Normalize(psi)
            psi *= scipy.exp(exp_prefactor*(potential+self.interaction(psi)))
            psik = scipy.fftpack.fft(psi)
            psik *= self.exp_2T
            psi = scipy.fftpack.ifft(psik)
            if precision != None:
                if ((scipy.absolute(psi-psi_old)/scipy.absolute(psi)).sum() < precision)*(i>50):
                    break
                else:
                    psi_old = psi
        if scipy.iscomplex(self.dt):
            psi = self.Normalize(psi)
        psi *= scipy.exp(-1j*self.dt/hbar*(potential+self.interaction(psi)))
        psik = scipy.fftpack.fft(psi)
        psik *= self.exp_T
        psi = scipy.fftpack.ifft(psik)
        if (i == max_its-1)*(precision != None):
            logging.warning('warning: algorithm did not converge!')
        return self.Normalize(psi)
Exemple #2
0
    def __call__(self, field, skip=1):
        '''
        Plot field.
        '''
        super(Plotter2d, self).__call__(field)

        dims = [0] * 4
        dimnames = ('time', 'lev', 'lat', 'lon')
        xind = dimnames.index(self.axes[0])
        dims[xind] = slice(None)
        yind = dimnames.index(self.axes[1])
        dims[yind] = slice(None)

        # Find plot arguments
        dd = dict(lon=field.grid['lon'][0, :],
                  lat=field.grid['lat'][:, 0],
                  lev=field.grid['lev'],
                  time=field.time)

        args = []
        args.append(dd[self.axes[0]][::skip])
        args.append(dd[self.axes[1]][::skip])

        if xind > yind:
            z = field.data[dims][::skip, ::skip]
        else:
            z = sp.ma.transpose(field.data[dims][::skip, ::skip])

        args.append(sp.real(z))
        if sp.any(sp.iscomplex(z.view(sp.ndarray))): args.append(sp.imag(z))

        cs = self.method(*args, **self.copts)

        if isinstance(cs, mlib.contour.ContourSet):
            if cs.filled:
                if self.cbar_opts is not None:
                    cb = pl.colorbar(**self.cbar_opts)
                    units = getattr(field, 'units', "")
                    cb.set_label(units)
            else:
                cs.clabel(**self.clab_opts)

        # If x-axis is time, apply default time formatting
        if self.axes[0] == 'time':
            fig = pl.gcf()
            fig.autofmt_xdate()

        return cs
Exemple #3
0
    def take_step_split(self, dtau, ham_is_Herm=True):
        """Take a time-step dtau using the split-step integrator.
        
        This is the one-site version of a DMRG-like time integrator described
        at:
          http://arxiv.org/abs/1408.5056
        
        It has a fourth-order local error and is symmetric. It requires
        iteratively computing two matrix exponentials per site, and thus
        has less predictable CPU time requirements than the Euler or RK4 
        methods.
        
        NOTE:
        This requires the expokit extension, which is included in evoMPS but 
        must be compiled during, e.g. using setup.py to build all extensions.
        
        Parameters
        ----------
        dtau : complex
            The (imaginary or real) amount of imaginary time (tau) to step.
        ham_is_Herm : bool
            Whether the Hamiltonian is really Hermitian. If so, the lanczos
            method will be used for imaginary time evolution.
        """
        #TODO: Compute eta.
        self.eta_sq.fill(0)
        self.eta = 0
        
        assert self.canonical_form == 'right', 'take_step_split only implemented for right canonical form'
        assert self.ham_sites == 2, 'take_step_split only implemented for nearest neighbour Hamiltonians'
        dtau *= -1
        from expokit_expmv import zexpmv, zexpmvh

        if sp.iscomplex(dtau) or not ham_is_Herm:
            expmv = zexpmv
            fac = 1.j
            dtau = sp.imag(dtau)
        else:
            expmv = zexpmvh
            fac = 1
            
        norm_est = abs(self.H_expect.real)
    
        KL = [None] * (self.N + 1)
        KL[1] = sp.zeros((self.D[1], self.D[1]), dtype=self.typ)
        for n in xrange(1, self.N + 1):
            lop = Vari_Opt_Single_Site_Op(self, n, KL[n - 1], tau=fac)
            #print "Befor A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real
            An = expmv(lop, self.A[n].ravel(), dtau/2., norm_est=norm_est)            
            self.A[n] = An.reshape((self.q[n], self.D[n - 1], self.D[n]))
            self.l[n] = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n])
            norm = m.adot(self.l[n], self.r[n])
            self.A[n] /= sp.sqrt(norm)
            #print "After A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real, norm.real
            
            #shift centre matrix right (RCF is like having a centre "matrix" at "1")
            G = tm.restore_LCF_l_seq(self.A[n - 1:n + 1], self.l[n - 1:n + 1],
                                     sanity_checks=self.sanity_checks) 
                                     
            if n > 1:
                self.AA[n - 1] = tm.calc_AA(self.A[n - 1], self.A[n])
                self.C[n - 1] = tm.calc_C_mat_op_AA(self.ham[n - 1], self.AA[n - 1])
                KL[n], ex = tm.calc_K_l(KL[n - 1], self.C[n - 1], self.l[n - 2], 
                                        self.r[n], self.A[n], self.AA[n - 1])
                
            if n < self.N:                    
                lop2 = Vari_Opt_SC_op(self, n, KL[n], tau=fac)
                #print "Befor G", n, sp.inner(G.ravel().conj(), lop2.matvec(G.ravel())).real
                G = expmv(lop2, G.ravel(), -dtau/2., norm_est=norm_est)
                G = G.reshape((self.D[n], self.D[n]))
                norm = sp.trace(self.l[n].dot(G).dot(self.r[n].dot(G.conj().T)))
                G /= sp.sqrt(norm)
                #print "After G", n, sp.inner(G.ravel().conj(), lop2.matvec(G.ravel())).real, norm.real
                
                for s in xrange(self.q[n + 1]):
                    self.A[n + 1][s] = G.dot(self.A[n + 1][s])                
                
                self.AA[n] = tm.calc_AA(self.A[n], self.A[n + 1])
                self.C[n] = tm.calc_C_mat_op_AA(self.ham[n], self.AA[n])           
   
        for n in xrange(self.N, 0, -1):
            lop = Vari_Opt_Single_Site_Op(self, n, KL[n - 1], tau=fac, sanity_checks=self.sanity_checks)
            #print "Before A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real
            An = expmv(lop, self.A[n].ravel(), dtau/2., norm_est=norm_est)
            self.A[n] = An.reshape((self.q[n], self.D[n - 1], self.D[n]))
            self.l[n] = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n])
            norm = m.adot(self.l[n], self.r[n])
            self.A[n] /= sp.sqrt(norm)
            #print "After A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real, norm.real
            
            #shift centre matrix left (LCF is like having a centre "matrix" at "N")
            Gi = tm.restore_RCF_r_seq(self.A[n - 1:n + 1], self.r[n - 1:n + 1],
                                      sanity_checks=self.sanity_checks)
                                      
            if n < self.N:
                self.AA[n] = tm.calc_AA(self.A[n], self.A[n + 1])
                self.C[n] = tm.calc_C_mat_op_AA(self.ham[n], self.AA[n])                                          
                self.calc_K(n_low=n, n_high=n)
            
            if n > 1:
                lop2 = Vari_Opt_SC_op(self, n - 1, KL[n - 1], tau=fac, sanity_checks=self.sanity_checks)
                Gi = expmv(lop2, Gi.ravel(), -dtau/2., norm_est=norm_est)
                Gi = Gi.reshape((self.D[n - 1], self.D[n - 1]))
                norm = sp.trace(self.l[n - 1].dot(Gi).dot(self.r[n - 1].dot(Gi.conj().T)))
                G /= sp.sqrt(norm)
                #print "After G", n, sp.inner(Gi.ravel().conj(), lop2.matvec(Gi.ravel())).real, norm.real

                for s in xrange(self.q[n - 1]):
                    self.A[n - 1][s] = self.A[n - 1][s].dot(Gi)
            
                self.AA[n - 1] = tm.calc_AA(self.A[n - 1], self.A[n])
                self.C[n - 1] = tm.calc_C_mat_op_AA(self.ham[n - 1], self.AA[n - 1])
Exemple #4
0
A * A  # matrix multiplication
A ** 2  # Matrix 2 to the power of 2 (same as A*A)
B = 5 * sp.diag([1.0, 3, 5])
sp.mat(B)  # converts B to matrix type
sp.mat(B).I  # computes matrix inverse of sp.mat(B)

# isnan, isfinite, isinf are newly added functions to NumPy
C = B  # copy matrix B into C
C[0, 1] = sp.nan  # insert NaN value into 1st row, 2nd column element
sp.isnan(C)  # yields all 'False' elements except one element as True

# looking at complex numbers
a4 = sp.array([1 + 1j, 2, 5j])  # create complex array
sp.iscomplexobj(a4)  # determine whether a4 is complex (TRUE)
sp.isreal(a4)  # determines element by element which are REAL or COMPLEX
sp.iscomplex(a4)  # determination of COMPLEX elements
type(a4)  # outputs type and functional dependencies

# concatenating matrices and arrays:
a5 = sp.array([1, 2, 3])
a6 = sp.array([4, 5, 6])
sp.vstack((a5, a6))  # vertical array concatenation
sp.hstack((a5, a6))  # horizontal array concat
dstack((a5, a6))  # vertical array concat, transposed

# view all variables that have been created thus far:
sp.who()  # python command, similar to MATLAB

# importing and using matplotlib (plotting library from MATLAB)
t = sp.linspace(0, 100)  # create time array 't'
y = sp.sin(2 * sp.pi * t)  # create sinusoidal series y