U
    ½mœdš�  ã                
   @   sŒ  d Z ddlmZmZ ddlZddlmZmZ ddlZ	ddl
mZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZ ddlmZ ddlmZmZ ddlmZmZ ddl m!Z! dddgZ"eedƒkrðddl
m#Z$ nddl
m$Z$ dd„ Z%d.dd„Z&dd „ Z'd/d"d#„Z(d$d%„ Z)G d&d'„ d'eeeeeed(�Z*G d)d„ de*ƒZ+G d*d„ de*ƒZ,G d+d,„ d,e*ƒZ-G d-d„ deeeƒZ.dS )0zG
The :mod:`sklearn.pls` module implements Partial Least Squares (PLS).
é    )ÚIntegralÚRealN)ÚABCMetaÚabstractmethod)Úsvdé   )ÚBaseEstimatorÚRegressorMixinÚTransformerMixin)ÚMultiOutputMixin)ÚClassNamePrefixFeaturesOutMixin)Úcheck_arrayÚcheck_consistent_length)Ú
sp_version)Úparse_version)Úsvd_flip)Úcheck_is_fittedÚFLOAT_DTYPES)ÚIntervalÚ
StrOptions)ÚConvergenceWarningÚPLSCanonicalÚPLSRegressionÚPLSSVDz1.7)Úpinv)Úpinv2c              
   C   sš   t | ddd�\}}}|jj ¡ }dddœ}t |¡||  t |¡j }t ||k¡}|d d …d |…f }||d |…  }t 	t 
t ||d |… ¡¡¡S )NF)Úfull_matricesÚcheck_finiteg     @�@g    €„.A)ÚfÚd)r   ÚdtypeÚcharÚlowerÚnpÚmaxÚfinfoÚepsÚsumZ	transposeÚ	conjugateÚdot)ÚaÚuÚsZvhÚtÚfactorZcondZrank© r/   úY/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/sklearn/cross_decomposition/_pls.pyÚ
_pinv2_old&   s    
r1   ÚAéô  ç�íµ ÷Æ°>Fc              
      s¤  t  | j¡j‰ zt‡ fdd„|jD ƒƒ}W n, tk
rV } ztdƒ|‚W 5 d}~X Y nX d}|dkrvt| ƒt|ƒ }	}
t|ƒD ]ü}|dkr˜t  	|	|¡}nt  	| j|¡t  	||¡ }|t  
t  	||¡¡ˆ   }t  	| |¡}|dkrît  	|
|¡}nt  	|j|¡t  	|j|¡ }|�r*|t  
t  	||¡¡ˆ   }t  	||¡t  	||¡ˆ   }|| }t  	||¡|k �sp|jd dk�rv �q||}q~|d }||k�ršt dt¡ |||fS )	a?  Return the first left and right singular vectors of X'Y.

    Provides an alternative to the svd(X'Y) and uses the power method instead.
    With norm_y_weights to True and in mode A, this corresponds to the
    algorithm section 11.3 of the Wegelin's review, except this starts at the
    "update saliences" part.
    c                 3   s&   | ]}t  t  |¡ˆ k¡r|V  qd S ©N)r#   ÚanyÚabs)Ú.0Úcol©r&   r/   r0   Ú	<genexpr>E   s      z;_get_first_singular_vectors_power_method.<locals>.<genexpr>úY residual is constantNéd   ÚBé   z$Maximum number of iterations reached)r#   r%   r    r&   ÚnextÚTÚStopIterationr1   Úranger)   ÚsqrtÚshapeÚwarningsÚwarnr   )ÚXÚYÚmodeÚmax_iterÚtolÚnorm_y_weightsZy_scoreÚeZx_weights_oldZX_pinvZY_pinvÚiÚ	x_weightsZx_scoreÚ	y_weightsZx_weights_diffZn_iterr/   r:   r0   Ú(_get_first_singular_vectors_power_method8   s8    "
