
    'YHhD                        d Z ddlmZmZmZ ddlZ ej                  d      Z G d d      Z	 G d d      Z
 G d	 d
      Z ej                  ej                        dz  Z G d d      ZdEdZdFdZdGdZ G d d      ZdHdZedk(  rg dZdZddlmZ ddlmZmZ  edd       edd      fZ eddgeej@                  ej@                  ge       Z! e       Z"d!ev rBe!e!d"kD  e!dk  z     dz  Z! ee!ed#d$      \  Z#Z$Z%Z&e#Z' ejP                  e#e$      Z) e*d%e#jW                                e#e#jW                         z
  Z# ejP                  e#e$      Z, e*d&e)e,       e#e,z  Z#dZ-e-rS ej\                  e!d'd(d)*        ej^                  e$e#dd+,        ej^                  e$e'dd-,        ej`                           e1e&dd       D ]8  \  Z2Z3 e1e&dd       D ]%  \  Z4Z5 e*e2e4 ejl                  d. d/d      d          ' : e&D ]  Z3 e* ejl                  d0 d/d              d1ev r e       jo                  e!ed#2      Z8 ejr                  e!jW                         e!ju                               Z$ e8e$      Z; ejl                  e8ge8jx                   d   Z= e*d3e=       e"j}                  e$ddgej@                  ej@                  ge4      Z?dZ-e-re ej                           ej\                  e!d'd(d)*        ej^                  e$e;dd+,        ej^                  e$e?dd5,        ej                  d6       d7ev rk e       Z8de8_B        e8jo                  e!e
d82      Z8 ejr                  e!jW                         e!ju                               Z$ e8e$      Z; ejl                  e8ge8jx                   d   Z= e*d3e=       e"j}                  e$ddgej@                  ej@                  ge4      Z?dZ-e-re ej                           ej\                  e!d'd(d)*        ej                  d9        ej^                  e$e;dd+,        ej^                  e$e?dd5,        e* ejt                   ej                   ee8jL                  dd dd      d    ej                  d      z
                     d:ev r| e       Z8de8_B        e8jo                  e!ed#2      Z8 ejr                  e!jW                         e!ju                               Z$ e8e$      Z; ejl                  e8ge8jx                   d   Z= e*d3e=       e"j}                  e$ddgej@                  ej@                  ge4      Z?dZ-e-rv ej                           ej\                  e!d'd(d)*        ej^                  e$e;dd+,        ej^                  e$e?dd5,        ej                  d;        ej`                           e* ejt                   ej                   ee8jL                  dd dd      d    ej                  d      z
                      eEd      D  cg c]
  }  e|        c} ZF eeFd<d=      d   ZG e* ejt                   ej                  eG ej                  d      z
                      e*eGd>z  j                  eI             dd?lJmKZKmLZL  eEd      D  cg c]
  }  eK|        c} ZM eeMd@dA      d   ZN e*eNd>z  j                  eI              eEdB      D  cg c]
  }  eL|        c} ZO eeOd/ddC D      \  ZPZQ e* ejt                   ej                  eP ej                   ej                  eP            z
                     yyc c} w c c} w c c} w )Ia  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 does not 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


    )stats	integratespecialN       @c                       e Zd ZdZd Zd Zy)FPolyaB  Orthonormal (for weight=1) Fourier Polynomial on [0,1]

    orthonormal polynomial but density needs corfactor that I do not 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                 B    || _         d| _        | j                  | _        y )N)r      )orderdomain	intdomainselfr   s     k/var/www/html/planif/env/lib/python3.12/site-packages/statsmodels/sandbox/nonparametric/densityorthopoly.py__init__zFPoly.__init__<   s    
    c                     | j                   dk(  rt        j                  |      S t        t        j                  t        j
                  | j                   z  |z        z  S Nr   )r   np	ones_likesqr2cospir   xs     r   __call__zFPoly.__call__A   sA    ::?<<?""&&!3a!7888r   N__name__
