U
    _»{j¥E ã                   @   sØ  d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	 ddl
ZddlmZ ddlmZ ddlmZmZmZmZ dd	lmZmZmZmZ dd
lmZmZmZmZ ddlm Z m!Z!m"Z"m#Z# ddl$m%Z%m&Z&m'Z' ddl(m)Z)m*Z* ddl+m,Z, dd„ Z-ddddddddddœ	dd„Z.e#dgdgddgddge"dddddhƒge!edddd�dge!e	dddd�dgd gddge!edddd�g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%d&„ƒZ/dddddddddddd'œd(d)„Z0dFd*d+„Z1d,d-„ Z2dGd.d/„Z3dHdd0ddddd1ddddd0dd0d0d0dddd2d3d4œd5d6„Z4e#dge"dd7hƒgd ge!edddd�gd8œdd#�d9d:dddddddddddd;œd<d=„ƒZ5G d>d?„ d?eeƒZ6G d@dA„ dAe6eƒZ7G dBdC„ dCe6eƒZ8G dDdE„ dEe6eƒZ9dS )Iz Dictionary learning.
é    N)Úceil)ÚIntegralÚReal)Úeffective_n_jobs)Úlinalgé   )ÚBaseEstimatorÚClassNamePrefixFeaturesOutMixinÚTransformerMixinÚ_fit_context)ÚLarsÚLassoÚ	LassoLarsÚorthogonal_mp_gram)Úcheck_arrayÚcheck_random_stateÚgen_batchesÚgen_even_slices)ÚHiddenÚIntervalÚ
StrOptionsÚvalidate_params)Úrandomized_svdÚ	row_normsÚsvd_flip)ÚParallelÚdelayed)Úcheck_is_fittedc                 C   s   |r| dkrt d | ¡ƒ‚d S )N)ÚompÚlarsz9Positive constraint not supported for '{}' coding method.)Ú
ValueErrorÚformat©ÚmethodÚpositive© r%   úc/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sklearn/decomposition/_dict_learning.pyÚ_check_positive_coding   s    ÿr'   Ú
lasso_larsTéè  F©	ÚgramÚcovÚ	algorithmÚregularizationÚcopy_covÚinitÚmax_iterÚverboser$   c       	      	   C   s¼  | j \}}|j d }|dkr|t|ƒ| }z@tjdd�}t|d|	|d|
|d�}|j|j| j|d� |j}W 5 tjf |Ž X �n4|dkrât|ƒ| }t|d||d	|
d
�}|dk	rÆ|j	d sÀt 
|¡}||_|j|j| jdd� |j}nÎ|dk�r>z@tjdd�}td|	|t|ƒdd�}|j|j| j|d� |j}W 5 tjf |Ž X nr|dk�r„t |¡t t |¡| d¡ j}|
�r°tj|dd|d� n,|dk�r°t||t|ƒdt| d	d�|d�j}| ||¡S )a¶	  Generic sparse coding with precomputed Gram and/or covariance matrices.

    Each row of the result is the solution to a Lasso problem.

    Parameters
    ----------
    X : ndarray of shape (n_samples, n_features)
        Data matrix.

    dictionary : ndarray of shape (n_components, n_features)
        The dictionary matrix against which to solve the sparse coding of
        the data. Some of the algorithms assume normalized rows.

    gram : ndarray of shape (n_components, n_components), default=None
        Precomputed Gram matrix, `dictionary * dictionary'`
        gram can be `None` if method is 'threshold'.

    cov : ndarray of shape (n_components, n_samples), default=None
        Precomputed covariance, `dictionary * X'`.

    algorithm : {'lasso_lars', 'lasso_cd', 'lars', 'omp', 'threshold'},             default='lasso_lars'
        The algorithm used:

        * `'lars'`: uses the least angle regression method
          (`linear_model.lars_path`);
        * `'lasso_lars'`: uses Lars to compute the Lasso solution;
        * `'lasso_cd'`: uses the coordinate descent method to compute the
          Lasso solution (`linear_model.Lasso`). lasso_lars will be faster if
          the estimated components are sparse;
        * `'omp'`: uses orthogonal matching pursuit to estimate the sparse
          solution;
        * `'threshold'`: squashes to zero all coefficients less than
          regularization from the projection `dictionary * data'`.

    regularization : int or float, default=None
        The regularization parameter. It corresponds to alpha when
        algorithm is `'lasso_lars'`, `'lasso_cd'` or `'threshold'`.
        Otherwise it corresponds to `n_nonzero_coefs`.

    init : ndarray of shape (n_samples, n_components), default=None
        Initialization value of the sparse code. Only used if
        `algorithm='lasso_cd'`.

    max_iter : int, default=1000
        Maximum number of iterations to perform if `algorithm='lasso_cd'` or
        `'lasso_lars'`.

    copy_cov : bool, default=True
        Whether to copy the precomputed covariance matrix; if `False`, it may
        be overwritten.

    verbose : int, default=0
        Controls the verbosity; the higher, the more messages.

    positive: bool, default=False
        Whether to enforce a positivity constraint on the sparse code.

        .. versionadded:: 0.20

    Returns
    -------
    code : ndarray of shape (n_components, n_features)
        The sparse codes.
    r   r(   Úignore)ÚallF)ÚalphaÚfit_interceptr2   Ú
precomputeÚfit_pathr$   r1   )ÚXyÚlasso_cdT)r5   r6   r7   r1   Z
warm_startr$   NZ	WRITEABLE)Úcheck_inputr   )r6   r2   r7   Ún_nonzero_coefsr8   Ú	threshold©Úoutr   )Zsquared)ZGramr9   r<   ÚtolZnorms_squaredZcopy_Xy)ÚshapeÚfloatÚnpZseterrr   ÚfitÚTZcoef_r   ÚflagsÚarrayr   ÚintÚsignÚmaximumÚabsÚclipr   r   Zreshape)ÚXÚ
dictionaryr+   r,   r-   r.   r/   r0   r1   r2   r$   Ú	n_samplesÚ
n_featuresÚn_componentsr5   Zerr_mgtr(   Znew_codeZclfr   r%   r%   r&   Ú_sparse_encode_precomputed&   sz    O

ù	
ú	


û

"

ú	rR   z
array-liker:   r   r   r=   é   Úleft©ÚclosedÚbooleanr2   ©rM   rN   r+   r,   r-   r<   r5   r/   r0   r1   Ún_jobsr;   r2   r$   ©Zprefer_skip_nested_validation)r+   r,   r-   r<   r5   r/   r0   r1   rY   r;   r2   r$   c                C   sž   |rJ|dkr:t |dtjtjgd�}t | dtjtjgd�} nt |ƒ}t | ƒ} |jd | jd krrtd |j| j¡ƒ‚t||ƒ t| |||||||||	|
||d�S )aF  Sparse coding.

    Each row of the result is the solution to a sparse coding problem.
    The goal is to find a sparse array `code` such that::

        X ~= code * dictionary

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

    Parameters
    ----------
    X : array-like of shape (n_samples, n_features)
        Data matrix.

    dictionary : array-like of shape (n_components, n_features)
        The dictionary matrix against which to solve the sparse coding of
        the data. Some of the algorithms assume normalized rows for meaningful
        output.

    gram : array-like of shape (n_components, n_components), default=None
        Precomputed Gram matrix, `dictionary * dictionary'`.

    cov : array-like of shape (n_components, n_samples), default=None
        Precomputed covariance, `dictionary' * X`.

    algorithm : {'lasso_lars', 'lasso_cd', 'lars', 'omp', 'threshold'},             default='lasso_lars'
        The algorithm used:

        * `'lars'`: uses the least angle regression method
          (`linear_model.lars_path`);
        * `'lasso_lars'`: uses Lars to compute the Lasso solution;
        * `'lasso_cd'`: uses the coordinate descent method to compute the
          Lasso solution (`linear_model.Lasso`). lasso_lars will be faster if
          the estimated components are sparse;
        * `'omp'`: uses orthogonal matching pursuit to estimate the sparse
          solution;
        * `'threshold'`: squashes to zero all coefficients less than
          regularization from the projection `dictionary * data'`.

    n_nonzero_coefs : int, default=None
        Number of nonzero coefficients to target in each column of the
        solution. This is only used by `algorithm='lars'` and `algorithm='omp'`
        and is overridden by `alpha` in the `omp` case. If `None`, then
        `n_nonzero_coefs=int(n_features / 10)`.

    alpha : float, default=None
        If `algorithm='lasso_lars'` or `algorithm='lasso_cd'`, `alpha` is the
        penalty applied to the L1 norm.
        If `algorithm='threshold'`, `alpha` is the absolute value of the
        threshold below which coefficients will be squashed to zero.
        If `algorithm='omp'`, `alpha` is the tolerance parameter: the value of
        the reconstruction error targeted. In this case, it overrides
        `n_nonzero_coefs`.
        If `None`, default to 1.

    copy_cov : bool, default=True
        Whether to copy the precomputed covariance matrix; if `False`, it may
        be overwritten.

    init : ndarray of shape (n_samples, n_components), default=None
        Initialization value of the sparse codes. Only used if
        `algorithm='lasso_cd'`.

    max_iter : int, default=1000
        Maximum number of iterations to perform if `algorithm='lasso_cd'` or
        `'lasso_lars'`.

    n_jobs : int, default=None
        Number of parallel jobs to run.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

    check_input : bool, default=True
        If `False`, the input arrays X and dictionary will not be checked.

    verbose : int, default=0
        Controls the verbosity; the higher, the more messages.

    positive : bool, default=False
        Whether to enforce positivity when finding the encoding.

        .. versionadded:: 0.20

    Returns
    -------
    code : ndarray of shape (n_samples, n_components)
        The sparse codes.

    See Also
    --------
    sklearn.linear_model.lars_path : Compute Least Angle Regression or Lasso
        path using LARS algorithm.
    sklearn.linear_model.orthogonal_mp : Solves Orthogonal Matching Pursuit problems.
    sklearn.linear_model.Lasso : Train Linear Model with L1 prior as regularizer.
    SparseCoder : Find a sparse representation of data from a fixed precomputed
        dictionary.
    r:   ÚC)ÚorderÚdtyperS   zRDictionary and X have different numbers of features:dictionary.shape: {} X.shape{}©r+   r,   r-   r<   r5   r/   r0   r1   rY   r2   r$   )	r   rC   Úfloat64Úfloat32rA   r    r!   r'   Ú_sparse_encoderX   r%   r%   r&   Úsparse_encodeÍ   sD       
