o
    þ0Gf(O  ã                   @   sà   d dl Z d dlZd dlZd dlmZ d dlm  m	Z
 d dlmZ G dd„ dejƒZG dd„ deƒZG dd	„ d	eƒZG d
d„ deƒZG dd„ dejƒZG dd„ de
jƒZe
 ee¡ dd„ ZG dd„ deƒZeZeZeZeZdS )é    N)Úmodel)ÚConvergenceWarningc                       ó(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )Ú_DimReductionRegressionzB
    A base class for dimension reduction regression methods.
    c                    s   t ƒ j||fi |¤Ž d S ©N)ÚsuperÚ__init__©ÚselfÚendogÚexogÚkwargs©Ú	__class__© ú=lib/python3.10/site-packages/statsmodels/regression/dimred.pyr      s   z _DimReductionRegression.__init__c                 C   s€   t  | j¡}| j|d d …f }|| d¡8 }t  |j|¡|jd  }t j 	|¡}t j 
||j¡j}|| _|| _t  ||¡| _d S ©Nr   )ÚnpÚargsortr   r   ÚmeanÚdotÚTÚshapeÚlinalgZcholeskyÚsolveÚwexogÚ_covxrÚarray_splitÚ_split_wexog)r
   Ún_sliceÚiiÚxÚcovxZcovxrr   r   r   Ú_prep   s   z_DimReductionRegression._prep)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r#   Ú__classcell__r   r   r   r   r      s    r   c                   @   s8   e Zd ZdZddd„Zdd„ Zdd„ Z		ddd„Zd
S )ÚSlicedInverseRega0  
    Sliced Inverse Regression (SIR)

    Parameters
    ----------
    endog : array_like (1d)
        The dependent variable
    exog : array_like (2d)
        The covariates

    References
    ----------
    KC Li (1991).  Sliced inverse regression for dimension reduction.
    JASA 86, 316-342.
    é   c                 K   sê   t |ƒdkrd}t |¡ | jjd | }|  |¡ dd„ | jD ƒ}dd„ | jD ƒ}t |¡}t |¡}t 	|j
|dd…df | ¡| ¡  }tj |¡\}}	t | ¡}
||
 }|	dd…|
f }	tj | jj
|	¡}t| ||d}t|ƒS )zÄ
        Estimate the EDR space using Sliced Inverse Regression.

        Parameters
        ----------
        slice_n : int, optional
            Target number of observations per slice
        r   z1SIR.fit does not take any extra keyword argumentsc                 S   ó   g | ]}|  d ¡‘qS ©r   ©r   ©Ú.0Úzr   r   r   Ú
<listcomp>J   ó    z(SlicedInverseReg.fit.<locals>.<listcomp>c                 S   ó   g | ]}|j d  ‘qS r,   ©r   r.   r   r   r   r1   K   r2   N©Úeigs)ÚlenÚwarningsÚwarnr   r   r#   r   r   Úasarrayr   r   Úsumr   Úeighr   r   r   ÚDimReductionResultsÚDimReductionResultsWrapper)r
   Úslice_nr   Úmsgr   ÚmnÚnZmncÚaÚbÚjjÚparamsÚresultsr   r   r   Úfit6   s"   



&zSlicedInverseReg.fitc                 C   sÆ   | j }| j}| j}| j}d}t ||| jf¡}t| jƒD ]}t | j	|d d …|f ¡}|t 
|| ¡7 }qt ||¡}	tj |	¡\}
}t |
t |
j|j¡¡}|j| }|t |||  
d¡¡7 }|S r   )Úk_varsÚ_covxÚ_slice_meansÚ_slice_propsr   ÚreshapeÚndimÚranger   Úpen_matr;   r   Zqrr   )r
   ÚAÚpr"   rA   ÚphÚvÚkÚuÚcovxaÚqÚ_ZqdZqur   r   r   Ú_regularized_objective[   s   
