o
    YiEf                  
   @   sD  d Z ddlZddlZddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZmZmZ ddlmZ ddlmZmZmZ ddlmZmZ ddlmZmZmZmZmZmZmZm Z m!Z!m"Z" eeeeeeee e!e"g
Z#d	Z$ej%e#d
ddd Z&G dd dZ'G dd dZ(G dd dZ)e) * Z+ej%e+dd e+D dddd Z,ej-j.dd Z/dd Z0dd Z1ej-2d ej-j3dd!d e) j+D d"d#gd$d%d& Z4d'd( Z5d)d* Z6ej-j7d+d,d-d. Z8d/d0 Z9d1d2 Z:ej-3de#d3d4 Z;ej-j.ej-3de) j+d5d6 Z<d7d8 Z=ej-3d9g d:d;d< Z>G d=d> d>Z?G d?d@ d@Z@dS )Az5 Test functions for the sparse.linalg._isolve module
    N)assert_array_equalassert_allclose)zerosarangearrayoneseyeiscomplexobj)norm)	dia_array	csr_arraykronsum)LinearOperatoraslinearoperator)
bicgbicgstabcgcgsgcrotmkgmreslgmresminresqmrtfqmrz-.*called without specifying `callback_type`.*session)paramsscopec                 C      | j S )z@
    Fixture for all solvers in scipy.sparse.linalg._isolve
    paramrequest r"   W/tmp/pip-target-1s0edx8b/lib/python/scipy/sparse/linalg/_isolve/tests/test_iterative.pysolver       r$   c                   @   s   e Zd ZdddZdS )CaseNc                 C   sb   || _ || _|d u rt|jd td| _n|| _|d u r g | _n|| _|d u r,g | _d S || _d S )Nr   dtype)nameAr   shapefloatbskipnonconvergence)selfr)   r*   r-   r.   r/   r"   r"   r#   __init__)   s   

zCase.__init__)NNN)__name__
__module____qualname__r1   r"   r"   r"   r#   r&   (   s    r&   c                   @   s   e Zd ZdddZdd ZdS )
SingleTestTc                 C   s,   || _ || _|| _|d |j | _|| _d S )N-)r*   r-   r$   r2   r)   convergence)r0   r*   r-   r$   casenamer7   r"   r"   r#   r1   ;   s
   
