o
    Rh                     @   s|   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mZ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    )ABCMetaabstractmethodN)linalg   )BaseEstimatorClassNamePrefixFeaturesOutMixinTransformerMixin)_fill_or_add_to_diagonaldeviceget_namespace)check_is_fittedvalidate_datac                   @   sT   e Zd ZdZdd Zdd ZedddZd	d
 Zd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   s   t | j\}}| j}| j}| jr|||ddtjf  }|| j }||| jk||j	dt
||jd}|j| | }t|| j| |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        )r
   dtype)r   components_explained_variance_whitensqrtnpnewaxisnoise_variance_whereasarrayr
   r   Tr	   )selfxp_r   exp_varexp_var_diffcov r!   ]/home/air/sanwanet/backup_V2/venv/lib/python3.10/site-packages/sklearn/decomposition/_base.pyget_covariance   s   
z_BasePCA.get_covariancec           	      C   s  t | j\}}| jjd }| jdkr||| j S |r!|jj}ntj}| jdkr/||  S | j}| j	}| j
rF|||ddtjf  }|| j }||| jk||jdt|d}||j | j }t|d| | |j|| | }|| jd   }t|d| j | |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   N)r
   g      ?r   )r   r   shapen_components_eyer   r   invr#   r   r   r   r   r   r   r   r
   r   r	   )	r   r   is_array_api_compliant
n_features
linalg_invr   r   r   	precisionr!   r!   r"   get_precision5   s2   



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"   fitb   s    z_BasePCA.fitc                 C   sF   t || j| j\}}t|  t| ||j|jgddd}| j||ddS )a  Apply dimensionality reduction to X.

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

        Parameters
        ----------
        X : {array-like, sparse matrix} 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.
        )csrcscF)r   accept_sparsereset)r   x_is_centered)r   r   r   r   r   float64float32
_transform)r   r.   r   r   r!   r!   r"   	transformt   s   
z_BasePCA.transformFc                 C   sb   || j j }|s||| jd| j j 8 }| jr/|| j}||jj	}||||k < || }|S )N)r$   )
r   r   reshapemean_r   r   r   finfor   eps)r   r.   r   r5   X_transformedscale	min_scaler!   r!   r"   r8      s   z_BasePCA._transformc                 C   sP   t |\}}| jr || jddtjf | j }|| | j S || j | j 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   scaled_componentsr!   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)F)__name__
__module____qualname____doc__r#   r-   r   r0   r9   r8   rC   propertyrD   r!   r!   r!   r"   r      s    -
 r   )	metaclass)rH   abcr   r   numpyr   scipyr   baser   r   r   utils._array_apir	   r
   r   utils.validationr   r   r   r!   r!   r!   r"   <module>   s    

