
    j6                        d dl Z d dlmZmZ d dlmZ ej        fdedej	        deej
        gej
        f         fdZddej        fd	ed
edej	        deej
        gej
        f         fdZddej        fdededej	        deej
        gej
        f         fdZej        fdej	        deej
        gej
        f         fdZd Zej        fdej	        deej
        egej
        f         fdZej        fdej	        deej
        egej
        f         fdZej        fdej	        deej
        ed         egej
        f         fdZej        fdej	        deej
        ed         egej
        f         fdZddej        fded	ed
edej	        deej
        gej
        f         f
dZdej        fdedej	        deej
        gej
        f         fdZdS )    N)CallableLiteralvaluedtypereturnc                 H     dt           j        dt           j        f fd}|S )a  An initializer that returns an array filled with ``value``.

    Args:
        value (float): The value to fill the array with.
        dtype (Dtype, optional): The data type of the array. Default:
          ``float32``.

    Returns:
        Callable[[array], array]: An initializer that returns an array with the
        same shape as the input, filled with ``value``.

    Example:

        >>> init_fn = nn.init.constant(0.5)
        >>> init_fn(mx.zeros((2, 2)))
        array([[0.5, 0.5],
               [0.5, 0.5]], dtype=float32)
    ar   c                 <    t          j        | j                  S Nr   )mxfullshape)r	   r   r   s    U/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/mlx/nn/init.pyinitializerzconstant.<locals>.initializer   s    wqwU3333    r   array)r   r   r   s   `` r   constantr   	   sA    ,4rx 4BH 4 4 4 4 4 4 4 r   g              ?meanstdc                 L     dt           j        dt           j        f fd}|S )a  An initializer that returns samples from a normal distribution.

    Args:
        mean (float, optional): Mean of the normal distribution. Default:
          ``0.0``.
        std (float, optional): Standard deviation of the normal distribution.
          Default: ``1.0``.
        dtype (Dtype, optional): The data type of the array. Default:
          ``float32``.

    Returns:
        Callable[[array], array]: An initializer that returns an array with the
        same shape as the input, filled with samples from a normal distribution.

    Example:

        >>> init_fn = nn.init.normal()
        >>> init_fn(mx.zeros((2, 2)))
        array([[-0.982273, -0.534422],
               [0.380709, 0.0645099]], dtype=float32)
    r	   r   c                 T    t           j                            | j                  S )Nr   scalelocr   )r   randomnormalr   )r	   r   r   r   s    r   r   znormal.<locals>.initializer>   s$    yagSd%PPPr   r   )r   r   r   r   s   ``` r   r   r   %   sQ    2Qrx QBH Q Q Q Q Q Q Q Q r   lowhighc                 L     dt           j        dt           j        f fd}|S )a  An initializer that returns samples from a uniform distribution.

    Args:
        low (float, optional): The lower bound of the uniform distribution.
          Default: ``0.0``.
        high (float, optional): The upper bound of the uniform distribution.
          Default: ``1.0``
        dtype (Dtype, optional): The data type of the array. Default: ``float32``.

    Returns:
        Callable[[array], array]: An initializer that returns an array
        with the same shape as the input, filled with samples from a uniform
        distribution

    Example:

        >>> init_fn = nn.init.uniform(low=0, high=1)
        >>> init_fn(mx.zeros((2, 2)))
        array([[0.883935, 0.863726],
               [0.617261, 0.417497]], dtype=float32)
    r	   r   c                 T    t           j                            | j                  S r   )r   r   uniformr   )r	   r   r!   r    s    r   r   zuniform.<locals>.initializer]   s$    y  dAG5 AAAr   r   )r    r!   r   r   s   ``` r   r$   r$   D   sQ    2Brx BBH B B B B B B B B r   c                 D     dt           j        dt           j        f fd}|S )a  An initializer that returns an identity matrix.

    Args:
        dtype (Dtype, optional): The data type of the array. Default:
          ``float32``.

    Returns:
        Callable[[array], array]: An initializer that returns an identity
        matrix with the same shape as the input.

    Example:

        >>> init_fn = nn.init.identity()
        >>> init_fn(mx.zeros((2, 2)))
        array([[1, 0],
               [0, 1]], dtype=float32)
    arrr   c                     | j         dk    s| j        d         | j        d         k    rt          d| j         d          t          j        | j        d                   S )N   r      z6The input array must be a square matrix but got shape .)nr   )ndimr   
