
    {KgLg                     0   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mZ ddlmZ ddlmZmZmZ dd	lmZmZmZmZ dd
lmZ ddgZd Zd Zd Zd Zd#dZ d Z!d Z" edgdgdgdgdd      	 d#ddddddddddddd d!       Z# G d" deee
      Z$y)$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ClassNamePrefixFeaturesOutMixinTransformerMixin_fit_context)ConvergenceWarning)as_float_arraycheck_arraycheck_random_state)IntervalOptions
StrOptionsvalidate_params)check_is_fittedfasticaFastICAc                 p    | t         j                  j                  | |d| j                  |d| g      z  } | 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js      b/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/sklearn/decomposition/_fastica.py_gs_decorrelationr       s9    * 		a2A!BQ%0	11AH    c                 v   t        j                  t        j                  | | j                              \  }}t        j
                  |t        j                  | j                        j                  d      }t        j                   j                  |dt        j                  |      z  z  |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us      r   _sym_decorrelationr-   9   s     ;;rvva~&DAq 	!''*//t<A 99S2771:%5 6Q?@@r   c                    |j                   d   }t        j                  ||f| j                        }g }t	        |      D ]>  }	||	ddf   j                         }
|
t        j                  |
dz  j                               z  }
t	        |      D ]  } |t        j                  |
j                  |       |      \  }}| |z  j                  d      |j                         |
z  z
  }t        |||	       |t        j                  |dz  j                               z  }t        j                  t        j                  ||
z  j                               dz
        }|}
||k  s n |j                  dz          |
||	ddf<   A |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lims                   r   _ica_defrI   H   sP    <<?L
,-QWW=AF < 1a4L	RWWadZZ\""xABFF133NH5KD%d(a(5::<!+;;Bb!Q'"''2q5++-((B&&a/!34CASy ! 	a!e!Q$' !* c&k>r   c                    t        |      }~t        | j                  d         }t        |      D ]  } |t	        j
                  ||       |      \  }	}
t        t	        j
                  |	| j                        |z  |
ddt        j                  f   |z  z
        }~	~
t        t        t        t	        j                  d||            dz
              }|}||k  s n t        j                  dt               |dz   fS )zCParallel FastICA.

    Used internally by FastICA --main loop

    r0   Nzij,ij->iz\FastICA did not converge. Consider increasing tolerance or the maximum number of iterations.)r-   floatr3   r5   r   r%   r   newaxisr;   r9   einsumwarningswarnr   )r<   r=   r>   r?   r@   rA   r   p_iirE   rF   W1rH   s                r   _ica_parrS   k   s     	6"A	qwwqz	BHoq!h/etQSS 1B 6q"**}9MPQ9Q QR% #c"))JA67!;<=9  	A 	
 b1f9r   c                    |j                  dd      }| |z  } t        j                  | |       }t        j                  | j                  d   | j
                        }t        |      D ]!  \  }}|d|dz  z
  z  j                         ||<   # ||fS )Nalphar#   r   r/   r0   r   )getr   tanhemptyr3   r(   	enumerater8   )xr?   rU   gxg_xrD   gx_is          r   _logcoshr^      s    LL#&EJA	AB