rR   c                 C   s@   t  | j|¡}t|dd�\}}}|dd…df |ddd…f fS )zbReturn the first left and right singular vectors of X'Y.

    Here the whole SVD is computed.
    F©r   Nr   )r#   r)   rA   r   )rH   rI   ÚCÚUÚ_ÚVtr/   r/   r0   Ú_get_first_singular_vectors_svds   s    rX   Tc                 C   s¢   | j dd�}| |8 } |j dd�}||8 }|rr| jddd�}d||dk< | | } |jddd�}d||dk< || }n t | jd ¡}t |jd ¡}| |||||fS )z{Center X, Y and scale if the scale parameter==True

    Returns
    -------
        X, Y, x_mean, y_mean, x_std, y_std
    r   ©Úaxisr?   )rZ   Zddofg      ð?ç        )ZmeanZstdr#   ZonesrE   )rH   rI   ÚscaleZx_meanZy_meanZx_stdZy_stdr/   r/   r0   Ú_center_scale_xy}   s    
r]   c                 C   s2   t  t  | ¡¡}t  | | ¡}| |9 } ||9 }dS )z7Same as svd_flip but works on 1d arrays, and is inplaceN)r#   Zargmaxr7   Úsign)r+   ÚvZbiggest_abs_val_idxr^   r/   r/   r0   Ú_svd_flip_1d—   s    r`   c                   @   sà   e Zd ZU dZeedddd�gdgeddhƒged	d
hƒgeddhƒgeedddd�geedddd�gdgdœZe	e
d< ed%ddd	dddddœdd„ƒZdd„ Zd&dd„Zd'dd„Zd(dd„Zd)dd „Zed!d"„ ƒZd#d$„ ZdS )*Ú_PLSa  Partial Least Squares (PLS)

    This class implements the generic PLS algorithm.

    Main ref: Wegelin, a survey of Partial Least Squares (PLS) methods,
    with emphasis on the two-block case
    https://stat.uw.edu/sites/default/files/files/reports/2000/tr371.pdf
    r?   NÚleft©ÚclosedÚbooleanÚ
regressionÚ	canonicalr2   r>   r   Únipalsr   ©Ún_componentsr\   Údeflation_moderJ   Ú	algorithmrK   rL   ÚcopyÚ_parameter_constraintsr   Tr3   r4   )r\   rk   rJ   rl   rK   rL   rm   c          	      C   s4   || _ || _|| _|| _|| _|| _|| _|| _d S r5   )rj   rk   rJ   r\   rl   rK   rL   rm   )	Úselfrj   r\   rk   rJ   rl   rK   rL   rm   r/   r/   r0   Ú__init__½   s    z_PLS.__init__c                 C   s  |   ¡  t||ƒ | j|tj| jdd�}t|dtj| jdd�}|jdkrT| dd¡}|j	d }|j	d }|j	d }| j
}| jd	kr†|n
t|||ƒ}||kr°td
|› d|› d�ƒ‚| jdk| _| j}t||| jƒ\}	}
| _| _| _| _t ||f¡| _t ||f¡| _t ||f¡| _t ||f¡| _t ||f¡| _t ||f¡| _g | _t |
j¡j}t |ƒD �]}| j!dk�r"tj"t #|
¡d| k dd�}d|
dd…|f< z$t$|	|
| j%| j&| j'|d�\}}}W nP t(k
�r } z0t)|ƒdk�ræ‚ t* +d|› �¡ W Y ¢
 �qzW 5 d}~X Y nX | j ,|¡ n| j!dk�r<t-|	|
