Changeset 305

Show
Ignore:
Timestamp:
11/07/08 19:25:32 (2 months ago)
Author:
emuller
Message:

Added some optimizations to OU_generator, weave implementation

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/stgen.py

    r304 r305  
    273273 
    274274 
    275     def _OU_generator_python(self, dt, tau, sigma, y0, t_start=0.0, t_stop=1000.0, array=False): 
     275    def _OU_generator_python(self, dt, tau, sigma, y0, t_start=0.0, t_stop=1000.0, array=False,time_it=False): 
    276276        """  
    277277        Generates an Orstein Ulbeck process using the forward euler method. The function returns 
     
    292292        """ 
    293293 
     294        import time 
     295 
     296        if time_it: 
     297            t1 = time.time() 
     298 
    294299        t     = numpy.arange(t_start,t_stop,dt) 
    295300        N     = len(t) 
     
    300305        noise = numpy.sqrt(2*fac)*sigma 
    301306         
     307 
    302308        # python loop... bad+slow! 
    303309        for i in xrange(1,N): 
    304310            y[i] = y[i-1]+fac*(y0-y[i-1])+noise*gauss[i-1] 
     311 
     312        if time_it: 
     313            print time.time()-1 
    305314         
    306315        if array: 
     
    314323    # TODO: provide optimized C/weave implementation if possible 
    315324 
    316     OU_generator = _OU_generator_python 
     325 
     326    def _OU_generator_python2(self, dt, tau, sigma, y0, t_start=0.0, t_stop=1000.0, array=False,time_it=False): 
     327        """  
     328        Generates an Orstein Ulbeck process using the forward euler method. The function returns 
     329        an AnalogSignal object 
     330         
     331        Inputs: 
     332            dt      - the time resolution in milliseconds of th signal 
     333            tau     - the correlation time in milliseconds 
     334            sigma   - std dev of the process 
     335            y0      - initial value of the process, at t_start 
     336            t_start - start time in milliseconds 
     337            t_stop  - end time in milliseconds 
     338            array   - if True, a numpy array of the OU signal is returned, 
     339                      rather than an AnalogSignal object. 
     340         
     341        Examples: 
     342            >> stgen.OU_generator(0.1, 2, 3, 0, 0, 10000) 
     343        """ 
     344 
     345        import time 
     346 
     347        if time_it: 
     348            t1 = time.time() 
     349 
     350        t     = numpy.arange(t_start,t_stop,dt) 
     351        N     = len(t) 
     352        y     = numpy.zeros(N,float) 
     353        y[0]  = y0 
     354        fac   = dt/tau 
     355        gauss = fac*y0+numpy.sqrt(2*fac)*sigma*self.rng.standard_normal(N-1) 
     356        mfac = 1-fac 
     357         
     358        # python loop... bad+slow! 
     359        for i in xrange(1,N): 
     360            idx = i-1 
     361            y[i] = y[idx]*mfac+gauss[idx] 
     362 
     363        if time_it: 
     364            print time.time()-t1 
     365 
     366        if array: 
     367            return (y,t) 
     368 
     369        result = AnalogSignal(y,dt,t_start=0,t_stop=t_stop-t_start) 
     370        result.time_offset(t_start) 
     371        return result 
     372         
     373    # use slow python implementation for the time being 
     374    # TODO: provide optimized C/weave implementation if possible 
     375 
     376 
     377    def OU_generator_weave1(self, dt,tau,sigma,y0,t_start=0.0,t_stop=1000.0,time_it=False): 
     378        """ generates an OU process using forward euler 
     379        dt = resolution 
     380        tau = correlation time 
     381        sigma = std dev of process 
     382        y0 = mean/initial value 
     383        tsim = how long to simulate 
     384        """ 
     385        import scipy.weave 
     386         
     387        import time 
     388 
     389        if time_it: 
     390            t1 = time.time() 
     391 
     392 
     393        t = numpy.arange(t_start,t_stop,dt) 
     394        N = len(t) 
     395        y = numpy.zeros(N,float) 
     396        y[0] = y0 
     397        fac = dt/tau 
     398        gauss = fac*y0+numpy.sqrt(2*fac)*sigma*self.rng.standard_normal(N-1) 
     399         
     400         
     401        # python loop... bad+slow! 
     402        #for i in xrange(1,len(t)): 
     403        #    y[i] = y[i-1]+dt/tau*(y0-y[i-1])+numpy.sqrt(2*dt/tau)*sigma*numpy.random.normal() 
     404 
     405        # use weave instead 
     406 
     407        code = """ 
     408 
     409        double f = 1.0-fac; 
     410 
     411        for(int i=1;i<Ny[0];i++) { 
     412          y(i) = y(i-1)*f + gauss(i-1); 
     413        } 
     414        """ 
     415 
     416        scipy.weave.inline(code,['y', 'gauss', 'fac'], 
     417                     type_converters=scipy.weave.converters.blitz) 
     418 
     419 
     420        if time_it: 
     421            print 'Elapsed ',time.time()-t1,' seconds.' 
     422 
     423        if array: 
     424            return (y,t) 
     425 
     426        result = AnalogSignal(y,dt,t_start=0,t_stop=t_stop-t_start) 
     427        result.time_offset(t_start) 
     428        return result 
     429 
     430 
     431 
     432    OU_generator = _OU_generator_python2 
    317433 
    318434    # TODO: inhomogeneous OU generator