B
    	\M                 @   s   d Z ddl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 dd
lmZmZmZ ddlmZ ddl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ZG d$d d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)linalg   )BaseEstimatorTransformerMixin)ConvergenceWarning)six)moves)string_types)check_arrayas_float_arraycheck_random_state)check_is_fitted)FLOAT_DTYPESfasticaFastICAc          	   C   s.   | t t | |d| j|d| 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)npdotT)wWj r   =lib/python3.7/site-packages/sklearn/decomposition/fastica_.py_gs_decorrelation   s    *r   c          	   C   s<   t t| | j\}}tt|dt|  |j| S )zA Symmetric decorrelation
    i.e. W <- (W * W.T) ^{-1/2} * W
    g      ?)r   Zeighr   r   r   sqrt)r   sur   r   r   _sym_decorrelation6   s    r   c             C   s  |j d }tj||f| jd}g }xt|D ]}	||	ddf  }
|
t|
d   }
xt	|D ]}|t
|
j| |\}}| | jdd| |
  }t|||	 |t|d   }tt||
  d }|}
||k rfP qfW ||d  |
||	ddf< q,W |t|fS )zcDeflationary FastICA using fun approx to neg-entropy function

    Used internally by FastICA.
    r   )dtypeNr      )axis)shaper   Zzerosr   rangecopyr   sumr   xranger   r   meanr   absappendmax)Xtolgfun_argsmax_iterw_initn_componentsr   n_iterr   r   igwtxg_wtxZw1limr   r   r   _ica_def@   s$    
r6   c          
   C   s   t |}~t| jd }xt|D ]|}|t|| |\}	}
t t|	| j| |
ddtjf |  }~	~
t	t
t
tt||jd }|}||k r$P q$W tdt ||d fS )zCParallel FastICA.

    Used internally by FastICA --main loop

    r   Nz\FastICA did not converge. Consider increasing tolerance or the maximum number of iterations.)r   floatr!   r   r%   r   r   r   newaxisr)   r'   Zdiagwarningswarnr   )r*   r+   r,   r-   r.   r/   r   Zp_Ziir3   r4   ZW1r5   r   r   r   _ica_parc   s    $r;   c             C   sf   | dd}| |9 } t| | }t| jd }x,t|D ] \}}|d|d    ||< q:W ||fS )Nalphag      ?r   r   r   )getr   Ztanhemptyr!   	enumerater&   )xr-   r<   gxg_xr2   Zgx_ir   r   r   _logcosh   s    rC   c             C   s<   t | d  d }| | }d| d  | }||jddfS )Nr   r   )r    )r   expr&   )r@   r-   rE   rA   rB   r   r   r   _exp   s    rF   c             C   s   | d d| d  j ddfS )N   r   rD   )r    )r&   )r@   r-   r   r   r   _cube   s    rH   parallelTlogcosh   -C6?Fc                s  t |	}	|dkri n|}t| |tddj} |dd}d|  krJdksTn td dkrbt}nR d	krpt}nD d
kr~t}n6t	 r fdd}n t
 tjrtnt}|d  | j\}}|s|dk	rd}td |dkrt||}|t||krt||}td|  |r| jdd}| |ddtjf 8 } tj| dd\}}}~|| jd| }~~t|| }|t|9 }nt| dd}|dkrtj|	j||fd|jd}n.t|}|j||fkrtdd||fi |||||d}|dkrt|f|\}}n$|dkr,t|f|\}}ntd~|r|rZtt||| j}nd}|
