B
    ¥	ˆ\Ü  ã               @   sz   d Z ddl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 G d
d„ de eee¡ƒZdS )z)Principal Component Analysis Base Classesé    N)Úlinalgé   )ÚBaseEstimatorÚTransformerMixin)Úcheck_array)Úcheck_is_fitted)Úsix)ÚABCMetaÚabstractmethodc               @   s>   e Zd ZdZdd„ Zdd„ Zeddd„ƒZd	d
„ Z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 )ar  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, shape=(n_features, n_features)
            Estimated covariance of data.
        Ng        é   )Úcomponents_Úexplained_variance_ÚwhitenÚnpÚsqrtÚnewaxisÚmaximumÚnoise_variance_ÚdotÚTÚflatÚlen)Úselfr   Úexp_varÚexp_var_diffZcov© r   ú9lib/python3.7/site-packages/sklearn/decomposition/base.pyÚget_covariance   s    "z_BasePCA.get_covariancec             C   s  | j jd }| jdkr&t |¡| j S | j|kr>t |  ¡ ¡S | j }| j	}| j
rl|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   Ng        g      ð?r   )r   ÚshapeZn_components_r   Zeyer   r   Úinvr   r   r   r   r   r   r   r   r   r   )r   Z
n_featuresr   r   r   Z	precisionr   r   r   Úget_precision0   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, 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   )ÚXÚyr   r   r   ÚfitQ   s    z_BasePCA.fitc             C   sX   t | ddgtd t|ƒ}| jdk	r.|| j }t || jj¡}| jrT|t 	| j
¡ }|S )an  Apply dimensionality reduction to X.

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

        Parameters
        ----------
        X : array-like, 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, shape (n_samples, n_components)

        Examples
        --------

        >>> import numpy as np
        >>> from sklearn.decomposition import IncrementalPCA
        >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
        >>> ipca = IncrementalPCA(n_components=2, batch_size=3)
        >>> ipca.fit(X)
        IncrementalPCA(batch_size=3, copy=True, n_components=2, whiten=False)
        >>> ipca.transform(X) # doctest: +SKIP
        Úmean_r   )Z
all_or_anyN)r   Úallr   r%   r   r   r   r   r   r   r   )r   r"   ZX_transformedr   r   r   Ú	transformc   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, 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, shape (n_samples, n_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_transform)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r!   r
   r$   r'   r(   r   r   r   r   r      s   !%r   )r,   Znumpyr   Zscipyr   Úbaser   r   Zutilsr   Zutils.validationr   Z	externalsr   Úabcr	   r
   Zwith_metaclassr   r   r   r   r   Ú<module>   s   
