B
     \^                @   s  d Z ddlmZmZmZ ddlZddlm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 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mZmZm Z  ddl!m"Z" ddl#m$Z$ e%dZ&e&' Z(e(Z)e%dZ*e*' Z+ej,Z,e,' Z-e	j.Z/ej.Z0ej1dej2dej3dej4diZ5dddZ6dd Z7dd Z8dd Z9G d d! d!Z:G d"d# d#Z;ej<d$d% Z=d&d' Z>d(d) Z?d*d+ Z@d,d- ZAd.d/ ZBd0d1 ZCd2d3 ZDd4d5 ZEd6d7 ZFdd9d:ZGee	jHejIejId;d< ZJe$ree
jKejIejIeJ ee	jLejIejId=d> ZLd?d@ ZMdAdB ZNdCdD ZOdEdF ZPee	jHejIejIejIdGdH ZQeR ZSeTdIeSZUedJdK ZVddMdNZWdOdP ZXedQdR ZYedSdT ZZee	j[j\dUdV Z]edWdX Z^ddYdZZ_ed[krRee	j[j`d\d] Zaee	j[jbd^d_ Zcee	j[jdd`da Zeee	j[jfdbdc Zgee	j[jhddde Ziee	j[jjddfdgZkee	j[jldhdi Zmdjdk Zneendldm Zodndo Zpeepdpdq Zqdrds Zreerdtdu Zsdvdw Zteetdxdy Zudzd{ Zveevd|d} Zwd~d Zxeexdd Zyee	j[jzdddZ{dd Z|ee|dd Z}ee	j[j~dd Zee	j[jdddZdd Zee	j[jdd Zee	j[jdd Zdd Zeedd Zdd Zeedd Zdd Zee	j[jdddZee	j[jdddZedd Zee	j[jdddZee	j[jdd Zee	jdddZdddZdd Zdd Zedkrfee	jdddZnee	jdd Zdd Zdd Zee	jdd ZdS )z.
Implementation of linear algebra operations.
    )print_functionabsolute_importdivisionN)ir)typescgutils)lower_builtinimpl_ret_borrowedimpl_ret_new_refimpl_ret_untracked)	signature)overloadregister_jitable)version)r   )numpy_support   )
make_array_empty_nd_impl
array_copy   )TypingError)HAS_MATMUL_OPERATOR       sdcz<BLAS function>c             C   s$   t | }|d kr td|f |S )Nzunsupported dtype for %s())_blas_kindsget	TypeError)dtype	func_namekind r%   3lib/python3.7/site-packages/numba/targets/linalg.pyget_blas_kind3   s    
r'   c              C   s.   ydd l } W n tk
r(   tdY nX d S )Nr   z*scipy 0.16+ is required for linear algebra)Zscipy.linalg.cython_blasImportError)scipyr%   r%   r&   ensure_blas:   s    r*   c              C   s.   ydd l } W n tk
r(   tdY nX d S )Nr   z*scipy 0.16+ is required for linear algebra)Zscipy.linalg.cython_lapackr(   )r)   r%   r%   r&   ensure_lapackA   s    r+   c             C   s   |  |||}t||S )N)Zget_constant_genericr   Zalloca_once_value)contextbuildertyvalZconstr%   r%   r&   make_constant_slotH   s    r0   c               @   s0   e Zd ZdZdd Zedd Zedd ZdS )	_BLASzM
    Functions to return type signatures for wrapped
    BLAS functions.
    c             C   s
   t   d S )N)r*   )selfr%   r%   r&   __init__S   s    z_BLAS.__init__c          	   C   s<   t |d|}ttjtjt|tjt|}td|S )Nunderlying_floatnumba_xxnrm2)getattrr   intccharintpCPointerExternalFunction)clsr"   rtypesigr%   r%   r&   r5   V   s    z_BLAS.numba_xxnrm2c             C   s`   t t jt jt jt jt jt jt |t |t jt |t jt |t |t j}t d|S )Nnumba_xxgemm)r   r7   r8   r9   r:   r;   )r<   r"   r>   r%   r%   r&   r?   a   s     z_BLAS.numba_xxgemmN)__name__
__module____qualname____doc__r3   classmethodr5   r?   r%   r%   r%   r&   r1   M   s   r1   c               @   s   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd ZdS )_LAPACKzO
    Functions to return type signatures for wrapped
    LAPACK functions.
    c             C   s
   t   d S )N)r+   )r2   r%   r%   r&   r3   |   s    z_LAPACK.__init__c          
   C   s4   t t jt jt jt |t jt t}t d|S )Nnumba_xxgetrf)r   r7   r8   r9   r:   F_INT_nbtyper;   )r<   r"   r>   r%   r%   r&   rF      s    z_LAPACK.numba_xxgetrfc          	   C   s0   t t jt jt |t jt t}t d|S )Nnumba_ez_xxgetri)r   r7   r8   r9   r:   rG   r;   )r<   r"   r>   r%   r%   r&   rH      s    z_LAPACK.numba_ez_xxgetric             C   sX   t t jt jt jt jt |t jt |t |t |t jt |t j}t d|S )Nnumba_ez_rgeev)r   r7   r8   r9   r:   r;   )r<   r"   r>   r%   r%   r&   rI      s    z_LAPACK.numba_ez_rgeevc             C   sP   t t jt jt jt jt |t jt |t |t jt |t j}t d|S )Nnumba_ez_cgeev)r   r7   r8   r9   r:   r;   )r<   r"   r>   r%   r%   r&   rJ      s    z_LAPACK.numba_ez_cgeevc             C   sD   t |d|}ttjtjtjtjt|tjt|}td|S )Nr4   numba_ez_xxxevd)r6   r   r7   r8   r9   r:   r;   )r<   r"   Zwtyper>   r%   r%   r&   rK      s    z_LAPACK.numba_ez_xxxevdc             C   s,   t t jt jt jt |t j}t d|S )Nnumba_xxpotrf)r   r7   r8   r9   r:   r;   )r<   r"   r>   r%   r%   r&   rL      s    z_LAPACK.numba_xxpotrfc             C   s\   t |d|}ttjtjtjtjt|tjt|t|tjt|tj}td|S )Nr4   numba_ez_gesdd)r6   r   r7   r8   r9   r:   r;   )r<   r"   styper>   r%   r%   r&   rM      s    z_LAPACK.numba_ez_gesddc          
   C   s4   t t jt jt jt |t jt |}t d|S )Nnumba_ez_geqrf)r   r7   r8   r9   r:   r;   )r<   r"   r>   r%   r%   r&   rO      s    z_LAPACK.numba_ez_geqrfc             C   s8   t t jt jt jt jt |t jt |}t d|S )Nnumba_ez_xxgqr)r   r7   r8   r9   r:   r;   )r<   r"   r>   r%   r%   r&   rP      s    z_LAPACK.numba_ez_xxgqrc             C   s^   t |d|}ttjtjtjtjt|tjt|tjt|tjttj}td|S )Nr4   numba_ez_gelsd)r6   r   r7   r8   r9   r:   float64r;   )r<   r"   r=   r>   r%   r%   r&   rQ      s    z_LAPACK.numba_ez_gelsdc             C   s@   t t jt jt jt |t jt tt |t j}t d|S )Nnumba_xgesv)r   r7   r8   r9   r:   rG   r;   )r<   r"   r>   r%   r%   r&   rS   
  s    z_LAPACK.numba_xgesvN)r@   rA   rB   rC   r3   rD   rF   rH   rI   rJ   rK   rL   rM   rO   rP   rQ   rS   r%   r%   r%   r&   rE   v   s   