zSingleTest.__init__c                 C   s   d| j  dS )N<>r)   )r0   r"   r"   r#   __repr__B   s   zSingleTest.__repr__N)T)r2   r3   r4   r1   r<   r"   r"   r"   r#   r5   :   s    
r5   c                   @   s   e Zd Zdd Zdd ZdS )IterativeParamsc                 C   s  t tg}tg}t g}g | _d}td|f}d|dd d f< d|dd d f< d|dd d f< t|g df||fd }| jtd	| | jtd
|dt gd | jtd| |d | jtd| d|t g d t	||}| jtd|t gd | jtd|dt gd t
g dgdd}t|dgfdd }| jtd||d | jtd|d|d tjd}	|	dd}| jtd||| d | jtd|d|| d tjd}	|	dd}||j }| jtd||d | jtd|d|d tjd tjdd}t| |j}| jtd| | jtd|dt gd tjd}	|	ddd |	dd  }|| | }
| jtd!||
d | jtd"|d#|
d tjd}	|	ddd |	dd  }||j  }| jtd$||| d | jtd%|d#|| d tjd}	|	ddd |	dd  }t| |j}| jtd&||d | jtd'|d#|d td(}d|dd d f< d|dd d f< t|ddgfdd }| jtd)||ttttg d | jtd*|d#|ttttg d tj
g d+g d,g d-g d.g d/g d0g d1g d2g d3g d4g d5gtd}tj
g d6td}||jk s`J | jtd7|||tttttgd8 d S )9N(         r      )r   rA   rB   r+   	poisson1dzpoisson1d-Ff)r.   zneg-poisson1dzneg-poisson1d-F	poisson2dzpoisson2d-F)
   r@      rA   
      i	   dr'   rJ   rJ   z	rand-diagzrand-diag-Fi  rK   randzrand-Fzrand-symz
rand-sym-FrM   zrand-sym-pdzrand-sym-pd-Fy              ?z
rand-cmplxzrand-cmplx-FFzrand-cmplx-hermzrand-cmplx-herm-Fzrand-cmplx-sym-pdzrand-cmplx-sym-pd-F)r@   rJ   nonsymposdefnonsymposdef-F)r   r   r   r   r   rB   rA   r   r   r   r   )r   r   r   r   r   r@   r   rA   r   r   r   )r   r   r   r   r   r@   r   r   rA   r   r   )r   r   r   r   r   r@   r   r   r   rA   r   )r   r   r   r   r   rB   r   r   r   r   rA   )rB   r@   r@   r@   rB   r   r   r   r   r   r   )rA   r   r   r   r   r   rA   r   r   r   r   )r   rA   r   r   r   r   r   rA   r   r   r   )r   r   rA   r   r   r   r   r   rA   r   r   )r   r   r   rA   r   r   r   r   r   rA   r   )r   r   r   r   rA   r   r   r   r   r   rA   )r   r   r   r   r   rB   r   r   r   r   r   	sym-nonpd)r.   r/   )r   r   casesr   r   tocsrappendr&   astyper   r   nprandomRandomStaterP   Tseeddotconjr   r   r   r   r,   allr   )r0   sym_solversposdef_solversreal_solversNdata	Poisson1D	Poisson2DRandDiagrng
skip_cmplxr*   r-   r"   r"   r#   r1   G   s   



zIterativeParams.__init__c              
   C   sn   g }| j D ]/}tD ]*}||jv rq	||jv r&|t|j|j||jddg7 }q	|t|j|j||jg7 }q	q|S )NF)r7   )rU   _SOLVERSr.   r/   r5   r*   r-   r)   )r0   testscaser$   r"   r"   r#   generate_tests   s   


zIterativeParams.generate_testsN)r2   r3   r4   r1   rn   r"   r"   r"   r#   r=   F   s    ~r=   c                 C   s   g | ]}|j qS r"   r;   .0xr"   r"   r#   
<listcomp>   s    rr   module)r   idsr   c                 C   r   )z2
    Fixture for all cases in IterativeParams
    r   r    r"   r"   r#   rm      r%   rm   c              	      s   j std j}d}j d  }g  fdd}jtkrHtjtt	d j| ||d|d\}}W d    n1 sBw   Y  nj| ||d|d\}}t
dks]J |dkscJ d S )	N$Solver - Breakdown case, see gh-8829g-q=r   c                    sB   | j dkrt j|    d S t j|    d S )Nr   )ndimrW   r
   r*   rq   r-   rm   	residualsr"   r#   callback   s   
ztest_maxiter.<locals>.callback)matchrB   x0rtolmaxiterrz   )r7   pytestr.   r*   r-   r$   r   warnsDeprecationWarningCB_TYPE_FILTERlen)rm   r*   r~   r}   rz   rq   infor"   rx   r#   test_maxiter   s    

r   c                 C   s   | j }|jjdv rd}nd}| j}d| }| j||||d\}}t|d|  | jrB|dks0J t|| | t|| ks@J d S |dksHJ t|| | t|ksVJ d S )NdD:0yE>{Gz?r   r}   r~   )r*   r(   charr-   r$   r   r7   r
   )rm   r*   r~   r-   r}   rq   r   r"   r"   r#   test_convergence   s   $ r   c                 C   sF  | j std d}ddd}| j}|j\}}| }t|t|kr2t	d| gdgf||fd | j
}d| }t|j||d}	| jtu rT| j|||	|	||d	\}
}n| j|||	||d
\}
}|dksfJ t||
 | t|| ksvJ t|}||_||_| j||||d\}
}|dksJ t||
 | t|| ksJ d S )Nru   r   c                 S   s   | S )ztrivial preconditionerr"   )r-   whichr"   r"   r#   identity  s   z$test_precond_dummy.<locals>.identity      ?r   rC   rmatvec)M1M2r}   r~   Mr}   r~   r   N)r7   r   r.   r*   r+   diagonalrY   count_nonzeror   r   r-   r   r$   r   r
   r   psolverpsolve)rm   r~   r   r*   r   rd   diagOfAr-   r}   precondrq   r   r"   r"   r#   test_precond_dummy  s.   



 $r   rJ   c                 C   s   g | ]	}|j d v r|qS ))rD   rF   r;   ro   r"   r"   r#   rr   :  s    
rD   rF   )rt   c                    s   t D ]s}| jv s|tu rqd}d fdd	}d fdd	}dg fdd} fd	d
} j}d| }t jj||d}	t jj||d}
dg||	||
||d\}}|dks\J t j| | t|| ksmJ d dksuJ qd S )Nr   c                    s(    j }t|tjs| }tj|| S zinverse preconditioner)r*   
isinstancerY   ndarraytoarraylinalgsolver-   r   r*   rm   r"   r#   inverseD  s   z%test_precond_inverse.<locals>.inversec                    s*    j }t|tjs| }tj|j| S r   )r*   r   rY   r   r   r   r   r\   r   r   r"   r#   rinverseK  s   z&test_precond_inverse.<locals>.rinverser   c                    s   d  d7  <  j |  S Nr   rB   )r*   r-   rm   matvec_countr"   r#   matvecT  s   
z$test_precond_inverse.<locals>.matvecc                    s   d  d7  <  j j|  S r   )r*   r\   r   r   r"   r#   r   X  s   z%test_precond_inverse.<locals>.rmatvecr   r   r?   r   )rk   r.   r   r-   r   r*   r+   r
   )rm   r$   r~   r   r   r   r   r-   r}   r*   r   rq   r   r"   r   r#   test_precond_inverse9  s&   "r   c              	   C   sx  | t tfv rtd tjd}|jddgd}||j dt	d  }d|jdd }tj
|}tjdtddd	tjf }|jd
d}||j }d d| d| g}t|||D ]]\}}	}
|	dkrj|
dkrjq\| tu r|d ur~t|}tt	d}nd }| |||||	|
d\}}n| ||||	|
d\}}|dksJ || | }tj
|}|	| }|dt|
| ksJ q\d S )NzTODO: Add atol to minres/tfqmrl   R'd rJ   sizeg     @@r   ir@   rI   rO   ư>g    .A)r   r   r~   atol)r   r~   r   g/$?)r   r   r   r.   rY   rZ   default_rnguniformr\   r   r   r
   r_logspaceinfstandard_normal	itertoolsproductr   r   max)r$   ri   r*   r-   b_normtolsM0Msr   r~   r   r   rq   r   residualerratol2r"   r"   r#   	test_atolm  s6   


r   c                 C   sN  t jd}|jddgd}||j dt d  }t d}t jt ddd }|D ]y}| |||d\}}|dks<J t|d	d
d | |||t	dd\}}|dksUJ t|d	|d | t
ur| |||dt	dd\}}|dkrvt|d | ||||d\}}|dksJ t|ddd | |||dd\}}|dksJ t|ddd q+d S )Nl   Yo/ rJ   r   ir@   rI   r~   r   g        V瞯<r   )r~   r}   )r~   r   r}   r~   r   gYn)rY   rZ   r   r\   r   r   r   r   r   r   r   )r$   ri   r*   r-   r   tolrq   r   r"   r"   r#   test_zero_rhs  s0   

r   zsee gh-18697reasonc           	      C   s   | t ttfvrtd | tu rt dvrtjdd t	g dg dg dg dg}t
d	}tj}d
}tddD ]8}| |||ddd\}}|dkr]t|| | dt| ks]J tj|| | }t||}||| kstJ q<d S )NzSolver breakdown case)	x86_64x86aarch64arm64z,fails on at least ppc64le, ppc64 and riscv64r   )gH|r   r   ghܾΤ?)r   yXq-DT!@r   r   )r   r   yXq-DT!r   )g |?                r   gܾΤĿrK   rM   rB      r   r   )r   r~   r   )r   r   r   r   r.   platformmachinexfailrY   r   r   r   ranger
   r   min)	r$   r*   v
best_error	slack_tolr   rq   r   errorr"   r"   r#   test_maxiter_worsening  s*   


 
r   c           	      C   s   t jd}d}|j||gd}||j }||}||}| tu r)tdd}ntddd}| ||fi |\}}|dks@J t|| | dt| ksPJ | ||fd|i|\}}|dkscJ t|| | d	t| kssJ d S )
N   p-Qs/ rJ   r   r   r   r   r   r~   r}   g?̔>)rY   rZ   r   r\   r   dictr
   )	r$   ri   nr*   r-   r}   kwrq   r   r"   r"   r#   test_x0_working  s   


 $r   c                 C   s   | j tu r| jdkrtd | j tu rtd | j}| j}d}d}| j ||||d\}}t|d |dks9J t	|| | |t	| ksIJ d S )Nznonsymposdef-bicgstabzISolver fails due to numerical noise on some architectures (see gh-15533).zSolver does not support x0='Mb'Mbr   r   r   )
r$   r   r)   r   r.   r   r*   r-   r   r
   )rm   r*   r-   r}   r~   rq   r   r"   r"   r#   test_x0_equals_Mb  s   



$r   c                 C   sD   t d}t ddg}| |||d\}}t|| |dks J d S )Nr@   g      )r}   r   )rY   r   r   r   )r$   matrhssolr   r"   r"   r#   test_x0_solves_problem_exactly  s
   

r   c                 C   sn   dd }t | j| j|dd\}}| \}}| jdkrd}n
| jdv r&d}nd	}||s/J |dks5J d S )
Nc                 S   s   d S r   r"   rw   r"   r"   r#   cb   s   ztest_show.<locals>.cbT)rz   showrT    )rR   rS   z?TFQMR: Linear solve not converged due to reach MAXIT iterationsz9TFQMR: Linear solve converged due to reach TOL iterations)r   r*   r-   
readouterrr)   
startswith)rm   capsysr   rq   r   outr   expr"   r"   r#   	test_show  s   

r   c                 C   s|   t jd}d}|j||gd}||j }||}||}tt | |||d W d    d S 1 s7w   Y  d S )Nr   rJ   r   h㈵>)rY   rZ   r   r\   r   raises	TypeError)r$   ri   r   r*   r-   r}   r"   r"   r#   test_positional_error3  s   


"r   r   )legacyNrA   c                 C   s   | t kr	td tjd}d}|j||gd}||j }||}||}tt | ||||d W d    d S 1 sAw   Y  d S )Nzminres has no `atol` argumentr   rJ   r   r   )	r   r   r.   rY   rZ   r   r\   r   
ValueError)r$   r   ri   r   r*   r-   r}   r"   r"   r#   test_invalid_atol?  s   



"r   c                   @   s    e Zd Zejddd ZdS )TestQMRz,ignore::scipy.sparse.SparseEfficiencyWarningc                    sL  ddl m} ddlm} d}t|}td| d| | gg df||fd}t|d	d
}t| d |gddgf||fd}td| | gddgf||fd}|| || fdd}	fdd}
 fdd}fdd}|||f|	|d}|||f|
|d}d}t|||d||d\}}|dksJ t|| | |t| ksJ dS )z8Check that QMR works with left and right preconditionersr   )splu)r   d   rK   )rA   r   rB   rC   rN   r'   r@   rA   rB   c                    
     | S r   r   r   L_solverr"   r#   L_solvea     
z/TestQMR.test_leftright_precond.<locals>.L_solvec                    r   r   r   r   U_solverr"   r#   U_solved  r   z/TestQMR.test_leftright_precond.<locals>.U_solvec                         | dS Nr\   r   r   r   r"   r#   LT_solveg     z0TestQMR.test_leftright_precond.<locals>.LT_solvec                    r  r  r   r   r   r"   r#   UT_solvej  r  z0TestQMR.test_leftright_precond.<locals>.UT_solve)r   r   r      )r~   r   r   r   N)	scipy.sparse.linalg._dsolver   scipy.sparse.linalg._interfacer   r   r   r   r   r
   )r0   r   r   r   datr*   r-   LUr   r  r  r  r   r   r~   rq   r   r"   )r   r  r#   test_leftright_precondO  s(   (""$zTestQMR.test_leftright_precondN)r2   r3   r4   r   markfilterwarningsr  r"   r"   r"   r#   r   N  s    
r   c                   @   s   e Zd Zdd Zejde ddd Zdd Z	ej
d	d
d Zdd Zdd Zejde ddd Zdd ZdS )	TestGMRESc                 C   sb   t t dd d d d d df }t d}d|d< t||ddd\}}t|d ddd	 d S )
NrJ   rB   rA   r      )restartr   g`"?r   r   )rY   vanderr   r   r   r   )r0   r*   r-   x_gmr   r"   r"   r#   
test_basicx  s
   &
