U
    3d)o                  
   @   s  d dl Z d dlZd dlmZ d dlZd dlm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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 d dlmZ d dlmZ d dlmZ ej ddgeddigeddigei ggdd Z!dd Z"ej#ddd Z$dd Z%dd Z&ee'dej ddgeddigeddigei ggej d d!ej d"d#ej d$d%d&d' Z(ej ddgeddigeddigei ggd(d) Z)d*d+ Z*ej dddgd,d- Z+d.d/ Z,ej ddgeddigeddigei ggd0d1 Z-ej dd2d3d4 Z.d5d6 Z/ej deegd7d8 Z0ej ddgeddigeddigei ggej d"d#ej d$d%d9d: Z1ej ddgeddigeddigei ggd;d< Z2ej d d=d>gej dd2ej d"d#ej d$d%d?d@ Z3dAdB Z4dCdD Z5dEdF Z6dGdH Z7eeddIdJ Z8dKdL Z9ej dMdNdOgdPdQ Z:ej ddgeddigeddigei ggdRdS Z;eedej dd2dTdU Z<dVdW Z=ej dXej>ej>fej?ej?fej@ej?fejAej?fgej ddgeddigeddigei ggdYdZ ZBej ddgeddigeddigei ggd[d\ ZCej deegd]d^ ZDej dMdNd d_d`dadbdcgddde ZEdfdg ZFdhdi ZGdjdk ZHdS )l    N)StringIO)linalg)NMFMiniBatchNMF)non_negative_factorization)_nmf
csc_matrix)assert_array_equal)assert_array_almost_equal)assert_almost_equal)assert_allclose)ignore_warnings)squared_norm)clone)ConvergenceWarning	Estimatorsolvercdmuc              	   C   sD   d}t d}tjt|d | f ddi|| W 5 Q R X d S )NzKMaximum number of iterations 1 reached. Increase it to improve convergence.   r   matchmax_iter   )nponespytestZwarnsr   fit)r   r   Zconvergence_warningA r!   H/tmp/pip-unpacked-wheel-zrfo1fqw/sklearn/decomposition/tests/test_nmf.pytest_convergence_warning   s
    
r#   c                  C   s`   t jjd} t | dd}dD ]6}tj|d|dd\}}|dk  sV|dk  r$t	q$d S )N*   
   )randomnndsvdnndsvdanndsvdarr   initrandom_state)
r   r&   mtrandRandomStateabsrandnnmf_initialize_nmfanyAssertionError)rngdatar+   WHr!   r!   r"   test_initialize_nn_output'   s
    r9   zbignore:The multiplicative update \('mu'\) solver cannot update zeros present in the initializationc               
   C   sf  t d} d}tjt|d tddd|  W 5 Q R X d}tjt|d t |   W 5 Q R X tdd	d
| }tjt|d ||   W 5 Q R X tjt|d t	|  dd W 5 Q R X dD ]}t
d|}tjt|d td|d|  W 5 Q R X tjt|d td|d|  W 5 Q R X tjt|d t	| d| W 5 Q R X qd S )Nr   zHInvalid beta_loss parameter: solver 'cd' does not handle beta_loss = 1.0r   r         ?)r   	beta_lossz!Negative values in data passed tor   皙?)tolr'   )r'   r(   r)   zLinit = '{}' can only be used when n_components <= min(n_samples, n_features)   r+   )r   r   r   raises
ValueErrorr   r   	transformr1   r2   reescapeformatr   )r    msgZclfr+   r!   r!   r"   test_parameter_checking0   s0    
rG   c                  C   sl   t jjd} t | dd}tj|ddd\}}t	t 
||| }t	||  }||kshtd S )Nr$   r%   r'   r?   )r   r&   r-   r.   r/   r0   r1   r2   r   normdotmeanr4   )r5   r    r7   r8   errorZsdevr!   r!   r"   test_initialize_closeS   s    rL   c            
      C   s   t jjd} t | dd}tj|ddd\}}tj|ddd\}}tj|dddd\}}||f||f||f||ffD ]"\}}	t|	|dk ||dk  qzd S )	Nr$   r%   r'   r?   r(   r)   r   r*   )	r   r&   r-   r.   r/   r0   r1   r2   r   )