ÿ ÿÿ
órb   r^   c                   sL  ˆ j \}}ˆj d }ˆdkr>|‰	ˆ	dkrNtt|d dƒ|ƒ‰	n|‰	ˆ	dkrNd‰	ˆdkrlˆdkrlt ˆˆj¡‰ˆdkrŽˆdkrŽd	‰t ˆˆ j¡‰t|
ƒdks¢ˆdkrÄtˆ ˆˆˆˆˆ	ˆˆˆˆ
ˆd
�}|S ˆ j d }ˆj d }t ||f¡}t	t
|t|
ƒƒƒ}t|
ˆ
d�‡ ‡‡‡‡‡‡‡‡‡	‡
fdd„|D ƒƒ}t||ƒD ]\}}|||< �q4|S )z1Sparse coding without input/parameter validation.r   )r   r   Né
   rS   g      ð?r=   r:   Fr*   )rY   r2   c                 3   s\   | ]T}t tƒˆ | ˆˆˆd k	r.ˆd d …|f nd ˆˆ	ˆˆd k	rFˆ| nd ˆˆ
ˆd�V  qd S )Nr*   )r   rR   )Ú.0Ú
this_slice©rM   r-   r/   r,   rN   r+   r0   r1   r$   r.   r2   r%   r&   Ú	<genexpr>µ  s   óõz!_sparse_encode.<locals>.<genexpr>)rA   ÚminÚmaxrC   ÚdotrE   r   rR   ÚemptyÚlistr   r   Úzip)rM   rN   r+   r,   r-   r<   r5   r/   r0   r1   rY   r2   r$   rO   rP   rQ   ÚcodeZslicesZ
code_viewsre   Z	this_viewr%   rf   r&   ra   z  sN    

õ

(òra   c              	   C   sF  |j \}}	t|ƒ}|dkr$|j| }|dkr6|j| }d}
t|	ƒD ]à}|||f dkrŒ| |  |dd…|f || |   |||f  7  < nV|| |¡ }d| ¡ p¦d }|jd|t|ƒd�}|| | |< d|dd…|f< |
d7 }
|�rtj	| | dd| | d� | |  t
t | | ¡dƒ  < qB|�rB|
dk�rBt|
› d�ƒ dS )	a¯  Update the dense dictionary factor in place.

    Parameters
    ----------
    dictionary : ndarray of shape (n_components, n_features)
        Value of the dictionary at the previous iteration.

    Y : ndarray of shape (n_samples, n_features)
        Data matrix.

    code : ndarray of shape (n_samples, n_components)
        Sparse coding of the data against which to optimize the dictionary.

    A : ndarray of shape (n_components, n_components), default=None
        Together with `B`, sufficient stats of the online model to update the
        dictionary.

    B : ndarray of shape (n_features, n_components), default=None
        Together with `A`, sufficient stats of the online model to update the
        dictionary.

    verbose: bool, default=False
        Degree of output the procedure will print.

    random_state : int, RandomState instance or None, default=None
        Used for randomly initializing the dictionary. Pass an int for
        reproducible results across multiple function calls.
        See :term:`Glossary <random_state>`.

    positive : bool, default=False
        Whether to enforce positivity when finding the dictionary.

        .. versionadded:: 0.20
    Nr   g�íµ ÷Æ°>g{®Gáz„?rS   )Úsizer>   z unused atoms resampled.)rA   r   rE   ÚrangeÚchoiceZstdÚnormalÚlenrC   rL   ri   r   ÚnormÚprint)rN   ÚYrn   ÚAÚBr2   Úrandom_stater$   rO   rQ   Zn_unusedÚkZnewdZnoise_levelÚnoiser%   r%   r&   Ú_update_dictÊ  s*    ,


6"r|   c                C   sp  t   ¡ }|dk	r,|dk	r,tj|dd�}|}n8tj| dd�\}}}t||ƒ\}}|dd…tjf | }t|ƒ}||krž|dd…d|…f }|d|…dd…f }nBtj|t 	t|ƒ|| f¡f }tj
|t 	|| |jd f¡f }t |¡}g }tj}|
dk�r
tddd	� d
}t|ƒD �]2}t   ¡ | }|
dk�rJtj d¡ tj ¡  n|
�rhtd|||d |f ƒ t| ||||||||
d�	}t|| ||
||d� dt | ||  d ¡ |t t |¡¡  }| |¡ |dk�r&|d |d
  }|||d
  k �r&|
dk�rtdƒ n|
�r td| ƒ  �qL|d dk�r|	dk	�r|	tƒ ƒ �q|�rb||||d fS |||fS dS )z"Main dictionary learning algorithmNÚF)r\   F)Zfull_matricesrS   ú[dict_learning]ú ©ÚendéÿÿÿÿÚ.zCIteration % 3i (elapsed time: % 3is, % 4.1fmn, current cost % 7.3f)é<   )r-   r5   r0   rY   r$   r1   r2   ©r2   ry   r$   ç      à?r   r   éþÿÿÿÚ z+--- Convergence reached after %d iterationsé   )ÚtimerC   rG   r   Zsvdr   Únewaxisrs   Zc_ÚzerosÚr_rA   ZasfortranarrayÚnanru   rp   ÚsysÚstdoutÚwriteÚflushrb   r|   ÚsumrK   ÚappendÚlocals)rM   rQ   r5   r1   r@   r#   rY   Ú	dict_initÚ	code_initÚcallbackr2   ry   Úreturn_n_iterÚpositive_dictÚpositive_codeÚmethod_max_iterÚt0rn   rN   ÚSÚrÚerrorsZcurrent_costÚiiÚdtZdEr%   r%   r&   Ú_dict_learning  sˆ     ÿ


