o
    iQW                     @   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,			dfd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Z3dgd7d8Z4dhd: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ZEdid[e(dedB de(fdbdcZFddde ZGdS )ja6  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lenZscipy.sparser/   
ValueError
isinstancenpmaZMaskedArray	TypeErrormatrixZndarrayZgenericdtypeZ
issubdtypenumberZbool_r   
asanyarray)arraysiarrayr/   msgr8   message r@   O/home/kim/smarthome/.venv/lib/python3.10/site-packages/scipy/_lib/_array_api.py_compliance_scipy9   s:   

rB   r=   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isfiniter2   r6   )r=   rC   r>   r@   r@   rA   _check_finiteh   s   rG   r;   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 Nr@   ).0r=   r@   r@   rA   
<listcomp>       z#array_namespace.<locals>.<listcomp>)_GLOBAL_CONFIG	np_compatrB   r   r   )r;   Z_arraysr@   r@   rA   r   r   s
   
r   )rC   check_finitesubokr8   order)KACFcopyrO   rP   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)rQ   r8   rP   )rQ   r8   )r8   rV      )r   r   r4   r=   r:   asarrayr6   rG   )r=   r8   rQ   rV   rC   rO   rP   Z
coerced_xpr@   r@   rA   r      s"   
r   rC   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)rV   rC   )r   r   rZ   rC   r@   r@   rA   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   typeZisscalarrX   r8   shapebroadcast_to)	actualdesiredrC   r]   r^   r_   r`   __tracebackhide___msgr@   r@   rA   _strict_check   s4   


rj   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: ra   )r3   tupler   __name__)rf   rg   rh   Zdesired_spacearrZ	arr_spaceri   r@   r@   rA   rb      s   rb    )r]   r^   r_   r`   err_msgrC   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 )NTr\   )ro   rn   r   FrtolatolZ	equal_nanr^   r>   )r   rj   r   testingZassert_array_equalr   assert_closer4   )	rf   rg   r]   r^   r_   r`   ro   rC   rh   r@   r@   rA   r     s    
r   )rq   rr   r]   r^   r_   r`   ro   rC   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 )NTr\   )real floatingcomplex floating      ?   gHz>)rq   rr   ro   rn   Frp   )r   rj   isdtyper8   Zfinfoepsr   rs   Zassert_allcloser   rt   r4   )rf   rg   rq   rr   r]   r^   r_   r`   ro   rC   rh   Zfloatingr@   r@   rA   r   $  s2   
r   )r]   r^   r_   r`   ro   verboserC   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 )NTr\   )ro   r{   r,   )
r   rj   r   rs   Zassert_array_lessr   r
   rc   r,   r4   )
rf   rg   r]   r^   r_   r`   ro   r{   rC   rh   r@   r@   rA   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)rr   rq   r^   r_   r   rf   rg   decimalargskwdsrq   rr   r@   r@   rA   r   _     r      c                 O   r}   r~   r   r   r@   r@   rA   r   h  r   r   paramc                 C   s   d| dS )Nz
Providing z$ is only supported for numpy arrays.r@   )r   r@   r@   rA   r*   q  s   r*   c                 C   s   | | jdS Nrv   )ry   r8   r[   r@   r@   rA   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:Zgpuzgpu:Ztpuztpu:)r   torchcudaZdevice_countr0   backendsr   Zis_availabler   cupyZruntimeZgetDeviceCountr   jax)
rC   Zdevicesr   Znum_cudar<   r   r   Znum_cpuZnum_gpuZnum_tpur@   r@   rA   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   cupyxZscipyr   r   r   )rC   r   r   r@   r@   rA   r     s   r   sourcec               C   sB   |d u rt |n|}tt| j}||}||g }|| |S rI   )r   listr0   ndimpopZpermute_dims)rZ   r   rC   Zaxestempr@   r@   rA   r$     s
   

r$   x1x2c               C   s4   |d u r	t | |n|}|| }||dk|| S )Nr   )r   abswhere)r   r   rC   Zabs_x1r@   r@   rA   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   r8   r   )	r   r   signZ
zeros_likerX   r8   r   isnannan)rZ   rC   r   oner@   r@   rA   r'     s   

r'      )axiskeepdimsordrC   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   rw   )r   r   r   )
r   r   hasattrr   Zvector_normr2   sumZconjr4   Znorm)rZ   r   r   r   rC   r@   r@   rA   r+     s   
r+   c               C   s    |d u rt | n|}|| dS )N))r   Zreshaper[   r@   r@   rA   r%     s   r%   c               C   s0   |d u rt | n|}|| jdr|| S | S r   )r   ry   r8   realr[   r@   r@   rA   r&     s   r&   r   )r   rC   rm   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   Ztake_along_dimr   NotImplementedErrorZtake_along_axis)rm   r   r   rC   r@   r@   rA   r)     s   r)   )ensure_writeableforce_floatingrC   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)rP   )r   rJ   argr@   r@   rA   rK     s   $ z(xp_broadcast_promote.<locals>.<listcomp>c                 S   rH   rI   r@   r   r@   r@   rA   rK     rL   g      ?c                 S   s   g | ]}|j qS r@   r   r   r@   r@   rA   rK         integralc                    s   g | ]
}  |d s|qS )r   )ry   )rJ   r8   rY   r@   rA   rK   !  s    

c                 S   s   h | ]}|j qS r@   )rd   r   r@   r@   rA   	<setcomp>+  r   z'xp_broadcast_promote.<locals>.<setcomp>r   r   z/Array shapes are incompatible for broadcasting.rP   T)rV   )r   rX   r8   Zresult_typery   r6   r1   r4   Zbroadcast_shapesrd   r2   appendr   re   astype)r   r   rC   r   Zargs_not_noneZdefault_floatZdtypesr8   Zfloat_dtypesZshapesrd   er?   outr   kwargsr@   rY   rA   xp_broadcast_promote  sR   




r   c                 C   sX   |d u rt | n|}| j}|||jr|| |j} | S ||dr*|| |j} | S )Nru   )r   r8   ry   Zfloat32r   Z	complex64Z
complex128)rm   rC   Z	arr_dtyper@   r@   rA   xp_float_to_complexH  s   r   c                 C   s   t | r|  S | jS )z@Query the namespace-dependent default floating-point dtype.
    )r   Zget_default_dtypeZfloat64rY   r@   r@   rA   xp_default_dtypeV  s   r   )NNN)r|   )r   rI   )H__doc__ostypesr   typingr   r   r   r	   r4   Znumpy.typingZnptZ
scipy._libr   Zscipy._lib.array_api_compatr   r   r(   rN   r
   r#   r   r   r   r   r   r   r   r   r   r   __all__environgetr   strbool__annotations__r   rM   r-   r.   rB   rG   r   r   r!   rj   rb   r   r   r    r   r   r*   r   r   r   r   intr$   r"   r'   rk   floatr+   r%   r&   r)   r   r   r   r@   r@   r@   rA   <module>   s    ,/
'
	
 /"


		$
$ 	

  	

7