o
    h08                     @   sH  d Z ddlmZ ddlmZ ddlZddlZddlm	Z	m
Z
mZ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mZmZmZmZmZ dd
lmZ ejejhZ ej!eej"ej#ej$ej%fZ&ej'ej(ej)fZ*e&e* Z+dd Z,dd Z-G dd dZ.G dd dZ/ej0j1ej02de+ej02de+ej02dddgdd Z3dS )z;Test functions for the sparse.linalg._expm_multiply module.    )partial)productN)assert_allcloseassert_assert_equalsuppress_warnings)SparseEfficiencyWarning)aslinearoperator)expm)_theta_compute_p_max_onenormest_matrix_powerexpm_multiply_expm_multiply_simple_expm_multiply_interval)np_longc                    s    fdd}|S )zIf trace is estimated, it should warn.

    We warn that estimation of trace might impact performance.
    All result have to be correct nevertheless!

    c                     s@   t jtdd  | i |W  d    S 1 sw   Y  d S )Nz%Trace of LinearOperator not available)match)pytestwarnsUserWarning)argskwdsfunc `/var/www/vscode/kcb/lib/python3.10/site-packages/scipy/sparse/linalg/tests/test_expm_multiply.pywrapped!   s
   $zestimated.<locals>.wrappedr   )r   r   r   r   r   	estimated   s   r   c                 C   s   t | |p	| |k S )N)npallclose)abr   r   r   less_than_or_close(   s   r"   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zej	j
d
d Zej	j
dd Zej	j
dd Zej	j
dd Zej	j
dd Zej	j
dd ZdS )TestExpmActionSimplezR
    These tests do not consider the case of multiple time steps in one call.
    c                 C   sH   t t }t|d d |dd  D ]\\}}\}}t||k  qd S )N   )sortedr   itemszipr   )selfpairsm_atheta_am_btheta_br   r   r   test_theta_monotonicity1   s   *z,TestExpmActionSimple.test_theta_monotonicityc                 C   s   d}d}t |}t|| d S )N7      )r   r   )r)   m_maxexpected_p_maxobserved_p_maxr   r   r   test_p_max_default6   s   z'TestExpmActionSimple.test_p_max_defaultc                 C   sT   t ddD ]"}t|}t||d  |d k |d }t||d  |d k qd S )Nr%   8   )ranger   r   )r)   r2   p_max	p_too_bigr   r   r   test_p_max_range<   s   z%TestExpmActionSimple.test_p_max_rangec           
      C   s   t jd}d}d}t|D ]=}tj|||}tdD ],}|s(t |}nt 	||}t
||}t j|d}	tt||	 tt|	d|  qqd S )N  (   
      r%      )r   randomRandomStater7   scipylinalginvrandnidentitydotr   normr   r"   )
r)   rngnnsamplesiApMr   exactr   r   r   test_onenormest_matrix_powerC   s   
z1TestExpmActionSimple.test_onenormest_matrix_powerc           
      C   s   t jd d}d}d}t|D ]G}tjt j||}t j||}t||}t 	t
||}t|| ttt||}t|| t |}	tt|||	d}t|| qd S )Nr;   r<   r?   r=   traceA)r   r@   seedr7   rB   rC   rD   rE   r   rG   sp_expmr   r   r	   trace)
r)   rJ   krK   rL   rM   BobservedexpectedrS   r   r   r   test_expm_multiplyS   s    



z'TestExpmActionSimple.test_expm_multiplyc                 C   s   t jd d}d}t|D ]3}tjt j||}t j|}t||}t 	t
||}t|| ttt||}t|| qd S )Nr;   r<   r=   )r   r@   rT   r7   rB   rC   rD   rE   r   rG   rU   r   r   r	   )r)   rJ   rK   rL   rM   vrY   rZ   r   r   r   test_matrix_vector_multiplye   s   

z0TestExpmActionSimple.test_matrix_vector_multiplyc           
   	   C   s   t jd d}d}d}tt|g dD ]R\}}t jdd@ tjt j	||}t j	||}t
|||d}t t|| |}	t||	 tt
t|||d}t||	 W d    n1 sbw   Y  qd S )	Nr;   r<   r?   r=   )g?g      ?g      ?ignore)invalidt)r   r@   rT   r   r7   errstaterB   rC   rD   rE   r   rG   rU   r   r   r	   )
r)   rJ   rW   rK   rL   ra   rM   rX   rY   rZ   r   r   r   test_scaled_expm_multiplys   s$   

z.TestExpmActionSimple.test_scaled_expm_multiplyc                 C   s   t jd d}d}d}t j||}t j||}t|||d}t|| |}t|| ttt	|||d}t|| d S )Nr;   皙?      r`   )
r   r@   rT   rE   r   rU   rG   r   r   r	   )r)   ra   rJ   rW   rM   rX   rY   rZ   r   r   r   *test_scaled_expm_multiply_single_timepoint   s   