ÿÿ÷ú
ÿ



r£   c                 C   s>   | dkr6d|› d�}|r&|d|› �7 }t  |t¡ | S |S d S )NÚ
deprecatedú'zB' is deprecated in version 1.1 and will be removed in version 1.4.r   )ÚwarningsÚwarnÚFutureWarning)ÚparamÚnameÚdefaultÚadditional_messageÚmsgr%   r%   r&   Ú_check_warn_deprecated‹  s    
ÿr®   r¤   é   çü©ñÒMbP?rc   )r5   Ún_iterr1   Úreturn_coder–   r˜   Ú
batch_sizer2   ÚshufflerY   r#   Úiter_offsetry   Úreturn_inner_statsÚinner_statsr™   rš   r›   rœ   r@   Úmax_no_improvementc          -      C   sÌ  ||||f}|dk	r.t dd„ |D ƒƒs.tdƒ‚t|ddd�}t|dd	d
d�}t|ddd�}t|dd	dd�}|dk	rÊd| }t|||||||
||||||||	|||d� | ¡}|s¶|jS | | ¡}||jfS t|dddd�}|dkrì| jd }|dkrütdƒ‚t||ƒ d| }t	 	¡ }| j\}}t
|ƒ}t|ƒ}|dk	�r@|}n*t| ||d�\}} }| dd…tjf | }t|ƒ}!||!k�r’|d|…dd…f }n(tj|tj||! |jd f|jd�f }|	dk�rÐtddd� |
�rê|  ¡ }"| |"¡ n| }"t|"dtjtjgd	d�}"t|d|"jd	d�}tj|dd �}t||ƒ}#t |#¡}#|dk�rntj||f|"jd�}$tj||f|"jd�}%n|d  ¡ }$|d  ¡ }%|d }&tt||| ƒ|#ƒD �]B\}&}'|"|' }(t	 	¡ | })|	dk�râtj  !d!¡ tj  "¡  n<|	�r|	d"k�s|&t#d#|	 ƒ dk�rtd$|&|)|)d% f ƒ t$|(||||d	|||	d&�	}*|&|d k �rXt
|&d | ƒ}+nt
|d' |& d | ƒ}+|+d | |+d  },|$|,9 }$|$t %|*j&|*¡7 }$|%|,9 }%|%t %|(j&|*¡7 }%t'||(|*|$|%|	||d(� |dk	�r¢|t(ƒ ƒ �q¢|�r|�r
||$|%f|&| d fS ||$|%ffS |�r®|	dk�r4td)dd� n|	dk�rJtd*dd� t$| ||||d	|||	d&�	}|	dk�rŽt	 	¡ | })td+|)|)d% f ƒ |�r¦|||&| d fS ||fS |�rÄ||&| d fS |S dS ),a[  Solve a dictionary learning matrix factorization problem online.

    Finds the best dictionary and the corresponding sparse code for
    approximating the data matrix X by solving::

        (U^*, V^*) = argmin 0.5 || X - U V ||_Fro^2 + alpha * || U ||_1,1
                     (U,V)
                     with || V_k ||_2 = 1 for all  0 <= k < n_components

    where V is the dictionary and U is the sparse code. ||.||_Fro stands for
    the Frobenius norm and ||.||_1,1 stands for the entry-wise matrix norm
    which is the sum of the absolute values of all the entries in the matrix.
    This is accomplished by repeatedly iterating over mini-batches by slicing
    the input data.

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

    Parameters
    ----------
    X : ndarray of shape (n_samples, n_features)
        Data matrix.

    n_components : int or None, default=2
        Number of dictionary atoms to extract. If None, then ``n_components``
        is set to ``n_features``.

    alpha : float, default=1
        Sparsity controlling parameter.

    n_iter : int, default=100
        Number of mini-batch iterations to perform.

        .. deprecated:: 1.1
           `n_iter` is deprecated in 1.1 and will be removed in 1.4. Use
           `max_iter` instead.

    max_iter : int, default=None
        Maximum number of iterations over the complete dataset before
        stopping independently of any early stopping criterion heuristics.
        If ``max_iter`` is not None, ``n_iter`` is ignored.

        .. versionadded:: 1.1

    return_code : bool, default=True
        Whether to also return the code U or just the dictionary `V`.

    dict_init : ndarray of shape (n_components, n_features), default=None
        Initial values for the dictionary for warm restart scenarios.
        If `None`, the initial values for the dictionary are created
        with an SVD decomposition of the data via
        :func:`~sklearn.utils.extmath.randomized_svd`.

    callback : callable, default=None
        A callable that gets invoked at the end of each iteration.

    batch_size : int, default=256
        The number of samples to take in each batch.

        .. versionchanged:: 1.3
           The default value of `batch_size` changed from 3 to 256 in version 1.3.

    verbose : bool, default=False
        To control the verbosity of the procedure.

    shuffle : bool, default=True
        Whether to shuffle the data before splitting it in batches.

    n_jobs : int, default=None
        Number of parallel jobs to run.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

    method : {'lars', 'cd'}, default='lars'
        * `'lars'`: uses the least angle regression method to solve the lasso
          problem (`linear_model.lars_path`);
        * `'cd'`: uses the coordinate descent method to compute the
          Lasso solution (`linear_model.Lasso`). Lars will be faster if
          the estimated components are sparse.

    iter_offset : int, default=0
        Number of previous iterations completed on the dictionary used for
        initialization.

        .. deprecated:: 1.1
           `iter_offset` serves internal purpose only and will be removed in 1.4.

    random_state : int, RandomState instance or None, default=None
        Used for initializing the dictionary when ``dict_init`` is not
        specified, randomly shuffling the data when ``shuffle`` is set to
        ``True``, and updating the dictionary. Pass an int for reproducible
        results across multiple function calls.
        See :term:`Glossary <random_state>`.

    return_inner_stats : bool, default=False
        Return the inner statistics A (dictionary covariance) and B
        (data approximation). Useful to restart the algorithm in an
        online setting. If `return_inner_stats` is `True`, `return_code` is
        ignored.

        .. deprecated:: 1.1
           `return_inner_stats` serves internal purpose only and will be removed in 1.4.

    inner_stats : tuple of (A, B) ndarrays, default=None
        Inner sufficient statistics that are kept by the algorithm.
        Passing them at initialization is useful in online settings, to
        avoid losing the history of the evolution.
        `A` `(n_components, n_components)` is the dictionary covariance matrix.
        `B` `(n_features, n_components)` is the data approximation matrix.

        .. deprecated:: 1.1
           `inner_stats` serves internal purpose only and will be removed in 1.4.

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

        .. deprecated:: 1.1
           `return_n_iter` will be removed in 1.4 and n_iter will never be returned.

    positive_dict : bool, default=False
        Whether to enforce positivity when finding the dictionary.

        .. versionadded:: 0.20

    positive_code : bool, default=False
        Whether to enforce positivity when finding the code.

        .. versionadded:: 0.20

    method_max_iter : int, default=1000
        Maximum number of iterations to perform when solving the lasso problem.

        .. versionadded:: 0.22

    tol : float, default=1e-3
        Control early stopping based on the norm of the differences in the
        dictionary between 2 steps. Used only if `max_iter` is not None.

        To disable early stopping based on changes in the dictionary, set
        `tol` to 0.0.

        .. versionadded:: 1.1

    max_no_improvement : int, default=10
        Control early stopping based on the consecutive number of mini batches
        that does not yield an improvement on the smoothed cost function. Used only if
        `max_iter` is not None.

        To disable convergence detection based on cost function, set
        `max_no_improvement` to None.

        .. versionadded:: 1.1

    Returns
    -------
    code : ndarray of shape (n_samples, n_components),
        The sparse code (only returned if `return_code=True`).

    dictionary : ndarray of shape (n_components, n_features),
        The solutions to the dictionary learning problem.

    n_iter : int
        Number of iterations run. Returned only if `return_n_iter` is
        set to `True`.

    See Also
    --------
    dict_learning : Solve a dictionary learning matrix factorization problem.
    DictionaryLearning : Find a dictionary that sparsely encodes data.
    MiniBatchDictionaryLearning : A faster, less accurate, version of the dictionary
        learning algorithm.
    SparsePCA : Sparse Principal Components Analysis.
    MiniBatchSparsePCA : Mini-batch Sparse Principal Components Analysis.
    Nc                 s   s   | ]}|d kV  qdS )r¤   Nr%   )rd   Úargr%   r%   r&   rg   a  s     z'dict_learning_online.<locals>.<genexpr>zuThe following arguments are incompatible with 'max_iter': return_n_iter, return_inner_stats, iter_offset, inner_statsrµ   r   )r«   r¶   Fz,From 1.4 inner_stats will never be returned.)r«   r¬   r·   r™   z�From 1.4 'n_iter' will never be returned. Refer to the 'n_iter_' and 'n_steps_' attributes of the MiniBatchDictionaryLearning object instead.Úlasso_)rQ   r5   r±   rY   Úfit_algorithmr³   r´   r–   ry   Útransform_algorithmÚtransform_alphar›   rš   Útransform_max_iterr2   r˜   r@   r¸   r±   éd   zUse 'max_iter' instead.rS   )r   Úcdz/Coding method not supported as a fit algorithm.©ry   ©r]   r~   r   r€   r[   ©r\   r]   Úcopyr}   ÚW©Úrequirementsrƒ   rc   ç      Y@z.Iteration % 3i (elapsed time: % 3is, % 4.1fmn)r„   )r-   r5   rY   r;   r$   r1   r2   r   r…   zLearning code...ú|z"done (total time: % 3is, % 4.1fmn)))r4   r    r®   ÚMiniBatchDictionaryLearningrD   Úcomponents_Ú	transformrA   r'   rŠ   rB   r   r   rC   r‹   rs   r�   rŒ   r]   ru   rÄ   r´   r   r_   r`   Úrequirer   Ú	itertoolsÚcyclerm   rp   r�   r�   r‘   r’   r   rb   rj   rE   r|   r•   )-rM   rQ   r5   r±   r1   r²   r–   r˜   r³   r2   r´   rY   r#   rµ   ry   r¶   r·   r™   rš   r›   rœ   r@   r¸   Údepsr¼   Zestrn   r�   rO   rP   rN   Ú_rž   rŸ   ÚX_trainÚbatchesrw   rx   r¡   ÚbatchZthis_Xr¢   Z	this_codeÚthetaÚbetar%   r%   r&   Údict_learning_online˜  sR    Iÿüû
îí

   ÿ




ÿÿ
  
 ÿ



 ÿ÷ø


÷
r×   rÀ   )rM   r#   r™   rœ   r¿   ç:Œ0âŽyE>)r1   r@   r#   rY   r–   r—   r˜   r2   ry   r™   rš   r›   rœ   c                C   sR   t ||||||||	||
||||d�}| | ¡}|rD||j|j|jfS ||j|jfS )a0  Solve a dictionary learning matrix factorization problem.

    Finds the best dictionary and the corresponding sparse code for
    approximating the data matrix X by solving::

        (U^*, V^*) = argmin 0.5 || X - U V ||_Fro^2 + alpha * || U ||_1,1
                     (U,V)
                    with || V_k ||_2 = 1 for all  0 <= k < n_components

    where V is the dictionary and U is the sparse code. ||.||_Fro stands for
    the Frobenius norm and ||.||_1,1 stands for the entry-wise matrix norm
    which is the sum of the absolute values of all the entries in the matrix.

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

    Parameters
    ----------
    X : array-like of shape (n_samples, n_features)
        Data matrix.

    n_components : int
        Number of dictionary atoms to extract.

    alpha : int or float
        Sparsity controlling parameter.

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

    tol : float, default=1e-8
        Tolerance for the stopping condition.

    method : {'lars', 'cd'}, default='lars'
        The method used:

        * `'lars'`: uses the least angle regression method to solve the lasso
           problem (`linear_model.lars_path`);
        * `'cd'`: uses the coordinate descent method to compute the
          Lasso solution (`linear_model.Lasso`). Lars will be faster if
          the estimated components are sparse.

    n_jobs : int, default=None
        Number of parallel jobs to run.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

    dict_init : ndarray of shape (n_components, n_features), default=None
        Initial value for the dictionary for warm restart scenarios. Only used
        if `code_init` and `dict_init` are not None.

    code_init : ndarray of shape (n_samples, n_components), default=None
        Initial value for the sparse code for warm restart scenarios. Only used
        if `code_init` and `dict_init` are not None.

    callback : callable, default=None
        Callable that gets invoked every five iterations.

    verbose : bool, default=False
        To control the verbosity of the procedure.

    random_state : int, RandomState instance or None, default=None
        Used for randomly initializing the dictionary. Pass an int for
        reproducible results across multiple function calls.
        See :term:`Glossary <random_state>`.

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

    positive_dict : bool, default=False
        Whether to enforce positivity when finding the dictionary.

        .. versionadded:: 0.20

    positive_code : bool, default=False
        Whether to enforce positivity when finding the code.

        .. versionadded:: 0.20

    method_max_iter : int, default=1000
        Maximum number of iterations to perform.

        .. versionadded:: 0.22

    Returns
    -------
    code : ndarray of shape (n_samples, n_components)
        The sparse code factor in the matrix factorization.

    dictionary : ndarray of shape (n_components, n_features),
        The dictionary factor in the matrix factorization.

    errors : array
        Vector of errors at each iteration.

    n_iter : int
        Number of iterations run. Returned only if `return_n_iter` is
        set to True.

    See Also
    --------
    dict_learning_online : Solve a dictionary learning matrix factorization
        problem online.
    DictionaryLearning : Find a dictionary that sparsely encodes data.
    MiniBatchDictionaryLearning : A faster, less accurate version
        of the dictionary learning algorithm.
    SparsePCA : Sparse Principal Components Analysis.
    MiniBatchSparsePCA : Mini-batch Sparse Principal Components Analysis.
    )rQ   r5   r1   r@   r»   rY   r–   r˜   r—   r2   ry   r›   rš   r¾   )ÚDictionaryLearningÚfit_transformrË   Úerror_Ún_iter_)rM   rQ   r5   r1   r@   r#   rY   r–   r—   r˜   r2   ry   r™   rš   r›   rœ   Z	estimatorrn   r%   r%   r&   Údict_learning6  s2     
ò
ürÝ   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú_BaseSparseCodingz>Base class from SparseCoder and DictionaryLearning algorithms.c                 C   s.   || _ || _|| _|| _|| _|| _|| _d S ©N)r¼   Útransform_n_nonzero_coefsr½   r¾   Ú
split_signrY   r›   )Úselfr¼   rà   r½   rá   rY   r›   r¾   r%   r%   r&   Ú__init__Ý  s    
z_BaseSparseCoding.__init__c              
   C   s¶   | j |dd�}t| dƒr*| jdkr*| j}n| j}t||| j| j|| j| j| j	d�}| j
r²|j\}}t |d| f¡}t |d¡|dd…d|…f< t |d¡ |dd…|d…f< |}|S )zWPrivate method allowing to accommodate both DictionaryLearning and
        SparseCoder.F)Úresetr5   N)r-   r<   r5   r1   rY   r$   r   r   )Ú_validate_dataÚhasattrr½   r5   rb   r¼   rà   r¾   rY   r›   rá   rA   rC   rk   rJ   Úminimum)râ   rM   rN   r½   rn   rO   rP   Z
split_coder%   r%   r&   Ú
_transformï  s*    ø
z_BaseSparseCoding._transformc                 C   s   t | ƒ |  || j¡S )aû  Encode the data as a sparse combination of the dictionary atoms.

        Coding method is determined by the object parameter
        `transform_algorithm`.

        Parameters
        ----------
        X : ndarray of shape (n_samples, n_features)
            Test data to be transformed, must have the same number of
            features as the data used to train the model.

        Returns
        -------
        X_new : ndarray of shape (n_samples, n_components)
            Transformed data.
        )r   rè   rË   ©râ   rM   r%   r%   r&   rÌ     s    z_BaseSparseCoding.transformN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rã   rè   rÌ   r%   r%   r%   r&   rÞ   Ú  s   rÞ   c                       s|   e Zd ZdZdgZddddddddœ‡ fdd	„
Zdd
d„Zd‡ fdd„	Zdd„ Ze	dd„ ƒZ
e	dd„ ƒZe	dd„ ƒZ‡  ZS )ÚSparseCodera  Sparse coding.

    Finds a sparse representation of data against a fixed, precomputed
    dictionary.

    Each row of the result is the solution to a sparse coding problem.
    The goal is to find a sparse array `code` such that::

        X ~= code * dictionary

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

    Parameters
    ----------
    dictionary : ndarray of shape (n_components, n_features)
        The dictionary atoms used for sparse coding. Lines are assumed to be
        normalized to unit norm.

    transform_algorithm : {'lasso_lars', 'lasso_cd', 'lars', 'omp',             'threshold'}, default='omp'
        Algorithm used to transform the data:

        - `'lars'`: uses the least angle regression method
          (`linear_model.lars_path`);
        - `'lasso_lars'`: uses Lars to compute the Lasso solution;
        - `'lasso_cd'`: uses the coordinate descent method to compute the
          Lasso solution (linear_model.Lasso). `'lasso_lars'` will be faster if
          the estimated components are sparse;
        - `'omp'`: uses orthogonal matching pursuit to estimate the sparse
          solution;
        - `'threshold'`: squashes to zero all coefficients less than alpha from
          the projection ``dictionary * X'``.

    transform_n_nonzero_coefs : int, default=None
        Number of nonzero coefficients to target in each column of the
        solution. This is only used by `algorithm='lars'` and `algorithm='omp'`
        and is overridden by `alpha` in the `omp` case. If `None`, then
        `transform_n_nonzero_coefs=int(n_features / 10)`.

    transform_alpha : float, default=None
        If `algorithm='lasso_lars'` or `algorithm='lasso_cd'`, `alpha` is the
        penalty applied to the L1 norm.
        If `algorithm='threshold'`, `alpha` is the absolute value of the
        threshold below which coefficients will be squashed to zero.
        If `algorithm='omp'`, `alpha` is the tolerance parameter: the value of
        the reconstruction error targeted. In this case, it overrides
        `n_nonzero_coefs`.
        If `None`, default to 1.

    split_sign : bool, default=False
        Whether to split the sparse feature vector into the concatenation of
        its negative part and its positive part. This can improve the
        performance of downstream classifiers.

    n_jobs : int, default=None
        Number of parallel jobs to run.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

    positive_code : bool, default=False
        Whether to enforce positivity when finding the code.

        .. versionadded:: 0.20

    transform_max_iter : int, default=1000
        Maximum number of iterations to perform if `algorithm='lasso_cd'` or
        `lasso_lars`.

        .. versionadded:: 0.22

    Attributes
    ----------
    n_components_ : int
        Number of atoms.

    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

    See Also
    --------
    DictionaryLearning : Find a dictionary that sparsely encodes data.
    MiniBatchDictionaryLearning : A faster, less accurate, version of the
        dictionary learning algorithm.
    MiniBatchSparsePCA : Mini-batch Sparse Principal Components Analysis.
    SparsePCA : Sparse Principal Components Analysis.
    sparse_encode : Sparse coding where each row of the result is the solution
        to a sparse coding problem.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.decomposition import SparseCoder
    >>> X = np.array([[-1, -1, -1], [0, 0, 3]])
    >>> dictionary = np.array(
    ...     [[0, 1, 0],
    ...      [-1, -1, 2],
    ...      [1, 1, 1],
    ...      [0, 1, 1],
    ...      [0, 2, 1]],
    ...    dtype=np.float64
    ... )
    >>> coder = SparseCoder(
    ...     dictionary=dictionary, transform_algorithm='lasso_lars',
    ...     transform_alpha=1e-10,
    ... )
    >>> coder.transform(X)
    array([[ 0.,  0., -1.,  0.,  0.],
           [ 0.,  1.,  1.,  0.,  0.]])
    rN   r   NFr)   )r¼   rà   r½   rá   rY   r›   r¾   c          	   	      s"   t ƒ  |||||||¡ || _d S rß   )Úsuperrã   rN   )	râ   rN   r¼   rà   r½   rá   rY   r›   r¾   ©Ú	__class__r%   r&   rã   �  s    ù	zSparseCoder.__init__c                 C   s   | S )aÌ  Do nothing and return the estimator unchanged.

        This method is just there to implement the usual API and hence
        work in pipelines.

        Parameters
        ----------
        X : Ignored
            Not used, present for API consistency by convention.

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

        Returns
        -------
        self : object
            Returns the instance itself.
        r%   ©râ   rM   Úyr%   r%   r&   rD   ´  s    zSparseCoder.fitc                    s   t ƒ  || j¡S )aQ  Encode the data as a sparse combination of the dictionary atoms.

        Coding method is determined by the object parameter
        `transform_algorithm`.

        Parameters
        ----------
        X : ndarray of shape (n_samples, n_features)
            Training vector, 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)
            Transformed data.
        )rï   rè   rN   rò   rð   r%   r&   rÌ   É  s    zSparseCoder.transformc                 C   s   dt jt jgdœS )NF)Zrequires_fitÚpreserves_dtype©rC   r_   r`   ©râ   r%   r%   r&   Ú