__module____qualname____doc__r   r    r   r   r   r   .   s    %
9r   r   c                       e Zd ZdZd Zd Zy)F2Polya  Orthogonal (for weight=1) Fourier Polynomial on [0,pi]

    is orthogonal but first component does not 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                 p    || _         dt        j                  f| _        | j                  | _        d| _        y r   )r   r   r   r   r   offsetfactorr   s     r   r   zF2Poly.__init__U   s+    
"%%jr   c                 ,   | j                   dk(  r9t        j                  |      t        j                  t        j                        z  S t
        t        j                  | j                   |z        z  t        j                  t        j                        z  S r   )r   r   r   sqrtr   r   r   r   s     r   r   zF2Poly.__call__[   sY    ::?<<?RWWRUU^33"&&a00277255>AAr   Nr   r"   r   r   r$   r$   G   s    Br   r$   c                       e Zd ZdZd Zd Zy)
ChebyTPolyaL  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                 b    || _         ddlm}  ||      | _        d| _        d| _        d| _        y )Nr   )chebyt)r
   )g!g!?g{Gz?)r   scipy.specialr,   polyr   r   r&   )r   r   r,   s      r   r   zChebyTPoly.__init__o   s-    
(5M	* r   c                 X   | j                   dk(  rEt        j                  |      d|dz  z
  dz  z  t        j                  t        j                        z  S | j                  |      d|dz  z
  dz  z  t        j                  t        j                        z  t        j                  d      z  S )Nr   r
      g      ?)r   r   r   r(   r   r/   r   s     r   r   zChebyTPoly.__call__y   s~    ::?<<?a1f%55rwwruu~EE 99Q<1QT6T"22BGGBEENBBGGAJNNr   Nr   r"   r   r   r*   r*   a   s    !Or   r*   r1   c                       e Zd ZdZd Zd Zy)HPolyzOrthonormal (for weight=1) Hermite Polynomial, uses finite bounds

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

    c                 T    || _         ddlm}  ||      | _        d| _        d| _        y )Nr   )hermite)         ?)r   r.   r5   r/   r   r&   )r   r   r5   s      r   r   zHPoly.__init__   s&    
)EN	r   c                     | j                   }d|t        j                  d      z  t        j                  |dz         z   t
        z   z  ||z  dz  z
  }t        j                  |      }| j                  |      |z  S )N      r   r
   r1   )r   r   logr   gammalnlogpi2expr/   )r   r   klnfactfacts        r   r   zHPoly.__call__   se    JJ!BFF2J,1)==FG!A#a%Ovvf~yy|d""r   Nr   r"   r   r   r3   r3      s    
 #r   r3      c           	          t        j                  t        |      D cg c]  }  ||      |        c}      }|S c c}w N)r   column_stackrange)r   polybaser   ipolyarrs        r   
polyvanderrJ      s4    oouU|D!{x{1~DEGN Es   ;c                    t        |       }t        j                  ||f      }|j                  t        j                         t        j
                  ||f      }t        |      D ]  }t        |dz         D ]n  }| |   | |    t        j                  fd||      \  }	}
