o
    h#V                     @   s  U d Z ddlZddlmZ ddlmZmZmZ ddlZ	ddl
mZ ddlmZ ddlmZmZmZmZmZmZmZmZmZ g dZej !dd	Z"e#e$B e%d< ej !d
dZ&e"e&dZ'eZ(ee%d< e(ej)B Z)ee%d< dd Z*de(deddfddZ+de(defddZ,			dddd	d	dde)deded dB de$dB dedB de$de$de(fd d!Z-dd"d#e(dedB de(fd$d%Z.d&d&d&d&d'd(d)Z/d*d+ Z0d&d&d&d&d,dd-d.d/Z1ddd&d&d&d&d,dd0d1d2Z2d&d&d&d&d,d&dd3d4d5Z3ded7d8Z4dfd:d;Z5d<ede#fd=d>Z6d#e(dede$fd?d@Z7dede8e# e8d B fdAdBZ9dededB fdCdDZ:dd"d#e(dEe;dedB de(fdFdGZ<dd"dHe(dIe(dedB de(fdJdKZ=dd"d#e(dedB de(fdLdMZ>dd	dNddOd#e(dPe;e?e; B dB dQe$dRe;e@B dedB de(fdSdTZAdd"d#e(dedB de(fdUdVZBdd"d#e(dedB de(fdWdXZCdYddZd[e(d\e(dPe;dedB de(f
d]d^ZDd	d	dd_d`daZEdgd[e(dedB de(fdbdcZFdS )ha6  Utility functions to use Python Array API compatible libraries.

For the context about the Array API see:
https://data-apis.org/array-api/latest/purpose_and_scope.html

The SciPy use case of the Array API is described on the following page:
https://data-apis.org/array-api/latest/use_cases.html#use-case-scipy
    N)
ModuleType)AnyLiteral	TypeAlias)array_api_compat)	is_array_api_objsizenumpydeviceis_numpy_namespaceis_cupy_namespaceis_torch_namespaceis_jax_namespaceis_array_api_strict_namespace)_asarrayarray_namespaceassert_almost_equalassert_array_almost_equalget_xp_devicesis_array_api_strict
is_complexis_cupyis_jaxis_numpyis_torchSCIPY_ARRAY_APISCIPY_DEVICEscipy_namespace_forxp_assert_closexp_assert_equalxp_assert_lessxp_copyxp_copysign	xp_devicexp_moveaxis_to_endxp_ravelxp_realxp_signxp_sizexp_take_along_axisxp_unsupported_param_msgxp_vector_normr   Fr   cpu)r   r   Array	ArrayLikec              	   C   s  t t| D ]}| | }ddlm} ||rd}t|t|tjjr't	dt|tj
r1t	dt|tjtjB rT|j}t|tjsSt|tjsSt	d|dqt|szt|}W n t	yj   t	dw |j}t|tjst|tjsd	|d}t	||| |< q| S )
a  Raise exceptions on known-bad subclasses.

    The following subclasses are not supported and raise and error:
    - `numpy.ma.MaskedArray`
    - `numpy.matrix`
    - NumPy arrays which do not have a boolean or numerical dtype
    - Any array-like which is neither array API compatible nor coercible by NumPy
    - Any array-like which is coerced by NumPy to an unsupported dtype
    r   )issparsezSparse arrays/matrices are not supported by this function. Perhaps one of the `scipy.sparse.linalg` functions would work instead.z8Inputs of type `numpy.ma.MaskedArray` are not supported.z0Inputs of type `numpy.matrix` are not supported.zAn argument has dtype `z3`; only boolean and numerical dtypes are supported.zCAn argument is neither array API compatible nor coercible by NumPy.z1An argument was coerced to an unsupported dtype `)rangelenscipy.sparser/   
ValueError
isinstancenpmaMaskedArray	TypeErrormatrixndarraygenericdtype
issubdtypenumberbool_r   
asanyarray)arraysiarrayr/   msgr<   message rF   I/var/www/vscode/kcb/lib/python3.10/site-packages/scipy/_lib/_array_api.py_compliance_scipy9   s:   

