U
    3d`                     @   sd   d 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mZ G dd	 d	eeeed
ZdS )z)Principal Component Analysis Base Classes    N)linalg   )BaseEstimatorTransformerMixinClassNamePrefixFeaturesOutMixin)check_is_fitted)ABCMetaabstractmethodc                   @   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-zrfo1fqw/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_precision1   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   fitR   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   	transformd   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.   Znumpyr   Zscipyr   baser   r   r   Zutils.validationr   abcr   r	   r
   r   r   r   r   <module>   s   

   