
    0Vhx                    p   U d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	m
Z
 ddlZddlmZ ddlmZmZ ddlmZmZ dd	lmZ g d
Z ede      Zded<    edej4                        Zded<   	 dddd	 	 	 	 	 	 	 	 	 ddZeZ	 	 	 	 	 	 	 	 ddZ	 	 	 	 ddZddZ 	 	 	 	 	 	 	 	 ddZ!	 	 	 	 	 	 	 	 	 	 	 	 ddZ"y)zIntegration with NumPy.    )annotationsN)AnyCallable)	TypeAlias)	ArrayLike)tree_flattentree_unflatten)
PyTreeSpecPyTreeTypeVar)safe_zip)ArrayLikeTree	ArrayTree
tree_ravelr   r   r   F )none_is_leaf	namespacec              |    t        | |||      \  }}t        |      \  }}|t        j                  t        ||      fS )a'  Ravel (flatten) a pytree of arrays down to a 1D array.

    >>> tree = {
    ...     'layer1': {
    ...         'weight': np.arange(0, 6, dtype=np.float32).reshape((2, 3)),
    ...         'bias': np.arange(6, 8, dtype=np.float32).reshape((2,)),
    ...     },
    ...     'layer2': {
    ...         'weight': np.arange(8, 10, dtype=np.float32).reshape((1, 2)),
    ...         'bias': np.arange(10, 11, dtype=np.float32).reshape((1,)),
    ...     },
    ... }
    >>> tree  # doctest: +IGNORE_WHITESPACE
    {
        'layer1': {
            'weight': array([[0., 1., 2.],
                             [3., 4., 5.]], dtype=float32),
            'bias': array([6., 7.], dtype=float32)
        },
        'layer2': {
            'weight': array([[8., 9.]], dtype=float32),
            'bias': array([10.], dtype=float32)
        }
    }
    >>> flat, unravel_func = tree_ravel(tree)
    >>> flat
    array([ 6.,  7.,  0.,  1.,  2.,  3.,  4.,  5., 10.,  8.,  9.], dtype=float32)
    >>> unravel_func(flat)  # doctest: +IGNORE_WHITESPACE
    {
        'layer1': {
            'weight': array([[0., 1., 2.],
                             [3., 4., 5.]], dtype=float32),
            'bias': array([6., 7.], dtype=float32)
        },
        'layer2': {
            'weight': array([[8., 9.]], dtype=float32),
            'bias': array([10.], dtype=float32)
        }
    }

    Args:
        tree (pytree): a pytree of arrays and scalars to ravel.
        is_leaf (callable, optional): An optionally specified function that will be called at each
            flattening step. It should return a boolean, with :data:`True` stopping the traversal
            and the whole subtree being treated as a leaf, and :data:`False` indicating the
            flattening should traverse the current object.
        none_is_leaf (bool, optional): Whether to treat :data:`None` as a leaf. If :data:`False`,
            :data:`None` is a non-leaf node with arity 0. Thus :data:`None` is contained in the
            treespec rather than in the leaves list and :data:`None` will be remain in the result
            pytree. (default: :data:`False`)
        namespace (str, optional): The registry namespace used for custom pytree node types.
            (default: :const:`''`, i.e., the global namespace)

    Returns:
        A pair ``(array, unravel_func)`` where the first element is a 1D array representing the
        flattened and concatenated leaf values, with ``dtype`` determined by promoting the
        ``dtype``\s of leaf values, and the second element is a callable for unflattening a 1D array
        of the same length back to a pytree of the same structure as the input ``tree``. If the
        input pytree is empty (i.e. has no leaves) then as a convention a 1D empty array of the
        default dtype is returned in the first component of the output.
    )is_leafr   r   )r   _ravel_leaves	functoolspartial_tree_unravel)treer   r   r   leavestreespecflatunravel_flats           I/home/dcms/DCMS/lib/python3.12/site-packages/optree/integrations/numpy.pyr   r   *   sK    J $!	FH 'v.D,""=(LIII    c               &    t        |  ||            S N)r	   )r   r   r   s      r   r   r   |   s     (L$677r   c                  | st        j                  d      t        fS t        d | D              }t        j                  |  t        d | D              }t        d | D              }t        t        j                  |            }t        fd|D              rSt        j                  | D cg c]  }t        j                  |       c}      }|t        j                  t        ||      fS t        j                  | D cg c]&  }t        j                  |      j                        ( c}      }|t        j                  t        |||      fS c c}w c c}w )Nr   c              3  F   K   | ]  }t        j                  |        y wr!   )npresult_type.0leafs     r   	<genexpr>z _ravel_leaves.<locals>.<genexpr>   s     @t,@   !c              3  F   K   | ]  }t        j                  |        y wr!   )r$   sizer&   s     r   r)   z _ravel_leaves.<locals>.<genexpr>   s     3D"''$-3r*   c              3  F   K   | ]  }t        j                  |        y wr!   )r$   shaper&   s     r   r)   z _ravel_leaves.<locals>.<genexpr>   s     5d288D>5r*   c              3  (   K   | ]	  }|k(    y wr!    )r'   dtto_dtypes     r   r)   z _ravel_leaves.<locals>.<genexpr>   s     
