
    Vpf:6                       d dl mZ d dlmZmZmZ d dlZd dlZd dlm	Z	 d dl
Z
d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d
Zd                    e          Zde dZd                    e          Zd                    e          Zeedf         Z e	Z!d5dZ"	 d6d7d Z#	 d6d8d&Z$	 d6d9d*Z%d:d2Z& e'            dd3d4Z(dS );    )annotations)Callable
CollectionSequenceN)Any)api)config)lax)	lax_numpy)safe_mapsafe_zipz\w+z(?:{0:}(?:,{0:})*)?z\(z\)z{0:}(?:,{0:})*z^{0:}->{0:}$.	signaturestrreturn%tuple[list[CoreDims], list[CoreDims]]c                    t          j        t          |           st          d|            d |                     d          D             \  }}||fS )a  Parse string signatures for a generalized universal function.

  Args:
    signature: generalized universal function signature, e.g.,
      ``(m,n),(n,p)->(m,p)`` for ``jnp.matmul``.

  Returns:
    Input and output core dimensions parsed from the signature.
  znot a valid gufunc signature: c              3  ^   K   | ](}d  t          j        t          |          D             V  )dS )c                \    g | ])}t          t          j        t          |                    *S  )tuplerefindall_DIMENSION_NAME.0args     X/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/_src/numpy/vectorize.py
<listcomp>z5_parse_gufunc_signature.<locals>.<genexpr>.<listcomp>8   s<     ? ? ? "*_c::;; ? ? ?    N)r   r   	_ARGUMENT)r   arg_lists     r   	<genexpr>z*_parse_gufunc_signature.<locals>.<genexpr>8   sY       : :? ? jH==? ? ? : : : : : :r   z->)r   match
_SIGNATURE
ValueErrorsplit)r   argsretvalss      r   _parse_gufunc_signaturer)   )   so     
*i	(	( 6
4446 6 6: :#,??4#8#8: : :-$ 
wr    	dim_sizesdict[str, int]shapetuple[int, ...]	core_dimsCoreDimserror_contextis_inputboolc                  t          |          }|r,t          |          |k     rt          d|d|d|          n+t          |          |k    rt          d|d|d|          |r|| d         nd}t          ||          D ]<\  }}|| vr|| |<   || |         k    r!t          d|d	|d
| |         d|          =dS )ae  Incrementally check and update core dimension sizes for a single argument.

  Args:
    dim_sizes: sizes of existing core dimensions. Will be updated in-place.
    shape: shape of this argument.
    core_dims: core dimensions for this argument.
    error_context: string context for error messages.
    is_input: are we parsing input or output arguments?
  zinput with shape z9 does not have enough dimensions for all core dimensions  zoutput shape z  does not match core dimensions Nr   z%inconsistent size for core dimension z: z vs )lenr%   zip)	r+   r-   r/   r1   r2   num_core_dims