ValueErrorr   eye)r&   r   s    r   r   zidentity.<locals>.initializerv   sc    8q==CIaLCIaL88UUUU   v	!E2222r   r   r   r   s   ` r   identityr0   c   s;    &3 3bh 3 3 3 3 3 3 r   c                     | j         dk     rt          d| j          d          | j        d         }| j        d         }| j         dk    r#d}| j        dd         D ]}||z  }||z  }||z  }||fS )Nr(   zPGlorot / He initialization requires at least 2 dimensional input but input with z dimensions.r   r)   )r,   r-   r   )xfan_infan_outreceptive_fieldds        r   _calculate_fan_in_fan_outr8      s    vzz4 v4 4 4
 
 	

 WR[FgajGvzz2 	! 	!Aq OO/)O+7?r   c                 T     ddt           j        dt          dt           j        f fd}|S )aW  A Glorot normal initializer.

    This initializer samples from a normal distribution with a standard
    deviation computed from the number of input (``fan_in``) and output
    (``fan_out``) units according to:

    .. math::
        \sigma = \gamma \sqrt{\frac{2.0}{\text{fan\_in} + \text{fan\_out}}}

    For more details see the original reference: `Understanding the difficulty
    of training deep feedforward neural networks
    <https://proceedings.mlr.press/v9/glorot10a.html>`_

    Args:
        dtype (Dtype, optional): The data type of the array. Default: ``float32``.

    Returns:
        Callable[[array, float], array]: An initializer that returns an array
        with the same shape as the input, filled with samples from the Glorot
        normal distribution.

    Example:

        >>> init_fn = nn.init.glorot_normal()
        >>> init_fn(mx.zeros((2, 2)))
        array([[0.191107, 1.61278],
               [-0.150594, -0.363207]], dtype=float32)
        >>> init_fn(mx.zeros((2, 2)), gain=4.0)
        array([[1.89613, -4.53947],
               [4.48095, 0.995016]], dtype=float32)
    r   r	   gainr   c                     t          |           \  }}|t          j        d||z   z            z  }t          j                            | j        |          S )Ng       @r   r   r   )r8   mathsqrtr   r   r   r   )r	   r:   r4   r5   r   r   s        r   r   z"glorot_normal.<locals>.initializer   sQ    3A66TYsfw&67888yagSFFFr   r   r   r   floatr/   s   ` r   glorot_normalrB      sR    FG Grx Gu Grx G G G G G G
 r   c                 T     ddt           j        dt          dt           j        f fd}|S )aQ  A Glorot uniform initializer.

    This initializer samples from a uniform distribution with a range
    computed from the number of input (``fan_in``) and output (``fan_out``)
    units according to:

    .. math::
        \sigma = \gamma \sqrt{\frac{6.0}{\text{fan\_in} + \text{fan\_out}}}

    For more details see the original reference: `Understanding the difficulty
    of training deep feedforward neural networks
    <https://proceedings.mlr.press/v9/glorot10a.html>`_

    Args:
        dtype (Dtype, optional): The data type of the array. Default: ``float32``.

    Returns:
        Callable[[array, float], array]: An initializer that returns an array
        with the same shape as the input, filled with samples from the Glorot
        uniform distribution.

    Example:

        >>> init_fn = nn.init.glorot_uniform()
        >>> init_fn(mx.zeros((2, 2)))
        array([[0.223404, -0.890597],
               [-0.379159, -0.776856]], dtype=float32)
        >>> init_fn(mx.zeros((2, 2)), gain=4.0)
        array([[-1.90041, 3.02264],
               [-0.912766, 4.12451]], dtype=float32)
    r   r	   r:   r   c                     t          |           \  }}|t          j        d||z   z            z  }t          j                            | || j                  S )Ng      @r   )r8   r=   r>   r   r   r$   r   )r	   r:   r4   r5   limitr   s        r   r   z#glorot_uniform.<locals>.initializer   sU    3A66ty(8!9:::y  %u EEEr   r?   r@   r/   s   ` r   glorot_uniformrF      sR    FF Frx Fu Frx F F F F F F
 r   r4   r5   c           	      r     	 	 d	dt           j        dt          d         dt          dt           j        f fd}|S )
