ó
áp7]c        	   @  s	  d  Z  d d l m Z d d l m Z d d l m Z m Z m Z d d l	 Z
 e
 j d ƒ Z d e f d „  ƒ  YZ d	 e f d
 „  ƒ  YZ d e f d „  ƒ  YZ e
 j e
 j ƒ d Z d e f d „  ƒ  YZ d d „ Z d d „ Z d d d „ Z d e f d „  ƒ  YZ d d d „ Z e d k r	d d d g Z d Z d d l j Z  d d l! m" Z" m# Z# e$ d d  d! d" ƒ e$ d d# d! d$ ƒ f Z% e" d# d% d d% g d& e d' e j& e j& g d( e% ƒZ' e# ƒ  Z( d) e k rˆe' e' d* k e' d k  @d Z' e e' e d+ d, d- d ƒ\ Z) Z* Z+ Z, e) Z- e j. e) e* ƒ Z/ e0 d. e) j1 ƒ  ƒ e) e) j1 ƒ  Z) e j. e) e* ƒ Z2 e0 d/ e/ e2 ƒ e) e2 :Z) d Z3 e3 rðe  j4 e' d0 d1 d2 e5 d3 d4 ƒe  j6 e* e) d5 d d3 d6 ƒe  j6 e* e- d5 d d3 d7 ƒe  j7 ƒ  n  xe e8 e, d  ƒ D]S \ Z9 Z: xD e8 e, d  ƒ D]2 \ Z; Z< e0 e9 e; e j= d8 „  d d# ƒ d ƒ qWqWx- e, D]" Z: e0 e j= d9 „  d d# ƒ ƒ q_Wn  d e k r·e ƒ  j> e' e d+ d, ƒZ? e
 j@ e' j1 ƒ  e' jA ƒ  ƒ Z* e? e* ƒ ZB e j= e? e? jC Œ d ZD e0 d: eD ƒ e( jE e* d# d% d d% g d' e j& e j& g d( e% ƒZF d# Z3 e3 r·e  jG ƒ  e  j4 e' d0 d1 d2 e5 d3 d4 ƒe  j6 e* eB d5 d d3 d6 ƒe  j6 e* eF d5 d d3 d; ƒe  jH d< ƒ q·n  d e k r5e ƒ  Z? d" e? _I e? j> e' e d+ d= ƒZ? e
 j@ e' j1 ƒ  e' jA ƒ  ƒ Z* e? e* ƒ ZB e j= e? e? jC Œ d ZD e0 d: eD ƒ e( jE e* d# d% d d% g d' e j& e j& g d( e% ƒZF d# Z3 e3 ròe  jG ƒ  e  j4 e' d0 d1 d2 e5 d3 d4 ƒe  jH d> ƒ e  j6 e* eB d5 d d3 d6 ƒe  j6 e* eF d5 d d3 d; ƒn  e0 e
 jA e
 jJ e e? j, d  d d# ƒ d e
 jK d ƒ ƒ ƒ ƒ n  d e k r½e ƒ  Z? d e? _I e? j> e' e d+ d, ƒZ? e
 j@ e' j1 ƒ  e' jA ƒ  ƒ Z* e? e* ƒ ZB e j= e? e? jC Œ d ZD e0 d: eD ƒ e( jE e* d# d% d d% g d' e j& e j& g d( e% ƒZF d# Z3 e3 rze  jG ƒ  e  j4 e' d0 d1 d2 e5 d3 d4 ƒe  j6 e* eB d5 d d3 d6 ƒe  j6 e* eF d5 d d3 d; ƒe  jH d? ƒ e  j7 ƒ  n  e0 e
 jA e
 jJ e e? j, d  d d# ƒ d e
 jK d ƒ ƒ ƒ ƒ n  g  eL d ƒ D] Z9 e e9 ƒ ^ qÊZM e eM d@ dA ƒ d ZN e0 e
 jA e
 jJ eN e
 jK d ƒ ƒ ƒ ƒ e0 eN dB jO eP ƒ ƒ d dC lQ mR ZR mS ZS g  eL d ƒ D] Z9 eR e9 ƒ ^ q[ZT e eT dD dE ƒ d ZU e0 eU dB jO eP ƒ ƒ g  eL dF ƒ D] Z9 eS e9 ƒ ^ q­ZV e eV d d# dG dH „  ƒ\ ZW ZX e0 e
 jA e
 jJ eW e
 jY e
 jY eW ƒ ƒ ƒ ƒ ƒ n  d S(I   sŠ  density estimation based on orthogonal polynomials


Author: Josef Perktold
Created: 2011-05017
License: BSD

2 versions work: based on Fourier, FPoly, and chebychev T, ChebyTPoly
also hermite polynomials, HPoly, works
other versions need normalization


TODO:

* check fourier case again:  base is orthonormal,
  but needs offsetfact = 0 and doesn't integrate to 1, rescaled looks good
* hermite: works but DensityOrthoPoly requires currently finite bounds
  I use it with offsettfactor 0.5 in example
* not implemented methods:
  - add bonafide density correction
  - add transformation to domain of polynomial base - DONE
    possible problem: what is the behavior at the boundary,
    offsetfact requires more work, check different cases, add as option
    moved to polynomial class by default, as attribute
* convert examples to test cases
* need examples with large density on boundary, beta ?
* organize poly classes in separate module, check new numpy.polynomials,
  polyvander
* MISE measures, order selection, ...

enhancements:
  * other polynomial bases: especially for open and half open support
  * wavelets
  * local or piecewise approximations


iÿÿÿÿ(   t   print_function(   t   zip(   t   statst	   integratet   specialNg       @t   FPolyc           B  s    e  Z d  Z d „  Z d „  Z RS(   sA  Orthonormal (for weight=1) Fourier Polynomial on [0,1]

    orthonormal polynomial but density needs corfactor that I don't see what
    it is analytically

    parameterization on [0,1] from

    Sam Efromovich: Orthogonal series density estimation,
    2010 John Wiley & Sons, Inc. WIREs Comp Stat 2010 2 467-476


    c         C  s"   | |  _  d |  _ |  j |  _ d  S(   Ni    i   (   i    i   (   t   ordert   domaint	   intdomain(   t   selfR   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   __init__?   s    		c         C  s?   |  j  d k r t j | ƒ St t j t j |  j  | ƒ Sd  S(   Ni    (   R   t   npt	   ones_liket   sqr2t   cost   pi(   R	   t   x(    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   __call__D   s    (   t   __name__t
   __module__t   __doc__R
   R   (    (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   1   s   	t   F2Polyc           B  s    e  Z d  Z d „  Z d „  Z RS(   s²  Orthogonal (for weight=1) Fourier Polynomial on [0,pi]

    is orthogonal but first component doesn't square-integrate to 1
    final result seems to need a correction factor of sqrt(pi)
    _corfactor = sqrt(pi) from integrating the density

    Parameterization on [0, pi] from

    Peter Hall, Cross-Validation and the Smoothing of Orthogonal Series Density
    Estimators, JOURNAL OF MULTIVARIATE ANALYSIS 21, 189-206 (1987)

    c         C  s4   | |  _  d t j f |  _ |  j |  _ d |  _ d  S(   Ni    (   R   R   R   R   R   t   offsetfactor(   R	   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR
   X   s    	c         C  sX   |  j  d k r, t j | ƒ t j t j ƒ St t j |  j  | ƒ t j t j ƒ Sd  S(   Ni    (   R   R   R   t   sqrtR   R   R   (   R	   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   ^   s    (   R   R   R   R
   R   (    (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   J   s   	t
   ChebyTPolyc           B  s    e  Z d  Z d „  Z d „  Z RS(   sL  Orthonormal (for weight=1) Chebychev Polynomial on (-1,1)


    Notes
    -----
    integration requires to stay away from boundary, offsetfactor > 0
    maybe this implies that we cannot use it for densities that are > 0 at
    boundary ???

    or maybe there is a mistake close to the boundary, sometimes integration works.

    c         C  sM   | |  _  d d l m } | | ƒ |  _ d |  _ d d f |  _ d |  _ d  S(	   Niÿÿÿÿ(   t   chebyti   gíµ ÷Æ°>g{®Gáz„?(   iÿÿÿÿi   gé!çýÿï¿gé!çýÿï?(   R   t   scipy.specialR   t   polyR   R   R   (   R	   R   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR
   r   s    		c         C  s‚   |  j  d k r@ t j | ƒ d | d d d t j t j ƒ S|  j | ƒ d | d d d t j t j ƒ t j d ƒ Sd  S(   Ni    i   i   g      @(   R   R   R   R   R   R   (   R	   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   |   s    1(   R   R   R   R
   R   (    (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   d   s   	
i   t   HPolyc           B  s    e  Z d  Z d „  Z d „  Z RS(   sŽ   Orthonormal (for weight=1) Hermite Polynomial, uses finite bounds

    for current use with DensityOrthoPoly domain is defined as [-6,6]

    c         C  sE   | |  _  d d l m } | | ƒ |  _ d d 
f |  _ d |  _ d  S(   Niÿÿÿÿ(   t   hermiteiúÿÿÿi   g      à?(   R   R   R   R   R   R   (   R	   R   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR
   Œ   s
    	c         C  sf   |  j  } d d | t j d ƒ t j | d ƒ t | | d } t j | ƒ } |  j | ƒ | S(   Ng      ð?i   g       @i   (   R   R   t   logR   t   gammalnt   logpi2t   expR   (   R	   R   t   kt   lnfactt   fact(    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   “   s    	=(   R   R   R   R
   R   (    (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   †   s   	i   c         C  s8   t  j g  t | ƒ D] } | | ƒ |  ƒ ^ q ƒ } | S(   N(   R   t   column_stackt   range(   R   t   polybaseR   t   it   polyarr(    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt
   polyvander›   s    4c           sE  t  |  ƒ } t j | | f ƒ } | j t j ƒ t j | | f ƒ } xò t | ƒ D]ä } xÛ t | d ƒ D]É } |  | ‰  |  | ‰ ˆ d k	 r½ t j	 ‡  ‡ ‡ f d †  | | ƒ \ }	 }
 n' t j	 ‡  ‡ f d †  | | ƒ \ }	 }
 |	 | | | f <|
 | | | f <| | k sj |	 | | | f <|
 | | | f <qj qj WqS W| | f S(   sµ  inner product of continuous function (with weight=1)

    Parameters
    ----------
    polys : list of callables
        polynomial instances
    lower : float
        lower integration limit
    upper : float
        upper integration limit
    weight : callable or None
        weighting function

    Returns
    -------
    innp : ndarray
        symmetric 2d square array with innerproduct of all function pairs
    err : ndarray
        numerical error estimate from scipy.integrate.quad, same dimension as innp

    Examples
    --------
    >>> from scipy.special import chebyt
    >>> polys = [chebyt(i) for i in range(4)]
    >>> r, e = inner_cont(polys, -1, 1)
    >>> r
    array([[ 2.        ,  0.        , -0.66666667,  0.        ],
           [ 0.        ,  0.66666667,  0.        , -0.4       ],
           [-0.66666667,  0.        ,  0.93333333,  0.        ],
           [ 0.        , -0.4       ,  0.        ,  0.97142857]])

    i   c           s   ˆ  |  ƒ ˆ |  ƒ ˆ |  ƒ S(   N(    (   R   (   t   p1t   p2t   weight(    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   <lambda>Ê   t    c           s   ˆ  |  ƒ ˆ |  ƒ S(   N(    (   R   (   R+   R,   (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR.   Í   R/   N(
   t   lenR   t   emptyt   fillt   nant   zerosR&   t   NoneR   t   quad(   t   polyst   lowert   upperR-   t   n_polyst	   innerprodt   interrR(   t   jt   innpt   err(    (   R+   R,   R-   sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt
   inner_contŸ   s$    !

'i    g:Œ0âŽyE>c      	     s   x– t  t |  ƒ ƒ D]‚ } xy t  | d ƒ D]g } |  | ‰  |  | ‰ t j ‡  ‡ f d †  | | ƒ d } t j | | | k d | d | ƒs* t Sq* Wq Wt S(   sZ  check whether functions are orthonormal

    Parameters
    ----------
    polys : list of polynomials or function

    Returns
    -------
    is_orthonormal : bool
        is False if the innerproducts are not close to 0 or 1

    Notes
    -----
    this stops as soon as the first deviation from orthonormality is found.

    Examples
    --------
    >>> from scipy.special import chebyt
    >>> polys = [chebyt(i) for i in range(4)]
    >>> r, e = inner_cont(polys, -1, 1)
    >>> r
    array([[ 2.        ,  0.        , -0.66666667,  0.        ],
           [ 0.        ,  0.66666667,  0.        , -0.4       ],
           [-0.66666667,  0.        ,  0.93333333,  0.        ],
           [ 0.        , -0.4       ,  0.        ,  0.97142857]])
    >>> is_orthonormal_cont(polys, -1, 1, atol=1e-6)
    False

    >>> polys = [ChebyTPoly(i) for i in range(4)]
    >>> r, e = inner_cont(polys, -1, 1)
    >>> r
    array([[  1.00000000e+00,   0.00000000e+00,  -9.31270888e-14,
              0.00000000e+00],
           [  0.00000000e+00,   1.00000000e+00,   0.00000000e+00,
             -9.47850712e-15],
           [ -9.31270888e-14,   0.00000000e+00,   1.00000000e+00,
              0.00000000e+00],
           [  0.00000000e+00,  -9.47850712e-15,   0.00000000e+00,
              1.00000000e+00]])
    >>> is_orthonormal_cont(polys, -1, 1, atol=1e-6)
    True

    i   c           s   ˆ  |  ƒ ˆ |  ƒ S(   N(    (   R   (   R+   R,   (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR.     R/   i    t   rtolt   atol(   R&   R0   R   R6   R   t   allcloset   Falset   True(   R7   R8   R9   RA   RB   R(   R=   R;   (    (   R+   R,   sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   is_orthonormal_cont×   s    ,

%$t   DensityOrthoPolyc           B  s_   e  Z d  Z d	 d d „ Z d	 d d	 d „ Z d	 d „ Z d „  Z d „  Z d „  Z	 d „  Z
 RS(
   s  Univariate density estimation by orthonormal series expansion


    Uses an orthonormal polynomial basis to approximate a univariate density.


    currently all arguments can be given to fit, I might change it to requiring
    arguments in __init__ instead.
    i   c         C  sZ   | d  k	 rD | |  _ g  t | ƒ D] } | | ƒ ^ q" |  _ } n  d |  _ d |  _ d  S(   Ni   i    (   R5   R'   R&   R7   t
   _corfactort	   _corshift(   R	   R'   R   R(   R7   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR
     s
    	/	c         C  sm  | d k r |  j |  } n5 | |  _ g  t | ƒ D] } | | ƒ ^ q2 |  _ } t |  d ƒ ss | d j |  _ n  | j ƒ  | j ƒ  } } | d k rÎ | | |  j |  _	 }	 | |	 | |	 f } |  _
 n  | d | d }
 | | } d |
 |  _ |
 | d }	 | |	 |  _ |  j | ƒ |  _ } g  | D] } | | ƒ j ƒ  ^ q/} | |  _ | |  _ |  j ƒ  |  S(   sI   estimate the orthogonal polynomial approximation to the density

        t	   offsetfaci    i   g      ð?g       @N(   R5   R7   R'   R&   t   hasattrR   RJ   t   mint   maxt   offsett   limitst   shrinkt   shiftt
   _transformR   t   meant   coeffst   _verify(   R	   R   R'   R   RO   R7   R(   t   xmint   xmaxRN   t   interval_lengtht	   xintervalt   pRT   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   fit(  s*    	,
%		
c           su   |  j  ˆ  ƒ ‰  | d  k r- t |  j ƒ } n  t ‡  f d †  t t |  j |  j ƒ ƒ |  Dƒ ƒ } |  j | ƒ } | S(   Nc         3  s%   |  ] \ } } | | ˆ  ƒ Vq d  S(   N(    (   t   .0t   cRZ   (   t   xeval(    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pys	   <genexpr>P  s    (	   RR   R5   R0   R7   t   sumt   listR   RT   t   _correction(   R	   R^   R   t   res(    (   R^   sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   evaluateL  s    5c         C  s   |  j  | ƒ S(   s,   alias for evaluate, except no order argument(   Rc   (   R	   R^   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR   T  s    c         C  s0   |  j  } d t j |  j | Œ d |  _ |  j S(   s—   check for bona fide density correction

        currently only checks that density integrates to 1

`       non-negativity - NotImplementedYet
        g      ð?i    (   RO   R   R6   Rc   RH   (   R	   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyRU   X  s    
	 c         C  sB   |  j  d k r | |  j  9} n  |  j d k r> | |  j 7} n  | S(   sh   bona fide density correction

        affine shift of density to make it into a proper density

        i   i    (   RH   RI   (   R	   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyRa   j  s
    c         C  sW   |  j  d j } | d | d } |  j | d |  j | } |  j | } | | | S(   s„   transform observation to the domain of the density


        uses shrink and shift attribute which are set in fit to stay


        i    i   (   R7   R   RQ   RP   (   R	   R   R   t   ilenRQ   RP   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyRR   x  s
    N(   R   R   R   R5   R
   R[   Rc   R   RU   Ra   RR   (    (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyRG     s   	$			c   	        s¯   ˆ  d  k r0 t j |  j ƒ  |  j ƒ  d ƒ ‰  n  g  t | ƒ D] } | | ƒ ^ q= } g  | D] } | |  ƒ j ƒ  ^ q\ } t ‡  f d †  t | | ƒ Dƒ ƒ } | ˆ  | | f S(   Ni2   c         3  s%   |  ] \ } } | | ˆ  ƒ Vq d  S(   N(    (   R\   R]   RZ   (   R^   (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pys	   <genexpr>  s    (	   R5   R   t   linspaceRL   RM   R&   RS   R_   R   (	   R   R'   R   R^   R(   R7   RZ   RT   Rb   (    (   R^   sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   density_orthopoly  s    $%%%t   __main__R   t   fourierR   i'  (   t   mixture_rvst   MixtureDistributiont   locg      à¿t   scaleg      à?i   gš™™™™™É?g      @t   sizet   distt   kwargst   chebyt_iþÿÿÿR   i   R^   s   f_hat.min()t   fint2t   binsi2   t   normedt   colort   redt   lwt   blackt   gc         C  s   t  |  ƒ t |  ƒ S(   N(   RZ   R,   (   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR.   Ø  R/   c         C  s   t  |  ƒ d S(   Ni   (   RZ   (   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR.   Û  R/   s   dop F integralt   greens   using Chebychev polynomialsi   s   using Fourier polynomialss   using Hermite polynomialsiúÿÿÿi   i † (   R   R   iöÿÿÿi
   i   R-   c         C  s   d |  |  d d S(   Ni   iÿÿÿÿg       @(    (   R   (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyR.   2  R/   (Z   R   t
   __future__R    t   statsmodels.compat.pythonR   t   scipyR   R   R   t   numpyR   R   R   t   objectR   R   R   R   R   R    R   R*   R5   R@   RF   RG   Rf   R   t   examplest   nobst   matplotlib.pyplott   pyplott   pltt%   statsmodels.distributions.mixture_rvsRi   Rj   t   dictt   mix_kwdst   normt   obs_distt   mixt   f_hatt   gridRT   R7   t   f_hat0t   trapzt   fintt   printRL   Rq   t   doplott   histRE   t   plott   showt	   enumerateR(   RZ   R=   R,   R6   R[   t   dopRe   RM   t   xfRO   t   dopintt   pdft   mpdft   figuret   titleRJ   t   abst   eyeR&   t   hpolyst   innt   astypet   intR   R   R   t   htpolyst   inntt   polysct   rt   et   diag(    (    (    sQ   lib/python2.7/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.pyt   <module>'   sØ    8;{*/		'
.#/	
		/	
C		/	
C%)%%!