class_docstr: Ornstein-Uhlenbeck
  
  :math::
    dx_t&=\lambda(\mu - x_t)dt+\sigma dW_t
  
  mean reverting process
  
  
  
  TODO: move exact higher up in class hierarchy
class_docstr_tok: ["Ornstein-Uhlenbeck",":","math",":",":","dx_t","&","=\\lambda","(","\\mu","-","x_t",")","dt+\\sigma","dW_t","mean","reverting","process","TODO",":","move","exact","higher","up","in","class","hierarchy"]
docstr: ddt : discrete delta t
  
  should be the same as an AR(1)
  not tested yet
  # after writing this I saw the same use of lfilter in sitmo
docstr_tok: ["ddt",":","discrete","delta","t","should","be","the","same","as","an","AR","(","1",")","not","tested","yet","#","after","writing","this","I","saw","the","same","use","of","lfilter","in","sitmo"]
code: def exactprocess(self, xzero, nobs, ddt=1.0, nrepl=2):
      """ddt : discrete delta t
  
      should be the same as an AR(1)
      not tested yet
      # after writing this I saw the same use of lfilter in sitmo
      """
      t = np.linspace(ddt, nobs * ddt, nobs)
      expnt = np.exp(-self.lambd * t)
      expddt = np.exp(-self.lambd * ddt)
      normrvs = np.random.normal(size=(nrepl, nobs))
      # do I need lfilter here AR(1) ? lfilter does not handle 2d arrays, it does?
      from scipy import signal
  
      # xzero * expnt
      inc = (
          self.mu * (1 - expddt)
          + self.sigma
          * np.sqrt((1 - expddt * expddt) / 2.0 / self.lambd)
          * normrvs
      )
  
      return signal.lfilter([1.0], [1.0, -expddt], inc)
  
imports: import numpy
  from scipy import stats, signal
  import matplotlib.pyplot
label_desc: Use image node_id 5 for calling the OUprocess obj's underlying member method code with example usage: obj.exactprocess(xzero, nobs, ddt, nrepl) and returns: signal