ƒ\}}t.||ƒ t /|	|¡}|�r^d}nt /||¡}t /|
|¡| }t /||	¡t /||¡ }|	t 0||¡8 }	| jdk�rÖt /||
¡t /||¡ }|
t 0||¡8 }
| jd	k�r
t /||
¡t /||¡ }|
t 0||¡8 }
|| jdd…|f< || jdd…|f< || jdd…|f< || jdd…|f< || jdd…|f< || jdd…|f< �q`t /| jt1t /| jj2| j¡dd�¡| _3t /| jt1t /| jj2| j¡dd�¡| _4t /| j3| jj2¡| _5| j5| j j2| _5| j| _6| j3j	d | _7| S )á  Fit model to data.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Training vectors, where `n_samples` is the number of samples and
            `n_features` is the number of predictors.

        Y : array-like of shape (n_samples,) or (n_samples, n_targets)
            Target vectors, where `n_samples` is the number of samples and
            `n_targets` is the number of response variables.

        Returns
        -------
        self : object
            Fitted model.
        r   ©r    rm   Zensure_min_samplesrI   F©Ú
input_namer    rm   Ú	ensure_2dr?   éÿÿÿÿr   rf   ú`n_components` upper bound is ú. Got ú  instead. Reduce `n_components`.rg   rh   é
   rY   r[   N)rJ   rK   rL   rM   r<   z$Y residual is constant at iteration r   )r   )8Ú_validate_paramsr   Ú_validate_datar#   Úfloat64rm   r   ÚndimÚreshaperE   rj   rk   ÚminÚ
ValueErrorZ_norm_y_weightsr]   r\   Ú_x_meanÚ_y_meanÚ_x_stdÚ_y_stdZzerosÚ
x_weights_Ú
y_weights_Ú	_x_scoresÚ	_y_scoresÚx_loadings_Úy_loadings_Ún_iter_r%   r    r&   rC   rl   Úallr7   rR   rJ   rK   rL   rB   ÚstrrF   rG   ÚappendrX   r`   r)   Úouterr   rA   Úx_rotations_Úy_rotations_Ú_coef_Ú
intercept_Ú_n_features_out)ro   rH   rI   ÚnÚpÚqrj   Úrank_upper_boundrM   ZXkZYkZY_epsÚkZYk_maskrP   rQ   rŒ   rN   Úx_scoresZy_ssÚy_scoresZ
x_loadingsZ
y_loadingsr/   r/   r0   ÚfitÓ   sÈ    
   ÿ    ÿ



ÿ  ÿúüý
	þþz_PLS.fitc                 C   sš   t | ƒ | j||tdd�}|| j8 }|| j }t || j¡}|dk	r–t|dd|td�}|j	dkrl| 
dd¡}|| j8 }|| j }t || j¡}||fS |S )a.  Apply the dimension reduction.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Samples to transform.

        Y : array-like of shape (n_samples, n_targets), default=None
            Target vectors.

        copy : bool, default=True
            Whether to copy `X` and `Y`, or perform in-place normalization.

        Returns
        -------
        x_scores, y_scores : array-like or tuple of array-like
            Return `x_scores` if `Y` is not given, `(x_scores, y_scores)` otherwise.
        F©rm   r    ÚresetNrI   )rt   ru   rm   r    r?   rv   )r   r|   r   r‚   r„   r#   r)   r‘   r   r~   r   rƒ   r…   r’   )ro   rH   rI   rm   r›   rœ   r/   r/   r0   Ú	transformi  s(    

    ÿ


z_PLS.transformc                 C   s€   t | ƒ t|dtd�}t || jj¡}|| j9 }|| j7 }|dk	r|t|dtd�}t || j	j¡}|| j
9 }|| j7 }||fS |S )ae  Transform data back to its original space.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_components)
            New data, where `n_samples` is the number of samples
            and `n_components` is the number of pls components.

        Y : array-like of shape (n_samples, n_components)
            New target, where `n_samples` is the number of samples
            and `n_components` is the number of pls components.

        Returns
        -------
        X_reconstructed : ndarray of shape (n_samples, n_features)
            Return the reconstructed `X` data.

        Y_reconstructed : ndarray of shape (n_samples, n_targets)
            Return the reconstructed `X` target. Only returned when `Y` is given.

        Notes
        -----
        This transformation will only be exact if `n_components=n_features`.
        rH   )rt   r    NrI   )r   r   r   r#   ÚmatmulrŠ   rA   r„   r‚   r‹   r…   rƒ   )ro   rH   rI   ZX_reconstructedZY_reconstructedr/   r/   r0   Úinverse_transform�  s    