z'SlicedInverseReg._regularized_objectivec                 C   s:  | j }| j}| j}| j}| j}| j}| ||f¡}dt | j	j
t | j	|¡¡ }| ||f¡}t ||¡}	t ||	¡}
t |	j
|	¡}tj |¡}t ||f¡}tj ||	j
¡}d g||  }t|ƒD ][}t|ƒD ]T}|d9 }d|||f< t |
j
|¡}||j
7 }t |t ||¡¡ }t t ||¡|¡}|t |	t ||	j
¡¡7 }|t |	tj |t |j
|¡¡¡7 }|||| | < qhqbtj |t |	j
|j
¡¡}|t |	|¡j
 }t|ƒD ]@}||d d …f }||d d …f }t|ƒD ])}t|ƒD ]"}t |t ||| |  |¡¡}|||f  d||  | 8  < qôqîqØ| ¡ S )Né   r   é   )rI   rN   rJ   r   rK   rL   rM   r   r   rP   r   r   ÚinvÚzerosr   rO   Úravel)r
   rQ   rR   rN   r"   r   rA   rS   ZgrrW   Zcovx2aÚQZQiZjmZqcvZftrX   ÚrZumatZfmatZchZcuÚirV   rT   Úfr   r   r   Ú_regularized_grads   sP   