rH   rC   xpreturnc                 C   s:   d}z| || st|W dS  ty   t|w )zCheck for NaNs or Infs.z#array must not contain infs or NaNsN)allisfiniter3   r8   )rC   rI   rD   rF   rF   rG   _check_finiteh   s   rM   rA   c                  G   s,   t d stS dd | D }t|}tj| S )a1  Get the array API compatible namespace for the arrays xs.

    Parameters
    ----------
    *arrays : sequence of array_like
        Arrays used to infer the common namespace.

    Returns
    -------
    namespace : module
        Common namespace.

    Notes
    -----
    Thin wrapper around `array_api_compat.array_namespace`.

    1. Check for the global switch: SCIPY_ARRAY_API. This can also be accessed
       dynamically through ``_GLOBAL_CONFIG['SCIPY_ARRAY_API']``.
    2. `_compliance_scipy` raise exceptions on known-bad subclasses. See
       its definition for more details.

    When the global switch is False, it defaults to the `numpy` namespace.
    In that case, there is no compliance check. This is a convenience to
    ease the adoption. Otherwise, arrays must comply with the new rules.
    r   c                 S      g | ]}|d ur|qS NrF   ).0rC   rF   rF   rG   
<listcomp>       z#array_namespace.<locals>.<listcomp>)_GLOBAL_CONFIG	np_compatrH   r   r   )rA   _arraysrF   rF   rG   r   r   s
   