_more_tagsß  s    
þzSparseCoder._more_tagsc                 C   s   | j jd S )zNumber of atoms.r   ©rN   rA   rö   r%   r%   r&   Ún_components_å  s    zSparseCoder.n_components_c                 C   s   | j jd S )z%Number of features seen during `fit`.rS   rø   rö   r%   r%   r&   Ún_features_in_ê  s    zSparseCoder.n_features_in_c                 C   s   | j S )ú&Number of transformed output features.)rù   rö   r%   r%   r&   Ú_n_features_outï  s    zSparseCoder._n_features_out)N)N)rê   rë   rì   rí   Z_required_parametersrã   rD   rÌ   r÷   Úpropertyrù   rú   rü   Ú__classcell__r%   r%   rð   r&   rî   #  s&   wö


rî   c                       sN  e Zd ZU dZeedddd�dgeedddd�geedddd�geedddd�geddhƒged	d
dddhƒgeedddd�dgeedddd�dgedgej	dgej	dge
dgdgdgdgdgdgeedddd�gdœZeed< d"ddddddddddddddddddœ‡ fdd„Zd#dd„Zedd�d$dd„ƒZedd„ ƒZd d!„ Z‡  ZS )%rÙ   aà  Dictionary learning.

    Finds a dictionary (a set of atoms) that performs well at sparsely
    encoding the fitted data.

    Solves the optimization problem::

        (U^*,V^*) = argmin 0.5 || X - U V ||_Fro^2 + alpha * || U ||_1,1
                    (U,V)
                    with || V_k ||_2 <= 1 for all  0 <= k < n_components

    ||.||_Fro stands for the Frobenius norm and ||.||_1,1 stands for
    the entry-wise matrix norm which is the sum of the absolute values
    of all the entries in the matrix.

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

    Parameters
    ----------
    n_components : int, default=None
        Number of dictionary elements to extract. If None, then ``n_components``
        is set to ``n_features``.

    alpha : float, default=1.0
        Sparsity controlling parameter.

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

    tol : float, default=1e-8
        Tolerance for numerical error.

    fit_algorithm : {'lars', 'cd'}, default='lars'
        * `'lars'`: uses the least angle regression method to solve the lasso
          problem (:func:`~sklearn.linear_model.lars_path`);
        * `'cd'`: uses the coordinate descent method to compute the
          Lasso solution (:class:`~sklearn.linear_model.Lasso`). Lars will be
          faster if the estimated components are sparse.

        .. versionadded:: 0.17
           *cd* coordinate descent method to improve speed.

    transform_algorithm : {'lasso_lars', 'lasso_cd', 'lars', 'omp',             'threshold'}, default='omp'
        Algorithm used to transform the data:

        - `'lars'`: uses the least angle regression method
          (:func:`~sklearn.linear_model.lars_path`);
        - `'lasso_lars'`: uses Lars to compute the Lasso solution.
        - `'lasso_cd'`: uses the coordinate descent method to compute the
          Lasso solution (:class:`~sklearn.linear_model.Lasso`). `'lasso_lars'`
          will be faster if the estimated components are sparse.
        - `'omp'`: uses orthogonal matching pursuit to estimate the sparse
          solution.
        - `'threshold'`: squashes to zero all coefficients less than alpha from
          the projection ``dictionary * X'``.

        .. versionadded:: 0.17
           *lasso_cd* coordinate descent method to improve speed.

    transform_n_nonzero_coefs : int, default=None
        Number of nonzero coefficients to target in each column of the
        solution. This is only used by `algorithm='lars'` and
        `algorithm='omp'`. If `None`, then
        `transform_n_nonzero_coefs=int(n_features / 10)`.

    transform_alpha : float, default=None
        If `algorithm='lasso_lars'` or `algorithm='lasso_cd'`, `alpha` is the
        penalty applied to the L1 norm.
        If `algorithm='threshold'`, `alpha` is the absolute value of the
        threshold below which coefficients will be squashed to zero.
        If `None`, defaults to `alpha`.

        .. versionchanged:: 1.2
            When None, default value changed from 1.0 to `alpha`.

    n_jobs : int or None, default=None
        Number of parallel jobs to run.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

    code_init : ndarray of shape (n_samples, n_components), default=None
        Initial value for the code, for warm restart. Only used if `code_init`
        and `dict_init` are not None.

    dict_init : ndarray of shape (n_components, n_features), default=None
        Initial values for the dictionary, for warm restart. Only used if
        `code_init` and `dict_init` are not None.

    callback : callable, default=None
        Callable that gets invoked every five iterations.

        .. versionadded:: 1.3

    verbose : bool, default=False
        To control the verbosity of the procedure.

    split_sign : bool, default=False
        Whether to split the sparse feature vector into the concatenation of
        its negative part and its positive part. This can improve the
        performance of downstream classifiers.

    random_state : int, RandomState instance or None, default=None
        Used for initializing the dictionary when ``dict_init`` is not
        specified, randomly shuffling the data when ``shuffle`` is set to
        ``True``, and updating the dictionary. Pass an int for reproducible
        results across multiple function calls.
        See :term:`Glossary <random_state>`.

    positive_code : bool, default=False
        Whether to enforce positivity when finding the code.

        .. versionadded:: 0.20

    positive_dict : bool, default=False
        Whether to enforce positivity when finding the dictionary.

        .. versionadded:: 0.20

    transform_max_iter : int, default=1000
        Maximum number of iterations to perform if `algorithm='lasso_cd'` or
        `'lasso_lars'`.

        .. versionadded:: 0.22

    Attributes
    ----------
    components_ : ndarray of shape (n_components, n_features)
        dictionary atoms extracted from the data

    error_ : array
        vector of errors at each iteration

    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
        Number of iterations run.

    See Also
    --------
    MiniBatchDictionaryLearning: A faster, less accurate, version of the
        dictionary learning algorithm.
    MiniBatchSparsePCA : Mini-batch Sparse Principal Components Analysis.
    SparseCoder : Find a sparse representation of data from a fixed,
        precomputed dictionary.
    SparsePCA : Sparse Principal Components Analysis.

    References
    ----------

    J. Mairal, F. Bach, J. Ponce, G. Sapiro, 2009: Online dictionary learning
    for sparse coding (https://www.di.ens.fr/sierra/pdfs/icml09.pdf)

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.datasets import make_sparse_coded_signal
    >>> from sklearn.decomposition import DictionaryLearning
    >>> X, dictionary, code = make_sparse_coded_signal(
    ...     n_samples=30, n_components=15, n_features=20, n_nonzero_coefs=10,
    ...     random_state=42,
    ... )
    >>> dict_learner = DictionaryLearning(
    ...     n_components=15, transform_algorithm='lasso_lars', transform_alpha=0.1,
    ...     random_state=42,
    ... )
    >>> X_transformed = dict_learner.fit(X).transform(X)

    We can check the level of sparsity of `X_transformed`:

    >>> np.mean(X_transformed == 0)
    0.52...

    We can compare the average squared euclidean norm of the reconstruction
    error of the sparse coded signal relative to the squared euclidean norm of
    the original signal:

    >>> X_hat = X_transformed @ dict_learner.components_
    >>> np.mean(np.sum((X_hat - X) ** 2, axis=1) / np.sum(X ** 2, axis=1))
    0.05...
    rS   NrT   rU   r   r   rÀ   r(   r:   r   r=   r2   rW   ry   )rQ   r5   r1   r@   r»   r¼   rà   r½   rY   r—   r–   r˜   r2   rá   ry   r›   rš   r¾   Ú_parameter_constraintsr)   rØ   F)r5   r1   r@   r»   r¼   rà   r½   rY   r—   r–   r˜   r2   rá   ry   r›   rš   r¾   c             	      s^   t ƒ  |||||	||¡ || _|| _|| _|| _|| _|