rE   c             c   s   g }g }g }xt |j|D ]r\}}t|tjr8|jdkrD|| }	}
n4|jdd}	t|	|}t| |||f}
|	|	|
f |	|	 |	|
 qW t|j
f| t|fV  x |D ]\}}| j||| qW dS )z
    Ensure that all array arguments are contiguous, if necessary by
    copying them.
    A new (sig, args) tuple is yielded.
    ZCFC)layoutN)zipargs
isinstancer   ArrayrU   copyr   r   appendreturn_typetupleZnrtZdecref)r,   r-   r>   rW   ZnewtysZnewargsZcopiesr.   r/   ZnewtyZnewvalZcopysigr%   r%   r&   make_contiguous  s    

r^   c                s0   d  fdd}|  ||ttjtj|f dS )z.
    Check whether *n* fits in a C `int`.
    ic                s   |  krt dd S )Nz$array size too large to fit in C int)OverflowError)n)_maxintr%   r&   impl8  s    zcheck_c_int.<locals>.implN)compile_internalr   r   noner9   )r,   r-   r`   rb   r%   )ra   r&   check_c_int2  s    re   c          	   C   sB   |j t||dd" | |}|  |d W dQ R X dS )z[
    Check the integer error return from one of the BLAS wrappers in
    _helperlib.c.
    F)likelyz#BLAS wrapper returned with an errorN)if_thenr   is_not_nullget_python_api
gil_ensurefatal_error)r,   r-   respyapir%   r%   r&   check_blas_return@  s    
rn   c          	   C   sB   |j t||dd" | |}|  |d W dQ R X dS )z]
    Check the integer error return from one of the LAPACK wrappers in
    _helperlib.c.
    F)rf   z%LAPACK wrapper returned with an errorN)rg   r   rh   ri   rj   rk   )r,   r-   rl   rm   r%   r%   r&   check_lapack_returnL  s    
ro   c             C   s   t t dttttttg}|jj|dd}	t|}
t 	tt
|
}t 	tt|}||	|||||t||t||tf}t| || dS )zQ
    Call the BLAS vector * vector product function for the given arguments.
    r   Znumba_xxdot)nameN)r   FunctionTypeIntTypell_charintp_t	ll_void_pmoduleget_or_insert_functionr'   Constantordintcallbitcastrn   )r,   r-   	conjugater"   r`   Za_dataZb_dataout_datafntyfnr$   kind_valrl   r%   r%   r&   
call_xxdotX  s    

r   c             C   s  t t dttttttttttg
}|jj|dd}	|j}
t	| ||
d}t	| ||
d}|j
dkrt|\}}|d }n|\}}|d }t|
}t tt|}t t|rtd	ntd
}||	||||||t||t|||t||t||tf
}t| || dS )zQ
    Call the BLAS matrix * vector product function for the given arguments.
    r   Znumba_xxgemv)rp   g      ?g        Fr   r   tr`   N)r   rq   rr   rs   rt   ru   rv   rw   r"   r0   rU   r'   rx   ry   r{   r|   rn   )r,   r-   do_transZm_typem_shapesm_datav_datar~   r   r   r"   alphabetamr`   ldar$   r   transrl   r%   r%   r&   call_xxgemvn  s0    




r   c       !         s8  t t dttttttttttttttg} jj|dd}|\}}|\}}|j}t	|  |d}t	|  |d}t 
ttdt 
ttd fdd	}||||\}}}||||\}}}||	|
\}}}t|}t 
tt|} ||||||| |t|||| |t||f} t|  |  d
S )zQ
    Call the BLAS matrix * matrix product function for the given arguments.
    r   r?   )rp   g      ?g        r   r`   c                s8   | j j krn| j dkr$|d n|d  |tfS )NrT   r   r   )rU   r|   ru   )r.   Zshapesdata)r-   notransout_typer   r%   r&   get_array_param  s    z$call_xxgemm.<locals>.get_array_paramN)r   rq   rr   rs   rt   ru   rv   rw   r"   r0   rx   ry   r'   r{   r|   rn   )!r,   r-   Zx_typex_shapesx_dataZy_typey_shapesy_datar   
out_shapesr~   r   r   r   k_kr`   r"   r   r   r   Ztransar   Zdata_aZtransbZldbZdata_b_ZldcZdata_cr$   r   rl   r%   )r-   r   r   r   r&   call_xxgemm  s4    


r   c             C   s(   dd }|  ||||}t| ||j|S )z 
    np.dot(matrix, matrix)
    c             S   s4   | j \}}|j \}}t||f| j}t| ||S )N)shapenpemptyr"   dot)abr   r   r   r`   outr%   r%   r&   dot_impl  s    

zdot_2_mm.<locals>.dot_impl)rc   r
   r\   )r,   r-   r>   rW   r   rl   r%   r%   r&   dot_2_mm  s    r   c             C   s(   dd }|  ||||}t| ||j|S )z 
    np.dot(vector, matrix)
    c             S   s0   | j \}|j \}}t|f| j}t| ||S )N)r   r   r   r"   r   )r   r   r   _mr`   r   r%   r%   r&   r     s    
zdot_2_vm.<locals>.dot_impl)rc   r
   r\   )r,   r-   r>   rW   r   rl   r%   r%   r&   dot_2_vm  s    r   c             C   s(   dd }|  ||||}t| ||j|S )z 
    np.dot(matrix, vector)
    c             S   s0   | j \}}|j \}t|f| j}t| ||S )N)r   r   r   r"   r   )r   r   r   r`   _nr   r%   r%   r&   r     s    
zdot_2_mv.<locals>.dot_impl)rc   r
   r\   )r,   r-   r>   rW   r   rl   r%   r%   r&   dot_2_mv  s    r   Fc          	   C   s   |j \}}|j}t|| ||d }t|| ||d }	t||j\}
dd }| ||ttj	f|j  | t
| ||
 t|| |}t| ||||
|j|	j| ||S )z<
    np.dot(vector, vector)
    np.vdot(vector, vector)
    r   r   c             S   s$   | j \}|j \}||kr tdd S )Nz;incompatible array sizes for np.dot(a, b) (vector * vector))r   