r|rx|||||fS ||||fS n|r||||fS |||fS n^|rt|| j}nd}|
r|rd||d|fS d||dfS n|rd|||fS d||fS dS )a  Perform Fast Independent Component Analysis.

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

    Parameters
    ----------
    X : array-like, 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, optional
        Number of components to extract. If None no dimension reduction
        is performed.

    algorithm : {'parallel', 'deflation'}, optional
        Apply a parallel or deflational FASTICA algorithm.

    whiten : boolean, optional
        If True perform an initial whitening of the data.
        If False, the data is assumed to have already been
        preprocessed: it should be centered, normed and white.
        Otherwise you will get incorrect results.
        In this case the parameter n_components will be ignored.

    fun : string or function, optional. 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, np.mean(3 * x ** 2, axis=-1)

    fun_args : dictionary, optional
        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, optional
        Maximum number of iterations to perform.

    tol : float, optional
        A positive scalar giving the tolerance at which the
        un-mixing matrix is considered to have converged.

    w_init : (n_components, n_components) array, optional
        Initial un-mixing array of dimension (n.comp,n.comp).
        If None (default) then an array of normal r.v.'s is used.

    random_state : int, RandomState instance or None, optional (default=None)
        If int, random_state is the seed used by the random number generator;
        If RandomState instance, random_state is the random number generator;
        If None, the random number generator is the RandomState instance used
        by `np.random`.

    return_X_mean : bool, optional
        If True, X_mean is returned too.

    compute_sources : bool, optional
        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, optional
        Whether or not to return the number of iterations.

    Returns
    -------
    K : array, shape (n_components, n_features) | 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 : array, shape (n_components, n_components)
        Estimated un-mixing matrix.
        The mixing matrix can be obtained by::

            w = np.dot(W, K.T)
            A = w.T * (w * w.T).I

    S : array, shape (n_samples, n_components) | None
        Estimated source matrix

    X_mean : array, 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.``

    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.

    Implemented using FastICA:
    `A. Hyvarinen and E. Oja, Independent Component Analysis:
    Algorithms and Applications, Neural Networks, 13(4-5), 2000,
    pp. 411-430`

    Nr   )r#   r   Zensure_min_samplesr<   g      ?r   zalpha must be in [1,2]rJ   rE   Zcubec                s    | f|S )Nr   )r@   r-   )funr   r   r,     s    zfastica.<locals>.gzJUnknown function %r; should be one of 'logcosh', 'exp', 'cube' or callablez(Ignoring n_components with whiten=False.z/n_components is too large: it will be set to %srD   )r    F)Zfull_matrices)r#   )size)r   z/w_init has invalid shape -- should be %(shape)sr!   )r+   r,   r-   r.   r/   rI   Z	deflationz<Invalid algorithm: must be either `parallel` or `deflation`.)r   r
   r   r   r=   
ValueErrorrC   rF   rH   callable
isinstancer   r	   	TypeErrorr!   r9   r:   minr&   r   r8   r   Zsvdr   r   r   ZasarrayZnormalr   r;   r6   )r*   r0   	algorithmwhitenrM   r-   r.   r+   r/   random_statereturn_X_meancompute_sourcesreturn_n_iterr<   r,   excnpX_meanr   d_KZX1kwargsr   r1   Sr   )rM   r   r      s    v









c            	       sT   e Zd ZdZd fdd		ZdddZdddZdddZdddZdddZ	  Z
S )r   a
  FastICA: a fast algorithm for Independent Component Analysis.

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

    Parameters
    ----------
    n_components : int, optional
        Number of components to use. If none is passed, all are used.

    algorithm : {'parallel', 'deflation'}
        Apply parallel or deflational algorithm for FastICA.

    whiten : boolean, optional
        If whiten is false, the data is already considered to be
        whitened, and no whitening is performed.

    fun : string or function, optional. 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. Example:

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

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

    max_iter : int, optional
        Maximum number of iterations during fit.

    tol : float, optional
        Tolerance on update at each iteration.

    w_init : None of an (n_components, n_components) ndarray
        The mixing matrix to be used to initialize the algorithm.

    random_state : int, RandomState instance or None, optional (default=None)
        If int, random_state is the seed used by the random number generator;
        If RandomState instance, random_state is the random number generator;
        If None, the random number generator is the RandomState instance used
        by `np.random`.

    Attributes
    ----------
    components_ : 2D array, shape (n_components, n_features)
        The unmixing matrix.

    mixing_ : array, shape (n_features, n_components)
        The mixing matrix.

    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.

    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)
    >>> X_transformed = transformer.fit_transform(X)
    >>> X_transformed.shape
    (1797, 7)

    Notes
    -----
    Implementation based on
    `A. Hyvarinen and E. Oja, Independent Component Analysis:
    Algorithms and Applications, Neural Networks, 13(4-5), 2000,
    pp. 411-430`

    NrI   TrJ   rK   -C6?c
       
         s^   t t|   |dk r$td||| _|| _|| _|| _|| _	|| _
