a
    Re_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 s20    Y  d S )Nz%Trace of LinearOperator not available)match)pytestZwarnsUserWarning)argskwdsfunc `/var/www/sunrise/env/lib/python3.9/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)npZ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pairsZm_aZtheta_aZm_bZ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_maxZexpected_p_maxZobserved_p_maxr   r   r   test_p_max_default6   s    z'TestExpmActionSimple.test_p_max_defaultc                 C   sT   t ddD ]D}t|}t||d  |d k |d }t||d  |d k q
d S )Nr#   8   )ranger   r   )r'   r,   Zp_maxZ	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 ]X}|sRt |}nt 	||}t
||}t j|d}tt|| tt|d|  q>qd S )N  (   
      r#      )r   randomseedr/   scipylinalginvrandnidentitydotr   Z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 ]}tjt j||}t j||}t||}t 	t
||}t|| ttt||}t|| t |}	tt|||	d}t|| q d S )Nr1   r2   r5   r3   traceA)r   r6   r7   r/   r8   r9   r:   r;   r   r=   sp_expmr   r   r	   trace)
r'   r>   kr?   r@   rA   BobservedexpectedrG   r   r   r   test_expm_multiplyS   s    



z'TestExpmActionSimple.test_expm_multiplyc                 C   s   t jd d}d}t|D ]f}tjt j||}t j|}t||}t 	t
||}t|| ttt||}t|| qd S )Nr1   r2   r3   )r   r6   r7   r/   r8   r9   r:   r;   r   r=   rH   r   r   r	   )r'   r>   r?   r@   rA   vrL   rM   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 ]\}}t jdd tjt j	||}t j	||}t
|||d}t t|| |}	t||	 tt
t|||d}t||	 W d    q*1 s0    Y  q*d S )	Nr1   r2   r5   r3   )g?g      ?g      ?ignore)invalidt)r   r6   r7   r   r/   Zerrstater8   r9   r:   r;   r   r=   rH   r   r   r	   )
r'   r>   rJ   r?   r@   rT   rA   rK   rL   rM   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 )Nr1   皙?      rS   )
r   r6   r7   r;   r   rH   r=   r   r   r	   )r'   rT   r>   rJ   rA   rK   rL   rM   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 ]}tjj||dd}t j||}t||}t	 6}|
td |
td t||}	W d    n1 s0    Y  t||	 ttt||}t||	 q d S )	Nr1   r2   r5   r3   皙?Zdensity&splu converted its input to CSC formatCspsolve is more efficient when sparse b is in the CSC matrix format)r   r6   r7   r/   r8   sparserandr;   r   r   filterr   rH   r=   r   r   r	   )
r'   r>   rJ   r?   r@   rA   rK   rL   suprM   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'   rA   rK   rL   rM   r   r   r   test_complex   s"    
(
z!TestExpmActionSimple.test_complexN)__name__
__module____qualname____doc__r)   r-   r0   rE   rN   rP   rU   rY   rb   rk   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 ]}tjj||dd	}t j||}t j|}	||	fD ]}
t||
||||d
}t j||||d
}t	 T}|
td |
td t||D ] \}}t|t|| |
 qW d    q\1 s0    Y  q\q$d S )Nr1   rV   皙	@r2   r5   T      rX   rZ   r[   startstopnumendpointr\   r]   )r   r6   r7   r8   r^   r_   r;   r   linspacer   r`   r   r&   r   rH   r=   )r'   rv   rw   r>   rJ   ry   rx   rA   rK   rO   targetXsamplesra   solutionrT   r   r   r   "test_sparse_expm_multiply_interval   s4    
z9TestExpmActionInterval.test_sparse_expm_multiply_intervalc                 C   sr  t jd dddd}tg dg dD ]@\}}tjt j||}t j|}t jf d|i|}t	||fd|i|}t
||D ] \}}	t|t|	| | qt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|| q,q*d S )Nr1   rV   rq   Trv   rw   ry   rr   r#   rX   rW      r2   rx   rG   rW   )r   r6   r7   r   r8   r9   r:   r;   rz   r   r&   r   rH   r=   r   r	   rI   )r'   intervalrx   r>   rA   rO   r}   r|   r~   rT   ZXguessZXgivenZXwrongZ	sol_guessZ	sol_givenZ	sol_wrongcorrectr   r   r   "test_expm_multiply_interval_vector   s6    