zTestGMRES.test_basiczignore:z:DeprecationWarningc              	      s   dd t tg dg dg dg dg dg dg}t|jd	 f}d
}t|d
  d d	<  fdd}t||t|jd	 d||d\}}t tddgdd dt|jd	  }t|d
  d d	< t|||d||d\}}t tddgdd d S )Nc                 S   s   | ||  d  d < d S r   )nonzeror   )rrvecr"   r"   r#   store_residual  s   z/TestGMRES.test_callback.<locals>.store_residual)r   rB   r   r   r   r   )rB   r   rB   r   r   r   )r   rB   r   rB   r   r   )r   r   rB   r   rB   r   )r   r   r   rB   r   rB   )r   r   r   r   rB   r   r   rB   r   c                    s
   |  S r   r"   r  r  r  r"   r#   rz     r   z)TestGMRES.test_callback.<locals>.callbackgؗҜ<r|   g>,p ?绽|=r   gMbP?)r   r~   r   rz   g!{bEJ?)	r   r   r   r+   r   r   r   rY   r   )r0   r*   r-   r   rz   rq   flagr   r"   r  r#   test_callback  s4   



zTestGMRES.test_callbackc                 C   sh   t d}td}t||\}}|t}t|t|t\}}t|s'J t|| ||ks2J d S )Nr@   )r   r   r   rX   complexr	   r   )r0   r*   r-   r_xr_inforq   r   r"   r"   r#   test_abi  s   