ValueError)r   r   r   r`   r%   r%   r&   
check_args  s    zdot_2_vv.<locals>.check_args)rW   r\   r   r   unpack_tupler   rc   r   r   rd   re   Zalloca_onceZget_value_typer   r   load)r,   r-   r>   rW   r}   ZatyZbtyr"   r   r   r`   r   r   r%   r%   r&   dot_2_vv  s    
r   c          	   C   s   t   t| |||\}}dd |jdd D }|ddgkrLt| |||S |ddgkrft| |||S |ddgkrt| |||S |ddgkrt| |||S dstW dQ R X dS )z 
    np.dot(a, b)
    a @ b
    c             S   s   g | ]
}|j qS r%   )ndim).0xr%   r%   r&   
<listcomp>  s    zdot_2.<locals>.<listcomp>Nr   r   r   )r*   r^   rW   r   r   r   r   AssertionError)r,   r-   r>   rW   ndimsr%   r%   r&   dot_2
  s    r   c          	   C   s6   t   t| |||\}}t| |||ddS Q R X dS )z
    np.vdot(a, b)
    T)r}   N)r*   r^   r   )r,   r-   r>   rW   r%   r%   r&   vdot#  s    r   c             C   s:   | j \}|j \}}||kr"td|j |fkr6tdd S )Nz;incompatible array sizes for np.dot(a, b) (vector * matrix)zFincompatible output array size for np.dot(a, b, out) (vector * matrix))r   r   )r   r   r   r   r   r`   r%   r%   r&   dot_3_vm_check_args.  s    
r   c             C   s:   | j \}}|j \}||kr"td|j |fkr6tdd S )Nz;incompatible array sizes for np.dot(a, b) (matrix * vector)zFincompatible output array size for np.dot(a, b, out) (matrix * vector))r   r   )r   r   r   r   r   r`   r%   r%   r&   dot_3_mv_check_args9  s    
r   c          	   C   sB  |j \}}}||jkst|j}t|| ||d }t|| ||d }	t|| ||d }
t||j}t||	j}t||
j}|j|jk r|}|}|j	dk}|	j
|j
 }}t}n$|}|}|j	dk}|j
|	j
 }}t}| ||ttjf|j  | x|D ]}t| || q W t| |||||||
j
 t| ||j|
 S )zE
    np.dot(vector, matrix, out)
    np.dot(matrix, vector, out)
    r   r   r   r   rT   )rW   r\   r   r"   r   r   r   r   r   rU   r   r   r   rc   r   r   rd   re   r   r	   	_getvalue)r,   r-   r>   rW   xtyytyouttyr"   r   yr   r   r   r   Zmtyr   r   r   r   r   r/   r%   r%   r&   dot_3_vmC  s8    




r   c              C   sb  |j \}}}||jkst|j}t|| ||d }t|| ||d }	t|| ||d }
t||j}t||	j}t||
j}|\}}|\}}|jdkstdd }| 	||t
tjf|j  | t| || t| || t| || |j}|	j}|
j}ttd}|d||}|d||}||\}}|x ||b\}}| t| |d||||| W d	Q R X |( |j|jk}t| ||||||| W d	Q R X W d	Q R X W d	Q R X |~ ||h\}}|( |j|jk}t| ||||||| W d	Q R X |" t| |||||||||| W d	Q R X W d	Q R X W d	Q R X W d	Q R X t| ||j|
 S )
z%
    np.dot(matrix, matrix, out)
    r   r   r   rT   c             S   s>   | j \}}|j \}}||kr$td|j ||fkr:tdd S )Nz;incompatible array sizes for np.dot(a, b) (matrix * matrix)zFincompatible output array size for np.dot(a, b, out) (matrix * matrix))r   r   )r   r   r   r   r   r   r`   r%   r%   r&   r     s    

zdot_3_mm.<locals>.check_argsz==FN)rW   r\   r   r"   r   r   r   r   rU   rc   r   r   rd   re   r   r   rx   rt   Zicmp_signedZif_elser   r   r   r	   r   ) r,   r-   r>   rW   r   r   r   r"   r   r   r   r   r   r   r   r   r   r`   r   r   r   r~   oneZis_left_vecZis_right_vecZr_vecZr_matZv_vZm_vr   Zv_mZm_mr%   r%   r&   dot_3_mmr  s^    

,2
r   c          	   C   s   t   t| |||h\}}tdd |jdd D }|tdgkrRt| |||S |tddgkrpt| |||S dsxtW dQ R X dS )z
    np.dot(a, b, out)
    c             s   s   | ]}|j V  qd S )N)r   )r   r   r%   r%   r&   	<genexpr>  s    zdot_3.<locals>.<genexpr>Nr   r   r   )r*   r^   setrW   r   r   r   )r,   r-   r>   rW   r   r%   r%   r&   dot_3  s    r   Znumba_fatal_errorc             C   s2   x,t | D ]}t | st jdqW d S )Nz$Array must not contain infs or NaNs.)r   ZnditerZisfiniteitemlinalgLinAlgError)r   vr%   r%   r&   _check_finite_matrix  s    r   Tc             C   s   |rdnd}||f}t | tjr&| j} t | tjsFd| }t|dd| jdksdd| }t|ddt | jtjtj	fsd| }t|ddd S )	Nz	np.linalgr   z&%s.%s() only supported for array typesF)highlightingr   z%%s.%s() only supported on 2-D arrays.z3%s.%s() only supported on float and complex arrays.)
rX   r   ZOptionaltyperY   r   r   r"   FloatComplex)r   r#   	la_prefixprefixinterpmsgr%   r%   r&   _check_linalg_matrix  s    
r   c             G   sB   |d j }x2|dd  D ]"}|j |krd|  }t|ddqW d S )Nr   r   zAnp.linalg.%s() only supports inputs that have homogeneous dtypes.F)r   )r"   r   )r#   r   Zt0r   r   r%   r%   r&   _check_homogeneous_types  s
    

r   c             C   s6   | dkr2| dk rt   dst| dkr2tjdd S )Nr   z(Matrix is singular to machine precision.)fatal_error_funcr   r   r   r   )rr%   r%   r&   _inv_err_handler  s    r   c             C   s   | d S )zFpass a list of variables to be preserved through dead code eliminationr   r%   )r   r%   r%   r&   _dummy_liveness_func  s    r   c                s\   t   t| d t | jt | jtt| jd| jdk  fdd}|S )Ninvr   c                s   | j d }| j d |kr(d}tj|t|   r@t| }n
t| }|dkrV|S tj|td}|||j	||j	}t
| ||j	||j	}t
| t|j|jg |S )Nz.Last 2 dimensions of the array must be square.r   )r"   )r   r   r   r   r   rZ   asfortranarrayr   F_INT_nptypectypesr   r   size)r   r`   r   acpyipivr   )F_layoutr$   rF   numba_xxgetrir%   r&   inv_impl  s"    

zinv_impl.<locals>.inv_impl)	r+   r   rE   rF   r"   rH   ry   r'   rU   )r   r   r%   )r   r$   rF   r   r&   r   	  s    