nt        j                  fd||      \  }	}
|	|||f<   |
|||f<   ||k(  ra|	|||f<   |
|||f<   p  ||fS )a  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]])

    r
   c                 8     |        |       z   |       z  S rD   r"   )r   p1p2weights    r   <lambda>zinner_cont.<locals>.<lambda>   s    RU2a5[5J r   c                 &     |        |       z  S rD   r"   r   rM   rN   s    r   rP   zinner_cont.<locals>.<lambda>   s    RU2a5[ r   )	lenr   emptyfillnanzerosrF   r   quad)polyslowerupperrO   n_polys	innerprodinterrrH   jinnperrrM   rN   s      `       @@r   
inner_contrb      s   B %jG'7+,INN266XXw()F7^ "qs 	"AqBqB!%NN+J',e5	c &NN+@%O	c!IacNF1Q3K6!%	!A#!qs	"" fr   c                    	 t        t        |             D ]\  }t        |dz         D ]I  }| |   | |   	t        j                  	fd||      d   }t	        j
                  |||k(  ||      rH  y ^ y)aZ  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

    r
   c                 &     |        |       z  S rD   r"   rR   s    r   rP   z%is_orthonormal_cont.<locals>.<lambda>  s    Ar!u r   r   )rtolatolFT)rF   rS   r   rX   r   allclose)
rY   rZ   r[   re   rf   rH   r_   r]   rM   rN   s
           @@r   is_orthonormal_contrh      s}    X 3u: qs 	AqBqB!'<eUKANI;;y!Q$TE	 r   c                   @    e Zd ZdZd
dZddZddZd Zd Zd Z	d	 Z
y)DensityOrthoPolya  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.
    Nc                     |-|| _         t        |      D cg c]
  } ||       c}x| _        }d| _        d| _        y c c}w )Nr
   r   )rG   rF   rY   
_corfactor	_corshift)r   rG   r   rH   rY   s        r   r   zDensityOrthoPoly.__init__  sD    $DM7<U|!D!(1+!DDDJ  "Es   ?c                 z   || j                   d| }n-|| _        t        |      D cg c]
  } ||       c}x| _         }t        | d      s|d   j                  | _        |j                         |j                         }}|*||z
  | j
                  z  x| _        }	||	z
  ||	z   fx}| _	        |d   |d   z
  }
||z
  }d|
z  | _
        |
|z
  dz  }	||	z
  | _        | j                  |      x| _        }|D cg c]  } ||      j                          }}|| _        || _         | j!                          | S c c}w c c}w )zIestimate the orthogonal polynomial approximation to the density

        N	offsetfacr   r
         ?r   )rY   rG   rF   hasattrr&   ro   minmaxoffsetlimitsshrinkshift
_transformr   meancoeffs_verify)r   r   rG   r   ru   rY   rH   xminxmaxrt   interval_length	xintervalprz   s                 r   fitzDensityOrthoPoly.fit%  sE    JJv&E$DM7<U|!D!(1+!DDDJ t[)"1X22DN UUWaeegd>$(4K4>>#AADK&$(6M4&=#AAFT[ )fQi/4K	?*!I-"4F]
__Q'')./A1Q4++-//
5 "E* 0s   D34D8c           	          | j                        |t        | j                        }t        fdt	        t        | j                  | j                              d | D              }| j                  |      }|S )Nc              3   :   K   | ]  \  }}| |      z    y wrD   r"   .0cr   xevals      r   	<genexpr>z,DensityOrthoPoly.evaluate.<locals>.<genexpr>M  s     TA!AeH*T   )rx   rS   rY   sumlistziprz   _correction)r   r   r   ress    `  r   evaluatezDensityOrthoPoly.evaluateI  sc    &=

OETc$++tzz.J)KFU)STTs#
r   c                 $    | j                  |      S )z,alias for evaluate, except no order argument)r   )r   r   s     r   r   zDensityOrthoPoly.__call__Q  s    }}U##r   c                     | j                   }dt        j                  | j                  g| d   z  | _        | j                  S )zcheck for bona fide density correction

        currently only checks that density integrates to 1