z?TestExpmActionSimple.test_scaled_expm_multiply_single_timepointc              	   C   s   t jd}d}d}d}t|D ]R}tjj||fd|d}|||f}t||}t	 }	|	
td |	
td t||}
W d    n1 sJw   Y  t||
 ttt||}t||
 qd S )	Nr;   r<   r?   r=   皙?densityrI   &splu converted its input to CSC formatCspsolve is more efficient when sparse b is in the CSC matrix format)r   r@   default_rngr7   rB   sparserandom_arraystandard_normalr   r   filterr   rU   rG   r   r   r	   )r)   rI   rJ   rW   rK   rL   rM   rX   rY   suprZ   r   r   r   test_sparse_expm_multiply   s*   

z.TestExpmActionSimple.test_sparse_expm_multiplyc                 C   s   t jddgddggtd}t ddg}t||}t jdt d ddt d t d   dt d gtd}t|| ttt	||}t|| d S )N              ?r   dtyper%   )
r   arraycomplexr   expcossinr   r   r	   )r)   rM   rX   rY   rZ   r   r   r   test_complex   s"   
(
z!TestExpmActionSimple.test_complexN)__name__
__module____qualname____doc__r/   r5   r:   rQ   r   markthread_unsafer[   r]   rc   rg   rs   r|   r   r   r   r   r#   ,   s$    




r#   c                   @   s   e Zd Zejddd Zejjejddd Zejjejddd Z	dd	 Z
d
d Zdd Zdd Zdd ZdS )TestExpmActionInterval   c              
   C   s   t jd}d}d}d}d}d}dD ]i}tjj||fd|d	}|||f}	||f}
|	|
fD ]J}t||||||d
}t j||||d
}t	 *}|
td |
td t||D ]\}}t|t|| | qZW d    n1 suw   Y  q0qd S )Nr;   rd   皙	@r<   r?   T      rf   rh   ri   startstopnumendpointrk   rl   )r   r@   rm   rB   rn   ro   rp   r   linspacer   rq   r   r(   r   rU   rG   )r)   rI   r   r   rJ   rW   r   r   rM   rX   r\   targetXsamplesrr   solutionra   r   r   r   "test_sparse_expm_multiply_interval   s>   
z9TestExpmActionInterval.test_sparse_expm_multiply_intervalc                 C   sn  t jd dddd}tg dg dD ]\}}tjt j||}t j|}t jdd|i|}t	||fd|i|}t
||D ]\}}	t|t|	| | qDtt	t||fd|i|}
t	t||fd|i|d	t |i}t	t||fd|i|d	t |d
 i}t
|
|||D ]\}}}}	t|	| |}t|| t|| t|| qqd S )Nr;   rd   r   Tr   r   r   r   r%   rf   re   r   r<   r   rS   re   r   )r   r@   rT   r   rB   rC   rD   rE   r   r   r(   r   rU   rG   r   r	   rV   )r)   intervalr   rJ   rM   r\   r   r   r   ra   XguessXgivenXwrong	sol_guess	sol_given	sol_wrongcorrectr   r   r   "test_expm_multiply_interval_vector   s:   