r   c             C   s2   | dkr.| dk rt   dst| dkr.tdd S )Nr   z&Internal algorithm failed to converge.)r   r   r   )r   r%   r%   r&   %_handle_err_maybe_convergence_problem6  s    r   c             C   sf   |rdnd}||f}t | tjs,td| | jdksBtd| t | jtjtjfsbtd| d S )Nz	np.linalgr   z'%s.%s() only supported for array types r   z+%s.%s() only supported on 1 and 2-D arrays z3%s.%s() only supported on float and complex arrays.)rX   r   rY   r   r   r"   r   r   )r   r#   r   r   r   r%   r%   r&   _check_linalg_1_or_2d_matrix@  s    
r   )r   r   c                sR   t   t| d t | jtt| jdtd td} fdd}|S )NcholeskyULc                s   | j d }| j d |kr(d}tj||  }|dkr<|S  ||j|}|dkr|dk rlt  dslt|dkrtjdx t|D ]}d|d ||f< qW |S )Nr   r   z.Last 2 dimensions of the array must be square.r   z Matrix is not positive definite.)	r   r   r   r   rZ   r   r   r   range)r   r`   r   r   r   col)UPr$   rL   r%   r&   cho_impl_  s$    
zcho_impl.<locals>.cho_impl)r+   r   rE   rL   r"   ry   r'   )r   ZLOr   r%   )r   r$   rL   r&   r   S  s    
r   c                s   t   t| d t | jt | jtt| jdtdtd| jdk  fdd} fdd}t	| jt
jjr|S |S d S )	NeigNVr   c                s  | j d }| j d |kr(d}tj|t|   r@t| }n
t| }d}|}tj|| jd}tj|| jd}tj||f| jd}tj||f| jd}	|dkr||	j	fS ||j
||j
|j
|j
||	j
|}
t|
 t|rtdt|j|j|	j|j|jg ||	j	fS )z?
            eig() implementation for real arrays.
            r   r   z.Last 2 dimensions of the array must be square.r   )r"   r   z.eig() argument must not cause a domain change.)r   r   r   r   r   rZ   r   r   r"   Tr   r   anyr   r   r   )r   r`   r   r   ldvlldvrwrwivlvrr   )r   JOBVLJOBVRr$   rI   r%   r&   real_eig_impl  sD    



zeig_impl.<locals>.real_eig_implc       
         s   | j d }| j d |kr(d}tj|t|   r@t| }n
t| }d}|}tj|| jd}tj||f| jd}tj||f| jd}|dkr||j	fS ||j
||j
|j
||j
|}	t|	 t|j|j|j|jg ||j	fS )zB
            eig() implementation for complex arrays.
            r   r   z.Last 2 dimensions of the array must be square.r   )r"   r   )r   r   r   r   r   rZ   r   r   r"   r   r   r   r   r   )
r   r`   r   r   r   r   wr   r   r   )r   r   r   r$   rJ   r%   r&   cmplx_eig_impl  s:    


z eig_impl.<locals>.cmplx_eig_impl)r+   r   rE   rI   r"   rJ   ry   r'   rU   rX   r   scalarsr   )r   r   r   r%   )r   r   r   r$   rJ   rI   r&   eig_impl  s    

;+r   c                s   t   t| d t | jt | jtt| jdtdtd| jdk  fdd} fdd}t	| jt
jjr|S |S d S )Neigvalsr   r   c                s   | j d }| j d |kr(d}tj|t|   r@t| }n
t| }d}d}tj|| jd}|dkrn|S tj|| jd}tjd| jd}tjd| jd}	||j	||j	|j	|j	||	j	|}
t
|
 t|rtdt|j|j|	j|j|jg |S )zC
            eigvals() implementation for real arrays.
            r   r   z.Last 2 dimensions of the array must be square.r   )r"   r   z2eigvals() argument must not cause a domain change.)r   r   r   r   r   rZ   r   r   r"   r   r   r   r   r   r   )r   r`   r   r   r   r   r   r   r   r   r   )r   r   r   r$   rI   r%   r&   real_eigvals_impl
  sD    


z'eigvals_impl.<locals>.real_eigvals_implc       
         s   | j d }| j d |kr(d}tj|t|   r@t| }n
t| }d}d}tj|| jd}|dkrn|S tjd| jd}tjd| jd}||j	||j	|j	||j	|}	t
|	 t|j|j|j|jg |S )zF
            eigvals() implementation for complex arrays.
            r   r   z.Last 2 dimensions of the array must be square.r   )r"   r   )r   r   r   r   r   rZ   r   r   r"   r   r   r   r   )
r   r`   r   r   r   r   r   r   r   r   )r   r   r   r$   rJ   r%   r&   cmplx_eigvals_implH  s:    

z(eigvals_impl.<locals>.cmplx_eigvals_impl)r+   r   rE   rI   r"   rJ   ry   r'   rU   rX   r   r   r   )r   r   r   r%   )r   r   r   r$   rJ   rI   r&   eigvals_impl  s    

>,r   c                s|   t   t| d | jdk t| jd| j}t|t | jt	t
| jdt	dt	d fdd}|S )Neighr   r4   r   r   c                s   | j d }| j d |kr(d}tj|t|   r@t| }n
t| }tj|d}|dkrh||fS ||j||j}t	| t
|j|jg ||fS )Nr   r   z.Last 2 dimensions of the array must be square.)r"   r   )r   r   r   r   r   rZ   r   r   r   r   r   r   )r   r`   r   r   r   r   )r   JOBZUPLOr$   rK   w_dtyper%   r&   	eigh_impl  s*    

zeigh_impl.<locals>.eigh_impl)r+   r   rU   r6   r"   
np_supportas_dtyperE   rK   ry   r'   )r   w_typer  r%   )r   r  r  r$   rK   r  r&   r  y  s    


!r  c                s|   t   t| d | jdk t| jd| j}t|t | jt	t
| jdt	dt	d fdd}|S )Neigvalshr   r4   r   r   c                s   | j d }| j d |kr(d}tj|t|   r@t| }n
t| }tj|d}|dkrd|S ||j||j}t	| t
|j|jg |S )Nr   r   z.Last 2 dimensions of the array must be square.)r"   r   )r   r   r   r   r   rZ   r   r   r   r   r   r   )r   r`   r   r   r   r   )r   r  r  r$   rK   r  r%   r&   eigvalsh_impl  s*    

z$eigvalsh_impl.<locals>.eigvalsh_impl)r+   r   rU   r6   r"   r  r  rE   rK   ry   r'   )r   r  r
  r%   )r   r  r  r$   rK   r  r&   r
    s    


!r
  c                s~   t   t| d | jdk t| jd| j}t|t | jt	t
| jdt	dt	dd	 fdd	}|S )
Nsvdr   r4   ASr   c                s  | j d }| j d }|dks$|dkr0tjdt|   rHt| }n
t| }|}t||}|rr}|}|}	n}|}|}	tj||f| j	d}
tj|d}tj||	f| j	d}||||j
||j
|
j
||j
|	}t| t|j|j|
j|jg |
j||jfS )Nr   r   r   zArrays cannot be empty)r"   )r   r   r   r   r   rZ   r   minr   r"   r   r   r   r   r   )r   full_matricesr`   r   r   lduminmnr  ucolldvtur   vtr   )r   JOBZ_AJOBZ_Sr$   rM   s_dtyper%   r&   svd_impl  sF    



zsvd_impl.<locals>.svd_impl)r   )r+   r   rU   r6   r"   r  r  rE   rM   ry   r'   )r   r  s_typer  r%   )r   r  r  r$   rM   r  r&   r    s    


1r  c                s\   t   t| d t | jt | jtt| jd| jdk  fdd}|S )Nqrr   c                sr  | j d }| j d }|dks$|dkr0tjdt|   rHt| }n
t| }|}t||}tj|| j	d}|||j
||j
}|dk rt  dsttj||f| j	dj}x:t|D ].}	x(t|	d D ]}
||
|	f ||
|	f< qW qW x:t||D ],}	x&t|D ]}
||
|	f ||
|	f< qW qW ||||j
||j
}t| t|j|jg |d d d |f |fS )Nr   r   r   zArrays cannot be empty)r"   r   )r   r   r   r   r   rZ   r   r  r   r"   r   r   r   zerosr   r   r   r   r   )r   r`   r   qr   r  Ztauretr   ij)r   r$   rO   rP   r%   r&   qr_impl?  sN    



