U
    9|eUh                     @   s  d 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mZmZ dd	lmZ dd
lmZmZmZ ddgZdd Zdd Zdd Zdd Zd&ddZdd Zdd Z d'dddddddd dd!d"d!d#d$dZ!G d%d deee
Z"dS )(z
Python implementation of the fast ICA algorithms.

Reference: Tables 8.3 and 8.4 page 196 in the book:
Independent Component Analysis, by  Hyvarinen et al.
    N)IntegralReal)linalg   )BaseEstimatorTransformerMixinClassNamePrefixFeaturesOutMixin)ConvergenceWarning)check_arrayas_float_arraycheck_random_state)check_is_fitted)HiddenInterval
StrOptionsfasticaFastICAc                 C   s,   | t j| |d| j|d| g8 } | S )a  
    Orthonormalize w wrt the first j rows of W.

    Parameters
    ----------
    w : ndarray of shape (n,)
        Array to be orthogonalized

    W : ndarray of shape (p, n)
        Null space definition

    j : int < p
        The no of (from the first) rows of Null space W wrt which w is
        orthogonalized.

    Notes
    -----
    Assumes that W is orthogonal
    w changed in place
    N)npr   	multi_dotT)wWj r   [/var/www/website-v5/atlas_env/lib/python3.8/site-packages/sklearn/decomposition/_fastica.py_gs_decorrelation   s    (r   c                 C   sT   t t| | j\}}tj|t| jjdd}tj 	|dt
|  |j| gS )z@Symmetric decorrelation
    i.e. W <- (W * W.T) ^{-1/2} * W
    N)a_mina_max      ?)r   eighr   dotr   clipfinfodtypetinyr   sqrt)r   sur   r   r   _sym_decorrelation4   s    r(   c                 C   s  |j d }tj||f| jd}g }t|D ]}	||	ddf  }
|
t|
d   }
t|D ]}|t|
j	| |\}}| | j
dd|
 |
  }t|||	 |t|d   }tt||
  d }|}
||k r` qq`||d  |
||	ddf< q*|t|fS )zcDeflationary FastICA using fun approx to neg-entropy function

    Used internally by FastICA.
    r   r#   Nr      axis)shaper   zerosr#   rangecopyr%   sumr    r   meanr   absappendmax)Xtolgfun_argsmax_iterw_initn_componentsr   n_iterr   r   igwtxg_wtxw1limr   r   r   _ica_defC   s$    
rC   c              	   C   s   t |}~t| jd }t|D ]x}|t|| |\}	}
t t|	| j| |
ddtjf |  }~	~
tt	t	t
d||d }|}||k r  qq tdt ||d fS )zCParallel FastICA.

    Used internally by FastICA --main loop

    r*   Nzij,ij->iz\FastICA did not converge. Consider increasing tolerance or the maximum number of iterations.)r(   floatr-   r/   r   r    r   newaxisr5   r3   einsumwarningswarnr	   )r6   r7   r8   r9   r:   r;   r   p_iir?   r@   W1rB   r   r   r   _ica_parf   s     ,rL   c                 C   sh   | dd}| |9 } t| | }tj| jd | jd}t|D ] \}}|d|d    ||< q>||fS )Nalphar   r   r)   r*   r   )getr   tanhemptyr-   r#   	enumerater2   )xr9   rM   gxg_xr>   Zgx_ir   r   r   _logcosh   s    rU   c                 C   s<   t | d  d }| | }d| d  | }||jddfS )Nr   r*   r+   )r   expr2   )rR   r9   rW   rS   rT   r   r   r   _exp   s    rX   c                 C   s   | d d| d  j ddfS )N   r   rV   r+   )r2   rR   r9   r   r   r   _cube   s    r[   parallelrH   logcosh   -C6?svdFT)	algorithmwhitenfunr9   r:   r7   r;   whiten_solverrandom_statereturn_X_meancompute_sourcesreturn_n_iterc                C   sx   t |||||||||	|