a  Build a He normal initializer.

    This initializer samples from a normal distribution with a standard
    deviation computed from the number of input (``fan_in``) or output
    (``fan_out``) units according to:

    .. math::
        \sigma = \gamma \frac{1}{\sqrt{\text{fan}}}

    where :math:`\text{fan}` is either the number of input units when the
    ``mode`` is ``"fan_in"`` or output units when the ``mode`` is
    ``"fan_out"``.

    For more details see the original reference: `Delving Deep into Rectifiers:
    Surpassing Human-Level Performance on ImageNet Classification
    <https://arxiv.org/abs/1502.01852>`_

    Args:
        dtype (Dtype, optional): The data type of the array. Default: ``float32``.

    Returns:
        Callable[[array, str, float], array]: An initializer that returns an
        array with the same shape as the input, filled with samples from the He
        normal distribution.

    Example:

        >>> init_fn = nn.init.he_normal()
        >>> init_fn(mx.zeros((2, 2)))  # uses fan_in
        array([[-1.25211, 0.458835],
               [-0.177208, -0.0137595]], dtype=float32)
        >>> init_fn(mx.zeros((2, 2)), mode="fan_out", gain=5)
        array([[5.6967, 4.02765],
               [-4.15268, -2.75787]], dtype=float32)
    r4   r   r	   moderG   r:   r   c                     t          |           \  }}|dk    r|}n|dk    r|}nt          d| d          |t          j        |          z  }t          j                            | j        |          S )Nr4   r5   Invalid mode: ". Valid modes are: fan_in, fan_outr<   )r8   r-   r=   r>   r   r   r   r   )r	   rI   r:   r4   r5   fanr   r   s          r   r   zhe_normal.<locals>.initializer  s    
 4A668CCYCCVdVVVWWWTYs^^#yagSFFFr   r4   r   r   r   r   rA   r/   s   ` r   	he_normalrP      sp    R .6G G8G)*G G 
	G G G G G G  r   c           	      r     	 	 d	dt           j        dt          d         dt          dt           j        f fd}|S )