zqr_impl.<locals>.qr_impl)	r+   r   rE   rO   r"   rP   ry   r'   rU   )r   r!  r%   )r   r$   rO   rP   r&   r!  ,  s    

<r!  c             C   s   t dS )z;
    Correctly copy 'b' into the 'bcpy' scratch space.
    N)NotImplementedError)bcpyr   nrhsr%   r%   r&   _system_copy_in_b  s    r%  c             C   s&   |j dkrdd }|S dd }|S d S )Nr   c             S   s   || d |j d df< d S )Nr   r   )r   )r#  r   r$  r%   r%   r&   	oneD_impl  s    z)_system_copy_in_b_impl.<locals>.oneD_implc             S   s   || d |j d d |f< d S )Nr   )r   )r#  r   r$  r%   r%   r&   	twoD_impl  s    z)_system_copy_in_b_impl.<locals>.twoD_impl)r   )r#  r   r$  r&  r'  r%   r%   r&   _system_copy_in_b_impl  s
    
r(  c             C   s   t dS )zK
    Compute the number of right hand sides in the system of equations
    N)r"  )r   r%   r%   r&   _system_compute_nrhs  s    r)  c             C   s&   | j dkrdd }|S dd }|S d S )Nr   c             S   s   dS )Nr   r%   )r   r%   r%   r&   r&    s    z,_system_compute_nrhs_impl.<locals>.oneD_implc             S   s
   | j d S )Nr   )r   )r   r%   r%   r&   r'    s    z,_system_compute_nrhs_impl.<locals>.twoD_impl)r   )r   r&  r'  r%   r%   r&   _system_compute_nrhs_impl  s
    
r*  c             C   s   t dS )zD
    Check that AX=B style system input is dimensionally valid.
    N)r"  )r   r   r%   r%   r&   !_system_check_dimensionally_valid  s    r+  c             C   s*   |j }|dkrdd }|S dd }|S d S )Nr   c             S   s,   | j d }|j d }||kr(tjdd S )Nr   r   z<Incompatible array sizes, system is not dimensionally valid.)r   r   r   r   )r   r   ambmr%   r%   r&   r&    s
    

z9_system_check_dimensionally_valid_impl.<locals>.oneD_implc             S   s,   | j d }|j d }||kr(tjdd S )Nr   z<Incompatible array sizes, system is not dimensionally valid.)r   r   r   r   )r   r   r,  r-  r%   r%   r&   r'    s
    

z9_system_check_dimensionally_valid_impl.<locals>.twoD_impl)r   )r   r   r   r&  r'  r%   r%   r&   &_system_check_dimensionally_valid_impl  s    r.  c             C   s   t dS )z:
    Check that AX=B style system input is not empty.
    N)r"  )r   r   r%   r%   r&   _system_check_non_empty  s    r/  c             C   s*   |j }|dkrdd }|S dd }|S d S )Nr   c             S   sF   | j d }| j d }|j d }|dks6|dks6|dkrBtjdd S )Nr   r   r   zArrays cannot be empty)r   r   r   r   )r   r   r,  anr-  r%   r%   r&   r&    s
    


z/_system_check_non_empty_impl.<locals>.oneD_implc             S   sX   | j d }| j d }|j d }|j d }|dksH|dksH|dksH|dkrTtjdd S )Nr   r   r   zArrays cannot be empty)r   r   r   r   )r   r   r,  r0  r-  bnr%   r%   r&   r'    s    



 z/_system_check_non_empty_impl.<locals>.twoD_impl)r   )r   r   r   r&  r'  r%   r%   r&   _system_check_non_empty_impl  s    r2  c             C   s   t dS )z:
    Compute the residual from the 'b' scratch space.
    N)r"  )r   r`   r$  r%   r%   r&   _lstsq_residual  s    r3  c                s   | j }| j}tt|d| |dkrTt|tjrB fdd}|S  fdd}|S n8|dks`tt|tjr| fdd}|S  fd	d}|S d S )
Nr4   r   c                s6   t jd d}t t | |d df d |d< |S )N)r   )r"   r   r   )r   r   sumabs)r   r`   r$  rl   )
real_dtyper%   r&   
cmplx_impl  s    $z(_lstsq_residual_impl.<locals>.cmplx_implc                s0   t jd d}t | |d df d |d< |S )N)r   )r"   r   r   )r   r   r4  )r   r`   r$  rl   )r6  r%   r&   	real_impl  s    z'_lstsq_residual_impl.<locals>.real_implr   c                sH   t j| d}x4t|D ](}t t | |d |f d ||< qW |S )N)r"   r   )r   r   r   r4  r5  )r   r`   r$  rl   r   )r6  r%   r&   r7    s    (c                sB   t j| d}x.t|D ]"}t | |d |f d ||< qW |S )N)r"   r   )r   r   r   r4  )r   r`   r$  rl   r   )r6  r%   r&   r8    s    ")	r   r"   r  r  r6   rX   r   r   r   )r   r`   r$  r   r"   r7  r8  r%   )r6  r&   _lstsq_residual_impl  s    r9  c             C   s   t dS )z
    Extract 'x' (the lstsq solution) from the 'bcpy' scratch space.
    Note 'b' is only used to check the system input dimension...
    N)r"  )r   r#  r`   r%   r%   r&   _lstsq_solution  s    r:  c             C   s&   | j dkrdd }|S dd }|S d S )Nr   c             S   s   |j  d | S )N)r   ravel)r   r#  r`   r%   r%   r&   r&    s    z'_lstsq_solution_impl.<locals>.oneD_implc             S   s   |d |d d f   S )N)rZ   )r   r#  r`   r%   r%   r&   r'    s    z'_lstsq_solution_impl.<locals>.twoD_impl)r   )r   r#  r`   r&  r'  r%   r%   r&   _lstsq_solution_impl  s
    
r<        c                s   t   t| d t|d | jdk |jdk}td| | t| j| j}t|d|}t|t	 
| jtt|dd fdd	}|S )Nlstsqr   r4         c                sF  | j d }| j d }t|}t|  t| t| | t| | t||}t||} rdt| }n
t	| }tj
||fdj}	t|	|| tj
|d}
tj
dtjd}||||j||	j||
j||j}t| |d }||k s||krtj
dd}nt|	||}t||	|}t|j|	j|
j|jg ||||
d | fS )Nr   r   )r"   r   r   )r   r)  r   r/  r+  r  maxr   rZ   r   r   r   r%  int32r   r   r3  r:  r   r   )r   r   rcondr`   r   r$  r  Zmaxmnr   r#  r   Zrank_ptrr   rankrl   r   )
a_F_layoutr$   np_dtrQ   r6  r%   r&   
lstsq_implA  sH    






