
    M/PhD                        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dIdZdJdZdKdZ G d d          ZdLd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 r[e!e!d#k    e!dk     z           dz  Z! ee!ed$d%          \  Z#Z$Z%Z&e#Z' ej(        e#e$          Z) e*d&e#+                                           e#e#+                                z
  Z# ej(        e#e$          Z, e*d'e)e,           e#e,z  Z#dZ-e-rK ej.        e!d(d)d*+            ej/        e$e#dd,-            ej/        e$e'dd.-            ej0                      e1e&dd                   D ]B\  Z2Z3 e1e&dd                   D ])\  Z4Z5 e*e2e4 ej6        d/ d0d          d                    *Ce&D ]Z3 e* ej6        d1 d0d                     d2ev r e            7                    e!ed$3          Z8 ej9        e!+                                e!:                                          Z$ e8e$          Z; ej6        e8ge8j<        R  d         Z= e*d4e=           e">                    e$dd gej         ej         ge5          Z?dZ-e-r[ ej@                      ej.        e!d(d)d*+            ej/        e$e;dd,-            ej/        e$e?dd6-            ejA        d7           d8ev rj e            Z8de8_B        e87                    e!e
d93          Z8 ej9        e!+                                e!:                                          Z$ e8e$          Z; ej6        e8ge8j<        R  d         Z= e*d4e=           e">                    e$dd gej         ej         ge5          Z?dZ-e-r[ ej@                      ej.        e!d(d)d*+            ejA        d:            ej/        e$e;dd,-            ej/        e$e?dd6-            e* ej:         ejC         ee8j&        dd         dd          d          ejD        d          z
                                 d;ev ry e            Z8de8_B        e87                    e!ed$3          Z8 ej9        e!+                                e!:                                          Z$ e8e$          Z; ej6        e8ge8j<        R  d         Z= e*d4e=           e">                    e$dd gej         ej         ge5          Z?dZ-e-rj ej@                      ej.        e!d(d)d*+            ej/        e$e;dd,-            ej/        e$e?dd6-            ejA        d<            ej0                      e* ej:         ejC         ee8j&        dd         dd          d          ejD        d          z
                                 d=  eEd          D             ZF eeFd>d?          d         ZG e* ej:         ejC        eG ejD        d          z
                                  e*eGd@z  H                    eI                     ddAlJmKZKmLZL dB  eEd          D             ZM eeMdCdD          d         ZN e*eNd@z  H                    eI                     dE  eEdF          D             ZO eeOd0ddG H          \  ZPZQ e* ej:         ejC        eP ejR         ejR        eP                    z
                                 dS dS )Ma  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dS )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                 :    || _         d| _        | j        | _        d S )N)r      )orderdomain	intdomainselfr   s     r/var/www/html/test/jupyter/venv/lib/python3.11/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   s>    :??<??""&!3a!78888r   N__name__