d
}|j| |d}|jdkrB|j}|j}nd}d}||j|g}|rd|| |rt||j |S )aW  Perform Fast Independent Component Analysis.

    The implementation is based on [1]_.

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

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

    n_components : int, default=None
        Number of components to use. If None is passed, all are used.

    algorithm : {'parallel', 'deflation'}, default='parallel'
        Specify which algorithm to use for FastICA.

    whiten : str or bool, default="warn"
        Specify the whitening strategy to use.

        - If 'arbitrary-variance' (default), a whitening with variance
          arbitrary is used.
        - If 'unit-variance', the whitening matrix is rescaled to ensure that
          each recovered source has unit variance.
        - If False, the data is already considered to be whitened, and no
          whitening is performed.

        .. deprecated:: 1.1
            Starting in v1.3, `whiten='unit-variance'` will be used by default.
            `whiten=True` is deprecated from 1.1 and will raise ValueError in 1.3.
            Use `whiten=arbitrary-variance` instead.

    fun : {'logcosh', 'exp', 'cube'} or callable, default='logcosh'
        The functional form of the G function used in the
        approximation to neg-entropy. Could be either 'logcosh', 'exp',
        or 'cube'.
        You can also provide your own function. It should return a tuple
        containing the value of the function, and of its derivative, in the
        point. The derivative should be averaged along its last dimension.
        Example::

            def my_g(x):
                return x ** 3, (3 * x ** 2).mean(axis=-1)

    fun_args : dict, default=None
        Arguments to send to the functional form.
        If empty or None and if fun='logcosh', fun_args will take value
        {'alpha' : 1.0}.

    max_iter : int, default=200
        Maximum number of iterations to perform.

    tol : float, default=1e-4
        A positive scalar giving the tolerance at which the
        un-mixing matrix is considered to have converged.

    w_init : ndarray of shape (n_components, n_components), default=None
        Initial un-mixing array. If `w_init=None`, then an array of values
        drawn from a normal distribution is used.

    whiten_solver : {"eigh", "svd"}, default="svd"
        The solver to use for whitening.

        - "svd" is more stable numerically if the problem is degenerate, and
          often faster when `n_samples <= n_features`.

        - "eigh" is generally more memory efficient when
          `n_samples >= n_features`, and can be faster when
          `n_samples >= 50 * n_features`.

        .. versionadded:: 1.2

    random_state : int, RandomState instance or None, default=None
        Used to initialize ``w_init`` when not specified, with a
        normal distribution. Pass an int, for reproducible results
        across multiple function calls.
        See :term:`Glossary <random_state>`.

    return_X_mean : bool, default=False
        If True, X_mean is returned too.

    compute_sources : bool, default=True
        If False, sources are not computed, but only the rotation matrix.
        This can save memory when working with big data. Defaults to True.

    return_n_iter : bool, default=False
        Whether or not to return the number of iterations.

    Returns
    -------
    K : ndarray of shape (n_components, n_features) or None
        If whiten is 'True', K is the pre-whitening matrix that projects data
        onto the first n_components principal components. If whiten is 'False',
        K is 'None'.

    W : ndarray of shape (n_components, n_components)
        The square matrix that unmixes the data after whitening.
        The mixing matrix is the pseudo-inverse of matrix ``W K``
        if K is not None, else it is the inverse of W.

    S : ndarray of shape (n_samples, n_components) or None
        Estimated source matrix.

    X_mean : ndarray of shape (n_features,)
        The mean over features. Returned only if return_X_mean is True.

    n_iter : int
        If the algorithm is "deflation", n_iter is the
        maximum number of iterations run across all components. Else
        they are just the number of iterations taken to converge. This is
        returned only when return_n_iter is set to `True`.

    Notes
    -----
    The data matrix X is considered to be a linear combination of
    non-Gaussian (independent) components i.e. X = AS where columns of S
    contain the independent components and A is a linear mixing
    matrix. In short ICA attempts to `un-mix' the data by estimating an
    un-mixing matrix W where ``S = W K X.``
    While FastICA was proposed to estimate as many sources
    as features, it is possible to estimate less by setting
    n_components < n_features. It this case K is not a square matrix
    and the estimated A is the pseudo-inverse of ``W K``.

    This implementation was originally made for data of shape
    [n_features, n_samples]. Now the input is transposed
    before the algorithm is applied. This makes it slightly
    faster for Fortran-ordered input.

    References
    ----------
    .. [1] A. Hyvarinen and E. Oja, "Fast Independent Component Analysis",
           Algorithms and Applications, Neural Networks, 13(4-5), 2000,
           pp. 411-430.
    
r<   ra   rb   rc   r9   r:   r7   r;   rd   re   rg   )unit-variancearbitrary-varianceN)r   _fit_transform_whiten
whitening_mean_	_unmixingr4   n_iter_)r6   r<   ra   rb   rc   r9   r:   r7   r;   rd   re   rf   rg   rh   estSKX_meanZreturned_valuesr   r   r   r      s2     

c                       s  e Zd ZU dZeedddddgeddhgeedhed	d
hdgedddhege	dgeeddddgee
ddddgddgeddhgdgd
Ze	ed< d+dddddddddd	 fddZd,ddZd-ddZd.d d!Zd/d#d$Zd0d%d&Zed'd( Zd)d* Z  ZS )1r   a}  FastICA: a fast algorithm for Independent Component Analysis.

    The implementation is based on [1]_.

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

    Parameters
    ----------
    n_components : int, default=None
        Number of components to use. If None is passed, all are used.

    algorithm : {'parallel', 'deflation'}, default='parallel'
        Specify which algorithm to use for FastICA.

    whiten : str or bool, default="warn"
        Specify the whitening strategy to use.

        - If 'arbitrary-variance' (default), a whitening with variance
          arbitrary is used.
        - If 'unit-variance', the whitening matrix is rescaled to ensure that
          each recovered source has unit variance.
        - If False, the data is already considered to be whitened, and no
          whitening is performed.

        .. deprecated:: 1.1
            Starting in v1.3, `whiten='unit-variance'` will be used by default.
            `whiten=True` is deprecated from 1.1 and will raise ValueError in 1.3.
            Use `whiten=arbitrary-variance` instead.

    fun : {'logcosh', 'exp', 'cube'} or callable, default='logcosh'
        The functional form of the G function used in the
        approximation to neg-entropy. Could be either 'logcosh', 'exp',
        or 'cube'.
        You can also provide your own function. It should return a tuple
        containing the value of the function, and of its derivative, in the
        point. The derivative should be averaged along its last dimension.
        Example::

            def my_g(x):
                return x ** 3, (3 * x ** 2).mean(axis=-1)

    fun_args : dict, default=None
        Arguments to send to the functional form.
        If empty or None and if fun='logcosh', fun_args will take value
        {'alpha' : 1.0}.

    max_iter : int, default=200
        Maximum number of iterations during fit.

    tol : float, default=1e-4
        A positive scalar giving the tolerance at which the
        un-mixing matrix is considered to have converged.

    w_init : array-like of shape (n_components, n_components), default=None
        Initial un-mixing array. If `w_init=None`, then an array of values
        drawn from a normal distribution is used.

    whiten_solver : {"eigh", "svd"}, default="svd"
        The solver to use for whitening.

        - "svd" is more stable numerically if the problem is degenerate, and
          often faster when `n_samples <= n_features`.

        - "eigh" is generally more memory efficient when
          `n_samples >= n_features`, and can be faster when
          `n_samples >= 50 * n_features`.

        .. versionadded:: 1.2

    random_state : int, RandomState instance or None, default=None
        Used to initialize ``w_init`` when not specified, with a
        normal distribution. Pass an int, for reproducible results
        across multiple function calls.
        See :term:`Glossary <random_state>`.

    Attributes
    ----------
    components_ : ndarray of shape (n_components, n_features)
        The linear operator to apply to the data to get the independent
        sources. This is equal to the unmixing matrix when ``whiten`` is
        False, and equal to ``np.dot(unmixing_matrix, self.whitening_)`` when
        ``whiten`` is True.

    mixing_ : ndarray of shape (n_features, n_components)
        The pseudo-inverse of ``components_``. It is the linear operator
        that maps independent sources to the data.

    mean_ : ndarray of shape(n_features,)
        The mean over features. Only set if `self.whiten` is True.

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

        .. versionadded:: 0.24

    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

    n_iter_ : int
        If the algorithm is "deflation", n_iter is the
        maximum number of iterations run across all components. Else
        they are just the number of iterations taken to converge.

    whitening_ : ndarray of shape (n_components, n_features)
        Only set if whiten is 'True'. This is the pre-whitening matrix
        that projects data onto the first `n_components` principal components.

    See Also
    --------
    PCA : Principal component analysis (PCA).
    IncrementalPCA : Incremental principal components analysis (IPCA).
    KernelPCA : Kernel Principal component analysis (KPCA).
    MiniBatchSparsePCA : Mini-batch Sparse Principal Components Analysis.
    SparsePCA : Sparse Principal Components Analysis (SparsePCA).

    References
    ----------
    .. [1] A. Hyvarinen and E. Oja, Independent Component Analysis:
           Algorithms and Applications, Neural Networks, 13(4-5), 2000,
           pp. 411-430.

    Examples
    --------
    >>> from sklearn.datasets import load_digits
    >>> from sklearn.decomposition import FastICA
    >>> X, _ = load_digits(return_X_y=True)
    >>> transformer = FastICA(n_components=7,
    ...         random_state=0,
    ...         whiten='unit-variance')
    >>> X_transformed = transformer.fit_transform(X)
    >>> X_transformed.shape
    (1797, 7)
    r*   Nleft)closedr\   	deflationrH   rl   rk   booleanr]   rW   cubeg        z
array-liker   r`   re   ri   _parameter_constraintsr^   r_   )	ra   rb   rc   r9   r:   r7   r;   rd   re   c       	            sJ   t    || _|| _|| _|| _|| _|| _|| _|| _	|	| _
|
| _d S N)super__init__r<   ra   rb   rc   r9   r:   r7   r;   rd   re   )selfr<   ra   rb   rc   r9   r:   r7   r;   rd   re   	__class__r   r   r     s    
zFastICA.__init__Fc                    s   j  _ jdkr$tdt d _ jdkrDtjdtdd d _ j| jtjtjgddj	} j
d	krpi n j
}t j}|d
d}d|  krdksn td jdkrt}n6 jdkrt}n& jdkrt}nt jr fdd}|j\}}	 j}
 js |
