U
    Ãmœd'  ã                   @   sn   d Z ddlZddlmZ ddlZddlZddlm	Z	 ddl
mZ ddlmZ G dd	„ d	e	ƒZG d
d„ dƒZdS )z4Canonical correlation analysis

author: Yichuan Liu
é    N)Úsvd)ÚModel)Úsummary2é   )Úmultivariate_statsc                       s4   e Zd ZdZd‡ fdd„	Zddd„Zd	d
„ Z‡  ZS )ÚCanCorraœ  
    Canonical correlation analysis using singular value decomposition

    For matrices exog=x and endog=y, find projections x_cancoef and y_cancoef
    such that:

        x1 = x * x_cancoef, x1' * x1 is identity matrix
        y1 = y * y_cancoef, y1' * y1 is identity matrix

    and the correlation between x1 and y1 is maximized.

    Attributes
    ----------
    endog : ndarray
        See Parameters.
    exog : ndarray
        See Parameters.
    cancorr : ndarray
        The canonical correlation values
    y_cancoeff : ndarray
        The canonical coefficients for endog
    x_cancoeff : ndarray
        The canonical coefficients for exog

    References
    ----------
    .. [*] http://numerical.recipes/whp/notes/CanonCorrBySVD.pdf
    .. [*] http://www.csun.edu/~ata20315/psy524/docs/Psy524%20Lecture%208%20CC.pdf
    .. [*] http://www.mathematica-journal.com/2014/06/canonical-correlation-analysis/
    ç:Œ0âŽyE>ÚnoneNc                    s.   t t| ƒj||f||dœ|—Ž |  |¡ d S )N)ÚmissingÚhasconst)Úsuperr   Ú__init__Ú_fit)ÚselfÚendogÚexogÚ	tolerancer
   r   Úkwargs©Ú	__class__© úY/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/multivariate/cancorr.pyr   0   s    ÿÿzCanCorr.__init__c                    sv  | j j\}}| jj\}}t ||g¡}t | j¡}|| d¡ }t | j ¡}|| d¡ }t|dƒ\}}	}
|
j}|	|k}| 	¡ t
|ƒk r�tdƒ‚|dd…|f  |	|   < t|dƒ\}}}|j}||k}| 	¡ t
|ƒk râtdƒ‚|dd…|f  ||   < t|j |¡dƒ\}‰ }t ‡ fdd„tt
ˆ ƒƒD ƒ¡| _| |dd…d|…f ¡| _| |jdd…d|…f ¡| _dS )a=  Fit the model

        A ValueError is raised if there are singular values smaller than the
        tolerance. The treatment of singular arrays might change in future.

        Parameters
        ----------
        tolerance : float
            eigenvalue tolerance, values smaller than which is considered 0
        r   zexog is collinear.Nzendog is collinear.c                    s    g | ]}t d tˆ | dƒƒ‘qS )r   r   )ÚmaxÚmin)Ú.0Úi©Úsr   r   Ú
<listcomp>Z   s     z CanCorr._fit.<locals>.<listcomp>)r   Úshaper   Únpr   ÚarrayZmeanr   ÚTÚsumÚlenÚ
ValueErrorÚdotÚrangeÚcancorrZ	x_cancoefZ	y_cancoef)r   r   ÚnobsÚk_yvarÚk_xvarÚkÚxÚyZuxÚsxZvxZvx_dsÚmaskZuyZsyZvyZvy_dsÚuÚvr   r   r   r   5   s.    "zCanCorr._fitc                 C   sö  | j j\}}| jj\}}t | jd¡}tjddddddgtt	t
|ƒd d	d	ƒƒd
�}d}t	t
|ƒd d	d	ƒD �]B}|d||  9 }|| }|| }	|| d ||	 d d  }
||	 d d }||	 }|d |	d  d dk�rt ||	 d d |d |	d  d  ¡}nd}|
| d|  }t |d| ¡}d| | | | }| j| |j|df< ||j|df< ||j|df< ||j|df< ||j|df< tjj |||¡}||j|df< ql|jjddd	… }|j|dd…f }t||||| d ƒ}t||ƒS )aI  Approximate F test
        Perform multivariate statistical tests of the hypothesis that
        there is no canonical correlation between endog and exog.
        For each canonical correlation, testing its significance based on
        Wilks' lambda.

        Returns
        -------
        CanCorrTestResults instance
        é   zCanonical CorrelationzWilks' lambdazNum DFzDen DFzF ValuezPr > Fr   éÿÿÿÿ)ÚcolumnsÚindexé   é   r   N)r   r   r   r    Úpowerr(   ÚpdZ	DataFrameÚlistr'   r$   ÚsqrtÚlocÚscipyÚstatsÚfZsfr6   Úvaluesr   ÚCanCorrTestResults)r   r)   r*   r+   Z	eigenvalsr?   Úprodr   ÚpÚqÚrr1   Zdf1ÚtZdf2ZlmdÚFZpvalÚindÚstats_mvr   r   r   Ú	corr_test_   sR       ÿþ,
  
ÿzCanCorr.corr_test)r   r	   N)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   rK   Ú__classcell__r   r   r   r   r      s   
*r   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	rB   zÿ
    Canonical correlation results class

    Attributes
    ----------
    stats : DataFrame
        Contain statistical tests results for each canonical correlation
    stats_mv : DataFrame
        Contain the multivariate statistical tests results
    c                 C   s   || _ || _d S ©N)r?   rJ   )r   r?   rJ   r   r   r   r   ¤   s    zCanCorrTestResults.__init__c                 C   s   |   ¡  ¡ S rQ   )ÚsummaryÚ__str__)r   r   r   r   rS   ¨   s    zCanCorrTestResults.__str__c                 C   sJ   t  ¡ }| d¡ | | j¡ | ddi¡ | ddi¡ | | j¡ |S )NzCancorr resultsÚ z,Multivariate Statistics and F Approximations)r   ÚSummaryZ	add_titleZadd_dfr?   Zadd_dictrJ   )r   Zsummr   r   r   rR   «   s    
zCanCorrTestResults.summaryN)rL   rM   rN   rO   r   rS   rR   r   r   r   r   rB   ™   s   
rB   )rO   Únumpyr    Znumpy.linalgr   r>   Zpandasr:   Zstatsmodels.base.modelr   Zstatsmodels.iolibr   Zmultivariate_olsr   r   rB   r   r   r   r   Ú<module>   s    	