o
    5ήc]6                     @   sB  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 ejejhZejej ej!ejej"ej#hZ$ejej%ej&hZ'e(e)e$e'A e*d
Z+dd Z,dd Z-G dd dZ.G dd dZ/ej01de+ej01de+ej01dddgdd Z2d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)keyc                    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 S/tmp/pip-target-vg8gfxp4/lib/python/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d
d Zdd Z	dd Z
dd Zdd Z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 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seedr7   scipylinalginvrandnidentitydotr   normr   r"   )	r)   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@   rA   r7   rB   rC   rD   rE   r   rG   sp_expmr   r   r	   trace)
r)   rI   krJ   rK   rL   BobservedexpectedrR   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@   rA   r7   rB   rC   rD   rE   r   rG   rS   r   r   r	   )r)   rI   rJ   rK   rL   vrW   rX   r   r   r   test_matrix_vector_multiplyd   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@   rA   r   r7   errstaterB   rC   rD   rE   r   rG   rS   r   r   r	   )
r)   rI   rU   rJ   rK   r_   rL   rV   rW   rX   r   r   r   test_scaled_expm_multiplyq   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@   rA   rE   r   rS   rG   r   r   r	   )r)   r_   rI   rU   rL   rV   rW   rX   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 ]P}tjj||dd}t j||}t||}t	 }|
td |
td t||}	W d    n1 sHw   Y  t||	 ttt||}t||	 qd S )	Nr;   r<   r?   r=   皙?density&splu converted its input to CSC formatCspsolve is more efficient when sparse b is in the CSC matrix format)r   r@   rA   r7   rB   sparserandrE   r   r   filterr   rS   rG   r   r   r	   )
r)   rI   rU   rJ   rK   rL   rV   rW   suprX   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)   rL   rV   rW   rX   r   r   r   test_complex   s"   
(
z!TestExpmActionSimple.test_complexN)__name__
__module____qualname____doc__r/   r5   r:   rP   rY   r[   ra   re   ro   rx   r   r   r   r   r#   ,   s    r#   c                   @   sL   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )TestExpmActionIntervalc              
   C   s   t jd d}d}d}d}d}dD ]g}tjj||dd	}t j||}t j|}	||	fD ]J}
t||
||||d
}t j||||d
}t	 *}|
td |
td t||D ]\}}t|t|| |
 qXW d    n1 ssw   Y  q.qd S )Nr;   rb   皙	@r<   r?   T      rd   rf   rg   startstopnumendpointri   rj   )r   r@   rA   rB   rk   rl   rE   r   linspacer   rm   r   r(   r   rS   rG   )r)   r   r   rI   rU   r   r   rL   rV   rZ   targetXsamplesrn   solutionr_   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;   rb   r~   Tr   r   r   r   r%   rd   rc      r<   r   rR   rc   r   )r   r@   rA   r   rB   rC   rD   rE   r   r   r(   r   rS   rG   r   r	   rT   )r)   intervalr   rI   rL   rZ   r   r   r   r_   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;   rb   r~   Tr   r   r   r%   rd   r   r   )r   r@   rA   r   rB   rC   rD   rE   r   r   r(   r   rS   rG   r   r	   )r)   r   r   rI   rU   rL   rV   r   r   r   r_   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 )Nrc   csr)formatrr   rq   )r   r   r%   r$   y             rp   )rB   rk   diagsr   arangeintonesru   r   r   rG   rt   full)r)   rL   rV   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   )Nrd   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 ]X}t j||}
t j||}t|
|||||dd}||krtt|
|||||dd\}}t|j|||f t j||||d}t||D ]\}}t	|t
||
 | q_|	d7 }	q|	sdt| d }t|d S )Nr;   rb   r~   r   Trc   rd   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   rS   rG   str	Exception)r)   target_statusr   r   r   r   rI   rU   nrepeats
nsuccessesrL   rV   statusr   r   r   r_   msgr   r   r   r     sB   
z?TestExpmActionInterval._help_test_specific_expm_interval_statusN)ry   rz   r{   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.gMbP?gh㈵>)rtolatolr;      r?   rp   rd   rQ   rb   r~   r   Tr   Nr   )	IMPRECISEr   r   r   r@   default_rngREAL_DTYPESrB   rC   rD   astyper   r   r	   rG   rS   rT   r   r(   )r   r   r   assert_allclose_rngrI   b_shaperL   rV   sol_matsol_op
direct_solr   r   X_matX_opr_   r   r   r   test_expm_multiply_dtype2  sB   





r   )3r|   	functoolsr   	itertoolsr   numpyr   r   numpy.testingr   r   r   r   scipy.sparser   scipy.sparse.linalgr	   scipy.linalgrB   r
   rS   "scipy.sparse.linalg._expm_multiplyr   r   r   r   r   r   singlecsingler   intcint_longlongdouble
longdoubler   cdoubleclongdoubleCOMPLEX_DTYPEStupler&   r   DTYPESr   r"   r#   r}   markparametrizer   r   r   r   r   <module>   s4      