
    +hE+                         S SK Jr  S SKJrJrJr  S SKrS SKJr	  S SK
Jr  SSKJrJr  SSKJrJrJrJrJr  \R*                  R                   " S	 S
5      5       r\ " S S\5      5       r " S S\\5      rg)    )	dataclass)OptionalTupleUnionN)	integrate   )ConfigMixinregister_to_config   )CommonSchedulerStateFlaxKarrasDiffusionSchedulersFlaxSchedulerMixinFlaxSchedulerOutputbroadcast_to_shape_from_leftc            	          \ rS rSr% \\S'   \R                  \S'   \R                  \S'   \R                  \S'   Sr\	\
   \S'   Sr\	\R                     \S'   \S\S\R                  S\R                  S\R                  4S	 j5       rS
rg)LMSDiscreteSchedulerState    commoninit_noise_sigma	timestepssigmasNnum_inference_stepsderivativesc                     U " XX4S9$ )Nr   r   r   r    )clsr   r   r   r   s        k/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_lms_discrete_flax.pycreate LMSDiscreteSchedulerState.create-   s     &yhh    r   )__name__
__module____qualname____firstlineno__r   __annotations__jnpndarrayr   r   intr   classmethodr   __static_attributes__r   r!   r   r   r       s       kk!{{KK)-#- *.K#++&-i)i=@[[iUXU`U`ijmjujui ir!   r   c                        \ rS rSr% \\S'   Srg)FlaxLMSSchedulerOutput4   stater   N)r"   r#   r$   r%   r   r&   r+   r   r!   r   r-   r-   4   s    $$r!   r-   c                   t   \ rS rSr% Sr\ V Vs/ s H  oR                  PM     snn r\R                  \
S'   \S 5       r\SSSSS	S
\R                  4S\S\S\S\S\\R&                     S\S\R                  4S jj5       rS'S\\   S\4S jjrS\S\R&                  S\S\R&                  4S jrS\4S jr S(S\S\S\S\4S jjr  S)S\S\R&                  S\S\R&                  S\S\S\\\4   4S  jjrS\S!\R&                  S"\R&                  S#\R&                  S\R&                  4
S$ jr S% r!S&r"g	s  snn f )*FlaxLMSDiscreteScheduler9   a>  
Linear Multistep Scheduler for discrete beta schedules. Based on the original k-diffusion implementation by
Katherine Crowson:
https://github.com/crowsonkb/k-diffusion/blob/481677d114f6ea445aa009cf5bd7a9cdee909e47/k_diffusion/sampling.py#L181

[`~ConfigMixin`] takes care of storing all config attributes that are passed in the scheduler's `__init__`
function, such as `num_train_timesteps`. They can be accessed via `scheduler.config.num_train_timesteps`.
[`SchedulerMixin`] provides general loading and saving functionality via the [`SchedulerMixin.save_pretrained`] and
[`~SchedulerMixin.from_pretrained`] functions.

Args:
    num_train_timesteps (`int`): number of diffusion steps used to train the model.
    beta_start (`float`): the starting `beta` value of inference.
    beta_end (`float`): the final `beta` value.
    beta_schedule (`str`):
        the beta schedule, a mapping from a beta range to a sequence of betas for stepping the model. Choose from
        `linear` or `scaled_linear`.
    trained_betas (`jnp.ndarray`, optional):
        option to pass an array of betas directly to the constructor to bypass `beta_start`, `beta_end` etc.
    prediction_type (`str`, default `epsilon`, optional):
        prediction type of the scheduler function, one of `epsilon` (predicting the noise of the diffusion
        process), `sample` (directly predicting the noisy sample`) or `v_prediction` (see section 2.4
        https://imagen.research.google/video/paper.pdf)
    dtype (`jnp.dtype`, *optional*, defaults to `jnp.float32`):
        the `dtype` used for params and computation.
dtypec                     g)NTr   selfs    r   	has_state"FlaxLMSDiscreteScheduler.has_stateY   s    r!   i  -C6?g{Gz?linearNepsilonnum_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasprediction_typec                     Xpl         g Nr3   )r6   r<   r=   r>   r?   r@   rA   r3   s           r   __init__!FlaxLMSDiscreteScheduler.__init__]   s	     
r!   r   returnc                 <   Uc  [         R                  " U 5      n[        R                  " SU R                  R
                  5      R                  5       S S S2   nSUR                  -
  UR                  -  S-  nUR                  5       n[        R                  UUUUS9$ )Nr   r         ?r   )
r   r   r'   arangeconfigr<   roundalphas_cumprodmaxr   )r6   r   r   r   r   s        r   create_state%FlaxLMSDiscreteScheduler.create_statej   s    >)006FJJq$++"A"ABHHJ4R4P	v,,,0E0EE#M "::<(//-	 0 
 	
r!   r/   sampletimestepc                     [         R                  " UR                  U:H  SS9u  nUS   nUR                  U   nX%S-  S-   S-  -  nU$ )a  
Scales the denoising model input by `(sigma**2 + 1) ** 0.5` to match the K-LMS algorithm.

Args:
    state (`LMSDiscreteSchedulerState`):
        the `FlaxLMSDiscreteScheduler` state data class instance.
    sample (`jnp.ndarray`):
        current instance of sample being created by diffusion process.
    timestep (`int`):
        current discrete timestep in the diffusion chain.

Returns:
    `jnp.ndarray`: scaled input sample
r   )sizer   r   rJ   )r'   wherer   r   )r6   r/   rR   rS   
step_indexsigmas         r   scale_model_input*FlaxLMSDiscreteScheduler.scale_model_input{   sP     		%//X"=AF]
Z(1HqLS01r!   c                    ^^^^ UUUU4S jn[         R                  " UTR                  T   TR                  TS-      SS9S   nU$ )zj
Compute a linear multistep coefficient.

Args:
    order (TODO):
    t (TODO):
    current_order (TODO):
c                    > Sn[        T5       HH  nTU:X  a  M  XTR                  TU-
     -
  TR                  TT-
     TR                  TU-
     -
  -  -  nMJ     U$ )N      ?)ranger   )tauprodkcurrent_orderorderr/   ts      r   lms_derivativeDFlaxLMSDiscreteScheduler.get_lms_coefficient.<locals>.lms_derivative   sm    D5\ A%u||AE22u||ADU7VY^YeYefgjkfkYl7lmm " Kr!   r   r9   )epsrelr   )r   quadr   )r6   r/   rc   rd   rb   re   integrated_coeffs    ````  r   get_lms_coefficient,FlaxLMSDiscreteScheduler.get_lms_coefficient   sI    	 	 %>>.%,,q/5<<XY\]X]K^gklmnor!   r   shapec                    [         R                  " U R                  R                  S-
  SX R                  S9n[         R
                  " U5      R                  [         R                  5      n[         R                  " U5      R                  [         R                  5      n[         R                  " US5      nSUR                  R                  -
  UR                  R                  -  S-  nSU-
  X   -  XxU   -  -   n[         R                  " U[         R                  " S/U R                  S9/5      nUR                  [         R                  5      n[         R                  " SU-   U R                  S9n	UR                  UUUU	S9$ )	aR  
Sets the timesteps used for the diffusion chain. Supporting function to be run before inference.

Args:
    state (`LMSDiscreteSchedulerState`):
        the `FlaxLMSDiscreteScheduler` state data class instance.
    num_inference_steps (`int`):
        the number of diffusion steps used when generating samples with a pre-trained model.
r   r   rD   r]   rJ   g        )r   )r   r   r   r   )r'   linspacerL   r<   r3   floorastypeint32ceilmodr   rN   concatenatearrayzerosreplace)
r6   r/   r   rl   r   low_idxhigh_idxfracr   r   s
             r   set_timesteps&FlaxLMSDiscreteScheduler.set_timesteps   s0    LL!@!@1!DaI\dndno	))I&--cii888I&--cii8wwy#&u||222ell6Q6QQVYYd(fo-h7G0GG&#))SE*L!MN$$SYY/	 iiuDJJ?}} 3#	  
 	
r!   model_outputrc   return_dictc           
      F   UR                   c  [        S5      eUR                  U   nU R                  R                  S:X  a  XGU-  -
  nOZU R                  R                  S:X  a  X'* US-  S-   S-  -  -  XGS-  S-   -  -   nO#[        SU R                  R                   S35      eXH-
  U-  n	UR                  [        R                  " UR                  U	5      S	9n[        UR                  5      U:  a.  UR                  [        R                  " UR                  S
5      S	9n[        US-   U5      n[        U5       V
s/ s H  oR                  XX:5      PM     nn
U[        S [        U[!        UR                  5      5       5       5      -   nU(       d  X4$ [#        XS9$ s  sn
f )ak  
Predict the sample at the previous timestep by reversing the SDE. Core function to propagate the diffusion
process from the learned model outputs (most often the predicted noise).

Args:
    state (`LMSDiscreteSchedulerState`): the `FlaxLMSDiscreteScheduler` state data class instance.
    model_output (`jnp.ndarray`): direct output from learned diffusion model.
    timestep (`int`): current discrete timestep in the diffusion chain.
    sample (`jnp.ndarray`):
        current instance of sample being created by diffusion process.
    order: coefficient for multi-step inference.
    return_dict (`bool`): option for returning tuple rather than FlaxLMSSchedulerOutput class

Returns:
    [`FlaxLMSSchedulerOutput`] or `tuple`: [`FlaxLMSSchedulerOutput`] if `return_dict` is True, otherwise a
    `tuple`. When returning a tuple, the first element is the sample tensor.

zaNumber of inference steps is 'None', you need to run 'set_timesteps' after creating the schedulerr;   v_predictionr   r   rJ   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`)r   r   c              3   .   #    U  H  u  pX-  v   M     g 7frC   r   ).0coeff
derivatives      r   	<genexpr>0FlaxLMSDiscreteScheduler.step.<locals>.<genexpr>  s      #
8d#45E8ds   )prev_sampler/   )r   
ValueErrorr   rL   rA   rw   r'   appendr   lendeleteminr^   rj   sumzipreversedr-   )r6   r/   r}   rS   rR   rc   r~   rX   pred_original_sampler   
curr_order
lms_coeffsr   s                r   stepFlaxLMSDiscreteScheduler.step   s   6 $$,s  X& ;;&&)3#)L,@#@ [[((N:#/6UAX\c<Q3Q#RV\gh`hkl`lVm#n +DKK,G,G+HHtu 
 3u<