r5   r6   W0H0ZWaZHaZWarZHarrefZevlr!   r!   r"   test_initialize_variants_   s    $rP   )categoryr+   )Nr'   r(   r)   r&   alpha_W)        r:   alpha_H)rS   r:   Zsamec                 C   sl   t jdt dd dt dd f }| f d|||dd|}||}|jdk  sd|dk  rhtd S )Ng      @r      r   r   )n_componentsr+   rR   rT   r,   )r   Zc_arangefit_transformcomponents_r3   r4   )r   r   r+   rR   rT   r    modeltransfr!   r!   r"   test_nmf_fit_nn_outputn   s    
&
r\   c                 C   sN   t jjd}| d	dddd|}t |dd}||jdk sJtd S )
Nr$      r)   r   iX  )r+   r,   r   rU   r<   )r]   )	r   r&   r-   r.   r/   r0   r   reconstruction_err_r4   )r   r   r5   ZpnmfXr!   r!   r"   test_nmf_fit_close   s     r`   c                  C   sH  d} d}d}d}d}d}t jjd}t | |g}t || }t|D ]}	||	|   ||	|  |	f< qLt ||g}
t ||}t|D ]}	||	|  |
|	| |	f< qt ||
}t	|d||d	d
}|
|}t ||j}|jdk stt|| t|||d	|d}|
|}t ||j}|jdk s6tt||dd d S )N   r%   r]   r   r>     r$   r   r   )rV   r   r;   r   r,   r<   )rV   r;   
batch_sizer,   r   atol)r   r&   r-   r.   zerosr/   r0   rangerI   r   rX   rY   r^   r4   r   r   )	n_samples
n_featuresrV   r;   rc   r   r5   ZW_trueZW_arrayjZH_trueZH_arrayr_   rZ   r[   ZX_calcZmbmodelr!   r!   r"   test_nmf_true_reconstruction   sL    


rk   c                 C   sX   t jjd}t |dd}t| ddddd}||}||}t	||d	d
 d S )Nr$   rU   r]   r>   r&   r   gư>)r   rV   r+   r,   r=   r<   rd   )
r   r&   r-   r.   r/   r0   r   rX   rB   r   )r   r5   r    mfttr!   r!   r"   test_nmf_transform   s    

ro   c                  C   sR   t jjd} t | dd}tddddd}||}||}t	|| d S )	Nr$   rU   r]   r>   r   MbP?T)rV   r,   r=   fresh_restarts)
r   r&   r-   r.   r/   r0   r   rX   rB   r   )r5   r    rl   rm   rn   r!   r!   r"   test_minibatch_nmf_transform   s    

rr   c           	      C   s   t jd}t |dd}d}t | | }t |||d }t ||d| }| f |dddd|}|j|||d || d S )	Nr   rU   r]      customrp   )rV   r+   r,   r=   r7   r8   )	r   r&   r.   r/   r0   sqrtrJ   rX   rB   )	r   r   r,   r    rV   avgZH_initZW_initrl   r!   r!   r"   test_nmf_transform_custom_init   s        rx   )r   r   c                 C   sV   t jd}t |dd}t| ddddd}||}||}t||dd d S )	Nr   rU   rs   r&   rb   )r   rV   r+   r,   r   r   decimal)	r   r&   r.   r/   r0   r   rX   inverse_transformr   )r   r,   r    rl   rm   A_newr!   r!   r"   test_nmf_inverse_transform   s    

r}   c                  C   sV   t jd} t | dd}t| dddd}||}||}t||dd	d
 d S )Nr   rU   rs     r)   T)r,   r   r+   rq   rp   {Gz?)Zrtolre   )	r   r&   r.   r/   r0   r   rX   r{   r   )r5   r    r1   rm   r|   r!   r!   r"   test_mbnmf_inverse_transform  s    

r   c                 C   s8   t jjd}t |dd}| dddd| d S )Nr$      r%   ra   r   r   )rV   r,   r=   )r   r&   r-   r.   r/   r0   r   )r   r5   r    r!   r!   r"   $test_n_components_greater_n_features  s    r   c              
   C   s   ddl m} tjjd}t|dd}d|d d dtd f< ||}| f dd||dddd	|}t	|}	|