z_PLS.inverse_transformc                 C   sD   t | ƒ | j||tdd�}|| j8 }|| j }|| jj }|| j S )aU  Predict targets of given samples.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Samples.

        copy : bool, default=True
            Whether to copy `X` and `Y`, or perform in-place normalization.

        Returns
        -------
        y_pred : ndarray of shape (n_samples,) or (n_samples, n_targets)
            Returns predicted values.

        Notes
        -----
        This call requires the estimation of a matrix of shape
        `(n_features, n_targets)`, which may be an issue in high dimensional
        space.
        Frž   )r   r|   r   r‚   r„   r“   rA   r”   )ro   rH   rm   ZYpredr/   r/   r0   Úpredict¼  s    

z_PLS.predictc                 C   s   |   ||¡ ||¡S )a£  Learn and apply the dimension reduction on the train data.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Training vectors, where `n_samples` is the number of samples and
            `n_features` is the number of predictors.

        y : array-like of shape (n_samples, n_targets), default=None
            Target vectors, where `n_samples` is the number of samples and
            `n_targets` is the number of response variables.

        Returns
        -------
        self : ndarray of shape (n_samples, n_components)
            Return `x_scores` if `Y` is not given, `(x_scores, y_scores)` otherwise.
        ©r�   r    ©ro   rH   Úyr/   r/   r0   Úfit_transformÛ  s    z_PLS.fit_transformc                 C   s0   t | dƒr(t| ddƒr(t dt¡ d| _| jjS )z%The coefficients of the linear model.r“   Ú_coef_warningTzïThe attribute `coef_` will be transposed in version 1.3 to be consistent with other linear models in scikit-learn. Currently, `coef_` has a shape of (n_features, n_targets) and in the future it will have a shape of (n_targets, n_features).F)ÚhasattrÚgetattrrF   rG   ÚFutureWarningr¨   r“   rA   ©ro   r/   r/   r0   Úcoef_ï  s    ûz
_PLS.coef_c                 C   s
   dddœS )NTF)Z
poor_scoreZ
requires_yr/   r¬   r/   r/   r0   Ú
_more_tags  s    z_PLS._more_tags)r   )NT)N)T)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   rn   ÚdictÚ__annotations__r   rp   r�   r    r¢   r£   r§   Úpropertyr­   r®   r/   r/   r/   r0   ra   ¡   s<   

ø þö 
'
,