| _|| _|| _	|| _
|| _|| _d S rß   )rï   rã   rQ   r5   r1   r@   r»   r—   r–   r˜   r2   ry   rš   )râ   rQ   r5   r1   r@   r»   r¼   rà   r½   rY   r—   r–   r˜   r2   rá   ry   r›   rš   r¾   rð   r%   r&   rã   Í  s(    ù	zDictionaryLearning.__init__c                 C   s   |   |¡ | S )á»  Fit the model from data in X.

        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.

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

        Returns
        -------
        self : object
            Returns the instance itself.
        )rÚ   rò   r%   r%   r&   rD   ø  s    
zDictionaryLearning.fitTrZ   c           	      C   s¢   t | j| jd� d| j }t| jƒ}|  |¡}| jdkrD|jd }n| j}t||| j	| j
| j|| j| j| j| j| j| j|d| j| jd�\}}}| _|| _|| _|S )añ  Fit the model from data in X and return the transformed data.

        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.

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

        Returns
        -------
        V : ndarray of shape (n_samples, n_components)
            Transformed data.
        r"   rº   NrS   T)r5   r@   r1   r#   rœ   rY   r—   r–   r˜   r2   ry   r™   rš   r›   )r'   r»   r›   r   ry   rå   rQ   rA   r£   r5   r@   r1   r¾   rY   r—   r–   r˜   r2   rš   rÜ   rË   rÛ   )	râ   rM   ró   r#   ry   rQ   ÚVÚUÚEr%   r%   r&   rÚ     s8    