core_shapedimsizes	            r   _update_dim_sizesr<   >   s9     i..- 	/
5zzM!!J %yyy--AB B B "
 5zz]""JUUIII}}./ / / *3:um^__%%*y*-- 8 8ic4
)inn	3		JSS$$$	#78 8 8 
 8 8r   r'   tuple[NDArray, ...]input_core_dimslist[CoreDims]&tuple[tuple[int, ...], dict[str, int]]c                   t          |           t          |          k    r2t          dt          |          dt          |           d|          g }i }t          | |          D ]W\  }}t          ||j        ||d           |j        t          |          z
  }|                    |j        d|                    Xt          j        | }||fS )a  Parse broadcast and core dimensions for vectorize with a signature.

  Args:
    args: tuple of input arguments to examine.
    input_core_dims: list of core dimensions corresponding to each input.
    error_context: string context for error messages.

  Returns:
    broadcast_shape: common shape to broadcast all non-core dimensions to.
    dim_sizes: common sizes for named core dimensions.
  z/wrong number of positional arguments: expected , got r5   Tr2   N)	r6   	TypeErrorr7   r<   r-   ndimappendr
   broadcast_shapes)	r'   r>   r1   shapesr+   r   r/   rE   broadcast_shapes	            r   _parse_input_dimensionsrJ   d   s      	YY#o&&&&
)TMM	;< < < & )D/22 $ $nc9iI}#% % % %8c)nn$D
MM#)ETE"####(&1/	)	##r   funcr   expected_output_core_dimsc                      fd}|S )z6Check that output core dimensions match the signature.c                 R    
|  }t          t          j        t          |t                    r|n|g          }	dgt          |          z  }n	}t          |          dk    r8t          |t                    s#t          d                    |                    t          |          t          |          k    r2t          dt          |          dt          |          d          t                    }t          ||          D ]\  }}t          |||d           |S )	Nr      zGoutput must be a tuple when multiple outputs are expected, got: {!r}
{}z+wrong number of output arguments: expected rB   r5   FrC   )mapjnpr-   
isinstancer   r6   rD   formatdictr7   r<   )r'   out
out_shapesoutput_core_dimssizesr-   r/   r+   r1   rL   rK   s          r   wrappedz#_check_output_dims.<locals>.wrapped   sT   
$+CSYz#u'='= HC5IIJ (J/2				"	":c5+A+A	""F3668 8 	8 
ZC 011	1	1i#$$$$c*oooo}}FG G 	G OOE
,<== ( (yui!&( ( ( ( ( Jr   r   )rK   r+   rL   r1   rY   s   ```` r   _check_output_dimsrZ      s5           . 
.r   Callable[..., Any]excludedCollection[int | str]Sequence[Any]kwargsdict[str, Any]8tuple[Callable[..., Any], Sequence[Any], dict[str, Any]]c                2    s |fS fdt                    D             }fd|                                D             }fdt          d D                       D             fd|                                D              fd}|||fS )zAPartially apply positional arguments in `excluded` to a function.c                "    g | ]\  }}|v	|S r   r   )r   ir   r\   s      r   r   z#_apply_excluded.<locals>.<listcomp>   s'    III&!Sq7H7H#7H7H7Hr   c                $    i | ]\  }}|v	||S r   r   r   keyvalr\   s      r   
<dictcomp>z#_apply_excluded.<locals>.<dictcomp>   s)    SSScs(?R?RC?R?R?Rr   c                J    g | ]}|t                    k     ||         f S r   )r6   )r   rd   r'   s     r   r   z#_apply_excluded.<locals>.<listcomp>   s7     # # #!D		MM T!W!MMr   c              3  D   K   | ]}t          |t                    |V  d S NrR   intr   es     r   r"   z"_apply_excluded.<locals>.<genexpr>   s3      -X-XAZPQSVEWEW-Xa-X-X-X-X-X-Xr   c                $    i | ]\  }}|v 	||S r   r   rf   s      r   ri   z#_apply_excluded.<locals>.<dictcomp>   s$    NNNScXoo3ooor   c                 r    t          |           } D ]\  }}|                     ||            | i |S rl   )listinsert)r'   r_   rd   r   rK   static_argsstatic_kwargss       r   new_funcz!_apply_excluded.<locals>.new_func   sR    ::D  3
kk!S411=111r   )	enumerateitemssorted)	rK   r\   r'   r_   dynamic_argsdynamic_kwargsrw   ru   rv   s	   ```    @@r   _apply_excludedr}      s    
 
 vIIIIIdOOIII,SSSSV\\^^SSS.# # # #v-X-X-X-X-X'X'X # # #+NNNNFLLNNNNN-2 2 2 2 2 2 2 
