U
    Ovfa  ã                   @   sd   d 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 G dd	„ d	e
ee	ed
ZdS )z)Principal Component Analysis Base Classesé    )ÚABCMetaÚabstractmethodN)Úlinalgé   )ÚBaseEstimatorÚClassNamePrefixFeaturesOutMixinÚTransformerMixin)Úcheck_is_fittedc                   @   sJ   e Zd ZdZdd„ Zdd„ Zeddd„ƒZd	d
„ Zdd„ Z	e
dd„ ƒZdS )Ú_BasePCAzwBase class for PCA methods.

    Warning: This class should not be used directly.
    Use derived classes instead.
    c                 C   sx   | j }| j}| jr.|t |dd…tjf ¡ }t || j d¡}t |j	| |¡}|j
ddt|ƒd …  | j7  < |S )as  Compute data covariance with the generative model.

        ``cov = components_.T * S**2 * components_ + sigma2 * eye(n_features)``
        where S**2 contains the explained variances, and sigma2 contains the
        noise variances.

        Returns
        -------
        cov : array of shape=(n_features, n_features)
            Estimated covariance of data.
        Nç        é   )Úcomponents_Úexplained_variance_ÚwhitenÚnpÚsqrtÚnewaxisÚmaximumÚnoise_variance_ÚdotÚTÚflatÚlen)Úselfr   Úexp_varÚexp_var_diffZcov© r   ú?/tmp/pip-unpacked-wheel-qu3nn_q2/sklearn/decomposition/_base.pyÚget_covariance   s    "z_BasePCA.get_covariancec                 C   s  | j jd }| jdkr&t |¡| j S tj| jdddrFt |  	¡ ¡S | j }| j
}| jrt|t |dd…tjf ¡ }t || j d¡}t ||j¡| j }|jddt|ƒd …  d| 7  < t |jt t |¡|¡¡}|| jd   }|jddt|ƒd …  d| j 7  < |S )a8  Compute data precision matrix with the generative model.

        Equals the inverse of the covariance but computed with
        the matrix inversion lemma for efficiency.

        Returns
        -------
        precision : array, shape=(n_features, n_features)
            Estimated precision of data.
        r   r   r   )ZatolNg      ð?r   )r   ÚshapeZn_components_r   Zeyer   Úiscloser   Úinvr   r   r   r   r   r   r   r   r   r   )r   Z
n_featuresr   r   r   Z	precisionr   r   r   Úget_precision2   s     
$&z_BasePCA.get_precisionNc                 C   s   dS )a¢  Placeholder for fit. Subclasses should implement this method!

        Fit the model with X.

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

        Returns
        -------
        self : object
            Returns the instance itself.
        Nr   )r   ÚXÚyr   r   r   ÚfitS   s    z_BasePCA.fitc                 C   s^   t | ƒ | j|tjtjgdd}| jdk	r4|| j }t || jj¡}| j	rZ|t 
| j¡ }|S )az  Apply dimensionality reduction to X.

        X is projected on the first principal components previously extracted
        from a training set.

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

        Returns
        -------
        X_new : array-like of shape (n_samples, n_components)
            Projection of X in the first principal components, where `n_samples`
            is the number of samples and `n_components` is the number of the components.
        F)ZdtypeÚresetN)r	   Z_validate_datar   Zfloat64Zfloat32Úmean_r   r   r   r   r   r   )r   r#   ZX_transformedr   r   r   Ú	transforme   s    

z_BasePCA.transformc                 C   sL   | j r4t |t | jdd…tjf ¡| j ¡| j S t || j¡| j S dS )aç  Transform data back to its original space.

        In other words, return an input `X_original` whose transform would be X.

        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 components.

        Returns
        -------
        X_original array-like of shape (n_samples, n_features)
            Original data, where `n_samples` is the number of samples
            and `n_features` is the number of features.

        Notes
        -----
        If whitening is enabled, inverse_transform will compute the
        exact inverse operation, which includes reversing whitening.
        N)r   r   r   r   r   r   r   r'   )r   r#   r   r   r   Úinverse_transform   s    þüÿz_BasePCA.inverse_transformc                 C   s   | j jd S )z&Number of transformed output features.r   )r   r   )r   r   r   r   Ú_n_features_out¢   s    z_BasePCA._n_features_out)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r"   r   r%   r(   r)   Úpropertyr*   r   r   r   r   r
      s   !!r
   )Ú	metaclass)r.   Úabcr   r   Znumpyr   Zscipyr   Úbaser   r   r   Zutils.validationr	   r
   r   r   r   r   Ú<module>   s   

   ÿ