U
    KvfwO  ã                   @   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                       s(   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 t| ƒj||f|Ž d S ©N)Úsuperr   Ú__init__©ÚselfÚendogÚexogÚkwargs©Ú	__class__© úA/tmp/pip-unpacked-wheel-2v6byqio/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                   @   s4   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   s   g | ]}|  d ¡‘qS ©r   ©r   ©Ú.0Úzr   r   r   Ú
<listcomp>J   s     z(SlicedInverseReg.fit.<locals>.<listcomp>c                 S   s   g | ]}|j d  ‘qS r*   ©r   r,   r   r   r   r/   K   s     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 ]0}t | j	|d d …|f ¡}|t 
|| ¡7 }q8t ||¡}	tj |	¡\}
}t |
t |
j|j¡¡}|j| }|t |||  
d¡¡7 }|S r   )Úk_varsÚ_covxÚ_slice_meansÚ_slice_propsr   ÚreshapeÚndimÚranger   Úpen_matr7   r   Zqrr   )r	   ÚAÚpr!   r=   Ú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 ]¨}|d9 }d|||f< t |
j
|¡}||j
7 }t |t ||¡¡ }t t ||¡|¡}|t |	t ||	j
¡¡7 }|t |	tj |t |j
|¡¡¡7 }|||| | < qÐqÄtj |t |	j
|j
¡¡}|t |	|¡j
 }t|ƒD ]†}||d d …f }||d d …f }t|ƒD ]V}t|ƒD ]F}t |t ||| |  |¡¡}|||f  d||  | 8  < qèqÜq°| ¡ S )Né   r   é   )rE   rJ   rF   r   rG   rH   rI   r   r   rL   r   r   ÚinvÚzerosr   rK   Úravel)r	   rM   rN   rJ   r!   r   r=   rO   ZgrrS   Zcovx2aÚQZQiZjmZqcvÚftrT   ÚrZumatZfmatÚchZcuÚirR   rP   Úfr   r   r   Ú_regularized_grads   sJ    
$ ,z"SlicedInverseReg._regularized_gradrX   Néd   çü©ñÒMbP?c                 K   sÀ  t |ƒdkrd}t |¡ |dk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kr8t | j|f¡}t |¡|d|…d|…f< |}n |jd |krTd}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   s   g | ]}|  d ¡‘qS r*   r+   r,   r   r   r   r/   å   s     z4SlicedInverseReg.fit_regularized.<locals>.<listcomp>c                 S   s   g | ]}|j d  ‘qS r*   r0   r,   r   r   r   r/   æ   s     rX   z1Shape of start_params is not compatible with ndimz,SIR.fit_regularized did not converge, |g|=%fr1   )!r3   r4   r5   Ú
ValueErrorÚgetr   r   r   r   r
   r   Úcovr   r   r6   r7   rH   rJ   rE   rL   rF   r   rG   rZ   ÚeyeÚ
_grass_optrV   rb   r[   Úsqrtr   r9   r:   )r	   rJ   rL   r;   ÚmaxiterÚgtolr   r<   re   r   r   r    r!   Z
split_exogr=   r>   rB   rU   ÚcnvrgÚgÚgnrC   r   r   r   Úfit_regularized¢   sX    *



  ÿ

z SlicedInverseReg.fit_regularized)r)   )rX   Nr)   rc   rd   )r#   r$   r%   r&   rD   rV   rb   rq   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¡ }|rRd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->jkNr1   )rg   r
   r   r   Z#statsmodels.regression.linear_modelrt   rD   rs   r   Zeinsumr3   rh   r   r   r   Zeigr   Úabsr9   r:   )r	   r   rs   Úyr    rt   r^   ÚcmZcxÚcbr?   r@   rA   rB   rC   r   r   r   rD     s"    zPrincipalHessianDirections.fitN)r#   r$   r%   r&   rD   r   r   r   r   rr     s   rr   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )Ú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                    s:   t t| ƒj||f|Ž d| _d|kr6|d dkr6d| _d S )NFÚbcT)r   ÚSAVEr   rz   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s¢d}t||ƒD ]*\}}	t 	|¡|	 }
||t 
|
|
¡ 7 }qf|t|ƒ }nd}|D ]}|t 
||¡7 }qª|t|ƒ }d}| jD ]R}|| d¡ }t|jd ƒD ]0}||dd…f }t ||¡}|t 
||¡7 }qöqÖ|| 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   rh   r   r,   r   r   r   r/   z  s     z7SlicedAverageVarianceEstimation.fit.<locals>.<listcomp>c                 S   s   g | ]}|j d  ‘qS r*   r0   r,   r   r   r   r/   {  s     rX   NrW   r1   )rg   r   r   r"   r   r   rz   Úzipr   ri   r   r3   r   rK   Úouterr7   r   r8   r   r   r   r   r9   r:   )r	   r   r;   r   ZcvÚnsrN   ZvmÚwZcvxZicvÚavÚcZvnr    r^   r`   rR   ÚmZk1Zk2Zav2r?   r@   rA   rB   rC   r   r   r   rD   h  sH    