|| _|| _|	| _d S )Nr   z4max_iter should be greater than 1, got (max_iter={}))superr   __init__rO   formatr0   rT   rU   rM   r-   r.   r+   r/   rV   )
selfr0   rT   rU   rM   r-   r.   r+   r/   rV   )	__class__r   r   re     s    zFastICA.__init__Fc             C   s   | j dkri n| j }t|| j| j| j| j|| j| j| j| j	d|dd\}}}}| _
| jrtt||| _|| _|| _n|| _t| j| _|r|| _|S )a  Fit the model

        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.

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

        Returns
        -------
            X_new : array-like, shape (n_samples, n_components)
        NT)r*   r0   rT   rU   rM   r-   r.   r+   r/   rV   rW   rX   rY   )r-   r   r0   rT   rU   rM   r.   r+   r/   rV   Zn_iter_r   r   components_mean_Z
whitening_r   Zpinvmixing_Z_FastICA__sources)rg   r*   rX   r-   Z	whiteningZunmixingZsourcesr]   r   r   r   _fit  s     

zFastICA._fitc             C   s   | j |ddS )a  Fit the model and recover the sources from 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.

        y : Ignored

        Returns
        -------
        X_new : array-like, shape (n_samples, n_components)
        T)rX   )rl   )rg   r*   yr   r   r   fit_transform	  s    zFastICA.fit_transformc             C   s   | j |dd | S )a6  Fit the model to 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.

        y : Ignored

        Returns
        -------
        self
        F)rX   )rl   )rg   r*   rm   r   r   r   fit  s    zFastICA.fit
deprecatedc             C   sV   t |tr|dkrtdt t| d t||td}| jrF|| j	8 }t
|| jjS )aQ  Recover the sources from X (apply the unmixing matrix).

        Parameters
        ----------
        X : array-like, shape (n_samples, n_features)
            Data to transform, where n_samples is the number of samples
            and n_features is the number of features.
        y : (ignored)
            .. deprecated:: 0.19
               This parameter will be removed in 0.21.
        copy : bool (optional)
            If False, data passed to fit are overwritten. Defaults to True.

        Returns
        -------
        X_new : array-like, shape (n_samples, n_components)
        rp   zSThe parameter y on transform() is deprecated since 0.19 and will be removed in 0.21rk   )r#   r   )rQ   r	   r9   r:   DeprecationWarningr   r
   r   rU   rj   r   r   ri   r   )rg   r*   rm   r#   r   r   r   	transform,  s    

zFastICA.transformc             C   sB   t | d t||o| jtd}t|| jj}| jr>|| j7 }|S )a  Transform the sources back to the mixed data (apply mixing matrix).

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

        Returns
        -------
        X_new : array-like, shape (n_samples, n_features)
        rk   )r#   r   )	r   r
   rU   r   r   r   rk   r   rj   )rg   r*   r#   r   r   r   inverse_transformK  s    

zFastICA.inverse_transform)	NrI   TrJ   NrK   rc   NN)F)N)N)rp   T)T)__name__
__module____qualname____doc__re   rl   rn   ro   rr   rs   __classcell__r   r   )rh   r   r     s   O  
'


)N)NrI   TrJ   NrK   rL   NNFTF)!rw   r9   Znumpyr   Zscipyr   baser   r   
exceptionsr   Z	externalsr   Zexternals.sixr   r	   Zutilsr
   r   r   Zutils.validationr   r   __all__r   r   r6   r;   rC   rF   rH   r   r   r   r   r   r   <module>   s2   
#
   
 h