U
    ÃmœdB  ã                   @   s  d Z ddlmZ ddlmZ ddlZdd„ ZG dd„ dejƒZ	d	d
„ Z
d\ZZd\ZZdd„ Zdd„ Zdd„ Ze	ejeeddddd�Ze	ejejejddddd�Ze	ejejejdd�ZG dd„ dejƒZG dd „ d ejƒZd!d"„ ZG d#d$„ d$ejƒZG d%d&„ d&ƒZeƒ Zeejejejejej ej!d'd(ej"dd)d*d+�Z#eej$ejejejej ej!d'd(ej"dd)d,d+�Z%d-d.„ Zd/d0„ Zd1d2„ Z d3d4„ Z!d5d6„ Z&eeje&eee e!d7ej" d(dd8d9d+�Z'd:d.„ Zd;d0„ Zd<d2„ Z d=d4„ Z!d>d?„ Z(eejej)eee e!d'd(ej"dd@dAd+�Z*dS )Ba{   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

é    )Ústats)ÚdistributionsNc                  K   s*   t dd„ |  ¡ D ƒƒ}| dd ¡}||fS )Nc                 s   s.   | ]&\}}|  d ¡r| d dd¡|fV  qdS )Zu_Ú é   N)Ú
startswithÚreplace)Ú.0ÚkÚv© r   úf/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/sandbox/distributions/transformed.pyÚ	<genexpr>.   s    
ÿz#get_u_argskwargs.<locals>.<genexpr>Úu_args)ÚdictÚitemsÚpop)ÚkwargsÚu_kwargsr   r   r   r   Úget_u_argskwargs,   s    r   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )Ú
Transf_genzUa class for non-linear monotonic transformation of a continuous random variable

    c                    s¢   || _ || _| dd¡| _| dd¡}| dd¡}| dd ¡}| dtj ¡}	| d	tj¡}
| d
d¡| _tf |Ž\| _| _	|| _
tt| ƒj|	|
||j|d� d S )NÚnumargsr   ÚnameÚ
transfdistÚlongnameú#Non-linear transformed distributionÚextradocÚaÚbÚdecrF©r   r   r   Úshapesr   )ÚfuncÚfuncinvr   r   ÚnpÚinfr   r   r   r   ÚklsÚsuperr   Ú__init__r    )Úselfr%   r!   r"   Úargsr   r   r   r   r   r   ©Ú	__class__r   r   r'   9   s    þzTransf_gen.__init__c                 O   sB   | j s | jj|  |¡f|ž|ŽS d| jj|  |¡f|ž|Ž S d S ©Nç      ð?)r   r%   Ú_cdfr"   ©r(   Úxr)   r   r   r   r   r.   V   s    zTransf_gen._cdfc                 O   sB   | j s |  | jj|f|ž|Ž¡S |  | jjd| f|ž|Ž¡S d S )Nr   )r   r!   r%   Ú_ppf)r(   Úqr)   r   r   r   r   r1   ^   s    zTransf_gen._ppf©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   r.   r1   Ú__classcell__r   r   r*   r   r   4   s   r   c                 C   s   t  d| ¡S r,   )r#   Údivide©r0   r   r   r   Úinversee   s    r;   )gš™™™™™©?gš™™™™™¹?)g      "@r-   c                 C   s   ddt  | t   S )Nr-   r   ©ÚmuxÚstdxr:   r   r   r   Úinversewm   s    r?   c                 C   s   d|  d t  t S r,   r<   r:   r   r   r   Úinversew_invq   s    r@   c                 C   s   | S ©Nr   r:   r   r   r   Úidentitu   s    rB   TZdiscfznormal-based discount factor)r   r   r   r   é   ZlnnormzExp transformed normal)r   r   r   r   r   )r   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚExpTransf_genúµ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                    sd   d|kr|d | _ nd| _ d|kr,|d }nd}d|krB|d }nd}tt| ƒj||d� || _d S ©Nr   r   r   zLog transformed distributionr   r   ©r   r   )r   r&   rD   r'   r%   ©r(   r%   r)   r   r   r   r*   r   r   r'   —   s    

zExpTransf_gen.__init__c                 G   s   | j jt |¡f|žŽ S rA   )r%   r.   r#   Úlog©r(   r0   r)   r   r   r   r.   ª   s    zExpTransf_gen._cdfc                 G   s   t  | jj|f|žŽ ¡S rA   )r#   Úexpr%   r1   ©r(   r2   r)   r   r   r   r1   ®   s    zExpTransf_gen._ppfr3   r   r   r*   r   rD   �   s   rD   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚLogTransf_genrE   c                    sd   d|kr|d | _ nd| _ d|kr,|d }nd}d|krB|d }nd}tt| ƒj||d� || _d S rF   )r   r&   rM   r'   r%   rH   r*   r   r   r'   º   s    

zLogTransf_gen.__init__c                 G   s   | j jt |¡f|žŽ S rA   )r%   r.   r#   rK   rJ   r   r   r   r.   Ì   s    zLogTransf_gen._cdfc                 G   s   t  | jj|f|žŽ ¡S rA   )r#   rI   r%   r1   rL   r   r   r   r1   Ð   s    zLogTransf_gen._ppfr3   r   r   r*   r   rM   ²   s   rM   c                  C   s  t dƒ ttjddd�} t |  d¡ƒ t tj dd¡ƒ t |  ¡ ƒ t tj d¡ƒ t | jdd�ƒ t dƒ ttjƒ}t | 	dd	¡ƒ t tj
 dd	¡ƒ t | 	d
d¡ƒ t tj
 d
