
    GJjT"                         d dl Z d dlmZmZ d dlmZ d dlmZ d dl	m
Z
  G d de
      Z G d de
      Z G d	 d
e
      Zy)    N)CallableOptional)tanh)Modulec            
       N     e Zd ZdZ	 	 d	dedededee   f fdZd Z	d
dZ
 xZS )RNNa  An Elman recurrent layer.

    The input is a sequence of shape ``NLD`` or ``LD`` where:

    * ``N`` is the optional batch dimension
    * ``L`` is the sequence length
    * ``D`` is the input's feature dimension

    Concretely, for each element along the sequence length axis, this
    layer applies the function:

    .. math::

        h_{t + 1} = \text{tanh} (W_{ih}x_t + W_{hh}h_t + b)

    The hidden state :math:`h` has shape ``NH`` or ``H``, depending on
    whether the input is batched or not. Returns the hidden state at each
    time step, of shape ``NLH`` or ``LH``.

    Args:
        input_size (int): Dimension of the input, ``D``.
        hidden_size (int): Dimension of the hidden state, ``H``.
        bias (bool, optional): Whether to use a bias. Default: ``True``.
        nonlinearity (callable, optional): Non-linearity to use. If ``None``,
            then func:`tanh` is used. Default: ``None``.
    
input_sizehidden_sizebiasnonlinearityc                    t         |           |xs t        | _        t	        | j                        st        d| d      dt        j                  |      z  }|| _        t        j                  j                  | |||f      | _        t        j                  j                  | |||f      | _        |r*t        j                  j                  | ||f      | _        y d | _        y )Nz.Nonlinearity must be callable. Current value: .      ?lowhighshape)super__init__r   r   callable
ValueErrormathsqrtr
   mxrandomuniformWxhWhhr   )selfr	   r
   r   r   scale	__class__s         a/Users/ahmed/devFolder/claude-voice/.venv/lib/python3.12/site-packages/mlx/nn/layers/recurrent.pyr   zRNN.__init__'   s     	(0D))*@aP  dii,,&99$$U;
*C % 
 99$$U;*D % 

  II5&u[NK 		  		    c           	          d| j                   j                  d    d| j                   d| j                   d| j                  d u S )Ninput_dims=   , hidden_size=z, nonlinearity=, bias=)r   r   r
   r   r   r   s    r"   _extra_reprzRNN._extra_reprD   sT    $((..+, -++, - --.gdiit6K5LN	
r#   c                    | j                   6t        j                  | j                   || j                  j                        }n|| j                  j                  z  }g }t        |j                  d         D ]d  }|4t        j                  |d|d d f   || j                  j                        }n
|d|d d f   }| j                  |      }|j                  |       f t        j                  |d      S )N.axis)r   r   addmmr   Tranger   r   r   appendstack)r   xhidden
all_hiddenidxs        r"   __call__zRNN.__call__K   s    99 Atxxzz2ADHHJJA
%C!!CaK.&$((**E3Q;&&v.Ff% & xx
,,r#   )TNN)__name__
__module____qualname____doc__intboolr   r   r   r*   r8   __classcell__r!   s   @r"   r   r      sJ    > +/

 
 	

 x(
:
-r#   r   c                   B     e Zd ZdZ	 ddededef fdZd Zd	dZ xZ	S )
GRUa  A gated recurrent unit (GRU) RNN layer.

    The input has shape ``NLD`` or ``LD`` where:

    * ``N`` is the optional batch dimension
    * ``L`` is the sequence length
    * ``D`` is the input's feature dimension

    Concretely, for each element of the sequence, this layer computes:

    .. math::

        \begin{aligned}
        r_t &= \sigma (W_{xr}x_t + W_{hr}h_t + b_{r}) \\
        z_t &= \sigma (W_{xz}x_t + W_{hz}h_t + b_{z}) \\
        n_t &= \text{tanh}(W_{xn}x_t + b_{n} + r_t \odot (W_{hn}h_t + b_{hn})) \\
        h_{t + 1} &= (1 - z_t) \odot n_t + z_t \odot h_t
        \end{aligned}

    The hidden state :math:`h` has shape ``NH`` or ``H`` depending on
    whether the input is batched or not. Returns the hidden state at each
    time step of shape ``NLH`` or ``LH``.

    Args:
        input_size (int): Dimension of the input, ``D``.
        hidden_size (int): Dimension of the hidden state, ``H``.
        bias (bool): Whether to use biases or not. Default: ``True``.
    r	   r
   r   c                    t         |           || _        dt        j                  |      z  }t
        j                  j                  | |d|z  |f      | _        t
        j                  j                  | |d|z  |f      | _	        |r't
        j                  j                  | |d|z  f      nd | _
        |r*t
        j                  j                  | ||f      | _        y d | _        y )Nr      r   )r   r   r
   r   r   r   r   r   WxWhbbhnr   r	   r
   r   r    r!   s        r"   r   zGRU.__init__{   s     	&dii,,))##U1{?J*G $ 
 ))##U1{?K*H $ 

  II5&uQ_<NO 	  II5&u[NK 	  	r#   c                 r    d| j                   j                  d    d| j                   d| j                  d u S Nr%   r&   r'   r(   )rF   r   r
   rH   r)   s    r"   r*   zGRU._extra_repr   sC    $''--*+ ,++,GDFF$4F3GI	