d	k	r d	}
td |
d	kr4t|	|}
|
t|	|kr\t|	|}
td|
   jr|jdd}||d	d	tjf 8 } jdkrt||\}}t|d	d	d }t|jj }||k }t!|rtd |||< tj"||d || |d	d	|f  }}n( jdkr@tj#|dddd	d \}}|t$|d 9 }|| j	d	|
 }~~t||}|t"|	9 }nt%|dd} j&}|d	krtj'|j(|
|
fd|jd }n.t'|}|j|
|
fkrtd!d"|
|
fi  j)|| j*|d#} j+d$krt,|f|\}}n j+d%kr:t-|f|\}}~| _.|rv jrftj/|||gj	}nt||j	}nd	} jr jd&kr|stj/|||gj	}tj0|ddd'}|| }||j	 }t|| _1| _2| _3n| _1tj4 j1dd( _5| _6|S ))ad  Fit the model.

        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.

        compute_sources : bool, default=False
            If False, sources are not computes but only the rotation matrix.
            This can save memory when working with big data. Defaults to False.

        Returns
        -------
        S : ndarray of shape (n_samples, n_components) or None
            Sources matrix. `None` if `compute_sources` is `False`.
        rH   zAStarting in v1.3, whiten='unit-variance' will be used by default.rl   TzStarting in v1.3, whiten=True should be specified as whiten='arbitrary-variance' (its current behaviour). This behavior is deprecated in 1.1 and will raise ValueError in 1.3.r   )