zlstsq_impl.<locals>.lstsq_impl)r?  )r+   r   r   rU   r   r  r  r"   r6   rE   rQ   ry   r'   )r   r   rB  
b_F_layoutnb_dtZr_typerF  r%   )rD  r$   rE  rQ   r6  r&   rF  !  s    




BrF  c             C   s   t dS )z
    Extract 'x' (the solution) from the 'bcpy' scratch space.
    Note 'b' is only used to check the system input dimension...
    N)r"  )r   r#  r%   r%   r&   _solve_compute_return  s    rI  c             C   s&   | j dkrdd }|S dd }|S d S )Nr   c             S   s
   |j  S )N)r   r;  )r   r#  r%   r%   r&   r&    s    z-_solve_compute_return_impl.<locals>.oneD_implc             S   s   |S )Nr%   )r   r#  r%   r%   r&   r'    s    z-_solve_compute_return_impl.<locals>.twoD_impl)r   )r   r#  r&  r'  r%   r%   r&   _solve_compute_return_impl  s
    
rJ  c                s~   t   t| d t|d | jdk |jdk}td| | t| j| j}t 	| jt
t|d fdd}|S )Nsolver   c          	      s   | j d }t|}t|  t| t| |  r<t| }n
t| }tj||fdj}|dkrlt	||S t
||| tj|td}|||j||j|j|}t| t|j|j|jg t	||S )Nr   )r"   r   )r   r)  r   r+  r   rZ   r   r   r   rI  r%  r   r   r   r   r   )r   r   r`   r$  r   r#  r   r   )rD  r$   rE  rS   r%   r&   
solve_impl  s2    



zsolve_impl.<locals>.solve_impl)r+   r   r   rU   r   r  r  r"   rE   rS   ry   r'   )r   r   rG  rH  rL  r%   )rD  r$   rE  rS   r&   rL    s    



,rL  V瞯<c                s   t   t| d t| jd| j}t|t | jt 	| j| j
dk tt| jdtdtdtdt| j}tjdg|d	tjdg|dd 	f
d
d	}|S )Npinvr4   r   r  rT   g        )r"   g      ?V瞯<c                s  | j d }| j d }t|   r,t| }n
t| }|dksF|dkrZ|j | j jS t||}tj	||f| j
d}tj	|d}tj	||f| j
d}|||j||j|j||j|}	t|	 |d | }
d}x0t|D ]$}|| |
krd||  ||< |}qW |d7 }||kr`xt|D ]6}x.t|D ]"}|||f ||  |||f< q2W q$W nHxFt|D ]:}|| }x*t|D ]}|||f | |||f< qW qjW |||j|j||j|	j|j|}	t|j|j|j|jj	jg |j | j jS )Nr   r   r   )r"   g      ?r   )r   r   r   rZ   r   r   r;  reshaper  r   r"   r   r   r   r   r   )r   rB  r`   r   r   r  r  r   r  r   Zcut_atZcut_idxr   r  r   Zs_local)
r   JOBTRANSATRANSBr$   rM   r?   r   r  zeror%   r&   	pinv_impl  st    '




*$	

zpinv_impl.<locals>.pinv_impl)rO  )r+   r   r6   r"   r  r  rE   rM   r1   r?   rU   ry   r'   r   array)r   rB  r  dtrU  r%   )
r   rQ  rR  rS  r$   rM   r?   r   r  rT  r&   rU    s"    


  rU  c             C   s2   t | jtjrtdd }|S tdd }|S dS )z
    Walks the diag of a LUP decomposed matrix
    uses that det(A) = prod(diag(lup(A)))
    and also that log(a)+log(b) = log(a*b)
    The return sign is adjusted based on the values found
    such that the log(value) stays in the real domain.
    c             S   sZ   |d }d}xDt | D ]8}t|||f }||||f |  }|t| }qW ||fS )Ny                g        )r   r   r5  log)r`   r   sgnZcsgnaccr   Zabselr%   r%   r&   cmplx_diag_walker  s    z3_get_slogdet_diag_walker.<locals>.cmplx_diag_walkerc             S   sP   d}x>t | D ]2}|||f }|dk r2| }| }|t| }qW |d |fS )Ng        )r   r   rX  )r`   r   rY  rZ  r   r   r%   r%   r&   real_diag_walker  s    z2_get_slogdet_diag_walker.<locals>.real_diag_walkerN)rX   r"   r   r   r   )r   r[  r\  r%   r%   r&   _get_slogdet_diag_walker  s
    
r]  c                sx   t   t| d t | jtt| jd| jdk t| | dt	| jd| jd fdd}|S )Nslogdetr   r   r4   r   c                s   | j d }| j d |kr(d}tj||dkr8fS t|   rPt| }n
t| }tj|td}|||j	||j	}|dkrdtj
 fS t| d}x$t|D ]}||| |d k }qW |d@ }|dkrd}t|jg |||S )Nr   r   z.Last 2 dimensions of the array must be square.r   )r"   g        r   )r   r   r   r   r   rZ   r   r   r   r   infr   r   r   r   )r   r`   r   r   r   r   rY  r   )r   ONEZEROdiag_walkerr$   rF   r%   r&   slogdet_impl  s.    

	z"slogdet_impl.<locals>.slogdet_impl)
r+   r   rE   rF   r"   ry   r'   rU   r]  r6   )r   rc  r%   )r   r`  ra  rb  r$   rF   r&   rc    s    


,rc  c             C   s   t   t| d dd }|S )Ndetc             S   s   t j| \}}|t | S )N)r   r   r^  exp)r   rY  r^  r%   r%   r&   det_impl  s    zdet_impl.<locals>.det_impl)r+   r   )r   rf  r%   r%   r&   rf    s    
rf  c             C   s   t dS )z)
    Compute singular values of *a*.
    N)r"  )r   r%   r%   r&   _compute_singular_values  s    rg  c                s   t  | jtt| jdtdt| jd| j}t|t| j}tj	d|dtj	d|d| j
dk  fdd}|S )	z>
    Returns a function to compute singular values of `a`
    r  r   r4   )r   r   )r"   r   c       
         s   | j d }| j d }|dks$|dkr0tjdt|  |}t||}d}d} r^t| }n
t| }tj|d}|||j	||j	j	|j	|}	t
|	 t|jjj|jg |S )z+
        Computes singular values.
        r   r   r   zArrays cannot be emptyr   )r"   )r   r   r   r   r   r  rZ   r   r   r   r   r   r   )
