ó
áp7]c           @  sl  d  Z  d d l m Z d d l m Z d d l m Z d d l m Z d d l	 Z
 d „  Z d e j f d	 „  ƒ  YZ d
 „  Z dH \ Z Z dI \ Z Z d „  Z d „  Z d „  Z e e j e e d e d d d d d d d d ƒZ e e j e
 j e
 j d d d d d d d d d d ƒZ e e j e
 j e
 j d d  ƒZ d! e j f d" „  ƒ  YZ d# e j f d$ „  ƒ  YZ d% „  Z d& e j f d' „  ƒ  YZ d( e  f d) „  ƒ  YZ! e! ƒ  Z" e e j e" j# e" j$ e" j% e" j& e" j' d* d+ d d, d- e
 j( d d d d. d d/ d d0 d1 ƒZ) e e j* e" j# e" j$ e" j% e" j& e" j' d* d+ d d, d- e
 j( d d  d d. d d2 d d3 d4 ƒZ+ d5 „  Z$ d6 „  Z% d7 „  Z& d8 „  Z' d9 „  Z, e e j e, e$ e% e& e' d* d: d e
 j( d- d, d d d d; d d< d d= d> ƒZ- d? „  Z$ d@ „  Z% dA „  Z& dB „  Z' dC „  Z. e e j e
 j/ e$ e% e& e' d* d+ d d, d- e
 j( d d d dD d dE d dF dG ƒZ0 d S(J   s{   A class for the distribution of a non-linear monotonic transformation of a continuous random variable

simplest usage:
example: create log-gamma distribution, i.e. y = log(x),
            where x is gamma distributed (also available in scipy.stats)
    loggammaexpg = Transf_gen(stats.gamma, np.log, np.exp)

example: what is the distribution of the discount factor y=1/(1+x)
            where interest rate x is normally distributed with N(mux,stdx**2)')?
            (just to come up with a story that implies a nice transformation)
    invnormalg = Transf_gen(stats.norm, inversew, inversew_inv, decr=True, a=-np.inf)

This class does not work well for distributions with difficult shapes,
    e.g. 1/x where x is standard normal, because of the singularity and jump at zero.

Note: I'm working from my version of scipy.stats.distribution.
      But this script runs under scipy 0.6.0 (checked with numpy: 1.2.0rc2 and python 2.4)

This is not yet thoroughly tested, polished or optimized

TODO:
  * numargs handling is not yet working properly, numargs needs to be specified (default = 0 or 1)
  * feeding args and kwargs to underlying distribution is untested and incomplete
  * distinguish args and kwargs for the transformed and the underlying distribution
    - currently all args and no kwargs are transmitted to underlying distribution
    - loc and scale only work for transformed, but not for underlying distribution
    - possible to separate args for transformation and underlying distribution parameters

  * add _rvs as method, will be faster in many cases


Created on Tuesday, October 28, 2008, 12:40:37 PM
Author: josef-pktd
License: BSD

iÿÿÿÿ(   t   print_function(   t	   iteritems(   t   stats(   t   distributionsNc          K  s8   t  d „  t |  ƒ Dƒ ƒ } | j d d  ƒ } | | f S(   Nc         s  s?   |  ]5 \ } } | j  d  ƒ r | j d  d d ƒ | f Vq d S(   t   u_t    i   N(   t
   startswitht   replace(   t   .0t   kt   v(    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pys	   <genexpr>3   s    	t   u_args(   t   dictR   t   popt   None(   t   kwargst   u_kwargsR   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   get_u_argskwargs1   s    t
   Transf_genc           B  s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   sU   a class for non-linear monotonic transformation of a continuous random variable

    c         O  sü   | |  _  | |  _ | j d d ƒ |  _ | j d d ƒ } | j d d ƒ } | j d d  ƒ } | j d t j ƒ }	 | j d	 t j ƒ }
 | j d
 t ƒ |  _ t	 |   \ |  _
 |  _ | |  _ t t |  ƒ j d |	 d	 |
 d | d | j d | d | ƒ d  S(   Nt   numargsi    t   namet
   transfdistt   longnames#   Non-linear transformed distributiont   extradoct   at   bt   decrt   shapes(   t   funct   funcinvR   R   R   t   npt   inft   FalseR   R   R   R   t   klst   superR   t   __init__R   (   t   selfR!   R   R   t   argsR   R   R   R   R   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR#   <   s    			$	c         O  sO   |  j  s( |  j j |  j | ƒ | | Ž Sd |  j j |  j | ƒ | | Ž Sd  S(   Ng      ð?(   R   R!   t   _cdfR   (   R$   t   xR%   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR&   Y   s    	c         O  sO   |  j  s( |  j |  j j | | | Ž ƒ S|  j |  j j d | | | Ž ƒ Sd  S(   Ni   (   R   R   R!   t   _ppf(   R$   t   qR%   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR(   `   s    	(   t   __name__t
   __module__t   __doc__R#   R&   R(   (    (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR   8   s   		c         C  s   t  j d |  ƒ S(   Ng      ð?(   R   t   divide(   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   inverseg   s    gš™™™™™©?gš™™™™™¹?g      "@g      ð?c         C  s   d d t  |  t S(   Ng      ð?i   (   t   muxt   stdx(   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   inversewl   s    c         C  s   d |  d t  t S(   Ng      ð?(   R/   R0   (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   inversew_invn   s    c         C  s   |  S(   N(    (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   identitq   s    R   R   i    R   t   discfR   s   normal-based discount factorR   sA   
distribution of discount factor y=1/(1+x)) with x N(0.05,0.1**2)i   R   t   lnnorms   Exp transformed normalso   
distribution of y = exp(x), with x standard normalprecision for moment andstats is not very high, 2-3 decimalsi   t   ExpTransf_genc           B  s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   sµ   Distribution based on log/exp transformation

    the constructor can be called with a distribution class
    and generates the distribution of the transformed random variable

    c         O  s   d | k r | d |  _  n	 d |  _  d | k r> | d } n d } d | k r] | d } n d } t t |  ƒ j d | d | ƒ | |  _ d  S(   NR   i   R   s   Log transformed distributionR   i    (   R   R"   R6   R#   R!   (   R$   R!   R%   R   R   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR#      s    	c         G  s   |  j  j t j | ƒ | Œ S(   N(   R!   R&   R   t   log(   R$   R'   R%   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR&   ¡   s    c         G  s   t  j |  j j | | Œ ƒ S(   N(   R   t   expR!   R(   (   R$   R)   R%   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR(   ¤   s    (   R*   R+   R,   R#   R&   R(   (    (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR6   ˆ   s   		t   LogTransf_genc           B  s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   sµ   Distribution based on log/exp transformation

    the constructor can be called with a distribution class
    and generates the distribution of the transformed random variable

    c         O  s   d | k r | d |  _  n	 d |  _  d | k r> | d } n d } d | k r] | d } n d } t t |  ƒ j d | d | ƒ | |  _ d  S(   NR   i   R   s   Log transformed distributionR   i    (   R   R"   R9   R#   R!   (   R$   R!   R%   R   R   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR#   ®   s    	c         G  s   |  j  j t j | ƒ | Œ S(   N(   R!   R&   R   R8   (   R$   R'   R%   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR&   À   s    c         G  s   t  j |  j j | | Œ ƒ S(   N(   R   R7   R!   R(   (   R$   R)   R%   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR(   Ã   s    (   R*   R+   R,   R#   R&   R(   (    (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR9   §   s   		c          C  su  t  d ƒ t t j d d d d ƒ}  t  |  j d ƒ ƒ t  t j j d d ƒ ƒ t  |  j ƒ  ƒ t  t j j d ƒ ƒ t  |  j d d ƒ ƒ t  d	 ƒ t t j ƒ } t  | j	 d d
 ƒ ƒ t  t j
 j d d
 ƒ ƒ t  | j	 d d ƒ ƒ t  t j
 j d d ƒ ƒ t  d ƒ t t j ƒ } t  | j	 d d
 ƒ ƒ t  t j j d d
 ƒ ƒ t t j ƒ } t  | j	 d d
 ƒ ƒ d  S(   Ns   Results for lognormalR   i    R   s   Log transformed normal generali   t   sizei   s   Results for expgammai
   i   i   s   Results for loglaplace(   t   printR6   R   t   normt   cdft   lognormt   rvsR9   t   gammaR&   t   loggammat   laplacet
   loglaplace(   t
   lognormalgt   loggammaexpgt   loglaplacegt   loglaplaceexpg(    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   examples_transfÆ   s&    


t   TransfTwo_genc           B  sD   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   sO  Distribution based on a non-monotonic (u- or hump-shaped transformation)

    the constructor can be called with a distribution class, and functions
    that define the non-linear transformation.
    and generates the distribution of the transformed random variable

    Note: the transformation, it's inverse and derivatives need to be fully
    specified: func, funcinvplus, funcinvminus, derivplus,  derivminus.
    Currently no numerical derivatives or inverse are calculated

    This can be used to generate distribution instances similar to the
    distributions in scipy.stats.

    c         O  s  | |  _  | |  _ | |  _ | |  _ | |  _ | j d d ƒ |  _ | j d d ƒ }	 | j d d ƒ }
 | j d d  ƒ } | j d t j	 ƒ } | j d	 t j	 ƒ } | j d
 t
 ƒ |  _ t |   \ |  _ |  _ | |  _ t t |  ƒ j d | d	 | d |	 d | j d |
 d | ƒ d  S(   NR   i    R   R   R   s#   Non-linear transformed distributionR   R   R   t   shapeR   (   R   t   funcinvplust   funcinvminust	   derivplust
   derivminusR   R   R   R   R   R    RJ   R   R   R   R!   R"   RI   R#   R   (   R$   R!   R   RK   RL   RM   RN   R%   R   R   R   R   R   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR#   '  s&    							c         G  s(   |  j  |  j _  |  j |  j j | Œ  ƒ S(   N(   t   _sizeR!   R   t   _rvs(   R$   R%   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRP   I  s    c         O  s˜   |  j  d k r d } n$ |  j  d k r0 d } n t d ƒ ‚ | |  j | ƒ |  j j |  j | ƒ | | Ž |  j | ƒ |  j j |  j | ƒ | | Ž S(   Nt   ui   t   humpiÿÿÿÿs   shape can only be `u` or `hump`(   RJ   t
   ValueErrorRM   R!   t   _pdfRK   RN   RL   (   R$   R'   R%   R   t   signpdf(    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRT   M  s    		.c         O  sh   |  j  d k rM |  j j |  j | ƒ | | Ž |  j j |  j | ƒ | | Ž Sd |  j | | | Ž Sd  S(   NRQ   g      ð?(   RJ   R!   R&   RK   RL   t   _sf(   R$   R'   R%   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR&   Z  s     c         O  sh   |  j  d k rM |  j j |  j | ƒ | | Ž |  j j |  j | ƒ | | Ž Sd |  j | | | Ž Sd  S(   NRR   g      ð?(   RJ   R!   R&   RK   RL   (   R$   R'   R%   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRV   c  s     c         O  s   |  j  | | Œ S(   N(   t   _mom0_sc(   R$   t   nR%   R   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   _munpl  s    (	   R*   R+   R,   R#   RP   RT   R&   RV   RY   (    (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRI     s   	"						t
   SquareFuncc           B  s;   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   s³   class to hold quadratic function with inverse function and derivative

    using instance methods instead of class methods, if we want extension
    to parameterized function
    c         C  s   t  j | ƒ S(   N(   R   t   sqrt(   R$   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   inverseplus~  s    c         C  s   d t  j | ƒ S(   Ng        (   R   R[   (   R$   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   inverseminus  s    c         C  s   d t  j | ƒ S(   Ng      à?(   R   R[   (   R$   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRM   „  s    c         C  s   d d t  j | ƒ S(   Ng        g      à?(   R   R[   (   R$   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRN   ‡  s    c         C  s   t  j | d ƒ S(   Ni   (   R   t   power(   R$   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt
   squarefuncŠ  s    (   R*   R+   R,   R\   R]   RM   RN   R_   (    (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRZ   x  s   				RJ   RQ   g        R   t
   squarenorms   squared normal distributions7   
distribution of the square of a normal random variables    y=x**2 with x N(0.0,1)s   squared t distributions2   
distribution of the square of a t random variables    y=x**2 with x t(dof,0.0,1)c         C  s   t  j |  ƒ S(   N(   R   R[   (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR\     s    c         C  s   d t  j |  ƒ S(   Ng        (   R   R[   (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR]      s    c         C  s   d d t  j |  ƒ S(   Ng        g      à?(   R   R[   (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRM   £  s    c         C  s   d t  j |  ƒ S(   Ng      à?(   R   R[   (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRN   ¦  s    c         C  s   t  j |  d ƒ S(   Ni   (   R   R^   (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   negsquarefunc©  s    RR   t   negsquarenorms$   negative squared normal distributions@   
distribution of the negative square of a normal random variables    y=-x**2 with x N(0.0,1)c         C  s   |  S(   N(    (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR\   ´  s    c         C  s   d |  S(   Ng        (    (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyR]   ·  s    c         C  s   d S(   Ng      ð?(    (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRM   º  s    c         C  s   d S(   Ng        g      ð?g      ð¿(    (   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyRN   ½  s    c         C  s   t  j |  ƒ S(   N(   R   t   abs(   R'   (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   absfuncÀ  s    t   absnorms   absolute of normal distributions?   
distribution of the absolute value of a normal random variables    y=abs(x) with x N(0,1)(   gš™™™™™©?gš™™™™™¹?(   g      "@g      ð?(1   R,   t
   __future__R    t   statsmodels.compat.pythonR   t   scipyR   t   scipy.statsR   t   numpyR   R   t   rv_continuousR   R.   R/   R0   R1   R2   R3   R<   t   Truet   invdnormalgR8   R7   RD   R@   RE   R6   R9   RH   RI   t   objectRZ   t   sqfuncR_   R\   R]   RM   RN   R   t   squarenormalgt   tt   squaretgRa   t   negsquarenormalgRd   Rc   t
   absnormalg(    (    (    sL   lib/python2.7/site-packages/statsmodels/sandbox/distributions/transformed.pyt   <module>(   sv   	/						!		Qa	

					
					