zTestGMRES.test_abirJ   c                 C   s  t d}td}t||dd\}}tj|| | dtj| ks%J t||ddd tjd}|	dd}d	td }t||d
dd\}}tj|| | d
ksWJ t d}dtd }t||ddd\}}tj|| | dtj| ksJ d S )Nr@   r   r   r   r   r   i90     r   gHz>r   )r~   r  r  r   )
r   r   r   rY   r   r
   r   rZ   r[   rP   )r0   r*   r-   rq   r   rndmr"   r"   r#   test_atol_legacy  s   (,zTestGMRES.test_atol_legacyc                 C   s   t d}d|d< t g d}t g d}t g d}t||||ddd\}}t | r3J |dkrKt j|| | dt j| ksKJ t	|||  ||  d S )	Nr?   r   )r@   r@   )r   rB   rB   rB   r   r   )r@   r?   rK   r   )r}   r   r~   r   )
rY   r   r   diagr   isnananyr   r
   r   )r0   r   r-   rq   r*   r   r"   r"   r#    test_defective_precond_breakdown  s   
(z*TestGMRES.test_defective_precond_breakdownc                 C   s   t g dg dg dg}t g d}d}t|||dd\}}t | r*J |dkrBt j|| | |t j| ksBJ t|||  ||  d S )N)r   rB   r   r'  )r   r   r   )rB   r   rB   r   r   r   )rY   r   r   r)  r*  r   r
   r   )r0   r*   r-   r~   rq   r   r"   r"   r#   test_defective_matrix_breakdown  s   (z)TestGMRES.test_defective_matrix_breakdownc              
      s>  t jd t jdd}t jd}dg  fdd} fdd}dg t||dd|d	d