r#   c                    | j                   6t        j                  | j                   || j                  j                        }n|| j                  j                  z  }|dd | j
                   f   }|d| j
                   d f   }g }t        |j                  d         D ]  }|d|d d f   }|a|| j                  j                  z  }|dd | j
                   f   }	|d| j
                   d f   }
| j                  |
| j                  z  }
||	z   }t        j                  |      }t        j                  |dd      \  }}|d|d d f   }|	||
z  z   }n| j                  ||| j                  z  z   }t        j                  |      }|d|z
  |z  ||z  z   }nd|z
  |z  }|j                  |        t        j                  |d      S )N.r,      r-   r&   )rH   r   r/   rF   r0   r
   r1   r   rG   rI   sigmoidsplitr   r2   r3   )r   r4   r5   x_rzx_nr6   r7   rzh_proj	h_proj_rzh_proj_nrzns                 r"   r8   zGRU.__call__   s   66DGGII.ADGGIIA))))))*d&&&(()
%Cc3k"B!$''))+"3(;4+;+;*;(;#;<	!#(8(8'8':":;88'(H)^BB88B+DAqCaK A!H$%DHH$
A!a%1q6z1a%1f%; &> xx
,,r#   Tr9   
r:   r;   r<   r=   r>   r?   r   r*   r8   r@   rA   s   @r"   rC   rC   ]   s9    B 	

 
 	
6
*-r#   rC   c                   B     e Zd ZdZ	 ddededef fdZd Zd	dZ xZ	S )
LSTMau  An LSTM recurrent layer.

    The input has shape ``NLD`` or ``LD`` where:

    * ``N`` is the optional batch dimension
    * ``L`` is the sequence length
    * ``D`` is the input's feature dimension

    Concretely, for each element of the sequence, this layer computes:

    .. math::
        \begin{aligned}
        i_t &= \sigma (W_{xi}x_t + W_{hi}h_t + b_{i}) \\
        f_t &= \sigma (W_{xf}x_t + W_{hf}h_t + b_{f}) \\
        g_t &= \text{tanh} (W_{xg}x_t + W_{hg}h_t + b_{g}) \\
        o_t &= \sigma (W_{xo}x_t + W_{ho}h_t + b_{o}) \\
        c_{t + 1} &= f_t \odot c_t + i_t \odot g_t \\
        h_{t + 1} &= o_t \text{tanh}(c_{t + 1})
        \end{aligned}

    The hidden state :math:`h` and cell state :math:`c` have shape ``NH``
    or ``H``, depending on whether the input is batched or not.

    The layer returns two arrays, the hidden state and the cell state at
    each time step, both of shape ``NLH`` or ``LH``.

    Args:
        input_size (int): Dimension of the input, ``D``.
        hidden_size (int): Dimension of the hidden state, ``H``.
        bias (bool): Whether to use biases or not. Default: ``True``.
    r	   r
   r   c                    t         |           || _        dt        j                  |      z  }t
        j                  j                  | |d|z  |f      | _        t
        j                  j                  | |d|z  |f      | _	        |r-t
        j                  j                  | |d|z  f      | _
        y d | _
        y )Nr      r   )r   r   r
   r   r   r   r   r   rF   rG   r   rJ   s        r"   r   zLSTM.__init__   s     	&dii,,))##U1{?J*G $ 
 ))##U1{?K*H $ 

  II5&uQ_<NO 		  		r#   c                 r    d| j                   j                  d    d| j                   d| j                  d u S rL   )rF   r   r
   r   r)   s    r"   r*   zLSTM._extra_repr   sC    $''--*+ ,++,GDIIT4I3JL	
r#   c                 @   | j                   6t        j                  | j                   || j                  j                        }n|| j                  j                  z  }g }g }t        |j                  d         D ]  }|d|d d f   }|+t        j                  ||| j                  j                        }t        j                  |dd      \  }}	}
}t        j                  |      }t        j                  |	      }	t        j                  |
      }
t        j                  |      }||	|z  ||
z  z   }n||
z  }|t        j                  |      z  }|j                  |       |j                  |        t        j                  |d      t        j                  |d      fS )Nr,   .r`   rO   r-   )r   r   r/   rF   r0   r1   r   rG   rQ   rP   r   r2   r3   )r   r4   r5   cellr6   all_cellr7   ifgoifgos               r"   r8   zLSTM.__call__  sI   99 Atwwyy1ADGGIIA
%CS#q[>D!xxfdggii8$3JAq!Q

1A

1A
A

1A4x!a%'1u&FOOD!f%% &( xx
,bhhxb.IIIr#   r[   )NNr\   rA   s   @r"   r^   r^      s:    H 	

 
 	
,
Jr#   r^   )r   typingr   r   mlx.corecorer   mlx.nn.layers.activationsr   mlx.nn.layers.baser   r   rC   r^    r#   r"   <module>rp      sD     %  * %O-& O-di-& i-XZJ6 ZJr#   