z9TestExpmActionInterval.test_expm_multiply_interval_vectorc                 C   s  t jd dddd}tg dg ddd	gD ]g\}}}tjt j||}t j||}t jdd
|i|}t	||fd
|i|}t
||D ]\}	}
t|	t|
| | qItt	t||fd
|i|}t
||D ]\}	}
t|	t|
| | qnqd S )Nr;   rd   r   Tr   r   r   r%   rf   r   r   )r   r@   rT   r   rB   rC   rD   rE   r   r   r(   r   rU   rG   r   r	   )r)   r   r   rJ   rW   rM   rX   r   r   r   ra   r   r   r   "test_expm_multiply_interval_matrix   s    "z9TestExpmActionInterval.test_expm_multiply_interval_matrixc                 C   s.  t jjtddtd}tjdtd}t jjttddd}tt	||ddd |
| t jjd	td dtd}tjdtd}t jjtd	td dd}tt	||ddd |
| t jjtddtd}tjdd
td}t jjttddd}tt	||ddd |
| d S )Nre   csr)formatrv   ru   )r   r   r%   r$   y             rt   )rB   rn   diags_arrayr   arangeintonesry   r   r   rG   rx   full)r)   rM   rX   Aexpmr   r   r   )test_sparse_expm_multiply_interval_dtypes  s    "z@TestExpmActionInterval.test_sparse_expm_multiply_interval_dtypesc                 C      |  d d S )Nr   (_help_test_specific_expm_interval_statusr)   r   r   r   $test_expm_multiply_interval_status_0     z;TestExpmActionInterval.test_expm_multiply_interval_status_0c                 C   r   )Nr%   r   r   r   r   r   $test_expm_multiply_interval_status_1  r   z;TestExpmActionInterval.test_expm_multiply_interval_status_1c                 C   r   )Nrf   r   r   r   r   r   $test_expm_multiply_interval_status_2  r   z;TestExpmActionInterval.test_expm_multiply_interval_status_2c              
   C   s  t jd}d}d}d}d}d}d}d}	d	}
g d
|	 D ]V}|||}|||}t||||||dd}||krrt||||||dd\}}t|j|||f t j||||d}t||D ]\}}t	|t
|| | q]|
d7 }
q|
sdt| d }t|d S )Nr;   rd   r   r   Tre   rf   r=   r   r   )r   r   r   r   status_onlyFr   r%   zfailed to find a status-z	 interval)r   r@   rA   rE   r   r   shaper   r(   r   rU   rG   str	Exception)r)   target_statusrI   r   r   r   r   rJ   rW   nrepeats
nsuccessesrM   rX   statusr   r   r   ra   msgr   r   r   r     sB   
z?TestExpmActionInterval._help_test_specific_expm_interval_statusN)r}   r~   r   r   r   	fail_slowr   r   r   r   r   r   r   r   r   r   r   r   r   r      s    



r   dtype_adtype_bb_is_matrixFTc                 C   s  | |ht @ rttdddnt}tjd}d}|r|dfn|f}| tv r3tj	|||g
| }ntj	|||gd|||g  
| }|tv rYd|| 
|}n||d||  
|}t||}	ttt||}
tt||}||	| ||
| tt||t|d	}
||
| d
dddd}tjdi |}t||fi |}ttt||fi |}t|||D ]\}	}
}t|| |}||	| ||
| qdS )zAMake sure `expm_multiply` handles all numerical dtypes correctly.gH}]?gh㈵>)rtolatolr;      r?   rt   rf   rR   rd   r   r   Tr   Nr   )	IMPRECISEr   r   r   r@   rm   REAL_DTYPESrB   rC   rD   astyper   r   r	   rG   rU   rV   r   r(   )r   r   r   assert_allclose_rI   rJ   b_shaperM   rX   sol_matsol_op
direct_solr   r   X_matX_opra   r   r   r   test_expm_multiply_dtype=  sB   





r   )4r   	functoolsr   	itertoolsr   numpyr   r   numpy.testingr   r   r   r   scipy.sparser   scipy.sparse.linalgr	   scipy.linalgrB   r
   rU   "scipy.sparse.linalg._expm_multiplyr   r   r   r   r   r   scipy._lib._utilr   singlecsingler   intclonglongfloat32float64
longdoubler   	complex64
complex128clongdoubleCOMPLEX_DTYPESDTYPESr   r"   r#   r   r   r   parametrizer   r   r   r   r   <module>   s:     
  