`       non-negativity - NotImplementedYet
        rp   r   )ru   r   rX   r   rl   )r   r   s     r   r{   zDensityOrthoPoly._verifyU  s<     KK	Y^^DMMFIFqII r   c                 ~    | j                   dk7  r|| j                   z  }| j                  dk7  r|| j                  z  }|S )zhbona fide density correction

        affine shift of density to make it into a proper density

        r
   r   )rl   rm   r   s     r   r   zDensityOrthoPoly._correctiong  s=     ??a A>>QAr   c                     | j                   d   j                  }|d   |d   z
  }| j                  |d   | j                  z  |z  z
  }| j                  |z  }||z
  |z  S )ztransform observation to the domain of the density


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


        r   r
   )rY   r   rw   rv   )r   r   r   ilenrw   rv   s         r   rx   zDensityOrthoPoly._transformu  sf     A%%q	F1I%

VAYt{{2477t#E	V##r   )NrB   )NrB   NrD   )r   r   r    r!   r   r   r   r   r{   r   rx   r"   r   r   rj   rj     s+    "H$$$r   rj   c                 L   3t        j                  | j                         | j                         d      t	        |      D cg c]
  } ||       }}|D cg c]  } ||       j                          }}t        fdt        ||      D              }|||fS c c}w c c}w )N2   c              3   :   K   | ]  \  }}| |      z    y wrD   r"   r   s      r   r   z$density_orthopoly.<locals>.<genexpr>  s     8TQa%j8r   )r   linspacerr   rs   rF   ry   r   r   )	r   rG   r   r   rH   rY   r   rz   r   s	      `     r   density_orthopolyr     s     }AEEGAEEGB/ #(,/QXa[/E/ &++qtkkm+F+
8S%78
8C vu$$ 0 ,s   BB!__main__)r,   fourierr5   i'  )mixture_rvsMixtureDistributionr:   r8   )locscaler
   g?gUUUUUU?gUUUUUU?)sizedistkwargschebyt_   )r   r   zf_hat.min()fint2r   Tred)binsnormedcolorblack)lwr   gc                 0    t        |       t        |       z  S rD   )r   rN   r   s    r   rP   rP     s    1Q41: r   r-   c                     t        |       dz  S )Nr1   )r   r   s    r   rP   rP     s    1Q47 r   r,   )r   zdop F integral)r   r   greenzusing Chebychev polynomialsr      zusing Fourier polynomialsr5   zusing Hermite polynomialsr6   r7   i )r5   r,   i
      c                     d| | z  z
  dz  S )Nr
   r:   r"   r   s    r   rP   rP   /  s    q1u6F r   )rO   )rB   rD   )r   g:0yE>)rB   N)Sr!   scipyr   r   r   numpyr   r(   r   r   r$   r*   r;   r   r=   r3   rJ   rb   rh   rj   r   r   examplesnobsmatplotlib.pyplotpyplotplt%statsmodels.distributions.mixture_rvsr   r   dictmix_kwdsnormobs_distmixf_hatgridrz   rY   f_hat0trapzfintprintrr   r   doplothistplotshow	enumeraterH   r   r_   rN   rX   r   dopr   rs   xfru   dopintpdfmpdffiguretitlero   abseyerF   hpolysinnastypeintr.   r5   r,   htpolysinntpolyscrediag)rH   s   0r   <module>r      sM  $J , +  rwwr{9 92B B4O O@ 
q# #*5p4vw$ w$v%. z/HD#R B'(<=HD;TUZZ8P"$H

C
 H Xb[XaZ89#= &7xSU]a%b"tVUyud+mUYY[)$	t,gtU# CHHXBt5ACHHT5Qg6CHHT6as3CHHJU2AY' 	ICAa!%), I"a.)..)=r!DQGHI	I  	;A.)..!2Bq9:	; 8 $$Xz$Dr{{8<<>8<<>:Y1cjj1!4'wwtd4[

EJJ/G"  $ CJJLCHHXBt5ACHHT2!73CHHT4AW5CII34 H gghbg1r{{8<<>8<<>:Y1cjj1!4'wwtd4[

EJJ/G"  $ CJJLCHHXBt5ACII12CHHT2!73CHHT4AW5 	fbffVRVVJsyy!}a;A>q	IJKLH gghRg0r{{8<<>8<<>:Y1cjj1!4'wwtd4[

EJJ/G"  $ CJJLCHHXBt5ACHHT2!73CHHT4AW5CII12CHHJ 	fbffVRVVJsyy!}a;A>q	IJKL
 !&a)1eAh)F
VR
#A
&C	&"&&fbffQi(
)*	3v:

c
"#-#(8,awqz,GgsB'*D	4;

s
#$!&q*AfQi*Ffb!,FGDAq	&"&&GBGGGBGGAJ//0
12_ F * - +s   3]+9]0<]5