z9TestExpmActionInterval.test_expm_multiply_interval_vectorc                 C   s  t jd dddd}tg dg ddd	gD ]\}}}tjt j||}t j||}t jf d
|i|}t	||fd
|i|}t
||D ] \}	}
t|	t|
| | qtt	t||fd
|i|}t
||D ] \}	}
t|	t|
| | qq0d S )Nr1   rV   rq   Tr   rr   r   r#   rX   rx   )r   r6   r7   r   r8   r9   r:   r;   rz   r   r&   r   rH   r=   r   r	   )r'   r   rx   r>   rJ   rA   rK   r}   r|   r~   rT   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 )NrW   Zcsr)formatre   rd   )r   r   r#   r"   y             rc   )r8   r^   Zdiagsr   ZarangeintZonesrh   r   r   r=   rg   full)r'   rA   rK   ZAexpmr   r   r   )test_sparse_expm_multiply_interval_dtypes   s     z@TestExpmActionInterval.test_sparse_expm_multiply_interval_dtypesc                 C   s   |  d d S )Nr   (_help_test_specific_expm_interval_statusr'   r   r   r   $test_expm_multiply_interval_status_0
  s    z;TestExpmActionInterval.test_expm_multiply_interval_status_0c                 C   s   |  d d S )Nr#   r   r   r   r   r   $test_expm_multiply_interval_status_1  s    z;TestExpmActionInterval.test_expm_multiply_interval_status_1c                 C   s   |  d d S )NrX   r   r   r   r   r   $test_expm_multiply_interval_status_2  s    z;TestExpmActionInterval.test_expm_multiply_interval_status_2c              
   C   s  t jd d}d}d}d}d}d}d}d	}	g d
| D ]}t j||}
t j||}t|
|||||dd}||kr8t|
|||||dd\}}t|j|||f t j||||d}t||D ] \}}t	|t
||
 | q|	d7 }	q8|	sdt| d }t|d S )Nr1   rV   rq   rt   TrW   rX   r3   r   rr   )rv   rw   rx   ry   Zstatus_onlyFru   r#   zfailed to find a status-z	 interval)r   r6   r7   r;   r   r   shaperz   r&   r   rH   r=   str	Exception)r'   Ztarget_statusrv   rw   rx   ry   r>   rJ   ZnrepeatsZ
nsuccessesrA   rK   statusr|   r}   r~   rT   msgr   r   r   r     s>    

z?TestExpmActionInterval._help_test_specific_expm_interval_statusN)rl   rm   rn   r   r   r   r   r   r   r   r   r   r   r   r   rp      s   rp   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 rftj	|||g
| }n.tj	|||gd|||g  
| }|tv rd|| 
|}n||d||  
|}t||}	ttt||}
tt||}||	| ||
| tt||t|d	}
||
| d
dddd}tjf i |}t||fi |}ttt||fi |}t|||D ]2\}	}
}t|| |}||	| ||
| qdS )zAMake sure `expm_multiply` handles all numerical dtypes correctly.ga2U0*S?gh㈵>)ZrtolZatolr1      r5   rc   rX   rF   rV   rq   rt   Tru   N)	IMPRECISEr   r   r   r6   Zdefault_rngREAL_DTYPESr8   r9   r:   Zastyper   r   r	   r=   rH   rI   rz   r&   )r   r   r   Zassert_allclose_rngr>   Zb_shaperA   rK   Zsol_matZsol_opZ
direct_solr   r}   ZX_matZX_oprT   r   r   r   test_expm_multiply_dtype2  s@    





r   )3ro   	functoolsr   	itertoolsr   numpyr   r   Znumpy.testingr   r   r   r   Zscipy.sparser   Zscipy.sparse.linalgr	   Zscipy.linalgr8   r
   rH   Z"scipy.sparse.linalg._expm_multiplyr   r   r   r   r   r   singleZcsingler   Zintcint_ZlonglongdoubleZ
longdoubler   ZcdoubleZclongdoubleZCOMPLEX_DTYPEStupler$   r   ZDTYPESr   r    r!   rp   markZparametrizer   r   r   r   r   <module>   s2     