((1771:QWW
-CR=41tQw;'--/A !s7Nr   c                     t        j                  | dz   dz        }| |z  }d| dz  z
  |z  }||j                  d      fS )Nr   r0   r1   )r   expr8   )rZ   r?   ra   r[   r\   s        r   _exprb      sK    
&&1a41
C	
SBq!t8s
CsxxRx   r   c                 <    | dz  d| dz  z  j                  d      fS )N   r   r`   r1   )r8   )rZ   r?   s     r   _cubere      s$    a4!ad(b)))r   
array-likeboolean)r<   return_X_meancompute_sourcesreturn_n_iterFprefer_skip_nested_validationparallelunit-variancelogcosh   -C6?svdT)	algorithmwhitenfunr?   r@   r=   rA   whiten_solverrandom_staterh   ri   rj   c                J   t        |||||||||	|

      }|j                          |j                  | |      }|j                  dv r|j                  }|j
                  }nd}d}||j                  |g}|r|j                  |       |r|j                  |j                         |S )a#  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='unit-variance'
        Specify the whitening strategy to use.

        - If 'arbitrary-variance', 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.

        .. versionchanged:: 1.3
            The default value of `whiten` changed to 'unit-variance' in 1.3.

    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.

    Examples
    --------
    >>> from sklearn.datasets import load_digits
    >>> from sklearn.decomposition import fastica
    >>> X, _ = load_digits(return_X_y=True)
    >>> K, W, S = fastica(X, n_components=7, random_state=0, whiten='unit-variance')
    >>> K.shape
    (7, 64)
    >>> W.shape
    (7, 7)
    >>> S.shape
    (1797, 7)
    
rB   rs   rt   ru   r?   r@   r=   rA   rv   rw   ri   )rn   arbitrary-varianceN)	r   _validate_params_fit_transformrt   
whitening_mean_	_unmixingr:   n_iter_)r<   rB   rs   rt   ru   r?   r@   r=   rA   rv   rw   rh   ri   rj   estSKX_meanreturned_valuess                      r   r   r      s    Z !#!C 1o>A
zz<<NN#--+Ov&s{{+r   c                   z    e Zd ZU dZ eeddd      dg eddh      g edd	h       eed
h      g eh d      e	ge
dg eeddd      g ee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Zd"dZ ed      d!d       Z ed      d!d       Zd#dZd#dZed        Zd  Z xZS )$r   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='unit-variance'
        Specify the whitening strategy to use.

        - If 'arbitrary-variance', 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.

        .. versionchanged:: 1.3
            The default value of `whiten` changed to 'unit-variance' in 1.3.

    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)
    r0   Nleft)closedrm   	deflationr{   rn   F>   ra   cubero   g        rf   r$   rr   rw   ry   _parameter_constraintsro   rp   rq   )	rs   rt   ru   r?   r@   r=   rA   rv   rw   c       	             t         |           || _        || _        || _        || _        || _        || _        || _        || _	        |	| _
        |
| _        y N)super__init__rB   rs   rt   ru   r?   r@   r=   rA   rv   rw   )selfrB   rs   rt   ru   r?   r@   r=   rA   rv   rw   	__class__s              r   r   zFastICA.__init__  sY     	("  *(r   c                 ~
     j                  | j                  t        j                  t        j                  gd      j
                  } j                  i n j                  }t         j                        }|j                  dd      }d|cxk  rdk  st        d       t        d       j                  dk(  rt        }nF j                  d	k(  rt        }n0 j                  d
k(  rt        }nt         j                        r fd}|j                   \  }}	 j"                  }
 j                  s|
d}
t%        j&                  d       |
t)        |	|      }
|
t)        |	|      kD  r$t)        |	|      }
t%        j&                  d|
z          j                  r|j+                  d      }||ddt        j,                  f   z  } j.                  dk(  rt1        j2                  |j5                  |            \  }}t        j6                  |      ddd   }t        j8                  |j:                        j<                  dz  }||k  }t        j>                  |      rt%        j&                  d       |||<   t        j@                  ||       ||   |dd|f   }}n- j.                  dk(  rt1        jB                  |dd      dd \  }}t        jD                  |d         z  }|z  j
                  d|
 }~~t        j4                  ||      }|t        j@                  |	      z  }ntG        |d      } jH                  }|4t        jJ                  |jM                  |
|
f      |j:                        }n8t        jJ                  |      }|j                   |
|
fk7  rt        dd|
|
fiz         jN                  | jP                  |d} jR                  dk(  rtU        |fi |\  }}n jR                  dk(  rtW        |fi |\  }}~ _,        |rZ j                  r-t        j0                  j[                  |g      j
                  }n#t        j4                  |      j
                  }nd} j                  r j                  d k(  rZ|s,t        j0                  j[                  |g      j
                  }t        j\                  |dd!"      }||z  }|j
                  z  }t        j4                         _/         _0        | _1        n _/        t1        jd                   j^                  d#       _3        | _4        |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`.
        r   )r6   r(   ensure_min_samplesNrU   r#   r0   zalpha must be in [1,2]ro   ra   r   c                 *     j                   | fi |S r   )ru   )rZ   r?   r   s     r   r>   z!FastICA._fit_transform.<locals>.gF  s    txx.X..r   z(Ignoring n_components with whiten=False.z/n_components is too large: it will be set to %sr`   r1   r$   
   zfThere are some small singular values, using whiten_solver = 'svd' might lead to more accurate results.)outrr   F)full_matricescheck_finiter   )r6   )sizer/   z/w_init has invalid shape -- should be %(shape)sr3   )r=   r>   r?   r@   rA   rm   r   rn   T)r2   keepdims)r   )5_validate_datart   r   float64float32r   r?   r   rw   rV   