ra   )Ú	metaclassc                       s`   e Zd ZU dZej–Zeed< dD ]Ze 	e¡ q"ddddddœ‡ fd	d
„Z
‡ fdd„Z‡  ZS )r   a©  PLS regression.

    PLSRegression is also known as PLS2 or PLS1, depending on the number of
    targets.

    Read more in the :ref:`User Guide <cross_decomposition>`.

    .. versionadded:: 0.8

    Parameters
    ----------
    n_components : int, default=2
        Number of components to keep. Should be in `[1, min(n_samples,
        n_features, n_targets)]`.

    scale : bool, default=True
        Whether to scale `X` and `Y`.

    max_iter : int, default=500
        The maximum number of iterations of the power method when
        `algorithm='nipals'`. Ignored otherwise.

    tol : float, default=1e-06
        The tolerance used as convergence criteria in the power method: the
        algorithm stops whenever the squared norm of `u_i - u_{i-1}` is less
        than `tol`, where `u` corresponds to the left singular vector.

    copy : bool, default=True
        Whether to copy `X` and `Y` in :term:`fit` before applying centering,
        and potentially scaling. If `False`, these operations will be done
        inplace, modifying both arrays.

    Attributes
    ----------
    x_weights_ : ndarray of shape (n_features, n_components)
        The left singular vectors of the cross-covariance matrices of each
        iteration.

    y_weights_ : ndarray of shape (n_targets, n_components)
        The right singular vectors of the cross-covariance matrices of each
        iteration.

    x_loadings_ : ndarray of shape (n_features, n_components)
        The loadings of `X`.

    y_loadings_ : ndarray of shape (n_targets, n_components)
        The loadings of `Y`.

    x_scores_ : ndarray of shape (n_samples, n_components)
        The transformed training samples.

    y_scores_ : ndarray of shape (n_samples, n_components)
        The transformed training targets.

    x_rotations_ : ndarray of shape (n_features, n_components)
        The projection matrix used to transform `X`.

    y_rotations_ : ndarray of shape (n_features, n_components)
        The projection matrix used to transform `Y`.

    coef_ : ndarray of shape (n_features, n_targets)
        The coefficients of the linear model such that `Y` is approximated as
        `Y = X @ coef_ + intercept_`.

    intercept_ : ndarray of shape (n_targets,)
        The intercepts of the linear model such that `Y` is approximated as
        `Y = X @ coef_ + intercept_`.

        .. versionadded:: 1.1

    n_iter_ : list of shape (n_components,)
        Number of iterations of the power method, for each
        component.

    n_features_in_ : int
        Number of features seen during :term:`fit`.

    feature_names_in_ : ndarray of shape (`n_features_in_`,)
        Names of features seen during :term:`fit`. Defined only when `X`
        has feature names that are all strings.

        .. versionadded:: 1.0

    See Also
    --------
    PLSCanonical : Partial Least Squares transformer and regressor.

    Examples
    --------
    >>> from sklearn.cross_decomposition import PLSRegression
    >>> X = [[0., 0., 1.], [1.,0.,0.], [2.,2.,2.], [2.,5.,4.]]
    >>> Y = [[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]]
    >>> pls2 = PLSRegression(n_components=2)
    >>> pls2.fit(X, Y)
    PLSRegression()
    >>> Y_pred = pls2.predict(X)
    rn   ©rk   rJ   rl   r   Tr3   r4   ©r\   rK   rL   rm   c             
      s    t ƒ j||ddd|||d� d S )Nrf   r2   rh   ri   ©Úsuperrp   ©ro   rj   r\   rK   rL   rm   ©Ú	__class__r/   r0   rp   t  s    øzPLSRegression.__init__c                    s"   t ƒ  ||¡ | j| _| j| _| S )rq   )rº   r�   rˆ   Z	x_scores_r‰   Z	y_scores_)ro   rH   rI   r¼   r/   r0   r�   ‚  s    zPLSRegression.fit)r   )r¯   r°   r±   r²   ra   rn   r³   r´   ÚparamÚpoprp   r�   Ú__classcell__r/   r/   r¼   r0   r     s   
b	 ÿ   ÿc                       sV   e Zd ZU dZej–Zeed< dD ]Ze 	e¡ q"ddddddd	œ‡ fd
d„Z
‡  ZS )r   a¸  Partial Least Squares transformer and regressor.

    Read more in the :ref:`User Guide <cross_decomposition>`.

    .. versionadded:: 0.8

    Parameters
    ----------
    n_components : int, default=2
        Number of components to keep. Should be in `[1, min(n_samples,
        n_features, n_targets)]`.

    scale : bool, default=True
        Whether to scale `X` and `Y`.

    algorithm : {'nipals', 'svd'}, default='nipals'
        The algorithm used to estimate the first singular vectors of the
        cross-covariance matrix. 'nipals' uses the power method while 'svd'
        will compute the whole SVD.

    max_iter : int, default=500
        The maximum number of iterations of the power method when
        `algorithm='nipals'`. Ignored otherwise.

    tol : float, default=1e-06
        The tolerance used as convergence criteria in the power method: the
        algorithm stops whenever the squared norm of `u_i - u_{i-1}` is less
        than `tol`, where `u` corresponds to the left singular vector.

    copy : bool, default=True
        Whether to copy `X` and `Y` in fit before applying centering, and
        potentially scaling. If False, these operations will be done inplace,
        modifying both arrays.

    Attributes
    ----------
    x_weights_ : ndarray of shape (n_features, n_components)
        The left singular vectors of the cross-covariance matrices of each
        iteration.

    y_weights_ : ndarray of shape (n_targets, n_components)
        The right singular vectors of the cross-covariance matrices of each
        iteration.

    x_loadings_ : ndarray of shape (n_features, n_components)
        The loadings of `X`.

    y_loadings_ : ndarray of shape (n_targets, n_components)
        The loadings of `Y`.

    x_rotations_ : ndarray of shape (n_features, n_components)
        The projection matrix used to transform `X`.

    y_rotations_ : ndarray of shape (n_features, n_components)
        The projection matrix used to transform `Y`.

    coef_ : ndarray of shape (n_features, n_targets)
        The coefficients of the linear model such that `Y` is approximated as
        `Y = X @ coef_ + intercept_`.

    intercept_ : ndarray of shape (n_targets,)
        The intercepts of the linear model such that `Y` is approximated as
        `Y = X @ coef_ + intercept_`.

        .. versionadded:: 1.1

    n_iter_ : list of shape (n_components,)
        Number of iterations of the power method, for each
        component. Empty if `algorithm='svd'`.

    n_features_in_ : int
        Number of features seen during :term:`fit`.

    feature_names_in_ : ndarray of shape (`n_features_in_`,)
        Names of features seen during :term:`fit`. Defined only when `X`
        has feature names that are all strings.

        .. versionadded:: 1.0

    See Also
    --------
    CCA : Canonical Correlation Analysis.
    PLSSVD : Partial Least Square SVD.

    Examples
    --------
    >>> from sklearn.cross_decomposition import PLSCanonical
    >>> X = [[0., 0., 1.], [1.,0.,0.], [2.,2.,2.], [2.,5.,4.]]
    >>> Y = [[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]]
    >>> plsca = PLSCanonical(n_components=2)
    >>> plsca.fit(X, Y)
    PLSCanonical()
    >>> X_c, Y_c = plsca.transform(X, Y)
    rn   )rk   rJ   r   Trh   r3   r4   )r\   rl   rK   rL   rm   c             
      s    t ƒ j||dd||||d� d S )Nrg   r2   ri   r¹   )ro   rj   r\   rl   rK   rL   rm   r¼   r/   r0   rp     s    
øzPLSCanonical.__init__)r   ©r¯   r°   r±   r²   ra   rn   r³   r´   r¾   r¿   rp   rÀ   r/   r/   r¼   r0   r   ›  s   
_ þøc                       sT   e Zd ZU dZej–Zeed< dD ]Ze 	e¡ q"ddddddœ‡ fd	d
„Z
‡  ZS )ÚCCAap  Canonical Correlation Analysis, also known as "Mode B" PLS.

    Read more in the :ref:`User Guide <cross_decomposition>`.

    Parameters
    ----------
    n_components : int, default=2
        Number of components to keep. Should be in `[1, min(n_samples,
        n_features, n_targets)]`.

    scale : bool, default=True
        Whether to scale `X` and `Y`.

    max_iter : int, default=500
        The maximum number of iterations of the power method.

    tol : float, default=1e-06
        The tolerance used as convergence criteria in the power method: the
        algorithm stops whenever the squared norm of `u_i - u_{i-1}` is less
        than `tol`, where `u` corresponds to the left singular vector.

    copy : bool, default=True
        Whether to copy `X` and `Y` in fit before applying centering, and
        potentially scaling. If False, these operations will be done inplace,
        modifying both arrays.

    Attributes
    ----------
    x_weights_ : ndarray of shape (n_features, n_components)
        The left singular vectors of the cross-covariance matrices of each
        iteration.

    y_weights_ : ndarray of shape (n_targets, n_components)
        The right singular vectors of the cross-covariance matrices of each
        iteration.

    x_loadings_ : ndarray of shape (n_features, n_components)
        The loadings of `X`.

    y_loadings_ : ndarray of shape (n_targets, n_components)
        The loadings of `Y`.

    x_rotations_ : ndarray of shape (n_features, n_components)
        The projection matrix used to transform `X`.

    y_rotations_ : ndarray of shape (n_features, n_components)
        The projection matrix used to transform `Y`.

    coef_ : ndarray of shape (n_features, n_targets)
        The coefficients of the linear model such that `Y` is approximated as
        `Y = X @ coef_ + intercept_`.

    intercept_ : ndarray of shape (n_targets,)
        The intercepts of the linear model such that `Y` is approximated as
        `Y = X @ coef_ + intercept_`.

        .. versionadded:: 1.1

    n_iter_ : list of shape (n_components,)
        Number of iterations of the power method, for each
        component.

    n_features_in_ : int
        Number of features seen during :term:`fit`.

    feature_names_in_ : ndarray of shape (`n_features_in_`,)
        Names of features seen during :term:`fit`. Defined only when `X`
        has feature names that are all strings.

        .. versionadded:: 1.0

    See Also
    --------
    PLSCanonical : Partial Least Squares transformer and regressor.
    PLSSVD : Partial Least Square SVD.

    Examples
    --------
    >>> from sklearn.cross_decomposition import CCA
    >>> X = [[0., 0., 1.], [1.,0.,0.], [2.,2.,2.], [3.,5.,4.]]
    >>> Y = [[0.1, -0.2], [0.9, 1.1], [6.2, 5.9], [11.9, 12.3]]
    >>> cca = CCA(n_components=1)
    >>> cca.fit(X, Y)
    CCA(n_components=1)
    >>> X_c, Y_c = cca.transform(X, Y)
    rn   r·   r   Tr3   r4   r¸   c             
      s    t ƒ j||ddd|||d� d S )Nrg   r>   rh   ri   r¹   r»   r¼   r/   r0   rp   y  s    øzCCA.__init__)r   rÁ   r/   r/   r¼   r0   rÂ     s   
W ÿ   ÿrÂ   c                   @   sf   e Zd ZU dZeedddd�gdgdgdœZeed< dd
d
dœdd„Z	dd„ Z
ddd„Zddd„ZdS )r   a¹  Partial Least Square SVD.

    This transformer simply performs a SVD on the cross-covariance matrix
    `X'Y`. It is able to project both the training data `X` and the targets
    `Y`. The training data `X` is projected on the left singular vectors, while
    the targets are projected on the right singular vectors.

    Read more in the :ref:`User Guide <cross_decomposition>`.

    .. versionadded:: 0.8

    Parameters
    ----------
    n_components : int, default=2
        The number of components to keep. Should be in `[1,
        min(n_samples, n_features, n_targets)]`.

    scale : bool, default=True
        Whether to scale `X` and `Y`.

    copy : bool, default=True
        Whether to copy `X` and `Y` in fit before applying centering, and
        potentially scaling. If `False`, these operations will be done inplace,
        modifying both arrays.

    Attributes
    ----------
    x_weights_ : ndarray of shape (n_features, n_components)
        The left singular vectors of the SVD of the cross-covariance matrix.
        Used to project `X` in :meth:`transform`.

    y_weights_ : ndarray of (n_targets, n_components)
        The right singular vectors of the SVD of the cross-covariance matrix.
        Used to project `X` in :meth:`transform`.

    n_features_in_ : int
        Number of features seen during :term:`fit`.

    feature_names_in_ : ndarray of shape (`n_features_in_`,)
        Names of features seen during :term:`fit`. Defined only when `X`
        has feature names that are all strings.

        .. versionadded:: 1.0

    See Also
    --------
    PLSCanonical : Partial Least Squares transformer and regressor.
    CCA : Canonical Correlation Analysis.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.cross_decomposition import PLSSVD
    >>> X = np.array([[0., 0., 1.],
    ...               [1., 0., 0.],
    ...               [2., 2., 2.],
    ...               [2., 5., 4.]])
    >>> Y = np.array([[0.1, -0.2],
    ...               [0.9, 1.1],
    ...               [6.2, 5.9],
    ...               [11.9, 12.3]])
    >>> pls = PLSSVD(n_components=2).fit(X, Y)
    >>> X_c, Y_c = pls.transform(X, Y)
    >>> X_c.shape, Y_c.shape
    ((4, 2), (4, 2))
    r?   Nrb   rc   re   ©rj   r\   rm   rn   r   T)r\   rm   c                C   s   || _ || _|| _d S r5   rÃ   )ro   rj   r\   rm   r/   r/   r0   rp   Ò  s    zPLSSVD.__init__c           
      C   s*  |   ¡  t||ƒ | j|tj| jdd�}t|dtj| jdd�}|jdkrT| dd¡}| j	}t