d\}}|d	ks8J  d d	ks@J dg t||dd|d	d
dd\}}|d	ksWJ  d d	ks_J dg t||dd|d	d
dd\}}|dksvJ  d d	ks~J dg t||dd|d	d
dd\}}|dksJ  d dksJ d S )NrB   r   r   c                    s"    d  d7  < t | tsJ d S r   )r   r,   r  cb_countr"   r#   
pr_norm_cb  s   z0TestGMRES.test_callback_type.<locals>.pr_norm_cbc                    s$    d  d7  < t | tjsJ d S r   )r   rY   r   rw   r-  r"   r#   x_cb  s   z*TestGMRES.test_callback_type.<locals>.x_cbr   r@   2   )r~   r   rz   r   r  r   r~   r   rz   r   r  callback_typepr_normrq   )rY   rZ   r]   rP   r   )r0   r*   r-   r/  r0  rq   r   r"   r-  r#   test_callback_type  s<   



zTestGMRES.test_callback_typec              
      s   t jd}|ddt d  |dt jgdg fdd}t dd|dddd	\}}|dks:J d dksBJ d S )
NrB   r   r   c                    s@   t j |   }|d ksJ |d< d  d7  < d S r   )rY   r   r
   )rq   r  r*   r-   countprev_rr"   r#   r0     s   z1TestGMRES.test_callback_x_monotonic.<locals>.x_cbr   rJ   rq   r2  )rY   rZ   r[   rP   r   r   r   )r0   ri   r0  rq   r   r"   r6  r#   test_callback_x_monotonic  s   

z#TestGMRES.test_callback_x_monotonicN)r2   r3   r4   r  r   r  r  r   r  r#  	fail_slowr&  r+  r,  r5  r9  r"   r"   r"   r#   r  w  s    	
&


,r  )A__doc__r   r   r   numpyrY   numpy.testingr   r   r   r   r   r   r   r	   numpy.linalgr
   scipy.sparser   r   r   scipy.sparse.linalgr   r   scipy.sparse.linalg._isolver   r   r   r   r   r   r   r   r   r   rk   r   fixturer$   r&   r5   r=   rn   rU   rm   r  thread_unsafer   r   r   r:  parametrizer   r   r   r   r   r   r   r   r   r   r   r   r  r"   r"   r"   r#   <module>   sb     0	
 



)03
(

)