ðz DictionaryLearning.fit_transformc                 C   s   | j jd S ©rû   r   ©rË   rA   rö   r%   r%   r&   rü   A  s    z"DictionaryLearning._n_features_outc                 C   s   dt jt jgiS ©Nrô   rõ   rö   r%   r%   r&   r÷   F  s     
ÿzDictionaryLearning._more_tags)N)N)N)rê   rë   rì   rí   r   r   r   r   rC   ÚndarrayÚcallablerÿ   ÚdictÚ__annotations__rã   rD   r   rÚ   rý   rü   r÷   rþ   r%   r%   rð   r&   rÙ   õ  s`   
 Bÿì þì+
4
rÙ   c                       sÂ  e Zd ZU dZeedddd�dgeedddd�geedddd�eedhƒƒgeedddd�dgedd	hƒgdegeedddd�gd
gde	j
geddd	ddhƒgeedddd�dgeedddd�dgdgd
gdgd
gd
geedddd�gdegeedddd�geedddd�dgdœZeed< d/dddd	dddddddddddddddddœ‡ fdd„Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zedd&�d0d'd(„ƒZedd&�d1d)d*„ƒZed+d,„ ƒZd-d.„ Z‡  ZS )2rÊ   a'  Mini-batch dictionary learning.

    Finds a dictionary (a set of atoms) that performs well at sparsely
    encoding the fitted data.

    Solves the optimization problem::

       (U^*,V^*) = argmin 0.5 || X - U V ||_Fro^2 + alpha * || U ||_1,1
                    (U,V)
                    with || V_k ||_2 <= 1 for all  0 <= k < n_components

    ||.||_Fro stands for the Frobenius norm and ||.||_1,1 stands for
    the entry-wise matrix norm which is the sum of the absolute values
    of all the entries in the matrix.

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

    Parameters
    ----------
    n_components : int, default=None
        Number of dictionary elements to extract.

    alpha : float, default=1
        Sparsity controlling parameter.

    n_iter : int, default=1000
        Total number of iterations over data batches to perform.

        .. deprecated:: 1.1
           ``n_iter`` is deprecated in 1.1 and will be removed in 1.4. Use
           ``max_iter`` instead.

    max_iter : int, default=None
        Maximum number of iterations over the complete dataset before
        stopping independently of any early stopping criterion heuristics.
        If ``max_iter`` is not None, ``n_iter`` is ignored.

        .. versionadded:: 1.1

    fit_algorithm : {'lars', 'cd'}, default='lars'
        The algorithm used:

        - `'lars'`: uses the least angle regression method to solve the lasso
          problem (`linear_model.lars_path`)
        - `'cd'`: uses the coordinate descent method to compute the
          Lasso solution (`linear_model.Lasso`). Lars will be faster if
          the estimated components are sparse.

    n_jobs : int, default=None
        Number of parallel jobs to run.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

    batch_size : int, default=256
        Number of samples in each mini-batch.

        .. versionchanged:: 1.3
           The default value of `batch_size` changed from 3 to 256 in version 1.3.

    shuffle : bool, default=True
        Whether to shuffle the samples before forming batches.

    dict_init : ndarray of shape (n_components, n_features), default=None
        Initial value of the dictionary for warm restart scenarios.

    transform_algorithm : {'lasso_lars', 'lasso_cd', 'lars', 'omp',             'threshold'}, default='omp'
        Algorithm used to transform the data:

        - `'lars'`: uses the least angle regression method
          (`linear_model.lars_path`);
        - `'lasso_lars'`: uses Lars to compute the Lasso solution.
        - `'lasso_cd'`: uses the coordinate descent method to compute the
          Lasso solution (`linear_model.Lasso`). `'lasso_lars'` will be faster
          if the estimated components are sparse.
        - `'omp'`: uses orthogonal matching pursuit to estimate the sparse
          solution.
        - `'threshold'`: squashes to zero all coefficients less than alpha from
          the projection ``dictionary * X'``.

    transform_n_nonzero_coefs : int, default=None
        Number of nonzero coefficients to target in each column of the
        solution. This is only used by `algorithm='lars'` and
        `algorithm='omp'`. If `None`, then
        `transform_n_nonzero_coefs=int(n_features / 10)`.

    transform_alpha : float, default=None
        If `algorithm='lasso_lars'` or `algorithm='lasso_cd'`, `alpha` is the
        penalty applied to the L1 norm.
        If `algorithm='threshold'`, `alpha` is the absolute value of the
        threshold below which coefficients will be squashed to zero.
        If `None`, defaults to `alpha`.

        .. versionchanged:: 1.2
            When None, default value changed from 1.0 to `alpha`.

    verbose : bool or int, default=False
        To control the verbosity of the procedure.

    split_sign : bool, default=False
        Whether to split the sparse feature vector into the concatenation of
        its negative part and its positive part. This can improve the
        performance of downstream classifiers.

    random_state : int, RandomState instance or None, default=None
        Used for initializing the dictionary when ``dict_init`` is not
        specified, randomly shuffling the data when ``shuffle`` is set to
        ``True``, and updating the dictionary. Pass an int for reproducible
        results across multiple function calls.
        See :term:`Glossary <random_state>`.

    positive_code : bool, default=False
        Whether to enforce positivity when finding the code.

        .. versionadded:: 0.20

    positive_dict : bool, default=False
        Whether to enforce positivity when finding the dictionary.

        .. versionadded:: 0.20

    transform_max_iter : int, default=1000
        Maximum number of iterations to perform if `algorithm='lasso_cd'` or
        `'lasso_lars'`.

        .. versionadded:: 0.22

    callback : callable, default=None
        A callable that gets invoked at the end of each iteration.

        .. versionadded:: 1.1

    tol : float, default=1e-3
        Control early stopping based on the norm of the differences in the
        dictionary between 2 steps. Used only if `max_iter` is not None.

        To disable early stopping based on changes in the dictionary, set
        `tol` to 0.0.

        .. versionadded:: 1.1

    max_no_improvement : int, default=10
        Control early stopping based on the consecutive number of mini batches
        that does not yield an improvement on the smoothed cost function. Used only if
        `max_iter` is not None.

        To disable convergence detection based on cost function, set
        `max_no_improvement` to None.

        .. versionadded:: 1.1

    Attributes
    ----------
    components_ : ndarray of shape (n_components, n_features)
        Components extracted from the data.

    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
        Number of iterations over the full dataset.

    n_steps_ : int
        Number of mini-batches processed.

        .. versionadded:: 1.1

    See Also
    --------
    DictionaryLearning : Find a dictionary that sparsely encodes data.
    MiniBatchSparsePCA : Mini-batch Sparse Principal Components Analysis.
    SparseCoder : Find a sparse representation of data from a fixed,
        precomputed dictionary.
    SparsePCA : Sparse Principal Components Analysis.

    References
    ----------

    J. Mairal, F. Bach, J. Ponce, G. Sapiro, 2009: Online dictionary learning
    for sparse coding (https://www.di.ens.fr/sierra/pdfs/icml09.pdf)

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.datasets import make_sparse_coded_signal
    >>> from sklearn.decomposition import MiniBatchDictionaryLearning
    >>> X, dictionary, code = make_sparse_coded_signal(
    ...     n_samples=30, n_components=15, n_features=20, n_nonzero_coefs=10,
    ...     random_state=42)
    >>> dict_learner = MiniBatchDictionaryLearning(
    ...     n_components=15, batch_size=3, transform_algorithm='lasso_lars',
    ...     transform_alpha=0.1, max_iter=20, random_state=42)
    >>> X_transformed = dict_learner.fit_transform(X)

    We can check the level of sparsity of `X_transformed`:

    >>> np.mean(X_transformed == 0) > 0.5
    True

    We can compare the average squared euclidean norm of the reconstruction
    error of the sparse coded signal relative to the squared euclidean norm of
    the original signal:

    >>> X_hat = X_transformed @ dict_learner.components_
    >>> np.mean(np.sum((X_hat - X) ** 2, axis=1) / np.sum(X ** 2, axis=1))
    0.052...
    rS   NrT   rU   r   r¤   rÀ   r   rW   r(   r:   r   r=   r2   ry   )rQ   r5   r±   r1   r»   rY   r³   r´   r–   r¼   rà   r½   r2   rá   ry   r›   rš   r¾   r˜   r@   r¸   rÿ   r¯   TFr)   r°   rc   )r5   r±   r1   r»   rY   r³   r´   r–   r¼   rà   r½   r2   rá   ry   r›   rš   r¾   r˜   r@   r¸   c             	      sv   t ƒ  |
||||||¡ || _|| _|| _|| _|| _|	| _|| _|| _	|| _
|| _|| _|| _|| _|| _|| _d S rß   )rï   rã   rQ   r5   r±   r1   r»   r–   r2   r´   r³   rá   ry   rš   r˜   r¸   r@   )râ   rQ   r5   r±   r1   r»   rY   r³   r´   r–   r¼   rà   r½   r2   rá   ry   r›   rš   r¾   r˜   r@   r¸   rð   r%   r&   rã   C  s0    ù	z$MiniBatchDictionaryLearning.__init__c                 C   sP   | j | _| jd kr|jd | _t| j| jƒ d| j | _t| j|jd ƒ| _	d S )NrS   rº   r   )
rQ   Ú_n_componentsrA   r'   r»   r›   Ú_fit_algorithmrh   r³   Ú_batch_sizeré   r%   r%   r&   Ú_check_paramsu  s    
z)MiniBatchDictionaryLearning._check_paramsc                 C   s¶   | j dk	r| j }n,t|| j|d�\}}}|dd…tjf | }| jt|ƒkrd|d| j…dd…f }n.t |tj| jt|ƒ |jd f|j	d�f¡}t
|d|j	dd�}tj|dd	�}|S )
z!Initialization of the dictionary.NrÁ   rS   rÂ   r}   FrÃ   rÅ   rÆ   )r–   r   r  rC   r‹   rs   ZconcatenaterŒ   rA   r]   r   rÍ   )râ   rM   ry   rN   rÑ   rž   r%   r%   r&   Ú_initialize_dict‚  s*    
  ÿþþÿ
z,MiniBatchDictionaryLearning._initialize_dictc                 C   s’   ||d k r|d | }n|d | d | }|d | |d  }|  j |9  _ |  j |j| | 7  _ |  j|9  _|  j|j| | 7  _dS )zUpdate the inner stats inplace.rS   r   N)Ú_ArE   Ú_B)râ   rM   rn   r³   ÚsteprÕ   rÖ   r%   r%   r&   Ú_update_inner_statsŸ  s    z/MiniBatchDictionaryLearning._update_inner_statsc              
   C   s”   |j d }t||| j| j| j| j| j| jd�}d|||  d  ¡  | jt	 t	 
|¡¡  | }|  ||||¡ t|||| j| j| j|| jd� |S )z7Perform the update on the dictionary for one minibatch.r   )r-   r5   rY   r$   r1   r2   r†   r   r…   )rA   ra   r  r5   rY   r›   r¾   r2   r“   rC   rK   r  r|   r  r  rš   )râ   rM   rN   ry   r  r³   rn   Ú
batch_costr%   r%   r&   Ú_minibatch_step¬  s8    
øÿýøz+MiniBatchDictionaryLearning._minibatch_stepc              	   C   sl  |j d }|d }|td|| ƒkrH| jrDtd|› d|› d|› �ƒ dS | jdkrZ|| _n.||d  }	t|	dƒ}	| jd|	  ||	  | _| jr°td|› d|› d|› d	| j› �ƒ t || ¡| j }
| jdkrö|
| jkrö| jròtd
|› d|› �ƒ dS | j	dk�s| j| j	k �r d| _
| j| _	n|  j
d7  _
| jdk	�rh| j
| jk�rh| j�rdtd|› d|› �ƒ dS dS )aÃ  Helper function to encapsulate the early stopping logic.

        Early stopping is based on two factors:
        - A small change of the dictionary between two minibatch updates. This is
          controlled by the tol parameter.
        - No more improvement on a smoothed estimate of the objective function for a
          a certain number of consecutive minibatch updates. This is controlled by
          the max_no_improvement parameter.
        r   rS   r¿   zMinibatch step ú/z: mean batch cost: FNz, ewa cost: z,Converged (small dictionary change) at step Tz>Converged (lack of improvement in objective function) at step )rA   rh   r2   ru   Ú	_ewa_costr   rt   r  r@   Ú_ewa_cost_minÚ_no_improvementr¸   )râ   rM   r  Znew_dictÚold_dictrO   r  Ún_stepsr³   r5   Z	dict_diffr%   r%   r&   Ú_check_convergenceÒ  sD    


ÿ
ÿ
þÿz.MiniBatchDictionaryLearning._check_convergencerZ   c              
   C   s˜  | j |tjtjgddd�}|  |¡ | jdkr@t dt¡ | j}t	| j
ƒ| _|  || j¡}| ¡ }| jr~| ¡ }| j |¡ n|}|j\}}| jrštdƒ tj| j| jf|jd�| _tj|| jf|jd�| _| jdk	�r¶d| _d| _d	| _t|| jƒ}	t |	¡}	tt  || j ¡ƒ}
| j|
 }d
}t!t"|ƒ|	ƒD ]f\}}|| }|  #||| j|¡}|  $|||||||¡�rp �q˜| j%dk	�rˆ|  %t&ƒ ¡ ||dd…< �q0|d | _'t  | j'|
 ¡| _(nØ| jdk�rÆdn| j}t|| jƒ}	t |	¡}	t!t"|ƒ|	ƒD ]v\}}|  #|| || j|¡ | j�o*|t d| j ƒ d	k}| jdk�s>|�rLt|› d�ƒ | j%dk	�rð|  %t&ƒ ¡ �qð|| _'t  |tt  || j ¡ƒ ¡| _(|| _)| S )r   r[   F)r]   r\   rÄ   r¤   z¼'n_iter' is deprecated in version 1.1 and will be removed in version 1.4. Use 'max_iter' and let 'n_iter' to its default value instead. 'n_iter' is also ignored if 'max_iter' is specified.r~   rÂ   Nr   r‚   rS   r)   rÈ   rc   z batches processed.)*rå   rC   r_   r`   r  r±   r¦   r§   r¨   r   ry   Ú_random_stater  rÄ   r´   rA   r2   ru   rŒ   r  r]   r  r  r1   r  r  r  r   r  rÎ   rÏ   rH   r   rm   rp   r  r  r˜   r•   Ún_steps_rÜ   rË   )râ   rM   ró   r±   rN   r  rÒ   rO   rP   rÓ   Zn_steps_per_iterr  ÚirÔ   ZX_batchr  Ztrigger_verboser%   r%   r&   rD   	  s”     
  ÿ