stacklevel)r0   r#   ensure_min_samplesNrM   r   r*   zalpha must be in [1,2]r]   rW   r{   c                    s    j | f|S r}   )rc   rZ   r   r   r   r8   @  s    z!FastICA._fit_transform.<locals>.gz(Ignoring n_components with whiten=False.z/n_components is too large: it will be set to %srV   r+   r   zfThere are some small singular values, using whiten_solver = 'svd' might lead to more accurate results.)outr`   F)full_matricescheck_finiter   )r0   )sizer)   z/w_init has invalid shape -- should be %(shape)sr-   )r7   r8   r9   r:   r;   r\   ry   rk   )r,   keepdims)r   )7rb   rn   rG   rH   FutureWarning_validate_datar   float64float32r   r9   r   re   rN   
ValueErrorrc   rU   rX   r[   callabler-   r<   minr2   rE   rd   r   r   r    argsortr"   r#   epsanyr%   r`   signr   r;   asarraynormalr7   r:   ra   rL   rC   rr   r   stdcomponents_rp   ro   pinvmixing_rq   )r   r6   rg   ZXTr9   re   rM   r8   
n_features	n_samplesr<   rv   dr'   sort_indicesr   Zdegenerate_idxru   X1r;   kwargsr   r=   rt   ZS_stdr   r   r   rm   	  s    

  
 










 


zFastICA._fit_transformc                 C   s   |    | j|ddS )a5  Fit the model and recover the sources from 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.

        y : Ignored
            Not used, present for API consistency by convention.

        Returns
        -------
        X_new : ndarray of shape (n_samples, n_components)
            Estimated sources obtained by transforming the data with the
            estimated unmixing matrix.
        Trj   _validate_paramsrm   r   r6   yr   r   r   fit_transform  s    zFastICA.fit_transformc                 C   s   |    | j|dd | S )a  Fit the model to 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.

        y : Ignored
            Not used, present for API consistency by convention.

        Returns
        -------
        self : object
            Returns the instance itself.
        Frj   r   r   r   r   r   fit  s    zFastICA.fitTc                 C   sH   t |  | j||o| jtjtjgdd}| jr8|| j8 }t|| jj	S )a_  Recover the sources from X (apply the unmixing matrix).

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

        copy : bool, default=True
            If False, data passed to fit can be overwritten. Defaults to True.

        Returns
        -------
        X_new : ndarray of shape (n_samples, n_components)
            Estimated sources obtained by transforming the data with the
            estimated unmixing matrix.
        F)r0   r#   reset)