$÷ "þÿz"SlicedInverseReg._regularized_gradr\   Néd   çü©ñÒMbP?c                 K   sº  t |ƒdkrd}t |¡ |du rtdƒ‚| dd¡}| dd¡}| jjd | }	t | j	¡}
| j|
dd…f }|| 
d¡8 }t |j¡}t ||	¡}dd	„ |D ƒ}d
d	„ |D ƒ}t |¡}t |¡}|| ¡  | _|| _|jd | _|| _|| _|	| _|| _|du r›t | j|f¡}t |¡|d|…d|…f< |}n|jd |kr¨d}t|ƒ‚|}t|| j| j||ƒ\}}}|sÒ|  | ¡ ¡}t t ||¡¡}d| }t |¡ t| |dd}t |ƒS )a©  
        Estimate the EDR space using regularized SIR.

        Parameters
        ----------
        ndim : int
            The number of EDR directions to estimate
        pen_mat : array_like
            A 2d array such that the squared Frobenius norm of
            `dot(pen_mat, dirs)`` is added to the objective function,
            where `dirs` is an orthogonal array whose columns span
            the estimated EDR space.
        slice_n : int, optional
            Target number of observations per slice
        maxiter :int
            The maximum number of iterations for estimating the EDR
            space.
        gtol : float
            If the norm of the gradient of the objective function
            falls below this value, the algorithm has converged.

        Returns
        -------
        A results class instance.

        Notes
        -----
        If each row of `exog` can be viewed as containing the values of a
        function evaluated at equally-spaced locations, then setting the
        rows of `pen_mat` to [[1, -2, 1, ...], [0, 1, -2, 1, ..], ...]
        will give smooth EDR coefficients.  This is a form of "functional
        SIR" using the squared second derivative as a penalty.

        References
        ----------
        L. Ferre, A.F. Yao (2003).  Functional sliced inverse regression
        analysis.  Statistics: a journal of theoretical and applied
        statistics 37(6) 475-488.
        r   z3SIR.fit_regularized does not take keyword argumentsNzpen_mat is a required argumentÚstart_paramsr?   r*   c                 S   r+   r,   r-   r.   r   r   r   r1   å   r2   z4SlicedInverseReg.fit_regularized.<locals>.<listcomp>c                 S   r3   r,   r4   r.   r   r   r   r1   æ   r2   r\   z1Shape of start_params is not compatible with ndimz,SIR.fit_regularized did not converge, |g|=%fr5   )!r7   r8   r9   Ú
ValueErrorÚgetr   r   r   r   r   r   Úcovr   r   r:   r;   rL   rN   rI   rP   rJ   r   rK   r^   ÚeyeÚ
_grass_optrZ   rd   r_   Úsqrtr   r=   r>   )r
   rN   rP   r?   ÚmaxiterÚgtolr   r@   rg   r   r    r!   r"   Z
split_exogrA   rB   rF   rY   ÚcnvrgÚgÚgnrG   r   r   r   Úfit_regularized¢   sT   *



ÿ
z SlicedInverseReg.fit_regularized)r*   )r\   Nr*   re   rf   )r$   r%   r&   r'   rH   rZ   rd   rs   r   r   r   r   r)   %   s    
%/ÿr)   c                   @   s   e Zd ZdZdd„ ZdS )ÚPrincipalHessianDirectionsa  
    Principal Hessian Directions (PHD)

    Parameters
    ----------
    endog : array_like (1d)
        The dependent variable
    exog : array_like (2d)
        The covariates

    Returns
    -------
    A model instance.  Call `fit` to obtain a results instance,
    from which the estimated parameters can be obtained.

    References
    ----------
    KC Li (1992).  On Principal Hessian Directions for Data
    Visualization and Dimension Reduction: Another application
    of Stein's lemma. JASA 87:420.
    c                 K   sØ   |  dd¡}| j| j ¡  }| j| j d¡ }|r)ddlm} |||ƒ ¡ }|j}t 	d|||¡}|t
|ƒ }t |j¡}tj ||¡}	tj |	¡\}
}t t |
¡ ¡}|
| }
|dd…|f }t| ||
d}t|ƒS )aŸ  
        Estimate the EDR space using PHD.

        Parameters
        ----------
        resid : bool, optional
            If True, use least squares regression to remove the
            linear relationship between each covariate and the
            response, before conducting PHD.

        Returns
        -------
        A results instance which can be used to access the estimated
        parameters.
        ÚresidFr   )ÚOLSzi,ij,ik->jkNr5   )ri   r   r   r   Z#statsmodels.regression.linear_modelrv   rH   ru   r   Zeinsumr7   rj   r   r   r   Zeigr   Úabsr=   r>   )r
   r   ru   Úyr!   rv   ra   ÚcmZcxÚcbrC   rD   rE   rF   rG   r   r   r   rH     s"   zPrincipalHessianDirections.fitN)r$   r%   r&   r'   rH   r   r   r   r   rt     s    rt   c                       r   )ÚSlicedAverageVarianceEstimationa]  
    Sliced Average Variance Estimation (SAVE)

    Parameters
    ----------
    endog : array_like (1d)
        The dependent variable
    exog : array_like (2d)
        The covariates
    bc : bool, optional
        If True, use the bias-corrected CSAVE method of Li and Zhu.

    References
    ----------
    RD Cook.  SAVE: A method for dimension reduction and graphics
    in regression.
    http://www.stat.umn.edu/RegGraph/RecentDev/save.pdf

    Y Li, L-X Zhu (2007). Asymptotics for sliced average
    variance estimation.  The Annals of Statistics.
    https://arxiv.org/pdf/0708.0462.pdf
    c                    sF   t t| ƒj||fi |¤Ž d| _d|v r|d du r!d| _d S d S d S )NFÚbcT)r   ÚSAVEr   r|   r	   r   r   r   r   a  s
   
ÿz(SlicedAverageVarianceEstimation.__init__c                 K   s  |  dd¡}| jjd | }|  |¡ dd„ | jD ƒ}dd„ | jD ƒ}| jjd }| jsPd}t||ƒD ]\}}	t 	|¡|	 }
||t 
|
|
¡ 7 }q3|t|ƒ }n„d}|D ]
}|t 
||¡7 }qT|t|ƒ }d}| jD ])}|| d¡ }t|jd ƒD ]}||dd…f }t ||¡}|t 
||¡7 }qzqj|| jjd  }t |¡}||d  |d d	 d  }|d |d d	 d  }|| ||  }t 	|¡d	t|ƒ t|ƒ  | }tj |¡\}}t | ¡}|| }|dd…|f }tj | jj|¡}t| ||d
}t|ƒS )z“
        Estimate the EDR space.

        Parameters
        ----------
        slice_n : int
            Number of observations per slice
        r?   é2   r   c                 S   s   g | ]}t  |j¡‘qS r   )r   rj   r   r.   r   r   r   r1   z  s    z7SlicedAverageVarianceEstimation.fit.<locals>.<listcomp>c                 S   r3   r,   r4   r.   r   r   r   r1   {  r2   r\   Nr[   r5   )ri   r   r   r#   r   r   r|   Úzipr   rk   r   r7   r   rO   Zouterr;   r   r<   r   r   r   r   r=   r>   )r
   r   r?   r   ZcvÚnsrR   ZvmÚwZcvxZicvÚavÚcZvnr!   ra   rb   rV   ÚmZk1Zk2Zav2rC   rD   rE   rF   rG   r   r   r   rH   h  sJ   

ý
"z#SlicedAverageVarianceEstimation.fit)r$   r%   r&   r'   r   rH   r(   r   r   r   r   r{   I  s    r{   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )r=   aV  
    Results class for a dimension reduction regression.

    Notes
    -----
    The `params` attribute is a matrix whose columns span
    the effective dimension reduction (EDR) space.  Some
    methods produce a corresponding set of eigenvalues
    (`eigs`) that indicate how much information is contained
    in each basis direction.
    c                    s   t ƒ  ||¡ || _d S r   )r   r   r6   )r
   r   rF   r6   r   r   r   r   ·  s   ÿ
zDimReductionResults.__init__)r$   r%   r&   r'   r   r(   r   r   r   r   r=   ª  s    r=   c                   @   s   e Zd ZddiZeZdS )r>   rF   ÚcolumnsN)r$   r%   r&   Ú_attrsZ_wrap_attrsr   r   r   r   r>   ½  s    ÿr>   c                    s  | j \}}|  ¡ } || ƒ}d}t|ƒD ]n}	|| ƒ}
|
t |
| ¡|  t | | ¡ 8 }
t t |
|
 ¡¡|k r9d} nI|
 ||f¡}tj 	|d¡\‰‰‰|  ||f¡}t |ˆj
¡‰ ‡ ‡‡‡fdd„}d}|dkr|| ƒ}||ƒ}||k ry|} |}n|d }|dksgq|  ||f¡} | ||fS )	a  
    Minimize a function on a Grassmann manifold.

    Parameters
    ----------
    params : array_like
        Starting value for the optimization.
    fun : function
        The function to be minimized.
    grad : function
        The gradient of fun.
    maxiter : int
        The maximum number of iterations.
    gtol : float
        Convergence occurs when the gradient norm falls below this value.

    Returns
    -------
    params : array_like
        The minimizing value for the objective function.
    fval : float
        The smallest achieved value of the objective function.
    cnvrg : bool
        True if the algorithm converged to a limit point.

    Notes
    -----
    `params` is 2-d, but `fun` and `grad` should take 1-d arrays
    `params.ravel()` as arguments.

    Reference
    ---------
    A Edelman, TA Arias, ST Smith (1998).  The geometry of algorithms with
    orthogonality constraints. SIAM J Matrix Anal Appl.
    http://math.mit.edu/~edelman/publications/geometry_of_algorithms.pdf
    FTr   c                    s4   ˆ t  ˆ|  ¡ ˆt  ˆ|  ¡  }t  |ˆ¡ ¡ S r   )r   ZcosZsinr   r_   )ÚtÚpa©Zpa0ÚsrV   Zvtr   r   Úgeo  s   $z_grass_opt.<locals>.geog       @g»½×Ùß|Û=r[   )r   r_   rO   r   r   rm   r;   rM   r   Zsvdr   )rF   ZfunZgradrn   ro   rR   ÚdZf0rp   rY   rq   ZgmZparamsmr‹   Ústeprˆ   Úf1r   r‰   r   rl   Ç  s8   
& 
ù€	
rl   c                       s:   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zddd„Z‡  ZS )ÚCovarianceReductiona/  
    Dimension reduction for covariance matrices (CORE).

    Parameters
    ----------
    endog : array_like
        The dependent variable, treated as group labels
    exog : array_like
        The independent variables.
    dim : int
        The dimension of the subspace onto which the covariance
        matrices are projected.

    Returns
    -------
    A model instance.  Call `fit` on the model instance to obtain
    a results instance, which contains the fitted model parameters.

    Notes
    -----
    This is a likelihood-based dimension reduction procedure based
    on Wishart models for sample covariance matrices.  The goal
    is to find a projection matrix P so that C_i | P'C_iP and
    C_j | P'C_jP are equal in distribution for all i, j, where
    the C_i are the within-group covariance matrices.

    The model and methodology are as described in Cook and Forzani.
    The optimization method follows Edelman et. al.

    References
    ----------
    DR Cook, L Forzani (2008).  Covariance reducing models: an alternative
    to spectral modeling of covariance matrices.  Biometrika 95:4.

    A Edelman, TA Arias, ST Smith (1998).  The geometry of algorithms with
    orthogonality constraints. SIAM J Matrix Anal Appl.
    http://math.mit.edu/~edelman/publications/geometry_of_algorithms.pdf
    c                    sº   t ƒ  ||¡ g g }}tj| j| jd}| |j¡D ]\}}| | 	¡ j
¡ | |jd ¡ qt|ƒ| _d}	t|ƒD ]\}
}|	||
 ||
  7 }	q;|	| j }	|	| _|| _|| _|| _d S )N)Úindexr   )r   r   ÚpdZ	DataFramer   r   Úgroupbyr   Úappendrj   Úvaluesr   r7   ÚnobsÚ	enumerateÚcovmÚcovsr€   Údim)r
   r   r   r™   r˜   r€   ZdfrY   rT   r—   rb   r   r   r   r   @  s   



zCovarianceReduction.__init__c           	      C   s¦   | j jd }| || jf¡}t |jt | j |¡¡}tj |¡\}}| j	| d }t
| jƒD ]"\}}t |jt ||¡¡}tj |¡\}}|| j| | d 8 }q.|S )zô
        Evaluate the log-likelihood

        Parameters
        ----------
        params : array_like
            The projection matrix used to reduce the covariances, flattened
            to 1d.

        Returns the log-likelihood.
        r   r[   )r—   r   rM   r™   r   r   r   r   Zslogdetr•   r–   r˜   r€   )	r
   rF   rR   Úprojrƒ   rY   Zldetrc   Újr   r   r   ÚloglikeW  s   zCovarianceReduction.loglikec           	      C   s¸   | j jd }| || jf¡}t |jt | j |¡¡}t | j |¡}| jtj 	||j¡j }t
| jƒD ]%\}}t |jt ||¡¡}t ||¡}|| j| tj 	||j¡j 8 }q2| ¡ S )a  
        Evaluate the score function.

        Parameters
        ----------
        params : array_like
            The projection matrix used to reduce the covariances,
            flattened to 1d.

        Returns the score function evaluated at 'params'.
        r   )r—   r   rM   r™   r   r   r   r•   r   r   r–   r˜   r€   r_   )	r
   rF   rR   rš   Zc0ZcPrq   r›   rƒ   r   r   r   Úscorer  s   "zCovarianceReduction.scoreNéÈ   ç-Cëâ6?c                    sÐ   ˆ j jd }ˆ j}|du r$t ||f¡}t |¡|d|…d|…f< |}n|}t|‡ fdd„‡ fdd„||ƒ\}}}|d9 }|sZˆ  | ¡ ¡}	t 	t 
|	|	 ¡¡}
d|
 }t |t¡ tˆ |dd}||_t|ƒS )	aö  
        Fit the covariance reduction model.

        Parameters
        ----------
        start_params : array_like
            Starting value for the projection matrix. May be
            rectangular, or flattened.
        maxiter : int
            The maximum number of gradient steps to take.
        gtol : float
            Convergence criterion for the gradient norm.

        Returns
        -------
        A results instance that can be used to access the
        fitted parameters.
        r   Nc                    ó   ˆ   | ¡ S r   )rœ   ©r!   ©r
   r   r   Ú<lambda>®  ó    z)CovarianceReduction.fit.<locals>.<lambda>c                    r    r   )r   r¡   r¢   r   r   r£   ¯  r¤   éÿÿÿÿz/CovReduce optimization did not converge, |g|=%fr5   )r—   r   r™   r   r^   rk   rl   r   r_   rm   r;   r8   r9   r   r=   Úllfr>   )r
   rg   rn   ro   rR   rŒ   rF   r¦   rp   rq   rr   r@   rG   r   r¢   r   rH     s(   
þzCovarianceReduction.fit)Nrž   rŸ   )	r$   r%   r&   r'   r   rœ   r   rH   r(   r   r   r   r   r     s    'r   )r8   Znumpyr   Zpandasr‘   Zstatsmodels.baser   Zstatsmodels.base.wrapperÚbaseÚwrapperÚwrapZstatsmodels.tools.sm_exceptionsr   ZModelr   r)   rt   r{   ZResultsr=   ZResultsWrapperr>   Zpopulate_wrapperrl   r   ZSIRZPHDr}   ZCOREr   r   r   r   Ú<module>   s.     dAaÿQ '