
    GJj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y)    N)CallableLiteralvaluedtypereturnc                 X     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                 H    t        j                  | j                        S Nr   )mxfullshape)r	   r   r   s    U/Users/ahmed/devFolder/claude-voice/.venv/lib/python3.12/site-packages/mlx/nn/init.pyinitializerzconstant.<locals>.initializer   s    wwqwwU33    r   array)r   r   r   s   `` r   constantr   	   s&    ,4rxx 4BHH 4 r   g              ?meanstdc                 \     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         j                  j                  | j                        S )Nr   scalelocr   )r   randomnormalr   )r	   r   r   r   s    r   r   znormal.<locals>.initializer>   s%    yyaggSd%PPr   r   )r   r   r   r   s   ``` r   r   r   %   s)    2Qrxx QBHH Q r   lowhighc                 \     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         j                  j                  | j                        S r   )r   r   uniformr   )r	   r   r!   r    s    r   r   zuniform.<locals>.initializer]   s%    yy  dAGG5 AAr   r   )r    r!   r   r   s   ``` r   r$   r$   D   s)    2Brxx BBHH B r   c                 T     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k7  s| j                  d   | j                  d   k7  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   s^    88q=CIIaLCIIaL8HSTU  vv		!E22r   r   r   r   s   ` r   identityr0   c   s&    &3 3bhh 3 r   c                     | j                   dk  rt        d| j                    d      | j                  d   }| j                  d   }| j                   dkD  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    vvz vvhl4
 	

 WWR[FggajGvvz2Aq O  /)O+7?r   c                 b     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	   gainr   c                     t        |       \  }}|t        j                  d||z   z        z  }t        j                  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   sN    3A6TYYsfw&6788yyaggSFFr   r   r   r   floatr/   s   ` r   glorot_normalrB      s2    FGrxx Gu Grxx G
 r   c                 b     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   c                     t        |       \  }}|t        j                  d||z   z        z  }t        j                  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   sR    3A6tyy(8!9::yy  %u EEr   r?   r@   r/   s   ` r   glorot_uniformrF      s2    FFrxx Fu Frxx F
 r   r4   r5   c           	      x     	 	 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)
    r	   moderG   r:   r   c                     t        |       \  }}|dk(  r|}n|dk(  r|}nt        d| d      |t        j                  |      z  }t        j
                  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  st    
 4A68CYC~dV3UVWWTYYs^#yyaggSFFr   r4   r   r   r   r   rA   r/   s   ` r   	he_normalrP      sP    R .6G88G)*G G 
	G  r   c           	      x     	 	 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)
    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                  | || 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8CYC~dV3UVWWtyys++yy  %u EEr   rN   rO   r/   s   ` r   
he_uniformrS   %  sP    V .6F88F)*F F 
	F  r   sparsityc                 `     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k7  rt        d      | j                  \  }}t        t	        j
                  |z              }t        j                  t        j                  j                  | j                        d      }t        j                  j                  | j                        } d| t        j                  |      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    66Q;KLLWW
d		(T/23	

299,,177,;!DII177#4uMDE"))D/
!
!$
*E!ZiZ-,@
@Ar   r   )rT   r   r   r   r   s   ```` r   sparserb   a  s+    <rxx BHH   r   r:   c                 X     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k7  rt        d      | j                  \  }}t        ||      }t        j
                  j                  ||f      }t        j                  j                  |t        j                        \  }}t	        j                  |      }|t	        j                  |      z  }|d |d |f   }|	z  }|j                        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    66Q;& 
 WW
ddOyyq!f- yy||D|01 GGAJ
N eteUdUlO Hxxr   r   )r:   r   r   s   `` r   
orthogonalrp     s&    rxx BHH 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      s    $  %'JJrxxj"(("#: C2::
!02rxxj"(("#@ C2::	!02rxxj"(("#>  "zz BHH hz2887K.L :, jj(88(rxx)*(X jj(88(rxx)*(X jj7887rxx!45u=rxxGH7v jj9889rxx!45u=rxxGH9| jj	,,
, 
, 88	,
 rxxj"(("#,` )
) hh)rxxj"(("#)r   