r   r`   r   r  r  r  r  r   r   r   )r   JOBZ_Nr$   np_ret_typerM   r  r  r%   r&   sv_function  s8    



z2_compute_singular_values_impl.<locals>.sv_function)rE   rM   r"   ry   r'   r6   r  r  r   r   rU   )r   nb_ret_typenp_dtyperj  r%   )r   rh  r$   ri  rM   r  r  r&   _compute_singular_values_impl  s    

2rm  c             C   s   t dS )z.
    Compute the L2-norm of 1D-array *a*.
    N)r"  )r   r%   r%   r&   _oneD_norm_2K  s    rn  c                sL   t | jd| j}t|t | jtt| jd  fdd}|S )Nr4   normc                sl   t | }tjdd}t| jd | j } || j||j}|dk rTt  dsTtt	|j
| j
g |d S )N)r   )r"   r   )lenr   r   rz   stridesitemsizer   r   r   r   r   )r   r`   r  Zjmpr   )r$   ri  xxnrm2r%   r&   rb   [  s    z_oneD_norm_2_impl.<locals>.impl)r6   r"   r  r  r1   r5   ry   r'   )r   rk  rb   r%   )r$   ri  rs  r&   _oneD_norm_2_implR  s    
rt  c       	         s
  t | jd| j}t|}t| j}t | j}tt| jd}| jdkrv|d t	j
fkrhddd}n
ddd}|S | jdk r|d t	j
fkr| jdkrtd	d
  n$| jdkrtdd
  ntdd
  d fdd	}nt|jjdfdd	}|S dstd S )Nr4   ro  r   c             S   s   t | S )N)rn  )r   ry   r%   r%   r&   r&    s    z!_get_norm_impl.<locals>.oneD_implc             S   sZ  t | }|dkrdS |dkr$t| S |tjkrjt| d }x*td|D ]}t| | }||krF|}qFW |S |tj krt| d }x*td|D ]}t| | }||k r|}qW |S |dkrd}x$t|D ]}| | dkr|d7 }qW |S |dkrd}x"t|D ]}|t| | 7 }q W |S d}x&t|D ]}|t| | | 7 }q,W |d|  S d S )Nr   g        r   r   g      ?)rp  rn  r   r_  r5  r   )r   ry   r`   r  r   r/   r%   r%   r&   r&    sD    

r   rT   c             S   s   | S )Nr%   )r   r%   r%   r&   array_prepare  s    z%_get_norm_impl.<locals>.array_preparer   c             S   s   | j S )N)r   )r   r%   r%   r&   ru    s    c             S   s   |   S )N)rZ   )r   r%   r%   r&   ru    s    c                s(   | j }|dkrdS  | }t||S )Nr   g        )r   rn  rP  )r   ry   r`   Za_c)ru  r%   r&   r'    s
    z!_get_norm_impl.<locals>.twoD_implc       	         s  | j d }| j d }| jdkr"dS |tjkr|d}xFt|D ]:}d}x$t|D ]}|t| ||f 7 }qLW ||kr:|}q:W |S |tj kr؈ }xFt|D ]:}d}x$t|D ]}|t| ||f 7 }qW ||k r|}qW |S |dkr4d}xHt|D ]<}d}x&t|D ]}|t| ||f 7 }qW ||kr|}qW |S |dkr }xLt|D ]@}d}x&t|D ]}|t| ||f 7 }q^W ||k rL|}qLW |S |dkrt| d S |dkrt| d S tdd S )Nr   r   r   g        r   r   z Invalid norm order for matrices.)r   r   r   r_  r   r5  rg  r   )	r   ry   r`   r   Z
global_maxZiiZtmpZjjZ
global_min)max_valr%   r&   r'    sZ    









r   )N)N)N)N)r6   r"   r  r  r1   r5   ry   r'   r   r   rd   rU   r   r   finfor   r@  r   )	r   Zord_flagrk  ri  rl  rs  r$   r&  r'  r%   )ru  rv  r&   _get_norm_implv  s,    


9

	Erx  c             C   s   t   t| d t| |S )Nro  )r+   r   rx  )r   ry   r%   r%   r&   	norm_impl=	  s    
ry  c             C   s"   t   t| d dd }|| |S )Ncondc             S   s.   |d t jfkrddd}|S ddd}|S d S )Nc             S   s   t | }|d |d  S )Nr   r   )rg  )r   pr   r%   r%   r&   cond_none_implO	  s    z9cond_impl.<locals>._get_cond_impl.<locals>.cond_none_implc             S   sr   |dks|dkrBt | }|dkr0|d |d  S |d |d  S n,tj| |}tjtj| |}|| S d S )Nr   r   r   r   )rg  r   r   ro  r   )r   r{  r   Znorm_aZ
norm_inv_ar%   r%   r&   cond_not_none_implT	  s    z=cond_impl.<locals>._get_cond_impl.<locals>.cond_not_none_impl)N)N)r   rd   )r   r{  r|  r}  r%   r%   r&   _get_cond_implL	  s
    

z!cond_impl.<locals>._get_cond_impl)r+   r   )r   r{  r~  r%   r%   r&   	cond_implF	  s    
'r  c             C   s6   d}x,t t| D ]}| | |kr,|d }qP qW |S )zJ
    Gets rank from singular values with cut-off at a given tolerance
    r   r   )r   rp  )Zsvr   rC  r   r%   r%   r&   _get_rank_from_singular_valuesv	  s    
r  c                s.   t   t| d dd   fdd}|| |S )ah  
    Computes rank for matrices and vectors.
    The only issue that may arise is that because numpy uses double
    precision lapack calls whereas numba uses type specific lapack
    calls, some singular values may differ and therefore counting the
    number of them above a tolerance may lead to different counts,
    and therefore rank, in some cases.
    matrix_rankc                sX   |d t jfkrFt| jd| j}t|}t|j d fdd	}|S ddd}|S d S )Nr4   c                s@   t | }| jd }| jd }t||}|d |   }t||S )Nr   r   )rg  r   r@  r  )r   tolr   r   r   lr   )eps_valr%   r&   _2d_tol_none_impl	  s    


zImatrix_rank_impl.<locals>._2d_matrix_rank_impl.<locals>._2d_tol_none_implc             S   s   t | }t||S )N)rg  r  )r   r  r   r%   r%   r&   _2d_tol_not_none_impl	  s    zMmatrix_rank_impl.<locals>._2d_matrix_rank_impl.<locals>._2d_tol_not_none_impl)N)N)	r   rd   r6   r"   r  r  r   rw  Zeps)r   r  Znb_typeZnp_typer  r  r%   )r  r&   _2d_matrix_rank_impl	  s    

z.matrix_rank_impl.<locals>._2d_matrix_rank_implc                s:   | j }|dkrddd}|S |dkr. | |S ds6td S )Nr   c             S   s*   x$t t| D ]}| | dkrdS qW dS )Ng        r   r   )r   rp  )r   r  r   r%   r%   r&   _1d_matrix_rank_impl	  s    zMmatrix_rank_impl.<locals>._get_matrix_rank_impl.<locals>._1d_matrix_rank_implr   r   )N)r   r   )r   r  r   r  )r  r%   r&   _get_matrix_rank_impl	  s    

z/matrix_rank_impl.<locals>._get_matrix_rank_impl)r+   r   )r   r  r  r%   )r  r&   matrix_rank_impl	  s
    