a  A He uniform (Kaiming uniform) initializer.

    This initializer samples from a uniform distribution with a range
    computed from the number of input (``fan_in``) or output (``fan_out``)
    units according to:

    .. math::

        \sigma = \gamma \sqrt{\frac{3.0}{\text{fan}}}

    where :math:`\text{fan}` is either the number of input units when the
    ``mode`` is ``"fan_in"`` or output units when the ``mode`` is
    ``"fan_out"``.

    For more details see the original reference: `Delving Deep into Rectifiers:
    Surpassing Human-Level Performance on ImageNet Classification
    <https://arxiv.org/abs/1502.01852>`_


    Args:
        dtype (Dtype, optional): The data type of the array. Default: ``float32``.

    Returns:
        Callable[[array, str, float], array]: An initializer that returns an
        array with the same shape as the input, filled with samples from  the
        He uniform distribution.

    Example:

        >>> init_fn = nn.init.he_uniform()
        >>> init_fn(mx.zeros((2, 2)))  # uses fan_in
        array([[0.0300242, -0.0184009],
               [0.793615, 0.666329]], dtype=float32)
        >>> init_fn(mx.zeros((2, 2)), mode="fan_out", gain=5)
        array([[-1.64331, -2.16506],
               [1.08619, 5.79854]], dtype=float32)
    r4   r   r	   rI   rG   r:   r   c                     t          |           \  }}|dk    r|}n|dk    r|}nt          d| d          |t          j        d|z            z  }t          j                            | || j                  S )Nr4   r5   rK   rL   g      @r   )r8   r-   r=   r>   r   r   r$   r   )r	   rI   r:   r4   r5   rM   rE   r   s          r   r   zhe_uniform.<locals>.initializerN  s    
 4A668CCYCCVdVVVWWWtys+++y  %u EEEr   rN   rO   r/   s   ` r   
he_uniformrS   %  sp    V .6F F8F)*F F 
	F F F F F F  r   sparsityc                 P     dt           j        dt           j        f fd}|S )a  An initializer that returns a sparse matrix.

    Args:
        sparsity (float): The fraction of elements in each column to be set to
        zero.
        mean (float, optional): Mean of the normal distribution. Default:
          ``0.0``.
        std (float, optional): Standard deviation of the normal distribution.
          Default: ``1.0``.
        dtype (Dtype, optional): The data type of the array. Default:
          ``float32``.

    Returns:
        Callable[[array], array]: An initializer that returns an array with the
        same shape as the input, filled with samples from a normal distribution.

    Example:

        >>> init_fn = nn.init.sparse(sparsity=0.5)
        >>> init_fn(mx.zeros((2, 2)))
        array([[-1.91187, -0.117483],
       [0, 0]], dtype=float32)
    r	   r   c                    | j         dk    rt          d          | j        \  }}t          t	          j        |z                      }t          j        t          j        	                    | j                  d          }t          j        
                    | j                  } d| t          j        |                              |d          |d d d |f         f<   | S )Nr(   z,Only tensors with 2 dimensions are supportedr   r)   )axisr   r   )r,   r-   r   intr=   ceilr   argsortr   r$   r   arangereshape)	r	   rowscols	num_zerosorderr   r   rT   r   s	        r   r   zsparse.<locals>.initializer  s    6Q;;KLLLW
d	(T/2233	
29,,17,;;!DDDI17#4uMMDE")D//
!
!$
*
*E!!!ZiZ-,@
@Ar   r   )rT   r   r   r   r   s   ```` r   sparserb   a  sM    <rx BH          r   r:   c                 H     dt           j        dt           j        f fd}|S )a  An initializer that returns an orthogonal matrix.

    Args:
        gain (float, optional): Scaling factor for the orthogonal matrix.
            Default: ``1.0``.
        dtype (Dtype, optional): Data type of the array. Default: ``float32``.

    Returns:
        Callable[[array], array]: An initializer that returns
        an orthogonal matrix with the same shape as the input.
    r	   r   c                    | j         dk    rt          d          | j        \  }}t          ||          }t          j                            ||f          }t          j                            |t          j	                  \  }}t	          j
        |          }|t	          j        |          z  }|d |d |f         }|	z  }|                              S )Nr(   zHOrthogonal initialization requires a 2D array but got a {a.ndim}D array.rW   )stream)r,   r-   r   maxr   r   r   linalgqrcpudiagsignastype)
r	   r^   r_   r+   rmatqrr7   r   r:   s
           r   r   zorthogonal.<locals>.initializer  s    6Q;;&  
 W
ddOOyq!f-- y||D|001 GAJJ

N eteUdUlO Hxxr   r   )r:   r   r   s   `` r   
orthogonalrp     sA    rx BH       4 r   )r=   typingr   r   mlx.corecorer   float32rA   Dtyper   r   r   r$   r0   r8   rB   rF   rP   rS   rb   rp    r   r   <module>rw      se    $ $ $ $ $ $ $ $       %'J rxj"("#   : C2: 
!02rxj"("#   @ C2: 	!02rxj"("#   >  "z  BH hz287K.L    :  , j( (8(rx)*( ( ( (X j( (8(rx)*( ( ( (X j7 787rx!45u=rxGH7 7 7 7v j9 989rx!45u=rxGH9 9 9 9| j	, ,,
, 
, 8	,
 rxj"("#, , , ,` ) )
) h)rxj"("#) ) ) ) ) )r   