__module____qualname____doc__r   r    r   r   r   r   .   s<         % % %
9 9 9 9 9r   r   c                       e Zd ZdZd Zd ZdS )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                 `    || _         dt          j        f| _        | j        | _        d| _        d S r   )r   r   r   r   r   offsetfactorr   s     r   r   zF2Poly.__init__U   s-    
"%jr   c                    | j         dk    r3t          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__[   sT    :??<??RWRU^^33"&a0002725>>AAr   Nr   r"   r   r   r$   r$   G   sA           B B B B Br   r$   c                       e Zd ZdZd Zd ZdS )
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                 j    || _         ddlm}  ||          | _        d| _        d| _        d| _        d S )Nr   chebyt)r
   )g!g!?g{Gz?)r   scipy.specialr-   polyr   r   r&   )r   r   r-   s      r   r   zChebyTPoly.__init__o   sF    
((((((F5MM	* r   c                 @   | j         dk    r?t          j        |          d|dz  z
  dz  z  t          j        t          j                  z  S |                     |          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   r0   r   s     r   r   zChebyTPoly.__call__y   s|    :??<??a1f%55rwru~~EE 99Q<<1QT6T"22BGBENNBBGAJJNNr   Nr   r"   r   r   r*   r*   a   sA         ! ! !O O O O Or   r*   r2   c                       e Zd ZdZd Zd ZdS )HPolyzOrthonormal (for weight=1) Hermite Polynomial, uses finite bounds

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

    c                 \    || _         ddlm}  ||          | _        d| _        d| _        d S )Nr   hermite)         ?)r   r/   r7   r0   r   r&   )r   r   r7   s      r   r   zHPoly.__init__   s?    
))))))GENN	r   c                     | j         }d|t          j        d          z  t          j        |dz             z   t
          z   z  ||z  dz  z
  }t          j        |          }|                     |          |z  S )N      r   r
   r2   )r   r   logr   gammalnlogpi2expr0   )r   r   klnfactfacts        r   r   zHPoly.__call__   sf    J!BF2JJ,1)=)==FG!A#a%Ovf~~yy||d""r   Nr   r"   r   r   r4   r4      s<         
     # # # # #r   r4      c                 f     t          j         fdt          |          D                       }|S )Nc                 8    g | ]}  |                    S r"   r"   ).0ipolybaser   s     r   
<listcomp>zpolyvander.<locals>.<listcomp>   s)    DDD!{xx{{1~~DDDr   )r   column_stackrange)r   rI   r   polyarrs   ``  r   
polyvanderrN      s6    oDDDDDuU||DDDEEGNr   c                    t          |           }t          j        ||f          }|                    t          j                   t          j        ||f          }t          |          D ]}t          |dz             D ]r}| |         | |         t          j        fd||          \  }	}
nt          j        fd||          \  }	}
|	|||f<   |
|||f<   ||k    s|	|||f<   |
|||f<   s||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
   Nc                 J     |            |           z   |           z  S Nr"   )r   p1p2weights    r   <lambda>zinner_cont.<locals>.<lambda>   s(    RRUU22a55[5J r   c                 2     |            |           z  S rQ   r"   r   rR   rS   s    r   rU   zinner_cont.<locals>.<lambda>   s    RRUU22a55[ r   )	lenr   emptyfillnanzerosrL   r   quad)polyslowerupperrT   n_polys	innerprodinterrrH   jinnperrrR   rS   s      `       @@r   
inner_contrg      s9   B %jjG'7+,,INN26Xw())F7^^ " "qs 	" 	"AqBqB!%N+J+J+J+J+J+J',e5 5	cc &N+@+@+@+@+@%OO	c!IacNF1Q3K66!%	!A#!qs	" fr   :0yE>c                   	 t          t          |                     D ]g}t          |dz             D ]R}| |         | |         	t          j        	fd||          d         }t	          j        |||k    ||          s  dS ShdS )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                 2     |            |           z  S rQ   r"   rW   s    r   rU   z%is_orthonormal_cont.<locals>.<lambda>  s    Arr!uu r   r   )rtolatolFT)rL   rX   r   r]   r   allclose)
r^   r_   r`   rk   rl   rH   rd   rb   rR   rS   s
           @@r   is_orthonormal_contrn      s    X 3u::  qs 	 	AqBqB!'<'<'<'<'<eUKKANI;y!Q$TEEE uuu	 4r   c                   B    e Zd ZdZddZddZddZd Zd Zd	 Z	d
 Z
dS )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.
    NrD   c                 z    )| _         fdt          |          D             x| _        }d| _        d| _        d S )Nc                 &    g | ]} |          S r"   r"   rG   rH   rI   s     r   rJ   z-DensityOrthoPoly.__init__.<locals>.<listcomp>  !    !D!D!D!((1++!D!D!Dr   r
   r   )rI   rL   r^   
_corfactor	_corshift)r   rI   r   r^   s    `  r   r   zDensityOrthoPoly.__init__  sJ    $DM!D!D!D!DuU||!D!D!DDDJ r   c                 ^   | j         d|         }n)| _        fdt          |          D             x| _         }t          | d          s|d         j        | _                                                                        }}|%||z
  | j        z  x| _        }||z
  ||z   fx}| _	        |d         |d         z
  }	||z
  }