<	//r   )r\   r   c                   t          d D                       r"t          d                                        t          d D                       rt          dd          t	          j                    fd            }|S )a   Define a vectorized function with broadcasting.

  :func:`vectorize` is a convenience wrapper for defining vectorized
  functions with broadcasting, in the style of NumPy's
  `generalized universal functions <https://numpy.org/doc/stable/reference/c-api/generalized-ufuncs.html>`_.
  It allows for defining functions that are automatically repeated across
  any leading dimensions, without the implementation of the function needing to
  be concerned about how to handle higher dimensional inputs.

  :func:`jax.numpy.vectorize` has the same interface as
  :class:`numpy.vectorize`, but it is syntactic sugar for an auto-batching
  transformation (:func:`vmap`) rather than a Python loop. This should be
  considerably more efficient, but the implementation must be written in terms
  of functions that act on JAX arrays.

  Args:
    pyfunc: function to vectorize.
    excluded: optional set of integers representing positional arguments for
      which the function will not be vectorized. These will be passed directly
      to ``pyfunc`` unmodified.
    signature: optional generalized universal function signature, e.g.,
      ``(m,n),(n)->(m)`` for vectorized matrix-vector multiplication. If
      provided, ``pyfunc`` will be called with (and expected to return) arrays
      with shapes given by the size of corresponding core dimensions. By
      default, pyfunc is assumed to take scalars arrays as input and output.

  Returns:
    Vectorized version of the given function.

  Here are a few examples of how one could write vectorized linear algebra
  routines using :func:`vectorize`:

  >>> from functools import partial

  >>> @partial(jnp.vectorize, signature='(k),(k)->(k)')
  ... def cross_product(a, b):
  ...   assert a.shape == b.shape and a.ndim == b.ndim == 1
  ...   return jnp.array([a[1] * b[2] - a[2] * b[1],
  ...                     a[2] * b[0] - a[0] * b[2],
  ...                     a[0] * b[1] - a[1] * b[0]])

  >>> @partial(jnp.vectorize, signature='(n,m),(m)->(n)')
  ... def matrix_vector_product(matrix, vector):
  ...   assert matrix.ndim == 2 and matrix.shape[1:] == vector.shape
  ...   return matrix @ vector

  These functions are only written to handle 1D or 2D arrays (the ``assert``
  statements will never be violated), but with vectorize they support
  arbitrary dimensional inputs with NumPy style broadcasting, e.g.,

  >>> cross_product(jnp.ones(3), jnp.ones(3)).shape
  (3,)
  >>> cross_product(jnp.ones((2, 3)), jnp.ones(3)).shape
  (2, 3)
  >>> cross_product(jnp.ones((1, 2, 3)), jnp.ones((2, 1, 3))).shape
  (2, 2, 3)
  >>> matrix_vector_product(jnp.ones(3), jnp.ones(3))  # doctest: +IGNORE_EXCEPTION_DETAIL
  Traceback (most recent call last):
  ValueError: input with shape (3,) does not have enough dimensions for all
  core dimensions ('n', 'k') on vectorized function with excluded=frozenset()
  and signature='(n,k),(k)->(k)'
  >>> matrix_vector_product(jnp.ones((2, 3)), jnp.ones(3)).shape
  (2,)
  >>> matrix_vector_product(jnp.ones((2, 3)), jnp.ones((4, 3))).shape
  (4, 2)

  Note that this has different semantics than `jnp.matmul`:

  >>> jnp.matmul(jnp.ones((2, 3)), jnp.ones((4, 3)))  # doctest: +IGNORE_EXCEPTION_DETAIL
  Traceback (most recent call last):
  TypeError: dot_general requires contracting dimensions to have the same shape, got [3] and [4].
  c              3  P   K   | ]!}t          |t          t          f           V  "d S rl   )rR   r   rn   )r   excludes     r   r"   zvectorize.<locals>.<genexpr>  s3      EEZ#s,,	,EEEEEEr   zSjax.numpy.vectorize can only exclude integer or string arguments, but excluded={!r}c              3  L   K   | ]}t          |t                    o|d k     V   dS )r   Nrm   ro   s     r   r"   zvectorize.<locals>.<genexpr>  s5      88!As			%A888888r   z	excluded=z contains negative numbersc                 (   d                               }t          | |          \  }} }t                    \  }ndgt          |           z  d }d t	          |           D             t                    rat          fdD                       rt          d d          t          || i           \  }} }fdt	                    D             t          t          t          j
        |                     } t          | |          \  }}t          ||||          }t          j        j        dk    rd	 t!          |           D             }	t          t#          |	                    d
k    radd | D              d d}
t          j        j        dk    rt%          j        |
           n$t          j        j        dk    rt          |
          g }g }t!          |           D ]\  }}|j        d |j        t          |          z
           }t          |          t          |          z
  }|dz  |z   }|                    |d d d                    t          d t	          |          D                       }t          j        ||          }|                    |           |}g t	          t!          |           D ]u\  }}t          d |D                       }t1          d |D                       r)                    t          |          d
