
    +hz/                         S SK Jr  S SK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  SS	KJr  \R&                  " \5      r\ " S
 S\5      5       r " S S\\
5      rg)    )	dataclass)OptionalTupleUnionN   )ConfigMixinregister_to_config)
BaseOutputlogging)randn_tensor   )SchedulerMixinc                   8    \ rS rSr% Sr\R                  \S'   Srg)$FlowMatchHeunDiscreteSchedulerOutput   a2  
Output class for the scheduler's `step` function output.

Args:
    prev_sample (`torch.FloatTensor` 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.
prev_sample N)	__name__
__module____qualname____firstlineno____doc__torchFloatTensor__annotations____static_attributes__r       r/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_flow_match_heun_discrete.pyr   r      s     """r   r   c                      \ rS rSrSr/ rSr\  S&S\S\	4S jj5       r
\S 5       r\S	 5       rS'S
\4S jjr S(S\R                   S\\	\R                   4   S\\R                      S\R                   4S jjrS rS(S\S\\\R,                  4   4S jjrS(S jrS r\S 5       rSS\	" S5      SSS4S\R                   S\\	\R                   4   S\R                   S\	S\	S\	S \	S!\\R6                     S"\S\\\4   4S# jjrS$ r S%r!g))FlowMatchHeunDiscreteScheduler,   a  
Heun scheduler.

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.
    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.
    shift (`float`, defaults to 1.0):
        The shift value for the timestep schedule.
r         ?num_train_timestepsshiftc                    [         R                  " SX[         R                  S9S S S2   R                  5       n[        R
                  " U5      R                  [        R                  S9nX1-  nX$-  SUS-
  U-  -   -  nXA-  U l        S U l        S U l	        UR                  S5      U l
        U R                  S   R                  5       U l        U R                  S   R                  5       U l        g )Nr   )dtypecpur   )nplinspacefloat32copyr   
from_numpyto	timesteps_step_index_begin_indexsigmasitem	sigma_min	sigma_max)selfr#   r$   r/   r2   s        r   __init__'FlowMatchHeunDiscreteScheduler.__init__@   s     KK#6SUS]S]^_cac_cdiik	$$Y/222G	01	V';#;<5 ii&R--/Q,,.r   c                     U R                   $ )zW
The index counter for current timestep. It will increase 1 after each scheduler step.
)r0   r6   s    r   
step_index)FlowMatchHeunDiscreteScheduler.step_indexU   s    
 r   c                     U R                   $ )za
The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
r1   r:   s    r   begin_index*FlowMatchHeunDiscreteScheduler.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>   )r6   r?   s     r   set_begin_index.FlowMatchHeunDiscreteScheduler.set_begin_indexd   s
     (r   Nsampletimestepnoisereturnc                     U R                   c  U R                  U5        U R                  U R                      nXC-  SU-
  U-  -   nU$ )z
Forward process in flow-matching

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

Returns:
    `torch.FloatTensor`:
        A scaled input sample.
r"   )r;   _init_step_indexr2   )r6   rD   rE   rF   sigmas        r   scale_noise*FlowMatchHeunDiscreteScheduler.scale_noisen   sH    & ??"!!(+DOO,#+!77r   c                 2    XR                   R                  -  $ Nconfigr#   )r6   rJ   s     r   _sigma_to_t*FlowMatchHeunDiscreteScheduler._sigma_to_t   s    {{6666r   num_inference_stepsdevicec                 j   Xl         [        R                  " U R                  U R                  5      U R                  U R
                  5      U5      nX0R                  R                  -  nU R                  R                  U-  SU R                  R                  S-
  U-  -   -  n[        R                  " U5      R                  [        R                  US9nX@R                  R                  -  n[        R                  " USS USS R                  S5      /5      nUR                  US9U l        [        R                  " U[        R                   " SUR"                  S9/5      n[        R                  " USS USS R                  S5      USS /5      U l        SU l        SU l        SU l        SU l        g)au  
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.
r   )r&   rT   Nr   )rT   r'   )rS   r)   r*   rQ   r5   r4   rP   r#   r$   r   r-   r.   r+   catrepeat_interleaver/   zerosrT   r2   prev_derivativedtr0   r1   )r6   rS   rT   r/   r2   s        r   set_timesteps,FlowMatchHeunDiscreteScheduler.set_timesteps   sq    $7 KKT^^,d.>.>t~~.NPc
	 [[<<<""V+qDKK4E4E4IV3S/ST!!&),,5==,P[[<<<	IIy!}im.M.Ma.PQR	"V4FEKK&--$HIJiiVAb\-K-KA-NPVWYWZP[ \]  $ 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   )r/   nonzerolenr3   )r6   rE   schedule_timestepsindicesposs        r   index_for_timestep1FlowMatchHeunDiscreteScheduler.index_for_timestep   sH    %!%%1::< w<!#a|  ""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 rN   )
r?   
isinstancer   Tensorr.   r/   rT   rc   r0   r1   )r6   rE   s     r   rI   /FlowMatchHeunDiscreteScheduler._init_step_index   sX    #(ELL11#;;t~~'<'<=#66x@D#00Dr   c                     U R                   S L $ rN   )rZ   r:   s    r   state_in_first_order3FlowMatchHeunDiscreteScheduler.state_in_first_order   s    ww$r           infTmodel_outputs_churns_tmins_tmaxs_noise	generatorreturn_dictc
                    [        U[        5      (       d>  [        U[        R                  5      (       d  [        U[        R                  5      (       a  [        S5      eU R                  c  U R                  U5        UR                  [        R                  5      n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XZs=::  a  U::  a(  O  O%[        U[        U R                  5      S-
  -  S5      OSnXS-   -  nUS:  aA  [        UR                  UR                   UR"                  US9nX-  nX?US-  U
S-  -
  S	-  -  -   nU R                  (       a(  X1U
-  -
  nUU-
  U-  nX-
  nUU l        UU l        X0l        ONX1U-  -
  nUU-
  U-  nS	U R$                  U-   -  nU R&                  nU R(                  nSU l        SU l        SU l        UUU-  -   nUR                  UR                   5      nU =R*                  S-  sl        U	(       d  U4$ [-        US
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.FloatTensor`):
        The direct output from learned diffusion model.
    timestep (`float`):
        The current discrete timestep in the diffusion chain.
    sample (`torch.FloatTensor`):
        A current instance of a sample created by the diffusion process.
    s_churn (`float`):
    s_tmin  (`float`):
    s_tmax  (`float`):
    s_noise (`float`, defaults to 1.0):
        Scaling factor for noise added to the sample.
    generator (`torch.Generator`, *optional*):
        A random number generator.
    return_dict (`bool`):
        Whether or not to return a
        [`~schedulers.scheduling_flow_match_heun_discrete.FlowMatchHeunDiscreteSchedulerOutput`] tuple.

Returns:
    [`~schedulers.scheduling_flow_match_heun_discrete.FlowMatchHeunDiscreteSchedulerOutput`] or `tuple`:
        If return_dict is `True`,
        [`~schedulers.scheduling_flow_match_heun_discrete.FlowMatchHeunDiscreteSchedulerOutput`] is returned,
        otherwise a tuple is returned where the first element is the sample tensor.
zPassing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to `FlowMatchHeunDiscreteScheduler.step()` is not supported. Make sure to pass one of the `scheduler.timesteps` as a timestep.Nr   g4y?rl   r   )r&   rT   rs   r   g      ?)r   )rf   intr   	IntTensor
LongTensor
ValueErrorr;   rI   r.   r+   rj   r2   minr_   r   shaper&   rT   rY   rZ   rD   r0   r   )r6   rn   rE   rD   ro   rp   rq   rr   rs   rt   rJ   
sigma_nextgamma	sigma_hatrF   epsdenoised
derivativerZ   r   s                       r   step#FlowMatchHeunDiscreteScheduler.step   sO   T x%%(EOO44(E$4$455G  ??"!!(+ 5==)$$KK0ET__q%89J KK! 34ET__5JEKE^X^E^Gs4;;/!34jAdgQY'	19 "",*<*<\EXEXdmE /CY\E1H%<$DDDF$$u 44H 8+y8J'B $.D DG K z 99H 8+z9J 4 4z ABJ B[[F $(D DGDKzB.!nn\%7%78 	A>!3LLr   c                 .    U R                   R                  $ rN   rO   r:   s    r   __len__&FlowMatchHeunDiscreteScheduler.__len__@  s    {{...r   )
r1   r0   rZ   rS   rY   rD   r5   r4   r2   r/   )i  r"   )r   rN   )"r   r   r   r   r   _compatiblesorderr	   rv   floatr7   propertyr;   r?   rB   r   r   r   r   rK   rQ   strrT   r[   rc   rI   rj   	Generatorboolr   r   r   r   r   r   r   r   r    r    ,   s     LE $(/ / / /(     ! !(3 ( .2	!! u0001 ))*	
 
		67 !  !eCDU>V  !D#1   e/3 vM''vM u0001vM !!	vM
 vM vM vM vM EOO,vM vM 
3U:	;vMp/r   r    )dataclassesr   typingr   r   r   numpyr)   r   configuration_utilsr   r	   utilsr
   r   utils.torch_utilsr   scheduling_utilsr   
get_loggerr   loggerr   r    r   r   r   <module>r      s_    " ) )   A ' , , 
		H	% 
#: 
# 
#U/^[ U/r   