#**U5F5F
*STu  !E)MMcjj9J9JA.NMOE HqL%(ejkpeqreqWa..uXReq
r s #
8;JQVQbQbHc8d#
  
 
 ''%+KK ss   <Foriginal_samplesnoiser   c                 x    UR                   U   R                  5       n[        XSR                  5      nX#U-  -   nU$ rC   )r   flattenr   rl   )r6   r/   r   r   r   rX   noisy_sampless          r   	add_noise"FlaxLMSDiscreteScheduler.add_noise  s;     Y'//1,UKK@(5=8r!   c                 .    U R                   R                  $ rC   )rL   r<   r5   s    r   __len__ FlaxLMSDiscreteScheduler.__len__  s    {{...r!   rD   rC   )r   )   T)#r"   r#   r$   r%   __doc__r   name_compatiblesr'   r3   r&   propertyr7   r
   float32r)   floatstrr   r(   rE   r   r   rP   rY   rj   r   r{   boolr   r-   r   r   r   r+   )r   es   00r   r1   r1   9   s   6 %BB$AqFF$ABL99   $("%/3(;;
 
 
 	

 
  ,
 
 yy
 

8,@#A 
Mf 
"'@ #++ ad ilitit , )B  . Z\"
."
EH"
QV"
	""
T  ?L(?L kk?L 	?L
 ?L ?L ?L 
%u,	-?LB( ++ {{	
 ;; 
/K Cs   D4r1   )dataclassesr   typingr   r   r   flax	jax.numpynumpyr'   scipyr   configuration_utilsr	   r
   scheduling_utils_flaxr   r   r   r   r   structr   r-   r1   r   r!   r   <module>r      sy    " ) )    A  i i i& %0 % %b/1; b/r!   