ù	

 ÿ

   ÿ      ÿ

 zMiniBatchDictionaryLearning.fitc                 C   sÀ   t | dƒ}| j|tjtjgd| d�}|sŽ|  |¡ t| jƒ| _|  	|| j¡}d| _
tj| j| jf|jd�| _tj|jd | jf|jd�| _n| j}|  ||| j| j
¡ || _|  j
d7  _
| S )aÒ  Update the model using the data in X as a mini-batch.

        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.

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

        Returns
        -------
        self : object
            Return the instance itself.
        rË   r[   )r]   r\   rä   r   rÂ   rS   )ræ   rå   rC   r_   r`   r  r   ry   r  r  r  rŒ   r  r]   r  rA   r  rË   r  )râ   rM   ró   Zhas_componentsrN   r%   r%   r&   Úpartial_fitŠ	  s&    
 
  ÿ
 z'MiniBatchDictionaryLearning.partial_fitc                 C   s   | j jd S r  r  rö   r%   r%   r&   rü   ·	  s    z+MiniBatchDictionaryLearning._n_features_outc                 C   s   dt jt jgiS r  rõ   rö   r%   r%   r&   r÷   ¼	  s     
ÿz&MiniBatchDictionaryLearning._more_tags)N)N)N)rê   rë   rì   rí   r   r   r   r   r   rC   r  r  rÿ   r	  r
  rã   r  r  r  r  r  r   rD   r   rý   rü   r÷   rþ   r%   r%   rð   r&   rÊ   L  s|   
 [þÿæ þé2&Ds,
rÊ   )NNFNF)N)r   ):rí   rÎ   r�   rŠ   r¦   Úmathr   Únumbersr   r   ÚnumpyrC   Zjoblibr   Zscipyr   Úbaser   r	   r
   r   Zlinear_modelr   r   r   r   Úutilsr   r   r   r   Zutils._param_validationr   r   r   r   Zutils.extmathr   r   r   Zutils.parallelr   r   Zutils.validationr   r'   rR   rb   ra   r|   r£   r®   r×   rÝ   rÞ   rî   rÙ   rÊ   r%   r%   r%   r&   Ú<module>   s  ô (ÿðíñ òT     ø
Pq
 þè   !üùï I S  Y