z
  |z
             `t3          j        ||          }v || }s|S t7          |t                    rt          fd|D                       S t          j        |          S )Nz<on vectorized function with excluded={!r} and signature={!r}r   c                    h | ]	\  }}||
S rl   r   )r   rd   r   s      r   	<setcomp>z-vectorize.<locals>.wrapped.<locals>.<setcomp>  s    @@@vq#CKKKKr   c              3  0   K   | ]}|         d k    V  dS )r   Nr   )r   rd   r>   s     r   r"   z-vectorize.<locals>.wrapped.<locals>.<genexpr>  s-      99!_Q2%999999r   zCannot pass None at locations z with signature=c                "    g | ]\  }}|v	|S r   r   )r   rd   r:   	none_argss      r   r   z.vectorize.<locals>.wrapped.<locals>.<listcomp>  s(    \\\CR[I[I[I[I[I[r   allowc                X    g | ]'\  }}|j         d k    |j         t          |          z
  (S )r   )rE   r6   )r   r   r/   s      r   r   z.vectorize.<locals>.wrapped.<locals>.<listcomp>(  s<     ! ! !!3	(a-- x#i..(--r   rO   zoperands with shapes c                    g | ]	}|j         
S r   )r-   r   s     r   r   z.vectorize.<locals>.wrapped.<locals>.<listcomp>,  s    'B'B'Bc	'B'B'Br   zB require rank promotion for jnp.vectorize function with signature z. Set the jax_numpy_rank_promotion config option to 'allow' to disable this message; for more information, see https://jax.readthedocs.io/en/latest/rank_promotion_warning.html.warnraise)rO   c              3  ,   K   | ]\  }}|d k    |V  dS )rO   Nr   )r   rd   r;   s      r   r"   z-vectorize.<locals>.wrapped.<locals>.<genexpr>H  s+      UUGAt4ST99a9999UUr   axisc              3  *   K   | ]}|d k    rdndV  dS )rO   Nr   r   )r   r;   s     r   r"   z-vectorize.<locals>.wrapped.<locals>.<genexpr>O  s.      FF4daiiddQFFFFFFr   c              3     K   | ]}|d u V  	d S rl   r   )r   r   s     r   r"   z-vectorize.<locals>.wrapped.<locals>.<genexpr>P  s&      ..dTT\......r   c              3  D   K   | ]}t          j        |           V  dS )r   N)rQ   expand_dims)r   rdims_to_expands     r   r"   z-vectorize.<locals>.wrapped.<locals>.<genexpr>Y  s2      KKq3?1>:::KKKKKKr   )rS   r}   r)   r6   rx   anyr%   r   rP   rQ   asarrayrJ   rZ   r	   numpy_rank_promotionvaluer7   setwarningsr   r-   rE   rF   squeezeallr   vmaprR   r   )r'   r_   r1   excluded_funcrW   _rI   r+   checked_funcranksmsgsqueezed_argsrev_filled_shapesr   r/   noncore_shapepad_ndimfilled_shapesqueeze_indicessqueezed_argvectorized_funcnegdim
axis_sizesin_axesresultr   r>   r   r\   pyfuncr   s                            @@@r   rY   zvectorize.<locals>.wrapped  s   &&,fXy&A&A "1&(D&"Q"QM4*A)*L*L'o''s4yy(o@@4@@@I
9~~ ]	9999y999	9	9 YW)WW9WWXXX.}irRRmT1\\\\9_+E+E\\\oS[$''((D!8o}". ".OY &y"2MC CL "(G33! !%(%?%?! ! !e 
SZZ1		T'B'BT'B'B'B T TGPT T T
 &,66
-



(.'993
 MdO44 	) 	)Yi :C	NN!: :;m_%%M(:(::h_}4l|DDbD1222UUy/G/GUUUUUo[?;;;l<(((("ON'->(?@@ = =
FF:FFFFFg	..g...	.	. =c/22Q6?@@@@(?G<<_m,F :m	FE	"	" :KKKKFKKKKKK_V.9999r   )r   rD   rS   r%   	functoolswraps)r   r\   r   rY   s   ``` r   	vectorizer      s    R 	EEHEEEEE :
 ((.x(8(8: : :88x88888 I
GGGG
H
HH?6O: O: O: O: O: O: O:b 
.r   )r   r   r   r   )r*   )
r+   r,   r-   r.   r/   r0   r1   r   r2   r3   )r'   r=   r>   r?   r1   r   r   r@   )
rK   r   r+   r,   rL   r?   r1   r   r   r   )
rK   r[   r\   r]   r'   r^   r_   r`   r   ra   ))
__future__r   collections.abcr   r   r   r   r   typingr   r   jax._srcr   r	   jaxr
   jax._src.numpyr   rQ   jax._src.utilr   rP   r   r7   r   rS   _CORE_DIMENSION_LISTr    _ARGUMENT_LISTr$   r   r   r0   NDArrayr)   r<   rJ   rZ   r}   	frozensetr   r   r   r   <module>r      s   # " " " " " : : : : : : : : : :     				                          + + + + + + : : : : : : : : ,33ODD *&***	!((33"">22
 c?
   2 	#8 #8 #8 #8 #8R $ $ $ $ $H 	    B0 0 0 0. #,)++ a a a a a a ar   