|jd |jd |jd ƒ}||kr–td	|› d
|› d�ƒ‚t||| jƒ\}}| _| _| _| _t |j|¡}t|dd�\}}}|dd…d|…f }|d|… }t||ƒ\}}|j}	|| _|	| _| jjd | _| S )aJ  Fit model to data.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Training samples.

        Y : array-like of shape (n_samples,) or (n_samples, n_targets)
            Targets.

        Returns
        -------
        self : object
            Fitted estimator.
        r   rr   rI   Frs   r?   rv   r   rw   rx   ry   rS   N)r{   r   r|   r#   r}   rm   r   r~   r   rj   r€   rE   r�   r]   r\   r‚   rƒ   r„   r…   r)   rA   r   r   r†   r‡   r•   )
ro   rH   rI   rj   r™   rT   rU   r,   rW   ÚVr/   r/   r0   r�   ×  sL    
   ÿ    ÿ
ÿ  ÿz
PLSSVD.fitc                 C   s’   t | ƒ | j|tjdd�}|| j | j }t || j¡}|dk	rŽt|ddtjd�}|j	dkrh| 
dd¡}|| j | j }t || j¡}||fS |S )a	  
        Apply the dimensionality reduction.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Samples to be transformed.

        Y : array-like of shape (n_samples,) or (n_samples, n_targets),                 default=None
            Targets.

        Returns
        -------
        x_scores : array-like or tuple of array-like
            The transformed data `X_transformed` if `Y is not None`,
            `(X_transformed, Y_transformed)` otherwise.
        F)r    rŸ   NrI   )rt   ru   r    r?   rv   )r   r|   r#   r}   r‚   r„   r)   r†   r   r~   r   rƒ   r…   r‡   )ro   rH   rI   ZXrr›   ZYrrœ   r/   r/   r0   r      s    
zPLSSVD.transformc                 C   s   |   ||¡ ||¡S )aü  Learn and apply the dimensionality reduction.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Training samples.

        y : array-like of shape (n_samples,) or (n_samples, n_targets),                 default=None
            Targets.

        Returns
        -------
        out : array-like or tuple of array-like
            The transformed data `X_transformed` if `Y is not None`,
            `(X_transformed, Y_transformed)` otherwise.
        r¤   r¥   r/   r/   r0   r§   /  s    zPLSSVD.fit_transform)r   )N)N)r¯   r°   r±   r²   r   r   rn   r³   r´   rp   r�   r    r§   r/   r/   r/   r0   r   ˆ  s   
Dý8
 )r2   r3   r4   F)T)/r²   Únumbersr   r   rF   Úabcr   r   Únumpyr#   Zscipy.linalgr   Úbaser   r	   r
   r   r   Úutilsr   r   Zutils.fixesr   r   Zutils.extmathr   Zutils.validationr   r   Zutils._param_validationr   r   Ú
exceptionsr   Ú__all__r   r   r1   rR   rX   r]   r`   ra   r   r   rÂ   r   r/   r/   r/   r0   Ú<module>   sX   
       ÿ
;



ú  h  k