|}
|	
|}|j}|	j}t|
| t|| d S )
Nr   r   r$   r%   r   r]   r&   d   )rV   r+   rR   rT   r,   r=   r   )scipy.sparser	   r   r&   r-   r.   r/   r0   rW   r   rX   rY   r   )r   r   rR   rT   r	   r5   r    ZA_sparseZest1Zest2W1W2H1H2r!   r!   r"   test_nmf_sparse_input&  s.    



r   c                 C   sl   t jjd}t |dd}d|d< t|}| f dddd|}||}||}t	||dd	 d S )
Nr$   r>   r   r   )r   r   i  )r,   rV   r   r<   rd   )
r   r&   r-   r.   r/   r0   r	   rX   rB   r   )r   r   r5   r    rZ   ZA_fit_trZA_trr!   r!   r"   test_nmf_sparse_transformJ  s    

r   r&   r'   c                 C   s   d}t jjd}t |dd}d|d d dt d f< t|| ||||ddd	\}}}	t||d
| ||||ddd
\}
}}	t| ||||ddd	}|	|}|
|}t|| t|
| d S )Nr~   r$   r%   r   r   r]   r   r   )r+   r   r   rR   rT   r,   r=   F)	r8   update_Hr+   r   r   rR   rT   r,   r=   )r   r&   r-   r.   r/   r0   rW   r   r   rX   rB   r   )r+   r   rR   rT   r   r5   r    ZW_nmfr8   _ZW_nmf_2Zmodel_classZW_clsZW_cls_2r!   r!   r"   +test_non_negative_factorization_consistency[  sN    
	


r   c               	   C   s   t d} t}td}tjt|d || | |  ddd W 5 Q R X td}tjt|d || |  | ddd W 5 Q R X td}tjt|d || | d	|  ddd W 5 Q R X d S )
Nr   z/Negative values in data passed to NMF (input H)r   r   rt   r?   z/Negative values in data passed to NMF (input W)z.Array passed to NMF (input H) is full of zerosr   )r   r   r   rC   rD   r   r@   rA   )r    ZnnmfrF   r!   r!   r"   (test_non_negative_factorization_checking  s    



r   c           	      C   s  t ||}|dkr$t| | d S || dk }| | dk }t j|d|d |dkrt |t ||  }|| |   7 }n|dkr|| }t || j t t | }nP||  }||d ||   7 }|||||d     8 }|||d   }|S )z~Compute the beta-divergence of X and W.H for dense array only.

    Used as a reference for testing nmf._beta_divergence.
    r   r   &.>outr   )r   rI   r   maximumsumlogsize)	r_   r7   r8   betaWHZWH_XnonzeroZ	X_nonzeroresdivr!   r!   r"   _beta_divergence_dense  s"    "r   c                  C   s   d} d}d}dddddd	g}t jjd
}|| |}t j|dd |d t|}tj	||dd
d\}}|D ]N}	t
||||	}
t||||	}t||||	}t|
|dd t|
|dd qld S )N   r%   r]   rS         ?r:         ?       @g      @r$   r   r   r&   r*      ry   )r   r&   r-   r.   r0   clipsp
csr_matrixr1   r2   r   _beta_divergencer   )rh   ri   rV   Zbeta_lossesr5   r_   X_csrr7   r8   r   rO   lossZloss_csrr!   r!   r"   test_beta_divergence  s    
r   c                  C   s   d} d}d}t jjd}|| |}t j|dd |d t|}t || |}t |||}t	
|||}t	
|||}	| \}
}t ||
|f  }t||	|
|f dd t|j|j t|j|j t|j|j d S )Nr%   r]   r>   r$   r   r   ry   )r   r&   r-   r.   r0   r   r   r   r/   r1   Z_special_sparse_dotZnonzeroZasarrayZravelr   r
   indicesZindptrshape)rh   ri   rV   r5   r_   r   r7   r8   ZWH_safer   iiZjjZWH_safe_datar!   r!   r"   test_special_sparse_dot  s"    