r  c                sF   t | d t| j t|d|}t|tjs6td fdd}|S )zL
    Computes matrix power. Only integer powers are supported in numpy.
    matrix_powerr"   zExponent must be an integer.c       
         sP  |dkr@t j| j d}x"t| jd D ]}d|||f< q(W |S | jd | jd  }}||krftd|dkrv|  S |dk rt j|  }|dkr|S | }n|dkr|  S | }|dk r|d	krt ||S |d
krt t |||S n\|}|}d}xJ|dkrF|d@ r.|r"|}	d}nt |	|}	t ||}|d? } qW |	S d S )Nr   )r"   g      ?r   r   zinput must be a square arrayr      r      TF)	r   r  r   r   r   rZ   r   r   r   )
r   r`   r  r   r,  r0  rZ  re  flagr  )rl  r%   r&   matrix_power_impl	  sF    
z,matrix_power_impl.<locals>.matrix_power_impl)	r   r  r  r"   r6   rX   r   Integerr!   )r   r`   ntr  r%   )rl  r&   r  	  s    
<r  c             C   s8   t | ddd t|ttjfs*td| ddd}|S )	z)
    Computes the trace of an array.
    traceF)r   z!integer argument expected, got %sr   c             S   s   | j \}}|}|dk r|| }|dkr.|| }tt||d}d}|dkrrxLt|D ]}|| ||| f 7 }qTW n&x$t|D ]}|| || |f 7 }q|W |S )Nr   )r   r@  r  r   )r   offsetZrowsZcolsr   r`   r  r  r%   r%   r&   matrix_trace_impl
  s    
z,matrix_trace_impl.<locals>.matrix_trace_impl)r   )r   rX   rz   r   r  r!   )r   r  r  r%   r%   r&   r  
  s
    
r  c             C   s>   |rdnd}||f}t | tjr:| jdks:td| ddd S )Nz	np.linalgr   r   z+%s.%s() only supported on 1 and 2-D arrays F)r   )rX   r   rY   r   r   )r   r#   r   r   r   r%   r%   r&   _check_scalar_or_lt_2d_mat3
  s    
r  c             C   s0   t | tjstdd }|S tdd }|S d S )Nc             S   s   t | fS )N)r   rV  )r   r%   r%   r&   asarray?
  s    z_get_as_array.<locals>.asarrayc             S   s   | S )Nr%   )r   r%   r%   r&   r  D
  s    )rX   r   rY   r   )r   r  r%   r%   r&   _get_as_array=
  s
    r  c                sN   t |  t ||d tjfkr4t fdd}|S t fdd}|S d S )Nc                s<    | }|}t | |jdf| d|jfS )Nr   )r   multiplyr;  rP  r   )r   r   r   aabb)a_arrb_arrr%   r&   
outer_implO
  s    z#_get_outer_impl.<locals>.outer_implc                sB    | }|}t | |jdf| d|jf| |S )Nr   )r   r  r;  rP  r   )r   r   r   r  r  )r  r  r%   r&   r  W
  s    )r  r   rd   r   )r   r   r   r  r%   )r  r  r&   _get_outer_implJ
  s    r  )r   	   c                s:   t | ddd t |ddd t| || d fdd	}|S )NouterF)r   c                s    | ||S )Nr%   )r   r   r   )rb   r%   r&   r  k
  s    zouter_impl.<locals>.outer_impl)N)r  r  )r   r   r   r  r%   )rb   r&   r  c
  s
    r  c                s8   t | ddd t |ddd t| |d   fdd}|S )Nr  F)r   c                s    | |d S )Nr%   )r   r   )rb   r%   r&   r  x
  s    zouter_impl.<locals>.outer_impl)r  r  )r   r   r  r%   )rb   r&   r  p
  s
    c             C   sL   t | tjr8| jdkr&tdd }|S tdd }|S ntdd }|S d S )Nr   c             S   s    | j d }| j d }| ||S )Nr   r   )r   rP  )r   xnZxmr%   r%   r&   	nrm_shape
  s    

z(_kron_normaliser_impl.<locals>.nrm_shapec             S   s   | j d }| d|S )Nr   r   )r   rP  )r   r  r%   r%   r&   r  
  s    
c             S   s   t dt| }| |d< |S )N)r   r   r   )r   r   r   )r   r   r%   r%   r&   r  
  s    )rX   r   rY   r   r   )r   r  r%   r%   r&   _kron_normaliser_impl~
  s    
r  c             C   s   t | tj}t |tj}|rV|rV| jdks4|jdkrDtdd }|S tdd }|S n8|rjtdd }|S |r~tdd }|S tdd }|S d S )Nr   c             S   s   |S )Nr%   )r   r   r   r%   r%   r&   r  
  s    z_kron_return.<locals>.retc             S   s   | |jS )N)rP  r   )r   r   r   r%   r%   r&   r  
  s    c             S   s   | | jS )N)rP  r   )r   r   r   r%   r%   r&   r  
  s    c             S   s   | |jS )N)rP  r   )r   r   r   r%   r%   r&   r  
  s    c             S   s   |d S )Nr   r%   )r   r   r   r%   r%   r&   r  
  s    )rX   r   rY   r   r   )r   r   Za_is_arrZb_is_arrr  r%   r%   r&   _kron_return
  s     r  c                sX   t | ddd t |ddd t| t|t| |t| d|   fdd}|S )NkronF)r   r"   c          	      s   | }|}|j d }|j d }|j d }|j d }|| }|| }	tj||	f d}
x|t|D ]p}|| }xbt|D ]V}|| }||d d f }x8t|D ],}|| }|||f | |
|||| f< qW qzW qdW | ||
S )Nr   r   )r"   )r   r   r   r   )r   r   r  r  r,  r0  r-  r1  cmZcnrT   r  Zrjmpr   ZirjmpZslcr   Zcjmp)rW  fix_afix_bret_cr%   r&   	kron_impl
  s$    



,zkron_impl.<locals>.kron_impl)r  r  r  r6   )r   r   r  r%   )rW  r  r  r  r&   r  
  s    
(r  )r   )F)T)T)r   )r=  )rM  )N)N)N)r   )T)N)rC   Z
__future__r   r   r   
contextlibZllvmliter   Znumpyr   operatorZnumbar   r   Znumba.targets.imputilsr   r	   r
   r   Znumba.typingr   Znumba.extendingr   r   Znumba.numpy_supportr   Znumpy_versionr   r  Zarrayobjr   r   r   errorsr   Zutilsr   rr   rs   Z
as_pointerZ	ll_char_pru   Zll_intcZ	ll_intc_prt   Z	ll_intp_prA  r   rG   Zfloat32rR   Z	complex64Z
complex128r   r'   r*   r+   r0   r1   rE   contextmanagerr^   re   rn   ro   r   r   r   r   r   r   r   r   rY   r   matmulr   r   r   r   r   r   r7   Zfatal_error_sigr;   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r
  r  r  r  r!  r%  r(  r)  r*  r+  r.  r/  r2  r3  r9  r:  r<  r>  rF  rI  rJ  rK  rL  rN  rU  r]  r^  rc  rd  rf  rg  rm  rn  rt  rx  ro  ry  rz  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r%   r%   r%   r&   <module>   s   



) $%2

/M

-


,{66
FV%
dC
 )$@L$ H

/
AN


"