
    +h<l                         S SK r S SKJr  S SKJrJrJrJr  S SKr	S SK
r
SSKJrJr  SSKJrJr  SSKJrJr  \" 5       (       a  S SKr\ " S	 S
\5      5       r  SS jr " S S\\5      rg)    N)	dataclass)ListOptionalTupleUnion   )ConfigMixinregister_to_config)
BaseOutputis_scipy_available   )KarrasDiffusionSchedulersSchedulerMixinc                   `    \ rS rSr% Sr\R                  \S'   Sr\	\R                     \S'   Sr
g)HeunDiscreteSchedulerOutput   aM  
Output class for the scheduler's `step` function output.

Args:
    prev_sample (`torch.Tensor` of shape `(batch_size, num_channels, height, width)` for images):
        Computed sample `(x_{t-1})` of previous timestep. `prev_sample` should be used as next model input in the
        denoising loop.
    pred_original_sample (`torch.Tensor` of shape `(batch_size, num_channels, height, width)` for images):
        The predicted denoised sample `(x_{0})` based on the model output from the current timestep.
        `pred_original_sample` can be used to preview progress or for guidance.
prev_sampleNpred_original_sample )__name__
__module____qualname____firstlineno____doc__torchTensor__annotations__r   r   __static_attributes__r       g/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_heun_discrete.pyr   r      s'    
 37(5<<07r   r   c           
      &   US:X  a  S nOUS:X  a  S nO[        SU 35      e/ n[        U 5       H<  nXP-  nUS-   U -  nUR                  [        SU" U5      U" U5      -  -
  U5      5        M>     [        R
                  " U[        R                  S9$ )a  
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
(1-beta) over time from t = [0,1].

Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
to that part of the diffusion process.


Args:
    num_diffusion_timesteps (`int`): the number of betas to produce.
    max_beta (`float`): the maximum beta to use; use values lower than 1 to
                 prevent singularities.
    alpha_transform_type (`str`, *optional*, default to `cosine`): the type of noise schedule for alpha_bar.
                 Choose from `cosine` or `exp`

Returns:
    betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
cosinec                 h    [         R                  " U S-   S-  [         R                  -  S-  5      S-  $ )NgMb?gT㥛 ?r   )mathcospits    r    alpha_bar_fn)betas_for_alpha_bar.<locals>.alpha_bar_fnL   s-    88QY%/$''9A=>!CCr   expc                 4    [         R                  " U S-  5      $ )Ng      ()r$   r+   r'   s    r    r)   r*   Q   s    88AI&&r   z"Unsupported alpha_transform_type: r   dtype)
ValueErrorrangeappendminr   tensorfloat32)num_diffusion_timestepsmax_betaalpha_transform_typer)   betasit1t2s           r    betas_for_alpha_barr<   3   s    . x'	D 
	&	' =>R=STUUE*+(!e..S\"-R0@@@(KL , <<U]]33r   c                      \ rS rSrSr\ V Vs/ s H  oR                  PM     snn rSr\	             S2S\
S\S\S\S	\\\R                   \\   4      S
\S\\   S\\   S\\   S\\   S\S\S\
4S jj5       rS3S jr\S 5       r\S 5       r\S 5       rS4S\
4S jjrS\R6                  S\\\R6                  4   S\R6                  4S jr    S5S\\
   S\\\R:                  4   S\\
   S\\\
      4S  jjrS! rS"\R6                  S\R6                  4S# jr S"\R6                  S\
S\R6                  4S$ jr! S6S"\R6                  S\
S%\S&\S\R6                  4
S' jjr"\S( 5       r#S) r$ S7S*\\R6                  \R                   4   S\\\R6                  4   S\\R6                  \R                   4   S+\S\\%\&4   4
S, jjr'S-\R6                  S.\R6                  S\R6                  S\R6                  4S/ jr(S0 r)S1r*gs  snn f )8HeunDiscreteScheduler_   u
  
Scheduler with Heun steps for discrete beta schedules.

This model inherits from [`SchedulerMixin`] and [`ConfigMixin`]. Check the superclass documentation for the generic
methods the library implements for all schedulers such as loading and saving.

Args:
    num_train_timesteps (`int`, defaults to 1000):
        The number of diffusion steps to train the model.
    beta_start (`float`, defaults to 0.0001):
        The starting `beta` value of inference.
    beta_end (`float`, defaults to 0.02):
        The final `beta` value.
    beta_schedule (`str`, defaults to `"linear"`):
        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 (`np.ndarray`, *optional*):
        Pass an array of betas directly to the constructor to bypass `beta_start` and `beta_end`.
    prediction_type (`str`, defaults to `epsilon`, *optional*):
        Prediction type of the scheduler function; can be `epsilon` (predicts the noise of the diffusion process),
        `sample` (directly predicts the noisy sample`) or `v_prediction` (see section 2.4 of [Imagen
        Video](https://imagen.research.google/video/paper.pdf) paper).
    clip_sample (`bool`, defaults to `True`):
        Clip the predicted sample for numerical stability.
    clip_sample_range (`float`, defaults to 1.0):
        The maximum magnitude for sample clipping. Valid only when `clip_sample=True`.
    use_karras_sigmas (`bool`, *optional*, defaults to `False`):
        Whether to use Karras sigmas for step sizes in the noise schedule during the sampling process. If `True`,
        the sigmas are determined according to a sequence of noise levels {σi}.
    use_exponential_sigmas (`bool`, *optional*, defaults to `False`):
        Whether to use exponential sigmas for step sizes in the noise schedule during the sampling process.
    use_beta_sigmas (`bool`, *optional*, defaults to `False`):
        Whether to use beta sigmas for step sizes in the noise schedule during the sampling process. Refer to [Beta
        Sampling is All You Need](https://huggingface.co/papers/2407.12173) for more information.
    timestep_spacing (`str`, defaults to `"linspace"`):
        The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and
        Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information.
    steps_offset (`int`, defaults to 0):
        An offset added to the inference steps, as required by some model families.
r   Nnum_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasprediction_typeuse_karras_sigmasuse_exponential_sigmasuse_beta_sigmasclip_sampleclip_sample_rangetimestep_spacingsteps_offsetc                    U R                   R                  (       a  [        5       (       d  [        S5      e[	        U R                   R                  U R                   R
                  U R                   R                  /5      S:  a  [        S5      eUb)  [        R                  " U[        R                  S9U l        OUS:X  a*  [        R                  " X#U[        R                  S9U l        OUS:X  a4  [        R                  " US-  US-  U[        R                  S9S-  U l        OFUS	:X  a  [        US
S9U l        O0US:X  a  [        USS9U l        O[        U SU R                   35      eSU R                  -
  U l        [        R"                  " U R                   SS9U l        U R'                  US U5        Xpl        S U l        S U l        U R,                  R/                  S5      U l        g )Nz:Make sure to install scipy if you want to use beta sigmas.r   znOnly one of `config.use_beta_sigmas`, `config.use_exponential_sigmas`, `config.use_karras_sigmas` can be used.r-   linearscaled_linear      ?r   squaredcos_cap_v2r"   )r7   r+   z is not implemented for       ?r   )dimcpu)configrH   r   ImportErrorsumrG   rF   r/   r   r3   r4   r8   linspacer<   NotImplementedError	__class__alphascumprodalphas_cumprodset_timesteps_step_index_begin_indexsigmasto)selfr@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   s                 r    __init__HeunDiscreteScheduler.__init__   s   " ;;&&/A/C/CZ[[++T[[-O-OQUQ\Q\QnQnopstt A  $m5==IDJh&
>QY^YfYfgDJo-
C3H[chcpcpquvvDJ11,-@W_`DJe#,-@W\]DJ%7OPTP^P^O_&`aaDJJ&#mmDKKQ? 	.6IJ!2 kknnU+r   c                     Uc  U R                   nX!:H  R                  5       n[        U5      S:  a  SOSnX4   R                  5       $ )Nr   r   )	timestepsnonzerolenitem)rc   timestepschedule_timestepsindicesposs        r    index_for_timestep(HeunDiscreteScheduler.index_for_timestep   sH    %!%%1::< w<!#a|  ""r   c                     U R                   R                  S;   a  U R                  R                  5       $ U R                  R                  5       S-  S-   S-  $ )N)rX   trailingr   r   rP   )rU   rK   ra   maxrc   s    r    init_noise_sigma&HeunDiscreteScheduler.init_noise_sigma   sH     ;;''+CC;;??$$!Q&*s22r   c                     U R                   $ )zW
The index counter for current timestep. It will increase 1 after each scheduler step.
)r_   rt   s    r    
step_index HeunDiscreteScheduler.step_index   s    
 r   c                     U R                   $ )za
The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
r`   rt   s    r    begin_index!HeunDiscreteScheduler.begin_index   s    
    r   r|   c                     Xl         g)z
Sets the begin index for the scheduler. This function should be run from pipeline before the inference.

Args:
    begin_index (`int`):
        The begin index for the scheduler.
Nr{   )rc   r|   s     r    set_begin_index%HeunDiscreteScheduler.set_begin_index   s
     (r   samplerk   returnc                     U R                   c  U R                  U5        U R                  U R                      nXS-  S-   S-  -  nU$ )aN  
Ensures interchangeability with schedulers that need to scale the denoising model input depending on the
current timestep.

Args:
    sample (`torch.Tensor`):
        The input sample.
    timestep (`int`, *optional*):
        The current timestep in the diffusion chain.

Returns:
    `torch.Tensor`:
        A scaled input sample.
r   r   rP   )rx   _init_step_indexra   )rc   r   rk   sigmas       r    scale_model_input'HeunDiscreteScheduler.scale_model_input   sH    & ??"!!(+DOO,1HqLS01r   num_inference_stepsdevicerg   c           	      
   Uc  Uc  [        S5      eUb  Ub  [        S5      eUb&  U R                  R                  (       a  [        S5      eUb&  U R                  R                  (       a  [        S5      eUb&  U R                  R                  (       a  [        S5      eU=(       d    [        U5      nXl        U=(       d    U R                  R                  nUb%  [        R                  " U[        R                  S9nGOU R                  R                  S:X  a>  [        R                  " S	US
-
  U[        R                  S9SSS2   R                  5       nGO<U R                  R                  S:X  a  X0R                  -  n[        R                  " S	U5      U-  R                  5       SSS2   R                  5       R!                  [        R                  5      nX@R                  R"                  -  nOU R                  R                  S:X  af  X0R                  -  n[        R                  " US	U* 5      R                  5       R                  5       R!                  [        R                  5      nUS
-  nO"[        U R                  R                   S35      e[        R                  " S
U R$                  -
  U R$                  -  S-  5      n[        R&                  " U5      n[        R(                  " U[        R                  " S	[        U5      5      U5      nU R                  R                  (       aO  U R+                  X`R                  S9n[        R                  " U Vs/ s H  oR-                  X5      PM     sn5      nOU R                  R                  (       aE  U R/                  XaS9n[        R                  " U Vs/ s H  oR-                  X5      PM     sn5      nO_U R                  R                  (       aD  U R1                  XaS9n[        R                  " U Vs/ s H  oR-                  X5      PM     sn5      n[        R2                  " US//5      R!                  [        R                  5      n[4        R6                  " U5      R9                  US9n[4        R:                  " USS
 US
S R=                  S5      USS /5      U l        [4        R6                  " U5      n[4        R:                  " USS
 US
S R=                  S5      /5      nUR9                  U[4        R                  S9U l         SU l!        SU l"        SU l#        SU l$        U R>                  R9                  S5      U l        gs  snf s  snf s  snf )ay  
Sets the discrete timesteps used for the diffusion chain (to be run before inference).

Args:
    num_inference_steps (`int`):
        The number of diffusion steps used when generating samples with a pre-trained model.
    device (`str` or `torch.device`, *optional*):
        The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
    num_train_timesteps (`int`, *optional*):
        The number of diffusion steps used when training the model. If `None`, the default
        `num_train_timesteps` attribute is used.
    timesteps (`List[int]`, *optional*):
        Custom timesteps used to support arbitrary spacing between timesteps. If `None`, timesteps will be
        generated based on the `timestep_spacing` attribute. If `timesteps` is passed, `num_inference_steps`
        must be `None`, and `timestep_spacing` attribute will be ignored.
NzEMust pass exactly one of `num_inference_steps` or `custom_timesteps`.zACan only pass one of `num_inference_steps` or `custom_timesteps`.z=Cannot use `timesteps` with `config.use_karras_sigmas = True`zCCannot set `timesteps` with `config.use_exponential_sigmas = True`.z<Cannot set `timesteps` with `config.use_beta_sigmas = True`.r-   rX   r   r   leadingrr   zY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.rP   )	in_sigmasr   g        )r   r   r   r.   rT   )%r/   rU   rF   rG   rH   ri   r   r@   nparrayr4   rK   rX   copyarangeroundastyperL   r]   loginterp_convert_to_karras_sigma_to_t_convert_to_exponential_convert_to_betaconcatenater   
from_numpyrb   catrepeat_interleavera   rg   prev_derivativedtr_   r`   )	rc   r   r   r@   rg   
step_ratiora   
log_sigmasr   s	            r    r^   #HeunDiscreteScheduler.set_timesteps  sn   . &9+<dee*y/D`aa T[[%B%B\]] T[[%G%Gbcc T[[%@%@[\\1CS^#6 1TT[[5T5T "**=I {{++z9KK+>+BDW_a_i_ijkomokopuuw	--:04L4LL
  YYq*=>KRRTUYWYUYZ__ahhikisist	[[555	--;03K3KK
  YY':A
{KRRTYY[bbcecmcmn	Q	 {{334  5N  O  A 3 33t7J7JJsRSVVF^
9bii3v;&?H;;((,,vSkSk,lFSY!ZSY%"2"25"ESY!Z[I[[//11F1lFSY!ZSY%"2"25"ESY!Z[I[[((**V*eFSY!ZSY%"2"25"ESY!Z[I#077

C!!&),,F,;iiVAb\-K-KA-NPVWYWZP[ \]$$Y/	IIy!}im.M.Ma.PQR	"V5==I  $ kknnU+/ "[ "[ "[s   U-:U2U7c                    [         R                  " [         R                  " US5      5      nX2S S 2[         R                  4   -
  n[         R                  " US:  SS9R                  SS9R                  UR                  S   S-
  S9nUS-   nX%   nX&   nXs-
  Xx-
  -  n	[         R                  " U	SS5      n	SU	-
  U-  X-  -   n
U
R                  UR                  5      n
U
$ )Ng|=r   )axisr   )rs   r   )	r   r   maximumnewaxiscumsumargmaxclipshapereshape)rc   r   r   	log_sigmadistslow_idxhigh_idxlowhighwr(   s              r    r   !HeunDiscreteScheduler._sigma_to_td  s    FF2::eU34	 q"**}55 ))UaZq188a8@EE*JZJZ[\J]`aJaEbQ;!# _,GGAq! Ug,IIekk"r   r   c                    [        U R                  S5      (       a  U R                  R                  nOSn[        U R                  S5      (       a  U R                  R                  nOSnUb  UOUS   R	                  5       nUb  UOUS   R	                  5       nSn[
        R                  " SSU5      nUSU-  -  nUSU-  -  nXXx-
  -  -   U-  n	U	$ )z6Constructs the noise schedule of Karras et al. (2022).	sigma_minN	sigma_maxr   r   g      @r   )hasattrrU   r   r   rj   r   rX   )
rc   r   r   r   r   rhorampmin_inv_rhomax_inv_rhora   s
             r    r   (HeunDiscreteScheduler._convert_to_karras|  s    
 4;;,,--II4;;,,--II!*!6IIbM<N<N<P	!*!6IIaL<M<M<O	{{1a!45AG,AG,(A BBsJr   c                    [        U R                  S5      (       a  U R                  R                  nOSn[        U R                  S5      (       a  U R                  R                  nOSnUb  UOUS   R	                  5       nUb  UOUS   R	                  5       n[
        R                  " [
        R                  " [        R                  " U5      [        R                  " U5      U5      5      nU$ )z)Constructs an exponential noise schedule.r   Nr   r   r   )
r   rU   r   r   rj   r   r+   rX   r$   r   )rc   r   r   r   r   ra   s         r    r   -HeunDiscreteScheduler._convert_to_exponential  s    
 4;;,,--II4;;,,--II!*!6IIbM<N<N<P	!*!6IIaL<M<M<O	DHHY$7)9LNabcr   alphabetac           
      J   [        U R                  S5      (       a  U R                  R                  nOSn[        U R                  S5      (       a  U R                  R                  nOSnUb  UOUS   R	                  5       nUb  UOUS   R	                  5       n[
        R                  " S[
        R                  " SSU5      -
   Vs/ s H-  n[        R                  R                  R                  XsU5      PM/     sn Vs/ s H  nXXXe-
  -  -   PM     sn5      n	U	$ s  snf s  snf )zJFrom "Beta Sampling is All You Need" [arXiv:2407.12173] (Lee et. al, 2024)r   Nr   r   r   r   )r   rU   r   r   rj   r   r   rX   scipystatsr   ppf)
rc   r   r   r   r   r   r   rk   r   ra   s
             r    r   &HeunDiscreteScheduler._convert_to_beta  s    4;;,,--II4;;,,--II!*!6IIbM<N<N<P	!*!6IIaL<M<M<O	
 %&Aq:M(N$N$N KK$$(($?$NC I$9:;
 s   4D?D c                     U R                   S L $ N)r   rt   s    r    state_in_first_order*HeunDiscreteScheduler.state_in_first_order  s    ww$r   c                     U R                   c[  [        U[        R                  5      (       a%  UR	                  U R
                  R                  5      nU R                  U5      U l        g U R                  U l        g r   )
r|   
isinstancer   r   rb   rg   r   ro   r_   r`   )rc   rk   s     r    r   &HeunDiscreteScheduler._init_step_index  sX    #(ELL11#;;t~~'<'<=#66x@D#00Dr   model_outputreturn_dictc                    U R                   c  U R                  U5        U R                  (       a6  U R                  U R                      nU R                  U R                   S-      nO5U R                  U R                   S-
     nU R                  U R                      nSnXWS-   -  nU R                  R
                  S:X  a  U R                  (       a  UOUn	X9U-  -
  n
OU R                  R
                  S:X  a2  U R                  (       a  UOUn	X* U	S-  S-   S-  -  -  X9S-  S-   -  -   n
O@U R                  R
                  S:X  a  Un
O#[        S	U R                  R
                   S
35      eU R                  R                  (       a;  U
R                  U R                  R                  * U R                  R                  5      n
U R                  (       a  X:-
  U-  nXh-
  nXl
        Xl        X0l        OFX:-
  U-  nU R                  U-   S-  nU R                  nU R                  nSU l
        SU l        SU l        X;U-  -   nU =R                  S-  sl        U(       d  UU
4$ [        XS9$ )a  
Predict the sample from the previous timestep by reversing the SDE. This function propagates the diffusion
process from the learned model outputs (most often the predicted noise).

Args:
    model_output (`torch.Tensor`):
        The direct output from learned diffusion model.
    timestep (`float`):
        The current discrete timestep in the diffusion chain.
    sample (`torch.Tensor`):
        A current instance of a sample created by the diffusion process.
    return_dict (`bool`):
        Whether or not to return a [`~schedulers.scheduling_heun_discrete.HeunDiscreteSchedulerOutput`] or
        tuple.

Returns:
    [`~schedulers.scheduling_heun_discrete.HeunDiscreteSchedulerOutput`] or `tuple`:
        If return_dict is `True`, [`~schedulers.scheduling_heun_discrete.HeunDiscreteSchedulerOutput`] is
        returned, otherwise a tuple is returned where the first element is the sample tensor.
Nr   r   epsilonv_predictionr   rP   r   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`)r   r   )rx   r   r   ra   rU   rE   r/   rI   clamprJ   r   r   r   r_   r   )rc   r   rk   r   r   r   
sigma_nextgamma	sigma_hatsigma_inputr   
derivativer   r   s                 r    stepHeunDiscreteScheduler.step  sO   6 ??"!!(+$$KK0ET__q%89J KK! 34ET__5J
 QY'	 ;;&&)3'+'@'@)jK#),,F#F [[((N:'+'@'@)jK#/<;PQ>TUCUZ]B]3]#^q.1,-$  [[((H4#/ +DKK,G,G+HHtu  ;;""#7#=#=...0M0M$  $$ 79DJ'B $. G K !7:EJ..;q@J B[[F $(D DGDKB. 	A$ 
 +{nnr   original_samplesnoisec                     U R                   R                  UR                  UR                  S9nUR                  R                  S:X  av  [
        R                  " U5      (       a[  U R                  R                  UR                  [
        R                  S9nUR                  UR                  [
        R                  S9nO@U R                  R                  UR                  5      nUR                  UR                  5      nU R                  c!  U Vs/ s H  o`R                  Xe5      PM     nnOHU R                  b  U R                  /UR                  S   -  nOU R                  /UR                  S   -  nXG   R                  5       n[        UR                  5      [        UR                  5      :  a?  UR                  S5      n[        UR                  5      [        UR                  5      :  a  M?  XU-  -   n	U	$ s  snf )Nr   mpsr-   r   r   )ra   rb   r   r.   typer   is_floating_pointrg   r4   r|   ro   rx   r   flattenri   	unsqueeze)
rc   r   r   rg   ra   rl   r(   step_indicesr   noisy_sampless
             r    	add_noiseHeunDiscreteScheduler.add_noise@  s    '7'>'>FVF\F\]""''50U5L5LY5W5W!%!2!23C3J3JRWR_R_!2!`!%5%<%<EMMRI!%!2!23C3J3J!K!%5%<%<=I #T]^T]q33AJT]L^L__( OO,yq/AAL !,,-	0BBL$,,.%++%5%;%;!<<OOB'E %++%5%;%;!<< )5=8 _s   G;c                 .    U R                   R                  $ r   )rU   r@   rt   s    r    __len__HeunDiscreteScheduler.__len__a  s    {{...r   )r`   r_   r[   r]   r8   r   r   r   r   ra   rg   rF   )i  g_QK?g~jt?rN   Nr   FFFFrR   rX   r   r   )r   )NNNN)333333?r   )T)+r   r   r   r   r   r   name_compatiblesorderr
   intfloatstrr   r   r   ndarrayr   boolrd   ro   propertyru   rx   r|   r   r   r   r   r   r^   r   r   r   r   r   r   r   r   r   r   r   r   ).0es   00r    r>   r>   _   sU   'R %>>$=qFF$=>LE $(#%BF(,116*/&+#& *., ., ., 	.,
 .,  bjj$u+&= >?., ., $D>., !)., "$., d^., !., ., ., .,b# 3 3     ! !(3 ( u||+, 
	8 .2+/-1)-Z,%c]Z, c5<<'(Z, &c]	Z,
 DI&Z,z0ELL RWR^R^ 4 TW \a\h\h . dg<?HM[`	>  1 !eoELL"**45eo u||+,eo ellBJJ./	eo
 eo 
*E1	2eoP,, || <<	
 
B/q ?s   Hr>   )g+?r"   )r$   dataclassesr   typingr   r   r   r   numpyr   r   configuration_utilsr	   r
   utilsr   r   scheduling_utilsr   r   scipy.statsr   r   r<   r>   r   r   r    <module>r      si     ! / /   A 2 G  8* 8 8( !)4XC/NK C/r   