ValueErrorru   r^   rb   re   callabler3   rB   rN   rO   minr8   rL   rv   r   r$   r%   argsortr'   r(   epsanyr*   rr   signr   rA   asarraynormalr=   r@   rs   rS   rI   r   r   stdcomponents_r   r~   pinvmixing_r   )r   r<   ri   XTr?   rw   rU   r>   
n_features	n_samplesrB   r   dr,   sort_indicesr   degenerate_idxr   X1rA   kwargsr   rC   r   S_stds   `                        r   r}   zFastICA._fit_transform"  s   $   DKK

BJJ'?TU ! 

! 	 .2DMM)$*;*;<Wc*EQ566 56688y AXXAXXAdhh/ !#
I(({{|7LMMDEy*5L#i44y*5LMMALP ;;WW"W%F&BJJ''B !!V+{{266!9-1!zz!}TrT2hhqww'++b0!"S66.)MM,
 %(.!q!!\/(:1##u,zz"ENrPQR1 1AQ		-<(A12B "'')$$B  /B>ZZ##,)E#FbhhF
 ZZ'F||l;; E| <=>  88 
 >>Z' .v.IAv^^{* .v.IAv{{II''Ar
355FF1bMOOA;;{{o-&		++Q2J799Aqq48U
UWW!vva|DDJDO D{{4#3#3%Hr   Trk   c                 (    | j                  |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.
        Trz   r}   r   r<   ys      r   fit_transformzFastICA.fit_transform  s    & ""1d";;r   c                 ,    | j                  |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.
        Frz   r   r   s      r   fitzFastICA.fit  s    $ 	Au5r   c                 $   t        |        | j                  ||xr | j                  t        j                  t        j
                  gd      }| j                  r|| j                  z  }t        j                  || 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)r6   r(   reset)
r   r   rt   r   r   r   r   r%   r   r   r   r<   r6   s      r   	transformzFastICA.transform  st    $ 	T)dkk2::rzz2JRW   
 ;;OAvva))++,,r   c                    t        |        t        ||xr | j                  t        j                  t        j
                  g      }t        j                  || j                  j                        }| j                  r|| j                  z  }|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.
        )r6   r(   )
r   r   rt   r   r   r   r%   r   r   r   r   s      r   inverse_transformzFastICA.inverse_transform  sa      	!5$++rzz2::>VWFF1dllnn%;;OAr   c                 4    | j                   j                  d   S )z&Number of transformed output features.r   )r   r3   r   s    r   _n_features_outzFastICA._n_features_out  s     %%a((r   c                 F    dt         j                  t         j                  giS )Npreserves_dtype)r   r   r   r   s    r   
_more_tagszFastICA._more_tags  s    !BJJ

#;<<r   r   )F)T)__name__
__module____qualname____doc__r   r   r   r   boolr   dictr   r   __annotations__r   r}   r
   r   r   r   r   propertyr   r   __classcell__)r   s   @r   r   r   p  s;   EP "(AtFCTJ *k!:;<,o>?D5'"
 56A4Lh4?@sD89&$fe_56'($D $ ) )4Rh 5< 6<( 5 6(-82 ) )=r   r   )%r   rN   numbersr   r   numpyr   scipyr   baser   r   r	   r
   
exceptionsr   utilsr   r   r   utils._param_validationr   r   r   r   utils.validationr   __all__r   r-   rI   rS   r^   rb   re   r   r    r   r   <module>r      s     "    , C C T T .i
 2A FD	!* ^#%;#	 #( @ @@Fk=-/? k=r   