d¡ƒ t dƒ ttjƒ}t | 	d
d	¡ƒ t tj d
d	¡ƒ ttjƒ}t | 	d
d	¡ƒ d S )NzResults for lognormalr   zLog transformed normal generalrG   r   é   )ÚsizezResults for expgammaé
   rC   é   zResults for loglaplace)ÚprintrD   r   ÚnormZcdfZlognormZrvsrM   Úgammar.   ZloggammaZlaplaceZ
loglaplace)Ú
lognormalgÚloggammaexpgZloglaplacegZloglaplaceexpgr   r   r   Úexamples_transfÔ   s&    


rW   c                       sH   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	‡  Z
S )ÚTransfTwo_genaO  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                    s´   || _ || _|| _|| _|| _| dd¡| _| dd¡}	| dd¡}
| dd ¡}| dtj ¡}| d	tj¡}| d
d¡| _	t
f |Ž\| _| _|| _tt| ƒj|||	|j|
d� d S )Nr   r   r   r   r   r   r   r   r   ÚshapeFr   )r!   ÚfuncinvplusÚfuncinvminusÚ	derivplusÚ
derivminusr   r   r#   r$   rY   r   r   r   r%   r&   rX   r'   r    )r(   r%   r!   rZ   r[   r\   r]   r)   r   r   r   r   r   r   r*   r   r   r'   3  s&    ýzTransfTwo_gen.__init__c                 G   s   | j | j_ |  | jj|Ž ¡S rA   )Ú_sizer%   r!   Ú_rvs)r(   r)   r   r   r   r_   U  s    
zTransfTwo_gen._rvsc                 O   st   | j dkrd}n| j dkr d}ntdƒ‚||  |¡| jj|  |¡f|ž|Ž |  |¡| jj|  |¡f|ž|Ž   S )NÚur   Úhumpéÿÿÿÿzshape can only be `u` or `hump`)rY   Ú
ValueErrorr\   r%   Ú_pdfrZ   r]   r[   )r(   r0   r)   r   Zsignpdfr   r   r   rd   Y  s    

$ÿÿzTransfTwo_gen._pdfc                 O   sX   | j dkr>| jj|  |¡f|ž|Ž| jj|  |¡f|ž|Ž S d| j|f|ž|Ž S d S )Nr`   r-   )rY   r%   r.   rZ   r[   Ú_sfr/   r   r   r   r.   g  s
    
ÿzTransfTwo_gen._cdfc                 O   sX   | j dkr>| jj|  |¡f|ž|Ž| jj|  |¡f|ž|Ž S d| j|f|ž|Ž S d S )Nra   r-   )rY   r%   r.   rZ   r[   r/   r   r   r   re   p  s
    
ÿzTransfTwo_gen._sfc                 O   s   | j |f|žŽ S rA   )Z_mom0_sc)r(   Únr)   r   r   r   r   Ú_munpy  s    zTransfTwo_gen._munp)r4   r5   r6   r7   r'   r_   rd   r.   re   rg   r8   r   r   r*   r   rX   "  s   "		rX   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )Ú
SquareFuncz²class to hold quadratic function with inverse function and derivative

    using instance methods instead of class methods, if we want extension
    to parametrized function
    c                 C   s
   t  |¡S rA   ©r#   Úsqrt©r(   r0   r   r   r   ÚinverseplusŽ  s    zSquareFunc.inverseplusc                 C   s   dt  |¡ S ©Nç        ri   rk   r   r   r   Úinverseminus‘  s    zSquareFunc.inverseminusc                 C   s   dt  |¡ S ©Nç      à?ri   rk   r   r   r   r\   ”  s    zSquareFunc.derivplusc                 C   s   ddt  |¡  S ©Nrn   rq   ri   rk   r   r   r   r]   —  s    zSquareFunc.derivminusc                 C   s   t  |d¡S ©NrC   ©r#   Úpowerrk   r   r   r   Ú
squarefuncš  s    zSquareFunc.squarefuncN)	r4   r5   r6   r7   rl   ro   r\   r]   rv   r   r   r   r   rh   ‡  s   rh   r`   rn   Z
squarenormzsquared normal distribution)rY   r   r   r   r   r   zsquared t distributionc                 C   s   t  |  ¡S rA   ri   r:   r   r   r   rl   ±  s    rl   c                 C   s   dt  |  ¡ S rm   ri   r:   r   r   r   ro   µ  s    ro   c                 C   s   ddt  |  ¡  S rr   ri   r:   r   r   r   r\   ¹  s    r\   c                 C   s   dt  |  ¡ S rp   ri   r:   r   r   r   r]   ½  s    r]   c                 C   s   t  | d¡ S rs   rt   r:   r   r   r   ÚnegsquarefuncÁ  s    rw   ra   Znegsquarenormz$negative squared normal distributionc                 C   s   | S rA   r   r:   r   r   r   rl   Ð  s    c                 C   s   d|  S rm   r   r:   r   r   r   ro   Ô  s    c                 C   s   dS r,   r   r:   r   r   r   r\   Ø  s    c                 C   s   dS )Ng      ð¿r   r:   r   r   r   r]   Ü  s    c                 C   s
   t  | ¡S rA   )r#   Úabsr:   r   r   r   Úabsfuncà  s    ry   Zabsnormzabsolute of normal distribution)+r7   Zscipyr   Zscipy.statsr   Únumpyr#   r   Zrv_continuousr   r;   r=   r>   r?   r@   rB   rS   ZinvdnormalgrK   rI   rU   rT   rV   rD   rM   rW   rX   rh   Zsqfuncrv   rl   ro   r\   r]   r$   ZsquarenormalgÚtZsquaretgrw   Znegsquarenormalgry   rx   Z
absnormalgr   r   r   r   Ú<module>   s¢   $1  ÿ  þ
#"Ne      ý      ý	     ý      þ