"z#SlicedAverageVarianceEstimation.fit)r#   r$   r%   r&   r   rD   r'   r   r   r   r   ry   I  s   ry   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )r9   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 t| ƒ ||¡ || _d S r   )r   r9   r   r2   )r	   r   rB   r2   r   r   r   r   ·  s
    
 ÿzDimReductionResults.__init__)r#   r$   r%   r&   r   r'   r   r   r   r   r9   ª  s   r9   c                   @   s   e Zd ZddiZeZdS )r:   rB   ÚcolumnsN)r#   r$   r%   Ú_attrsZ_wrap_attrsr   r   r   r   r:   ½  s    ÿr:   c                    s  | j \}}|  ¡ } || ƒ}d}t|ƒD ]Ö}	|| ƒ}
|
t |
| ¡|  t | | ¡ 8 }
t t |
|
 ¡¡|k rrd} qþ|
 ||f¡}tj 	|d¡\‰‰‰|  ||f¡}t |ˆj
¡‰ ‡ ‡‡‡fdd„}d}|dkr&|| ƒ}||ƒ}||k rò|} |}q&|d }qÆq&|  ||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   ÚcosÚsinr   r[   )ÚtÚpa©Zpa0ÚsrR   Zvtr   r   Úgeo  s    $z_grass_opt.<locals>.geog       @g»½×Ùß|Û=rW   )r   r[   rK   r   r   rk   r7   rI   r   Zsvdr   )rB   ZfunZgradrl   rm   rN   ÚdZf0rn   rU   ro   ZgmZparamsmrŒ   Ústepr‰   Úf1r   rŠ   r   rj   Ç  s4    &
 
rj   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 t| ƒ ||¡ g g  }}tj| j| jd}| |j¡D ](\}}| 	| 
¡ j¡ | 	|jd ¡ q:t|ƒ| _d}	t|ƒD ]\}
}|	||
 ||
  7 }	qz|	| j }	|	| _|| _|| _|| _d S )N)Úindexr   )r   r   r   ÚpdZ	DataFramer   r
   Úgroupbyr‘   Úappendrh   Úvaluesr   r3   ÚnobsÚ	enumerateÚcovmÚcovsr   Údim)r	   r
   r   rš   r™   r   ZdfrU   rP   r˜   r`   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 ]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   rW   )r˜   r   rI   rš   r   r   r   r   Zslogdetr–   r—   r™   r   )	r	   rB   rN   Úprojr‚   rU   Zldetra   Ú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 ]J\}}t |jt ||¡¡}t ||¡}|| j| tj 	||j¡j 8 }qd| ¡ 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   rI   rš   r   r   r   r–   r   r   r—   r™   r   r[   )	r	   rB   rN   r›   Zc0ZcPro   rœ   r‚   r   r   r   Úscorer  s    "zCovarianceReduction.scoreNéÈ   ç-Cëâ6?c                    sÐ   ˆ j jd }ˆ j}|dkrHt ||f¡}t |¡|d|…d|…f< |}n|}t|‡ fdd„‡ fdd„||ƒ\}}}|d9 }|s´ˆ  | ¡ ¡}	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   ˆ   | ¡ S r   )r   ©r    ©r	   r   r   Ú<lambda>®  ó    z)CovarianceReduction.fit.<locals>.<lambda>c                    s   ˆ   | ¡ S r   )rž   r¡   r¢   r   r   r£   ¯  r¤   éÿÿÿÿz/CovReduce optimization did not converge, |g|=%fr1   )r˜   r   rš   r   rZ   ri   rj   rž   r[   rk   r7   r4   r5   r   r9   Úllfr:   )r	   re   rl   rm   rN   r   rB   r¦   rn   ro   rp   r<   rC   r   r¢   r   rD     s*    
 þ
zCovarianceReduction.fit)NrŸ   r    )	r#   r$   r%   r&   r   r   rž   rD   r'   r   r   r   r   r     s
   'r   )r4   Znumpyr   Zpandasr’   Zstatsmodels.baser   Zstatsmodels.base.wrapperÚbaseÚwrapperÚwrapZstatsmodels.tools.sm_exceptionsr   ZModelr   r(   rr   ry   ZResultsr9   ZResultsWrapperr:   Zpopulate_wrapperrj   r   ZSIRZPHDr{   ZCOREr   r   r   r   Ú<module>   s,    dAaÿQ '