r   c                  C   sR  d} d}d}d}d}d}t jjd}|| |}t |}t|}tj	||ddd	\}	}
d
D ]}|	
 |

  }}t||||ddd||||dd\}}}|	
 |

  }}t||||ddd||||dd\}}}t||dd t||dd |d8 }|	
 |

  }}t||||ddd||||dd\}}}t||dd t||dd q`d S )Nr   r%   r]   r<   r   i9  r&   r$   r*   g333333r   皙?r:   r         @rt   Tr   )r+   r   r   r;   r   rR   l1_ratior,   gHz>rd   h㈵>g-C6?)r   r&   r-   r.   r0   r/   r   r   r1   r2   copyr   r   )rh   ri   rV   alphar   Zn_iterr5   r_   r   rM   rN   r;   r7   r8   r   r   r   r   r   ZW3ZH3r!   r!   r"   %test_nmf_multiplicative_update_sparse  s|    

r   c               
      s   d} d}d t jjd}|| |}t j|dd |d t|} fdd}d	}d
D ]6}tj	t
|d ||| W 5 Q R X ||d | qVdD ]}||| ||| qd S )NrU   r]   r>   r$   r   r   c              	      sH   t | d d|ddd\}}}tt|r0ttt|rDtd S )Nr&   r   r   rb   )r+   rV   r   r;   r,   r   )r   r   r3   isnanr4   )r_   r;   r7   r8   r   rV   r!   r"   _assert_nmf_no_nanM  s    	z7test_nmf_negative_beta_loss.<locals>._assert_nmf_no_nanAWhen beta_loss <= 0 and X contains zeros, the solver may diverge.)g333333rS   r   r   )r   r:   g333333?r   r   )r   r&   r-   r.   r0   r   r   r   r   r@   rA   )rh   ri   r5   r_   r   r   rF   r;   r!   r   r"   test_nmf_negative_beta_lossA  s     

r   r;   g      rS   c              	   C   s\   t jd}|jdd}d||dk < t| dd}d}tjt|d || W 5 Q R X dS )zDCheck that an error is raised if beta_loss < 0 and X contains zeros.r   )rU   r]   )r   )r;   r,   r   r   N)	r   r&   r.   normalr   r   r@   rA   r   )r;   r5   r_   r1   rF   r!   r!   r"   %test_minibatch_nmf_negative_beta_losse  s    r   c                 C   st  d}d}d}t jjd}t |||}d}| f |d|dd|}| f |d|dd|}	||}
|	|}|j}|	j}t t j	j
}|
|
|k j}|||k j}|||k j}|||k j}||kst||kstd}| f |d|dd|}| f |d|dd|}	||}
|	|}|j}|	j}t|d	 t|d	  t|
d	 t|d	  ksptd S )
NrU   r]   r>   r$   r:   r   )rV   rR   r   r,   rS   r   )r   r&   r-   r.   r/   r0   rX   rY   Zfinfofloat64epsr   r4   r   rH   )r   r   rh   ri   rV   r5   r_   r   ZregulrZ   ZW_regulZW_modelZH_regulZH_modelr   ZW_regul_n_zerosZW_model_n_zerosZH_regul_n_zerosZH_model_n_zerosr!   r!   r"   test_nmf_regularizations  sx    



r   c                 C   sN  d}d}d}d}d}d}t jjd}|||}t || tj||ddd	\}	}
d
D ]}| dkrn|dkrnqX|	 |
  }}d }t	dD ]}t
||||d|d|| ||dddd\}}}t|||||| | |   || | |   |d|  | |d    |d|  | |d    }|d k	rB||ksBt|}qqXd S )Nr   ra   r%   r<   r   rS   r$   r&   r*   r   r   r   r   rt   r   r   T)r;   r+   rV   r   rR   r   r=   r   verboser,   r   )r   r&   r-   r.   r0   r/   r1   r2   r   rg   r   r   r   r4   )r   rh   ri   rV   r   r   r=   r5   r_   rM   rN   r;   r7   r8   Zprevious_lossr   r   r!   r!   r"   test_nmf_decreasing  sZ    
r   c            	      C   s   t jd} d\}}}t | ||d }t | ||d }t | ||}d|d< tj|||dd}d|d< tj|||dd}t|| d S )Nr   )r%   r   r   r%   )r   r   r:   )r   g       )r   r&   r.   r/   r0   r1   r   r   )	r5   rh   ri   rV   r_   r7   r8   rO   r   r!   r!   r"   test_nmf_underflow  s    
r   zdtype_in, dtype_outc                 C   s   t jdddj|dd}t j||d | f ddddd	|}|||j|ks^t	|
|j|ksrt	|jj|kst	d S )
Nr   r   ra   F)r   r   r:   r   )rR   rT   r=   r,   )r   r&   r.   r0   astyper/   r   rB   Zdtyper4   rX   rY   )r   r   Zdtype_inZ	dtype_outr_   r1   r!   r!   r"   test_nmf_dtype_match  s    r   c                 C   sx   t jddd}t j||d | f ddd|}||t j}| f ddd|}||}t||dd d S )	Nr   2   r   r   rp   )r,   r=   r   rd   )	r   r&   r.   r0   r/   rX   r   float32r   )r   r   r_   Znmf32ZW32Znmf64ZW64r!   r!   r"   $test_nmf_float32_float64_consistency  s    
r   c              	   C   s   t jd}|d}|dt j}|d}tjtdd | ddj	|||d W 5 Q R X tjtdd t
||d	d
 W 5 Q R X d S )Nr   )r   ra   )ra   ra   zshould have the same dtype as Xr   rt   r?   )r8   r7   F)r8   r   )r   r&   r.   random_sampler   r   r   r@   	TypeErrorr   r   )r   r5   r_   r8   r7   r!   r!   r"    test_nmf_custom_init_dtype_error*  s    

 r   r   r   r   r   r   c              	   C   sp   t jjd}t |dd}td| dddd}td| ddd |jd dd}|	|}|	|}t
|| d S )	Nr$   0   r]   r   r   )rV   r;   r   r,   r=   rS   )rV   r;   r,   r=   max_no_improvementrc   Zforget_factor)r   r&   r-   r.   r/   r0   r   r   r   rX   r   )r;   r5   r_   r1   Zmbnmfr7   ZmbWr!   r!   r"   !test_nmf_minibatchnmf_equivalence:  s*    	

r   c               
   C   s   t jjd} t | dd}d}d}d}t|dd||dd dd	}t|ddd
}tj||ddd
\}}|j	|||d t
|D ]6}	t
|D ](}
|j||
|
|  |d | |d qq|j|jkstt|j|j d S )Nr$   r   r]   r%   r   rt   r   F)rV   r+   r,   r   rc   r=   r   rq   )rV   r+   r,   r&   ru   )r   r&   r-   r.   r/   r0   r   r1   r2   r   rg   Zpartial_fitZn_steps_r4   r   rY   )r5   r_   rV   rc   r   Zmbnmf1Zmbnmf2r7   r8   irj   r!   r!   r"   test_minibatch_nmf_partial_fitV  s8    
   
(r   c                  C   sR   t jd} t | dd}tdd|}| }tdd t	dD | dS )	z Check feature names out for NMF.r   r%   rs   r>   r   c                 S   s   g | ]}d | qS )r1   r!   ).0r   r!   r!   r"   
<listcomp>  s     z*test_feature_names_out.<locals>.<listcomp>N)
r   r&   r.   r/   r0   r   r   Zget_feature_names_outr
   rg   )r,   r_   r1   namesr!   r!   r"   test_feature_names_outy  s
    r   c                  C   sJ   t jdd} tdddd}tj}t t_z||  W 5 |t_X d S )Nr   )r   r%   r   r   )r=   r,   r   )	r   r&   r.   r   r   sysstdoutr   r   )r    r1   Z
old_stdoutr!   r!   r"   test_minibatch_nmf_verbose  s    r   )IrC   r   ior   Znumpyr   r   sparser   Zscipyr   Zsklearn.decompositionr   r   r   r   r1   r	   r   Zsklearn.utils._testingr
   r   r   r   r   Zsklearn.utils.extmathr   Zsklearn.baser   Zsklearn.exceptionsr   markZparametrizer#   r9   filterwarningsrG   rL   rP   UserWarningr\   r`   rk   ro   rr   rx   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zint32Zint64r   r   r   r   r   r   r   r!   r!   r!   r"   <module>   s   
		

0




/
N$

E4



	


#