r   r   rn   r   r   r   rp   r    r   r   r   r6   r0   r   r   r   	transform  s      
 
zFastICA.transformc                 C   sH   t |  t||o| jtjtjgd}t|| jj}| jrD|| j	7 }|S )a1  Transform the sources back to the mixed data (apply mixing matrix).

        Parameters
        ----------
        X : array-like of shape (n_samples, n_components)
            Sources, where `n_samples` is the number of samples
            and `n_components` is the number of components.
        copy : bool, default=True
            If False, data passed to fit are overwritten. Defaults to True.

        Returns
        -------
        X_new : ndarray of shape (n_samples, n_features)
            Reconstructed data obtained with the mixing matrix.
        )r0   r#   )
r   r
   rn   r   r   r   r    r   r   rp   r   r   r   r   inverse_transform  s    
zFastICA.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FastICA._n_features_outc                 C   s   dt jt jgiS )Npreserves_dtype)r   r   r   r   r   r   r   
_more_tags  s    zFastICA._more_tags)N)F)N)N)T)T)__name__
__module____qualname____doc__r   r   r   r   r   dictr   r|   __annotations__r   rm   r   r   r   r   propertyr   r   __classcell__r   r   r   r   r   T  sJ   
 
 
 (




)N)N)#r   rG   numbersr   r   numpyr   scipyr   baser   r   r   
exceptionsr	   utilsr
   r   r   utils.validationr   utils._param_validationr   r   r   __all__r   r(   rC   rL   rU   rX   r[   r   r   r   r   r   r   <module>   sD   # 
  8