d|	z  | _
        |	|
z
  dz  }||z
  | _        |                               x| _        fd|D             }|| _        || _         |                                  | S )	zIestimate the orthogonal polynomial approximation to the density

        Nc                 &    g | ]} |          S r"   r"   rs   s     r   rJ   z(DensityOrthoPoly.fit.<locals>.<listcomp>-  rt   r   	offsetfacr   r
         ?r   c                 J    g | ]} |                                            S r"   meanrG   pr   s     r   rJ   z(DensityOrthoPoly.fit.<locals>.<listcomp>B  s)    ///A11Q44++--///r   )r^   rI   rL   hasattrr&   ry   minmaxoffsetlimitsshrinkshift
_transformr   coeffs_verify)r   r   rI   r   r   r^   xminxmaxr   interval_length	xintervalr   s    ``         r   fitzDensityOrthoPoly.fit%  sO    Jvv&EE$DM!D!D!D!DuU||!D!D!DDDJ t[)) 	3"1X2DN UUWWaeeggd>$(4K4>#AADK&$(6M4&=#AAFT[ )fQi/4K	?*!I-"4F]
__Q'''///////
r   c           	         |                                |t          | j                  }t          fdt	          t          | j        | j                            d |         D                       }|                     |          }|S )Nc              3   :   K   | ]\  }}| |          z  V  d S rQ   r"   rG   cr   xevals      r   	<genexpr>z,DensityOrthoPoly.evaluate.<locals>.<genexpr>M  s3      TTA!AAeHH*TTTTTTr   )r   rX   r^   sumlistzipr   _correction)r   r   r   ress    `  r   evaluatezDensityOrthoPoly.evaluateI  s    &&=
OOETTTTc$+tz.J.J)K)KFUF)STTTTTs##
r   c                 ,    |                      |          S )z,alias for evaluate, except no order argument)r   )r   r   s     r   r   zDensityOrthoPoly.__call__Q  s    }}U###r   c                 h    | j         }dt          j        | j        g|R  d         z  | _        | j        S )zcheck for bona fide density correction

        currently only checks that density integrates to 1

`       non-negativity - NotImplementedYet
        rz   r   )r   r   r]   r   ru   )r   r   s     r   r   zDensityOrthoPoly._verifyU  s:     K	Y^DMFIFFFqII r   c                 Z    | j         dk    r
|| j         z  }| j        dk    r
|| j        z  }|S )zhbona fide density correction

        affine shift of density to make it into a proper density

        r
   r   )ru   rv   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
   )r^   r   r   r   )r   r   r   ilenr   r   s         r   r   zDensityOrthoPoly._transformu  s[     A%q	F1I%
VAYt{2477t#E	V##r   )NrD   )NrD   NrQ   )r   r   r    r!   r   r   r   r   r   r   r   r"   r   r   rp   rp     s            " " " "H   $ $ $  $  $ $ $ $ $r   rp   c                 0    :t          j                                                                          d          fdt	          |          D             } fd|D             }t          fdt          ||          D                       }|||fS )N2   c                 &    g | ]} |          S r"   r"   rs   s     r   rJ   z%density_orthopoly.<locals>.<listcomp>  s!    ///QXXa[[///r   c                 J    g | ]} |                                            S r"   r|   r~   s     r   rJ   z%density_orthopoly.<locals>.<listcomp>  s)    +++qqttkkmm+++r   c              3   :   K   | ]\  }}| |          z  V  d S rQ   r"   r   s      r   r   z$density_orthopoly.<locals>.<genexpr>  s3      88TQa%j888888r   )r   linspacer   r   rL   r   r   )r   rI   r   r   r^   r   r   s   `` `   r   density_orthopolyr     s     }AEEGGAEEGGB// 0///%,,///E ,+++U+++F
8888S%7%7888
8
8C vu$$r   __main__)r-   fourierr7   i'  )mixture_rvsMixtureDistributionr<   r:   )locscaler
   g?gUUUUUU?gUUUUUU?)sizedistkwargschebyt_   )r   r   zf_hat.min()fint2r   Tred)binsnormedcolorblack)lwr   gc                 @    t          |           t          |           z  S rQ   )r   rS   r   s    r   rU   rU     s    1Q441: r   r.   c                 &    t          |           dz  S )Nr2   )r   r   s    r   rU   rU     s    1Q447 r   r-   )r   zdop F integral)r   r   greenzusing Chebychev polynomialsr      zusing Fourier polynomialsr7   zusing Hermite polynomialsc                 ,    g | ]}t          |          S r"   )r4   rG   rH   s     r   rJ   rJ   $  s    )))1eAhh)))r   r8   r9   i )r7   r-   c                 ,    g | ]}t          |          S r"   r6   r   s     r   rJ   rJ   *  s    ,,,awqzz,,,r   i
   c                 ,    g | ]}t          |          S r"   r,   r   s     r   rJ   rJ   .  s    ***AfQii***r      c                     d| | z  z
  dz  S )Nr
   r<   r"   r   s    r   rU   rU   /  s    q1u6F r   )rT   )rD   rQ   )r   rh   )rD   N)Sr!   scipyr   r   r   numpyr   r(   r   r   r$   r*   r=   r   r?   r4   rN   rg   rn   rp   r   r   examplesnobsmatplotlib.pyplotpyplotplt%statsmodels.distributions.mixture_rvsr   r   dictmix_kwdsnormobs_distmixf_hatgridr   r^   f_hat0trapzfintprintr   r   doplothistplotshow	enumeraterH   r   rd   rS   r]   r   dopr   r   xfr   dopintpdfmpdffiguretitlery   abseyerL   hpolysinnastypeintr/   r7   r-   htpolysinntpolyscrediagr"   r   r   <module>r      s\
  $ $J , + + + + + + + + +     rwr{{9 9 9 9 9 9 9 92B B B B B B B B4O O O O O O O O@ 
q# # # # # # # #*   5 5 5 5p4 4 4 4vw$ w$ w$ w$ w$ w$ w$ w$v% % % %. z///HD######R R R R R R R R B'''(<(<(<=H{D;TUZ8P"$ $ $H



C
 H Xb[XaZ89#= &7%6xSU]a%b%b%b"tVUyud++mUYY[[)))$	t,,gtU###  	CHXBt5AAAACHT5Qg6666CHT6as3333CHJJJ9U2A2Y'' 	I 	ICAa!	%),, I I"a.).)=)=r!DDQGHHHHI  	; 	;AE.).!2!2Bq99::::
 8  $$Xz$DDr{8<<>>8<<>>::SYY1cj111!4'''wwtd4[
EJ/G"  $ $  	5CJLLLCHXBt5AAAACHT2!73333CHT4AW5555CI3444 H  gghbg11r{8<<>>8<<>>::SYY1cj111!4'''wwtd4[
EJ/G"  $ $  	6CJLLLCHXBt5AAAACI1222CHT2!73333CHT4AW5555 	fbfVRVJJsy!}a;;A>q		IJJKKLLLH  gghRg00r{8<<>>8<<>>::SYY1cj111!4'''wwtd4[
EJ/G"  $ $  	CJLLLCHXBt5AAAACHT2!73333CHT4AW5555CI1222CHJJJ 	fbfVRVJJsy!}a;;A>q		IJJKKLLL
 *)a)))F
*VR
#
#A
&C	E&"&fbfQii((
)
)***	E3v:

c
"
"###--------,,5588,,,G:gsB''*D	E4;

s
#
#$$$**q***F:fb!,F,FGGGDAq	E&"&GBGGBGAJJ///00
1
122222_ r   