0b2>
0s   )r$   zeros_unravel_emptytupler%   	itertools
accumulateallconcatenateravelr   r   _unravel_leaves_single_dtypeastype_unravel_leaves)r   from_dtypessizesshapesindicesr(   raveledr2   s          @r   r   r      s    ^,,@@@K~~v&H3F33E5f55FI((/0G

0K
00..V!DT"((4.!DE:GVL
 	
 nn&Q$bhhtn33H=QRG/7FKR  "E Rs   ,E?+Ec                   t        j                  |       dk7  r%t        dd dt        j                  |        d      g S )N)r   0The unravel function expected an array of shape , got shape .)r$   r.   
ValueError)r   s    r   r4   r4      sG    	xx~>tfLQSQYQYZ^Q_P``ab
 	
 Ir   c               &   t        j                  |      | d   fk7  r)t        d| d   f dt        j                  |       d      t        j                  || d d       }t	        ||      D cg c]  \  }}|j                  |       c}}S c c}}w )NrD   rE   rF   )r$   r.   rG   splitr   reshape)rA   r@   r   chunkschunkr.   s         r   r;   r;      s     
xx~'"+'>~>N O$(+
 	

 XXdGCRL)F5=ff5MN\UEEMM% NNNs   .Bc          	     $   t        j                  |      | d   fk7  r)t        d| d   f dt        j                  |       d      t        j                  |      }||k7  rt        d| d| d      t        j                  || d d       }t        j                         5  t        j                  d       t        |||      D 	cg c]&  \  }}}	|j                  |      j                  |	      ( c}	}}cd d d        S c c}	}}w # 1 sw Y   y xY w)NrI   rD   rE   rF   z0The unravel function expected an array of dtype z, got dtype ignore)r$   r.   rG   r%   rJ   warningscatch_warningssimplefilterr   rK   r<   )
rA   r@   r>   r2   r   array_dtyperL   rM   r.   dtypes
             r   r=   r=      s    
xx~'"+'>~>N O$(+
 	
 ..&Kh>xjU`Taabc
 	
 XXdGCRL)F		 	 	" 
h' (0'L
 
#ue MM% ''.

 


 
s   'D+C?
1D?DDr!   )
r   zCallable[[Any], bool] | Noner   r   r   boolr   strreturnz4tuple[np.ndarray, Callable[[np.ndarray], ArrayTree]])r   r
   r   z(Callable[[np.ndarray], list[np.ndarray]]r   
np.ndarrayrW   r   )r   list[np.ndarray]rW   z;tuple[np.ndarray, Callable[[np.ndarray], list[np.ndarray]]])r   rX   rW   rY   )rA   tuple[int, ...]r@   tuple[tuple[int, ...], ...]r   rX   rW   rY   )rA   rZ   r@   r[   r>   ztuple[np.dtype, ...]r2   znp.dtyper   rX   rW   rY   )#__doc__
__future__r   r   r6   rP   typingr   r   typing_extensionsr   numpyr$   numpy.typingr   
optree.opsr   r	   optree.typingr
   r   optree.utilsr   __all__r   __annotations__ndarrayr   r   ravel_pytreer   r   r4   r;   r=   r0   r   r   <module>ri      sj    #      '  " 3 3 ! 7 ))Dy D$["**=	9 = -1LJ
 LJ *LJ
LJ
 LJ LJ :LJ^ 88:8 8
 8BOO'O O
 O 

'
 &
 	

 
 
r   