
    j              	           d dl Z d dlmZmZ d dlmZ dededefdZdedede	defdZ
dded
e	dedefdZdee         dee	         defdZdedede	defdZdS )    N)CallableListinit
decay_ratereturnc                       fd}|S )a   Make an exponential decay scheduler.

    Args:
        init (float): Initial value.
        decay_rate (float): Multiplicative factor to decay by.

    Example:
        >>> lr_schedule = optim.exponential_decay(1e-1, 0.9)
        >>> optimizer = optim.SGD(learning_rate=lr_schedule)
        >>> optimizer.learning_rate
        array(0.1, dtype=float32)
        >>>
        >>> for _ in range(5): optimizer.update({}, {})
        ...
        >>> optimizer.learning_rate
        array(0.06561, dtype=float32)
    c                     | z  z  S N )stepr   r   s    c/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/mlx/optimizers/schedulers.pyschedulez#exponential_decay.<locals>.schedule   s    j$&&&    r   )r   r   r   s   `` r   exponential_decayr   	   s)    &' ' ' ' ' ' Or   	step_sizec                       fd}|S )a/  Make a step decay scheduler.

    Args:
        init (float): Initial value.
        decay_rate (float): Multiplicative factor to decay by.
        step_size (int): Decay every ``step_size`` steps.

    Example:

        >>> lr_schedule = optim.step_decay(1e-1, 0.9, 10)
        >>> optimizer = optim.SGD(learning_rate=lr_schedule)
        >>> optimizer.learning_rate
        array(0.1, dtype=float32)
        >>>
        >>> for _ in range(21): optimizer.update({}, {})
        ...
        >>> optimizer.learning_rate
        array(0.081, dtype=float32)
    c                     | z  z  z  S r
   r   )r   r   r   r   s    r   r   zstep_decay.<locals>.schedule7   s    zdi&7899r   r   )r   r   r   r   s   ``` r   
step_decayr   "   s/    *: : : : : : : Or           decay_stepsendc                       fd}|S )a  Make a cosine decay scheduler.

    Args:
        init (float): Initial value.
        decay_steps (int): Number of steps to decay over. The decayed
            value is constant for steps beyond ``decay_steps``.
        end (float, optional): Final value to decay to. Default: ``0``.

    Example:

        >>> lr_schedule = optim.cosine_decay(1e-1, 1000)
        >>> optimizer = optim.SGD(learning_rate=lr_schedule)
        >>> optimizer.learning_rate
        array(0.1, dtype=float32)
        >>>
        >>> for _ in range(5): optimizer.update({}, {})
        ...
        >>> optimizer.learning_rate
        array(0.0999961, dtype=float32)
    c                     t          j        |           }ddt          j        t          j        z  |z            z   z  }|z
  z  z   S )Ng      ?g      ?)mxminimumcosmathpi)r   sdecayr   r   r   s      r   r   zcosine_decay.<locals>.scheduleS   sM    Jt[))sRVTW{%:a$?@@@AUdSj)))r   r   )r   r   r   r   s   ``` r   cosine_decayr!   =   s/    ,* * * * * * *
 Or   	schedules
boundariesc                     t                     dk    rt          d          t                     t                    dz   k    r3t          dt                     dt                     dz
   d           fd}|S )ag  Join multiple schedules to create a new schedule.

    Args:
        schedules (list(Callable)): A list of schedules. Schedule :math:`i+1`
          receives a step count indicating the number of steps since
          the :math:`i`-th boundary.
        boundaries (list(int)): A list of integers of length ``len(schedules) - 1``
          that indicates when to transition between schedules.

    Example:
        >>> linear = optim.linear_schedule(0, 1e-1, steps=10)
        >>> cosine = optim.cosine_decay(1e-1, 200)
        >>> lr_schedule = optim.join_schedules([linear, cosine], [10])
        >>> optimizer = optim.Adam(learning_rate=lr_schedule)
        >>> optimizer.learning_rate
        array(0.0, dtype=float32)
        >>> for _ in range(12): optimizer.update({}, {})
        ...
        >>> optimizer.learning_rate
        array(0.0999938, dtype=float32)
    r   z)Must provide at least 1 schedule to join.   z	Received z boundaries but expected .c           	           d         |           }t          dd                    D ]+\  }}t          j        | |k     | || |z
                      },|S )Nr   r%   )zipr   where)r   outputboundaryr   r#   r"   s       r   r   z join_schedules.<locals>.schedulez   sj    1d##"%j)ABB-"@"@ 	R 	RHhXdXovxxx7P7PQQFFr   )len
ValueError)r"   r#   r   s   `` r   join_schedulesr.   [   s    , 9~~DEEE
9~~Z1,,,.J . .I*. . .
 
 	

      Or   stepsc                 L     dk     rt          d d           fd}|S )aL  Make a linear scheduler.

    Args:
        init (float): Initial value.
        end (float): Final value.
        steps (int): Number of steps to apply the schedule over. The value is
          ``end`` for any steps beyond ``steps``.

    Example:

        >>> lr_schedule = optim.linear_schedule(0, 1e-1, 100)
        >>> optimizer = optim.Adam(learning_rate=lr_schedule)
        >>> optimizer.learning_rate
        array(0.0, dtype=float32)
        >>> for _ in range(101): optimizer.update({}, {})
        ...
        >>> optimizer.learning_rate
        array(0.1, dtype=float32)
    r%   z&steps must be greater than 0, but got r&   c                 J    t          j        |           } | z
  z  z  z   S r
   )r   r   )r   r   r   r/   s    r   r   z!linear_schedule.<locals>.schedule   s-    z$&&d
e+,t33r   )r-   )r   r   r/   r   s   ``` r   linear_scheduler2      sT    ( qyyJ%JJJKKK4 4 4 4 4 4 4 Or   )r   )r   typingr   r   mlx.corecorer   floatr   intr   r!   r.   r2   r   r   r   <module>r8      s4    ! ! ! ! ! ! ! !      E u     2U  # (    6 u 3 U X    <%d8n %$s) % % % % %P% e C H      r   