r   )rI   check_finitesubokr<   order)KACFcopyrV   rW   c                C   s   |du rt | }t|r.|du rtj| |||d} n7|r%tj| ||d} n,tj| ||d} n#z
|j| ||d} W n tyP   t |d}|j| ||d} Y nw |rXt| | | S )a`  SciPy-specific replacement for `np.asarray` with `order`, `check_finite`, and
    `subok`.

    Memory layout parameter `order` is not exposed in the Array API standard.
    `order` is only enforced if the input array implementation
    is NumPy based, otherwise `order` is just silently ignored.

    `check_finite` is also not a keyword in the array API standard; included
    here for convenience rather than that having to be a separate function
    call inside SciPy functions.

    `subok` is included to allow this function to preserve the behaviour of
    `np.asanyarray` for NumPy based inputs.
    NT)rX   r<   rW   )rX   r<   )r<   r]      )r   r   r5   rC   r@   asarrayr8   rM   )rC   r<   rX   r]   rI   rV   rW   
coerced_xprF   rF   rG   r      s"   
r   rI   xc                C   s   |du rt | }t| d|dS )a3  
    Copies an array.

    Parameters
    ----------
    x : array

    xp : array_namespace

    Returns
    -------
    copy : array
        Copied array

    Notes
    -----
    This copy function does not offer all the semantics of `np.copy`, i.e. the
    `subok` and `order` keywords are not used.
    NT)r]   rI   )r   r   rb   rI   rF   rF   rG   r!      s   r!   Tcheck_namespacecheck_dtypecheck_shapecheck_0dc          	      C   s   d}|r	t | | t|r3|r3dt|  dt| }|| r%||s3|| s/||r3J ||| } ||}|rSd| j d|j }| j|jksSJ ||rid| j d|j }| j|jksiJ |||| j}| |fS )NTz$Array-ness does not match:
 Actual: z
 Desired: zdtypes do not match.
Actual: 

Desired: zShapes do not match.
Actual: )_assert_matching_namespacer   typeisscalarr_   r<   shapebroadcast_to)	actualdesiredrI   re   rf   rg   rh   __tracebackhide___msgrF   rF   rG   _strict_check   s4   


rs   c                 C   sZ   d}t | tr	| n| f} t|}| D ]}t|}d|j d|j }||ks*J |qd S )NTz!Namespaces do not match.
Actual: ri   )r4   tupler   __name__)ro   rp   rq   desired_spacearr	arr_spacerr   rF   rF   rG   rj      s   rj    )re   rf   rg   rh   err_msgrI   c          	   	   C   s   d}|d u r
t | }t| ||||||d\} }t|r$|jj| ||dS t|r=|dkr.d n|}|jj| |dddd|dS tjj| ||dS )NTrd   )rz   ry   r   Frtolatol	equal_nanrf   rD   )r   rs   r   testingassert_array_equalr   assert_closer5   )	ro   rp   re   rf   rg   rh   rz   rI   rq   rF   rF   rG   r     s    
r   )r|   r}   re   rf   rg   rh   rz   rI   c             	   C   s   d}
|	d u r
t | }	t| ||	||||d\} }|	| jd}|d u r0|r0|	| jjd d }n|d u r6d}t|	rE|	jj| ||||dS t	|	r^|dkrOd n|}|	jj
| |||dd	|d
S tjj| ||||dS )NTrd   )real floatingcomplex floating      ?   gHz>)r|   r}   rz   ry   Fr{   )r   rs   isdtyper<   finfoepsr   r   assert_allcloser   r   r5   )ro   rp   r|   r}   re   rf   rg   rh   rz   rI   rq   floatingrF   rF   rG   r   $  s2   
r   )re   rf   rg   rh   rz   verboserI   c          
   	   C   s   d}	|d u r
t | }t| ||||||d\} }t|r%|jj| |||dS t|r=| jjdkr3|  } |jjdkr=| }t	jj| |||dS )NTrd   )rz   r   r,   )
r   rs   r   r   assert_array_lessr   r
   rk   r,   r5   )
ro   rp   re   rf   rg   rh   rz   r   rI   rq   rF   rF   rG   r    F  s(   


r       c                 O   6   ddd|   }}t | |g|R ||ddd|S zPBackwards compatible replacement. In new code, use xp_assert_close instead.
    r   g      ?
   F)r}   r|   rf   rg   r   ro   rp   decimalargskwdsr|   r}   rF   rF   rG   r   _     r      c                 O   r   r   r   r   rF   rF   rG   r   h  r   r   paramc                 C   s   d| dS )Nz
Providing z$ is only supported for numpy arrays.rF   )r   rF   rF   rG   r*   q  s   r*   c                 C   s   | | jdS Nr   )r   r<   rc   rF   rF   rG   r   u  s   r   c           
      C   s@  g }t | r1|dg7 }ddl}|j }td|D ]
}|d| g7 }q|jj r/|dg7 }|S t| rQddl	}|jj
 }td|D ]
}|d| g7 }qD|S t| rddl}|jdd}td|D ]
}|d| g7 }qd|jdd}td|D ]
}|d	| g7 }qz|jd
d}	td|	D ]
}|d| g7 }q|S dgS )z<Returns a list of available devices for the given namespace.r,   r   Nzcuda:mps)backendzcpu:gpuzgpu:tpuztpu:)r   torchcudadevice_countr0   backendsr   is_availabler   cupyruntimegetDeviceCountr   jax)
rI   devicesr   num_cudarB   r   r   num_cpunum_gpunum_tpurF   rF   rG   r   y  s:   


r   c                 C   s<   t | rddl}|jS t| rddl}|jS t| r| S dS )a  Return the `scipy`-like namespace of a non-NumPy backend

    That is, return the namespace corresponding with backend `xp` that contains
    `scipy` sub-namespaces like `linalg` and `special`. If no such namespace
    exists, return ``None``. Useful for dispatching.
    r   N)r   cupyxscipyr   r   r   )rI   r   r   rF   rF   rG   r     s   r   sourcec               C   sB   |d u rt |n|}tt| j}||}||g }|| |S rO   )r   listr0   ndimpoppermute_dims)rb   r   rI   axestemprF   rF   rG   r$     s
   

r$   x1x2c               C   s4   |d u r	t | |n|}|| }||dk|| S )Nr   )r   abswhere)r   r   rI   abs_x1rF   rF   rG   r"     s   
r"   c               C   s   |d u rt | n|}t|r|| S || }|jd| jd}|| dk||}|| dk | |}||| |j| |}|S )N   r<   r   )	r   r   sign
zeros_liker_   r<   r   isnannan)rb   rI   r   onerF   rF   rG   r'     s   

r'      )axiskeepdimsordrI   r   r   r   c               C   sx   |d u rt | n|}tr2t|dr|jj| |||dS |dkr#td|j|| |  ||dd S tjj	| |||dS )Nlinalg)r   r   r   r   zonly the Euclidean norm (`ord=2`) is currently supported in `xp_vector_norm` for backends not implementing the `linalg` extension.)r   r   r   )r   r   r   )
r   r   hasattrr   vector_normr3   sumconjr5   norm)rb   r   r   r   rI   rF   rF   rG   r+     s   
r+   c               C   s    |d u rt | n|}|| dS )N))r   reshaperc   rF   rF   rG   r%     s   r%   c               C   s0   |d u rt | n|}|| jdr|| S | S r   )r   r   r<   realrc   rF   rF   rG   r&     s   r&   r   )r   rI   rw   indicesc               C   sJ   |d u rt | n|}t|r|j| ||dS t|rtd|| ||S )N)dimz2Array API standard does not define take_along_axis)r   r   take_along_dimr   NotImplementedErrortake_along_axis)rw   r   r   rI   rF   rF   rG   r)     s   r)   )ensure_writeableforce_floatingrI   c              
      s   d u rt | n  dd |D }dd |D } dj}dd |D }z j| }|r9 |dr9 ||}W n) tyc    fdd|D }|rW jg ||R  }n
|r\|}n j| }Y nw dd	 |D }	zt|	d
krwtj|	 n|d j	}
W n t
y } zd}t
||d }~ww g }|D ]9}|d u r|| q|j	|
krt rddini } j||
fi |}|j|ks| rɈ j||dd}|| q|S )Nc                 S   s$   g | ]}|d urt |ddn|qS )NT)rW   )r   rP   argrF   rF   rG   rQ     s   $ z(xp_broadcast_promote.<locals>.<listcomp>c                 S   rN   rO   rF   r   rF   rF   rG   rQ     rR   g      ?c                 S   s   g | ]}|j qS rF   r   r   rF   rF   rG   rQ         integralc                    s   g | ]
}  |d s|qS )r   )r   )rP   r<   ra   rF   rG   rQ   !  s    

c                 S   s   h | ]}|j qS rF   )rm   r   rF   rF   rG   	<setcomp>+  r   z'xp_broadcast_promote.<locals>.<setcomp>r   r   z/Array shapes are incompatible for broadcasting.rW   T)r]   )r   r_   r<   result_typer   r8   r1   r5   broadcast_shapesrm   r3   appendr   rn   astype)r   r   rI   r   args_not_nonedefault_floatdtypesr<   float_dtypesshapesrm   erE   outr   kwargsrF   ra   rG   xp_broadcast_promote  sR   




r   c                 C   sX   |d u rt | n|}| j}|||jr|| |j} | S ||dr*|| |j} | S )Nr   )r   r<   r   float32r   	complex64
complex128)rw   rI   	arr_dtyperF   rF   rG   xp_float_to_complexH  s   r   )NNN)r   )r   rO   )G__doc__ostypesr   typingr   r   r   r	   r5   numpy.typingnpt
scipy._libr   scipy._lib.array_api_compatr   r   r(   rT   r
   r#   r   r   r   r   r   r   r   r   r   r   __all__environgetr   strbool__annotations__r   rS   r-   r.   rH   rM   r   r   r!   rs   rj   r   r   r    r   r   r*   r   r   r   r   intr$   r"   r'   rt   floatr+   r%   r&   r)   r   r   rF   rF   rF   rG   <module>   s    ,/
'
	
 /"


		$
$ 	

  	

 7