
    biL                         d dl Z d dlmZmZmZmZmZ d dlZd dl	Z	ddl
mZmZ ddlmZmZ ddlmZ ddlmZmZmZ  e       rd dlZ	 	 dd	Z G d
 dee      Zy)    N)CallableListOptionalTupleUnion   )ConfigMixinregister_to_config)	deprecateis_scipy_available)randn_tensor   )KarrasDiffusionSchedulersSchedulerMixinSchedulerOutputc           
      $   |dk(  rd }n|dk(  rd }nt        d|       g }t        |       D ]<  }|| z  }|dz   | z  }|j                  t        d ||       ||      z  z
  |             > t	        j
                  |t        j                        S )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                 f    t        j                  | dz   dz  t         j                  z  dz        dz  S )NgMb?gT㥛 ?r   )mathcospits    c/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/schedulers/scheduling_sasolver.pyalpha_bar_fnz)betas_for_alpha_bar.<locals>.alpha_bar_fn<   s-    88QY%/$''9A=>!CC    expc                 2    t        j                  | dz        S )Ng      ()r   r   r   s    r   r   z)betas_for_alpha_bar.<locals>.alpha_bar_fnA   s    88AI&&r   z"Unsupported alpha_transform_type: r   dtype)
ValueErrorrangeappendmintorchtensorfloat32)num_diffusion_timestepsmax_betaalpha_transform_typer   betasit1t2s           r   betas_for_alpha_barr/   #   s    . x'	D 
	&	' =>R=STUUE*+ M((!e..S\"-R0@@@(KLM <<U]]33r   c            0       L   e Zd ZdZeD  cg c]  }|j
                   c}} ZdZedddddddd	dd
ddddd
d
d
d
d e	d       dddfde
de	de	dedeeej                  ee	   f      de
de
dedee   dede	de	deded ee   d!ee   d"ee   d#ee   d$ee	   d%e	d&ee   d'ed(e
f.d)       Zed*        Zed+        ZdVd,e
fd-ZdWd.e
d/eeej2                  f   fd0Zd1ej6                  d2ej6                  fd3Zd4 Zd5 Zd6ej6                  d2ej6                  fd7Zd6ej6                  d.e
d2ej6                  fd8Z 	 dXd6ej6                  d.e
d9e	d:e	d2ej6                  f
d;Z!dd<d=ej6                  d1ej6                  d2ej6                  fd>Z"d? Z#d@ Z$dA Z%dB Z&d=ej6                  d1ej6                  dCej6                  dDe
dEej6                  d2ej6                  fdFZ'dGej6                  dHej6                  dIej6                  dJej6                  dDe
dEej6                  d2ej6                  fdKZ(dYdLZ)dM Z*	 	 dZd=ej6                  dNe
d1ej6                  dOed2ee+e,f   f
dPZ-d1ej6                  d2ej6                  fdQZ.dRej6                  dCej6                  dSej^                  d2ej6                  fdTZ0dU Z1yc c}} w )[SASolverScheduleru  
    `SASolverScheduler` is a fast dedicated high-order solver for diffusion SDEs.

    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`, `scaled_linear`, or `squaredcos_cap_v2`.
        trained_betas (`np.ndarray`, *optional*):
            Pass an array of betas directly to the constructor to bypass `beta_start` and `beta_end`.
        predictor_order (`int`, defaults to 2):
            The predictor order which can be `1` or `2` or `3` or '4'. It is recommended to use `predictor_order=2` for
            guided sampling, and `predictor_order=3` for unconditional sampling.
        corrector_order (`int`, defaults to 2):
            The corrector order which can be `1` or `2` or `3` or '4'. It is recommended to use `corrector_order=2` for
            guided sampling, and `corrector_order=3` for unconditional sampling.
        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).
        tau_func (`Callable`, *optional*):
            Stochasticity during the sampling. Default in init is `lambda t: 1 if t >= 200 and t <= 800 else 0`.
            SA-Solver will sample from vanilla diffusion ODE if tau_func is set to `lambda t: 0`. SA-Solver will sample
            from vanilla diffusion SDE if tau_func is set to `lambda t: 1`. For more details, please check
            https://huggingface.co/papers/2309.05019
        thresholding (`bool`, defaults to `False`):
            Whether to use the "dynamic thresholding" method. This is unsuitable for latent-space diffusion models such
            as Stable Diffusion.
        dynamic_thresholding_ratio (`float`, defaults to 0.995):
            The ratio for the dynamic thresholding method. Valid only when `thresholding=True`.
        sample_max_value (`float`, defaults to 1.0):
            The threshold value for dynamic thresholding. Valid only when `thresholding=True` and
            `algorithm_type="dpmsolver++"`.
        algorithm_type (`str`, defaults to `data_prediction`):
            Algorithm type for the solver; can be `data_prediction` or `noise_prediction`. It is recommended to use
            `data_prediction` with `solver_order=2` for guided sampling like in Stable Diffusion.
        lower_order_final (`bool`, defaults to `True`):
            Whether to use lower-order solvers in the final steps. Default = 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.
        lambda_min_clipped (`float`, defaults to `-inf`):
            Clipping threshold for the minimum value of `lambda(t)` for numerical stability. This is critical for the
            cosine (`squaredcos_cap_v2`) noise schedule.
        variance_type (`str`, *optional*):
            Set to "learned" or "learned_range" for diffusion models that predict variance. If set, the model's output
            contains the predicted Gaussian variance.
        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   i  g-C6?g{Gz?linearNr   epsilonFgףp=
?      ?data_predictionTinflinspacer   num_train_timesteps
beta_startbeta_endbeta_scheduletrained_betaspredictor_ordercorrector_orderprediction_typetau_functhresholdingdynamic_thresholding_ratiosample_max_valuealgorithm_typelower_order_finaluse_karras_sigmasuse_exponential_sigmasuse_beta_sigmasuse_flow_sigmas
flow_shiftlambda_min_clippedvariance_typetimestep_spacingsteps_offsetc                    | j                   j                  rt               st        d      t	        | j                   j                  | j                   j
                  | j                   j                  g      dkD  rt        d      |+t        j                  |t        j                        | _        n|dk(  r-t        j                  |||t        j                        | _        nk|dk(  r6t        j                  |dz  |dz  |t        j                        dz  | _        n0|d	k(  rt        |      | _        nt        | d
| j                         d| j                  z
  | _        t        j"                  | j                   d      | _        t        j&                  | j$                        | _        t        j&                  d| j$                  z
        | _        t        j,                  | j(                        t        j,                  | j*                        z
  | _        d| j$                  z
  | j$                  z  dz  | _        d| _        |dvrt        | d
| j                         d | _        t7        j                  d|dz
  |t6        j                        d d d   j9                         }t        j:                  |      | _        d gt?        ||dz
        z  | _         d gt?        ||dz
        z  | _!        |		d | _"        n|	| _"        |dk(  | _#        d| _$        d | _%        d | _&        d | _'        | j0                  jQ                  d      | _        y )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   r2   scaled_linear      ?r   squaredcos_cap_v2z is not implemented for r4   r   dim)r5   noise_predictionc                     | dk\  r| dk  rdS dS )N   i   r   r    r   s    r   <lambda>z,SASolverScheduler.__init__.<locals>.<lambda>   s    18Sa a r   r5   cpu))configrH   r   ImportErrorsumrG   rF   r!   r%   r&   r'   r+   r7   r/   NotImplementedError	__class__alphascumprodalphas_cumprodsqrtalpha_tsigma_tloglambda_tsigmasinit_noise_sigmanum_inference_stepsnpcopy
from_numpy	timestepsmaxtimestep_listmodel_outputsr@   
predict_x0lower_order_numslast_sample_step_index_begin_indexto)selfr8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   ro   s                            r   __init__zSASolverScheduler.__init__   s   6 ;;&&/A/CZ[[++T[[-O-OQUQ\Q\QnQnopstt A  $m5==IDJh&
H>QY^YfYfgDJo- OcM'--	  J 11,-@ADJ%7OPTP^P^O_&`aaDJJ&#mmDKKQ?zz$"5"56zz!d&9&9"9:		$,,/%))DLL2IID///43F3FF3N !$!HH%(88PQUQ_Q_P`&abb $( KK#6#:<OWYWaWabcgegcghmmo	)))4"Vc/?Q;N&OO"Vc/?Q;N&OOGDM$DM(,== ! kknnU+r   c                     | j                   S )zg
        The index counter for current timestep. It will increase 1 after each scheduler step.
        )rv   ry   s    r   
step_indexzSASolverScheduler.step_index   s    
 r   c                     | j                   S )zq
        The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
        rw   r|   s    r   begin_indexzSASolverScheduler.begin_index   s    
    r   r   c                     || _         y)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   )ry   r   s     r   set_begin_indexz!SASolverScheduler.set_begin_index   s     (r   rk   devicec           	      ~   t        j                  t        j                  | j                  dg      | j                  j
                        }| j                  j                  |z
  j                         j                         }| j                  j                  dk(  rat        j                  d|dz
  |dz         j                         ddd   dd j                         j                  t        j                        }nD| j                  j                  dk(  r||dz   z  }t        j                   d|dz         |z  j                         ddd   dd j                         j                  t        j                        }|| j                  j"                  z  }n| j                  j                  dk(  rp| j                  j                  |z  }t        j                   |d|       j                         j                         j                  t        j                        }|dz  }n"t%        | j                  j                   d      t        j&                  d| j(                  z
  | j(                  z  d	z        }t        j*                  |      }| j                  j,                  rt        j                  |      j                         }| j/                  ||
      }t        j&                  |D 	cg c]  }	| j1                  |	|       c}	      j                         }t        j2                  ||dd g      j                  t        j4                        }n| j                  j6                  rt        j                  |      j                         }| j9                  ||
      }t        j&                  |D 	cg c]  }	| j1                  |	|       c}	      }t        j2                  ||dd g      j                  t        j4                        }nN| j                  j:                  rt        j                  |      j                         }| j=                  ||
      }t        j&                  |D 	cg c]  }	| j1                  |	|       c}	      }t        j2                  ||dd g      j                  t        j4                        }n| j                  j>                  rt        j                  dd| j                  j                  z  |dz         }
d|
z
  }t        j                  | j                  j@                  |z  d| j                  j@                  dz
  |z  z   z        dd j                         }|| j                  j                  z  j                         }t        j2                  ||dd g      j                  t        j4                        }nt        jB                  |t        j                   dtE        |            |      }d| j(                  d   z
  | j(                  d   z  d	z  }t        j2                  ||gg      j                  t        j4                        }t        jF                  |      | _$        t        jF                  |      jK                  |t         j                        | _&        tE        |      | _'        dgtQ        | j                  jR                  | j                  jT                  dz
        z  | _+        d| _,        d| _-        d| _.        d| _/        | jH                  jK                  d      | _$        yc c}	w c c}	w c c}	w )a  
        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   r7   r   NrV   leadingtrailingzY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.rQ   )	in_sigmasrk   r4   )r   r    r[   )0r%   searchsortedfliprh   r\   rK   r8   numpyitemrM   rl   r7   roundrm   astypeint64arangerN   r!   arrayrc   rg   rF   _convert_to_karras_sigma_to_tconcatenater'   rG   _convert_to_exponentialrH   _convert_to_betarI   rJ   interplenrn   ri   rx   ro   rk   rp   r=   r>   rr   rt   ru   rv   rw   )ry   rk   r   clipped_idxlast_timestepro   
step_ratiori   
log_sigmassigmara   
sigma_lasts               r   set_timestepszSASolverScheduler.set_timesteps  s    ((DMMA3)GIgIgh++99KGNNPVVX ;;'':5A}q02E2IJPPRSWUWSWXY\Z\]bbdkklnltltu  [[))Y6&+>+BCJ 1&9A&=>KRRTUYWYUYZ[^\^_ddfmmnpnvnvwI111I[[))Z788;NNJ 		-ZK@FFHMMOVVWYW_W_`INI;;//0  1J  K  A 3 33t7J7JJsRSVVF^
;;((WWV_))+F,,vSf,gFSY!Z%$"2"25*"E!Z[aacI^^VVBC[$9:AA"**MF[[//WWV_))+F11FXk1lFSY!Z%$"2"25*"E!Z[I^^VVBC[$9:AA"**MF[[((WWV_))+F**VQd*eFSY!Z%$"2"25*"E!Z[I^^VVBC[$9:AA"**MF[[(([[A(G(G$GI\_`I`aF6\FWWT[[33f<T[[E[E[^_E_ciDi@ijklomopuuwF$++"A"AAGGII^^VVBC[$9:AA"**MFYYy"))As6{*CVLFt221559L9LQ9OOTWWJ^^Vj\$:;BB2::NF&&v.)))477vU[[7Y#&y> 
++T[[-H-H1-LMN !"   kknnU+I "[
 "[
 "[s   #\0)\5!\:samplereturnc                 b   |j                   }|j                  ^}}}|t        j                  t        j                  fvr|j                         }|j                  ||t        j                  |      z        }|j                         }t        j                  || j                  j                  d      }t        j                  |d| j                  j                        }|j                  d      }t        j                  || |      |z  } |j                  ||g| }|j!                  |      }|S )a{  
        "Dynamic thresholding: At each sampling step we set s to a certain percentile absolute pixel value in xt0 (the
        prediction of x_0 at timestep t), and if s > 1, then we threshold xt0 to the range [-s, s] and then divide by
        s. Dynamic thresholding pushes saturated pixels (those near -1 and 1) inwards, thereby actively preventing
        pixels from saturation at each step. We find that dynamic thresholding results in significantly better
        photorealism as well as better image-text alignment, especially when using very large guidance weights."

        https://huggingface.co/papers/2205.11487
        r   rS   )r$   rp   )r    shaper%   r'   float64floatreshaperl   prodabsquantiler\   rB   clamprC   	unsqueezerx   )ry   r   r    
batch_sizechannelsremaining_dims
abs_sampless           r   _threshold_samplez#SASolverScheduler._threshold_sampleW  s     06-
H~66\\^F 
Hrww~7N,NOZZ\
NN:t{{'M'MSTUKK1$++66
 KKNVaR+a/
HF~F5!r   c                    t        j                  t        j                  |d            }||d d t         j                  f   z
  }t        j                  |dk\  d      j                  d      j                  |j                  d   dz
        }|dz   }||   }||   }||z
  ||z
  z  }	t        j                  |	dd      }	d|	z
  |z  |	|z  z   }
|
j                  |j                        }
|
S )Ng|=r   )axisr   )rp   r   )	rl   rg   maximumnewaxiscumsumargmaxclipr   r   )ry   r   r   	log_sigmadistslow_idxhigh_idxlowhighwr   s              r   r   zSASolverScheduler._sigma_to_ty  s    FF2::eU34	 Jq"**}55 ))UaZq188a8@EE*JZJZ[\J]`aJaEbQ;!(# 9_t,GGAq! UgH,IIekk"r   c                 r    | j                   j                  rd|z
  }|}||fS d|dz  dz   dz  z  }||z  }||fS )Nr   r   rQ   )r\   rI   )ry   r   re   rf   s       r   _sigma_to_alpha_sigma_tz)SASolverScheduler._sigma_to_alpha_sigma_t  sW    ;;&&%iGG
  E1HqLS01GgoGr   r   c                    t        | j                  d      r| j                  j                  }nd}t        | j                  d      r| j                  j                  }nd}||n|d   j	                         }||n|d   j	                         }d}t        j                  dd|      }|d|z  z  }|d|z  z  }||||z
  z  z   |z  }	|	S )z6Constructs the noise schedule of Karras et al. (2022).	sigma_minN	sigma_maxrV   r   g      @r   )hasattrr\   r   r   r   rl   r7   )
ry   r   rk   r   r   rhorampmin_inv_rhomax_inv_rhori   s
             r   r   z$SASolverScheduler._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,k(A BBsJr   c                    t        | j                  d      r| j                  j                  }nd}t        | j                  d      r| j                  j                  }nd}||n|d   j	                         }||n|d   j	                         }t        j                  t        j                  t        j                  |      t        j                  |      |            }|S )z)Constructs an exponential noise schedule.r   Nr   rV   r   )
r   r\   r   r   r   rl   r   r7   r   rg   )ry   r   rk   r   r   ri   s         r   r   z)SASolverScheduler._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           
      (   t        | j                  d      r| j                  j                  }nd}t        | j                  d      r| j                  j                  }nd}||n|d   j	                         }||n|d   j	                         }t        j                  dt        j                  dd|      z
  D cg c]-  }t        j                  j                  j                  |||      / c}D cg c]  }||||z
  z  z    c}      }	|	S c c}w c c}w )zJFrom "Beta Sampling is All You Need" [arXiv:2407.12173] (Lee et. al, 2024)r   Nr   rV   r   r   )r   r\   r   r   r   rl   r   r7   scipystatsr   ppf)
ry   r   rk   r   r   r   r   timestepr   ri   s
             r   r   z"SASolverScheduler._convert_to_beta  s     4;;,--II4;;,--II!*!6IIbM<N<N<P	!*!6IIaL<M<M<O	
 %&Aq:M(N$N  KK$$((5$? SI	$9:;
 s   82D
/Dr   model_outputc                   t        |      dkD  r|d   n|j                  dd      }|t        |      dkD  r|d   }nt        d      |t        ddd       | j                  | j
                     }| j                  |      \  }}| j                  j                  d	v r| j                  j                  d
k(  r/| j                  j                  dv r|ddddf   }|||z  z
  |z  }	n| j                  j                  dk(  r|}	n| j                  j                  dk(  r||z  ||z  z
  }	n^| j                  j                  dk(  r"| j                  | j
                     }|||z  z
  }	n#t        d| j                  j                   d      | j                  j                  r| j                  |	      }	|	S | j                  j                  dv r
| j                  j                  d
k(  r'| j                  j                  dv r|ddddf   }
np|}
nm| j                  j                  dk(  r|||z  z
  |z  }
nH| j                  j                  dk(  r||z  ||z  z   }
n#t        d| j                  j                   d      | j                  j                  rE| j                  |   | j                  |   }}|||
z  z
  |z  }	| j                  |	      }	|||	z  z
  |z  }
|
S y)aO  
        Convert the model output to the corresponding type the data_prediction/noise_prediction algorithm needs.
        Noise_prediction is designed to discretize an integral of the noise prediction model, and data_prediction is
        designed to discretize an integral of the data prediction model.

        <Tip>

        The algorithm and model type are decoupled. You can use either data_prediction or noise_prediction for both
        noise prediction and data prediction models.

        </Tip>

        Args:
            model_output (`torch.Tensor`):
                The direct output from the learned diffusion model.
            sample (`torch.Tensor`):
                A current instance of a sample created by the diffusion process.

        Returns:
            `torch.Tensor`:
                The converted model output.
        r   r   Nr   /missing `sample` as a required keyword argumentro   1.0.0zPassing `timesteps` is deprecated and has no effect as model output conversion is now handled via an internal counter `self.step_index`)r5   r3   )learnedlearned_range   r   v_predictionflow_predictionzprediction_type given as zd must be one of `epsilon`, `sample`, `v_prediction`, or `flow_prediction` for the SASolverScheduler.)rU   zQ must be one of `epsilon`, `sample`, or `v_prediction` for the SASolverScheduler.)r   popr!   r   ri   r}   r   r\   rD   r?   rL   rA   r   re   rf   )ry   r   r   argskwargsr   r   re   rf   x0_predr3   s              r   convert_model_outputz&SASolverScheduler.convert_model_output  s   : "$i!m47J1M>4y1}a !RSS Z DOO,77>;;%%)<<{{**i7;;,,0LL#/2A2#6L!Gl$::gE,,8&,,>!F*W|-CC,,0AA++doo6 7\#99 /0K0K/L MV V 
 {{''009N [[''+??{{**i7;;,,0LL*1bqb51G*G,,8!Gl$::gE,,>!L07V3CC /0K0K/L MA A 
 {{''#'<<#94<<;Q!Gg$55@009!Gg$55@N/ @r   c                 t   |dv sJ d       |dk(  r2t        j                  |       t        j                  ||z
        dz
  z  S |dk(  r;t        j                  |       |dz   t        j                  ||z
        z  |dz   z
  z  S |dk(  rMt        j                  |       |dz  d|z  z   dz   t        j                  ||z
        z  |dz  d|z  z   dz   z
  z  S |dk(  r_t        j                  |       |dz  d|dz  z  z   d|z  z   dz   t        j                  ||z
        z  |dz  d|dz  z  z   d|z  z   dz   z
  z  S y)	zd
        Calculate the integral of exp(-x) * x^order dx from interval_start to interval_end
        r   r   r   r   )order is only supported for 0, 1, 2 and 3r   r   r   r      Nr%   r   )ry   orderinterval_startinterval_ends       r   %get_coefficients_exponential_negativez7SASolverScheduler.get_coefficients_exponential_negativeJ  s    $Q&QQ$A:99l]+uyy9V/WZ[/[\\aZ99l]+!#uyy1N'OOS_bcScd  aZ99l]+"Q%77!;uyyXfIf?gg?Q%559;  aZ99l]+"Q):%::Q=OORSS))L>9:;?Qq%881|;KKaOQ  r   c                    |dv sJ d       d|dz  z   |z  }d|dz  z   |z  }|dk(  r;t        j                  |      dt        j                  ||z
         z
  z  d|dz  z   z  S |dk(  rGt        j                  |      |dz
  |dz
  t        j                  ||z
         z  z
  z  d|dz  z   dz  z  S |dk(  rYt        j                  |      |dz  d|z  z
  dz   |dz  d|z  z
  dz   t        j                  ||z
         z  z
  z  d|dz  z   dz  z  S |dk(  rkt        j                  |      |dz  d|dz  z  z
  d|z  z   dz
  |dz  d|dz  z  z
  d|z  z   dz
  t        j                  ||z
         z  z
  z  d|dz  z   dz  z  S y	)
zl
        Calculate the integral of exp(x(1+tau^2)) * x^order dx from interval_start to interval_end
        r   r   r   r   r   r   r      Nr   )ry   r   r   r   tauinterval_end_covinterval_start_covs          r   %get_coefficients_exponential_positivez7SASolverScheduler.get_coefficients_exponential_positiveb  s&    $Q&QQ$ QJ,6#q&jN:A:		*+q599?ORd?d=e3f/fgklortuoukuv aZ		*+%))A-=MPb=b;c1dde
 QJ1$& aZ		*+%q(1/?+??!C)1,q3E/EEIii"25G"G HIJJ QJ1$& aZ		*+%q(1/?/B+BBQIYEYY\]])1,q3Eq3H/HH1OaKaadeeii"25G"G HIJJ QJ1$& r   c           	         |dv sJ |t        |      dz
  k(  sJ |dk(  rdggS |dk(  r@d|d   |d   z
  z  |d    |d   |d   z
  z  gd|d   |d   z
  z  |d    |d   |d   z
  z  ggS |dk(  r|d   |d   z
  |d   |d   z
  z  }|d   |d   z
  |d   |d   z
  z  }|d   |d   z
  |d   |d   z
  z  }d|z  |d    |d   z
  |z  |d   |d   z  |z  gd|z  |d    |d   z
  |z  |d   |d   z  |z  gd|z  |d    |d   z
  |z  |d   |d   z  |z  ggS |dk(  r|d   |d   z
  |d   |d   z
  z  |d   |d   z
  z  }|d   |d   z
  |d   |d   z
  z  |d   |d   z
  z  }|d   |d   z
  |d   |d   z
  z  |d   |d   z
  z  }|d   |d   z
  |d   |d   z
  z  |d   |d   z
  z  }d|z  |d    |d   z
  |d   z
  |z  |d   |d   z  |d   |d   z  z   |d   |d   z  z   |z  |d    |d   z  |d   z  |z  gd|z  |d    |d   z
  |d   z
  |z  |d   |d   z  |d   |d   z  z   |d   |d   z  z   |z  |d    |d   z  |d   z  |z  gd|z  |d    |d   z
  |d   z
  |z  |d   |d   z  |d   |d   z  z   |d   |d   z  z   |z  |d    |d   z  |d   z  |z  gd|z  |d    |d   z
  |d   z
  |z  |d   |d   z  |d   |d   z  z   |d   |d   z  z   |z  |d    |d   z  |d   z  |z  ggS y)zB
        Calculate the coefficient of lagrange polynomial
        r   r   r   r   r   N)r   )ry   r   lambda_listdenominator1denominator2denominator3denominator4s          r   lagrange_polynomial_coefficientz1SASolverScheduler.lagrange_polynomial_coefficient  sa   
 $$$K(1,,,,A:C5LaZ Q+a.89 ^O{1~A'FG
 Q+a.89 ^O{1~A'FG	 	 aZ'N[^;AQ\]^Q_@_`L'N[^;AQ\]^Q_@_`L'N[^;AQ\]^Q_@_`L $!!n_{1~5EN[^3lB $!!n_{1~5EN[^3lB $!!n_{1~5EN[^3lB " aZQ+a.0q>KN24q>KN24  Q+a.0q>KN24q>KN24  Q+a.0q>KN24q>KN24  Q+a.0q>KN24q>KN24  $!!n_{1~5AF,V#AQ7%a.;q>9:%a.;q>9: ## "!n_{1~5AF,V
 $!!n_{1~5AF,V#AQ7%a.;q>9:%a.;q>9: ## "!n_{1~5AF,V
 $!!n_{1~5AF,V#AQ7%a.;q>9:%a.;q>9: ## "!n_{1~5AF,V
 $!!n_{1~5AF,V#AQ7%a.;q>9:%a.;q>9: ## "!n_{1~5AF,V
E- -+ r   c           
         |dv sJ |t        |      k(  sJ d       g }| j                  |dz
  |      }t        |      D ]}  }d}	t        |      D ]Z  }
| j                  r'|	||   |
   | j	                  |dz
  |
z
  |||      z  z  }	6|	||   |
   | j                  |dz
  |
z
  ||      z  z  }	\ |j                  |	        t        |      |k(  sJ d       |S )N)r   r   r   r   z4the length of lambda list must be equal to the orderr   r   z3the length of coefficients does not match the order)r   r   r"   rs   r   r   r#   )ry   r   r   r   r   r   coefficientslagrange_coefficientr,   coefficientjs              r   get_coefficients_fnz%SASolverScheduler.get_coefficients_fn  s   $$$K((`*``(#CCEAI{[u 	-AK5\ ??#7#:1#=@j@j	A~|SA $ K  #7#:1#=@j@j	A~|A $ K ,	- < E)`+``)r   noiser   r   c                	   t        |      dkD  r|d   n|j                  dd      }|t        |      dkD  r|d   }nt        d      |t        |      dkD  r|d   }nt        d      |t        |      dkD  r|d   }nt        d	      |t        |      d
kD  r|d
   }nt        d      |t        ddd       | j                  }	| j
                  | j                  dz      | j
                  | j                     }}
| j                  |
      \  }}
| j                  |      \  }}t        j                  |      t        j                  |
      z
  }t        j                  |      t        j                  |      z
  }t        j                  |      }||z
  }g }t        |      D ]n  }| j                  |z
  }| j                  | j
                  |         \  }}t        j                  |      t        j                  |      z
  }|j                  |       p | j                  |||||      }|}| j                  rM|dk(  rG| j
                  | j                  dz
     }| j                  |      \  }}t        j                  |      t        j                  |      z
  }|dxx   dt        j                  d|dz  z   |z        z  |dz  dz  |d|dz  z   z  dz
  t        j                  d|dz  z   | z        z   d|dz  z   dz  z  z
  z  ||z
  z  z  cc<   |dxx   dt        j                  d|dz  z   |z        z  |dz  dz  |d|dz  z   z  dz
  t        j                  d|dz  z   | z        z   d|dz  z   dz  z  z
  z  ||z
  z  z  cc<   t        |      D ]i  }| j                  r<|d|dz  z   |
z  t        j                  |dz   |z        z  ||   z  |	|dz       z  z  }K|d|dz  z    |z  ||   z  |	|dz       z  z  }k | j                  r;|
t        j                   dt        j                  d|dz  z  |z        z
        z  |z  }n7||
z  t        j                   t        j                  d|z        dz
        z  |z  }| j                  r,t        j                  |dz   |z        |
|z  z  |z  |z   |z   }n||z  |z  |z   |z   }|j#                  |j$                        }|S )ag  
        One step for the SA-Predictor.

        Args:
            model_output (`torch.Tensor`):
                The direct output from the learned diffusion model at the current timestep.
            prev_timestep (`int`):
                The previous discrete timestep in the diffusion chain.
            sample (`torch.Tensor`):
                A current instance of a sample created by the diffusion process.
            order (`int`):
                The order of SA-Predictor at this timestep.

        Returns:
            `torch.Tensor`:
                The sample tensor at the previous timestep.
        r   prev_timestepNr   r   r   z.missing `noise` as a required keyword argumentr   .missing `order` as a required keyword argumentr   ,missing `tau` as a required keyword argumentr   zPassing `prev_timestep` is deprecated and has no effect as model output conversion is now handled via an internal counter `self.step_index`r4   r   r   r!   r   rr   ri   r}   r   r%   rg   
zeros_liker"   r#   r   rs   r   rd   rx   r    ) ry   r   r   r   r   r   r   r   r   model_output_listrf   sigma_s0re   alpha_s0rh   	lambda_s0gradient_parthr   r,   sialpha_sisigma_si	lambda_sigradient_coefficientsx
temp_sigmatemp_alpha_stemp_sigma_stemp_lambda_s
noise_partx_ts                                    r   !stochastic_adams_bashforth_updatez3SASolverScheduler.stochastic_adams_bashforth_update  s;   6 $'t9q=QfjjRV6W>4y1}a !RSS=4y1}Q !QRR=4y1}Q !QRR;4y1}1g !OPP$ ^
 !..KK!+,KK(   77@!99(C(99W%		'(::IIh'%))H*==	((0y u 	*A1$B!%!=!=dkk"o!NHh		(+eii.AAIy)		* !% 8 8	8U`be f??
 "[[1)<=
-1-I-I*-U*l %		, 7%))L:Q Q%a(iiS!Vx 789!tax1CF
#3a#7%))QaZUVTVDW:X#X^_beghbh^hmn]n"ooq !=02( &a(iiS!Vx 789!tax1CF
#3a#7%))QaZUVTVDW:X#X^_beghbh^hmn]n"ooq !=02( u 
	rAaZii#q&	H 456 ,A./ (!a%1	2 1sAv:!8;PQR;S!SVgjknojohpVq!qq
	r ?? 5::a%))BaK!O2L.L#MMPUUJwEIIa!e4Dq4H)IIEQJ??))c1fIM*g.@AAEUXbbCX%*]:ZGCffQWWo
r   this_model_outputru   
last_noisethis_samplec                .	   t        |      dkD  r|d   n|j                  dd      }	|t        |      dkD  r|d   }nt        d      |t        |      dkD  r|d   }nt        d      |t        |      dkD  r|d   }nt        d	      |t        |      d
kD  r|d
   }nt        d      |t        |      dkD  r|d   }nt        d      |	t        ddd       | j                  }
| j
                  | j                     | j
                  | j                  dz
     }}| j                  |      \  }}| j                  |      \  }}t        j                  |      t        j                  |      z
  }t        j                  |      t        j                  |      z
  }t        j                  |      }||z
  }g }t        |      D ]n  }| j                  |z
  }| j                  | j
                  |         \  }}t        j                  |      t        j                  |      z
  }|j                  |       p |
|gz   }| j                  |||||      }|}| j                  r|dk(  r|dxx   dt        j                  d|dz  z   |z        z  |dz  |d|dz  z   z  dz
  t        j                  d|dz  z   | z        z   d|dz  z   dz  |z  z  z
  z  z  cc<   |dxx   dt        j                  d|dz  z   |z        z  |dz  |d|dz  z   z  dz
  t        j                  d|dz  z   | z        z   d|dz  z   dz  |z  z  z
  z  z  cc<   t        |      D ]i  }| j                  r<|d|dz  z   |z  t        j                  |dz   |z        z  ||   z  ||dz       z  z  }K|d|dz  z    |z  ||   z  ||dz       z  z  }k | j                  r;|t        j                   dt        j                  d|dz  z  |z        z
        z  |z  }n7||z  t        j                   t        j                  d|z        dz
        z  |z  }| j                  r,t        j                  |dz   |z        ||z  z  |z  |z   |z   }n||z  |z  |z   |z   }|j#                  |j$                        }|S )a  
        One step for the SA-Corrector.

        Args:
            this_model_output (`torch.Tensor`):
                The model outputs at `x_t`.
            this_timestep (`int`):
                The current timestep `t`.
            last_sample (`torch.Tensor`):
                The generated sample before the last predictor `x_{t-1}`.
            this_sample (`torch.Tensor`):
                The generated sample after the last predictor `x_{t}`.
            order (`int`):
                The order of SA-Corrector at this step.

        Returns:
            `torch.Tensor`:
                The corrected sample tensor at the current timestep.
        r   this_timestepNr   z4missing `last_sample` as a required keyword argumentr   z3missing `last_noise` as a required keyword argumentr   z4missing `this_sample` as a required keyword argumentr   r      r   r   zPassing `this_timestep` is deprecated and has no effect as model output conversion is now handled via an internal counter `self.step_index`r4   r  r  )ry   r  ru   r  r  r   r   r   r   r  r  rf   r  re   r  rh   r  r  r	  r   r,   r
  r  r  r  model_prev_listr  r  r  r  s                                 r   stochastic_adams_moulton_updatez1SASolverScheduler.stochastic_adams_moulton_update  s   > $'t9q=QfjjRV6W4y1}"1g !WXX4y1}!!W
 !VWW4y1}"1g !WXX=4y1}Q !QRR;4y1}1g !OPP$ ^ !..KK(KK!+,   77@!99(C(99W%		'(::IIh'%))H*==	((5y u 	*A1$B!%!=!=dkk"o!NHh		(+eii.AAIy)		* ,/@.AA $ 8 8	8U`be f??
 &a(iiS!Vx 7891uQaZ 01 4uyy!c1f*RSQSAT7U U[\_bde_e[ejkZknoZoppr(
 &a(iiS!Vx 7891uQaZ 01 4uyy!c1f*RSQSAT7U U[\_bde_e[ejkZknoZoppr( u 
	pAaZii#q&	H 456 ,A./ &Ah/	0 1sAv:!8;PQR;S!SVehilmhmfnVo!oo
	p ?? 5::a%))BaK!O2L.L#MMPZZJwEIIa!e4Dq4H)IIJVJ??))c1fIM*g.@AAEUXbbCX%*]:ZGCffQWWo
r   c                    || j                   }||k(  j                         }t        |      dk(  rt        | j                         dz
  }|S t        |      dkD  r|d   j                         }|S |d   j                         }|S )Nr   r   )ro   nonzeror   r   )ry   r   schedule_timestepsindex_candidatesr}   s        r   index_for_timestepz$SASolverScheduler.index_for_timestep  s    %!%.(:CCE A%T^^,q0J  !"Q&)!,113J  *!,113Jr   c                     | j                   Vt        |t        j                        r%|j	                  | j
                  j                        }| j                  |      | _        y| j                  | _        y)zF
        Initialize the step_index counter for the scheduler.
        N)
r   
isinstancer%   Tensorrx   ro   r   r#  rv   rw   )ry   r   s     r   _init_step_indexz"SASolverScheduler._init_step_index(  sW    
 #(ELL1#;;t~~'<'<=#66x@D#00Dr   r   return_dictc                    | j                   t        d      | j                  | j                  |       | j                  dkD  xr | j                  du}| j                  ||      }|rS| j                  | j                  d         }| j                  || j                  | j                  || j                  |      }t        t        | j                  j                  | j                  j                  dz
        dz
        D ]@  }	| j                   |	dz      | j                   |	<   | j                  |	dz      | j                  |	<   B || j                   d<   || j                  d<   t#        |j$                  ||j&                  |j(                        }
| j                  j*                  rt-        | j                  j                  t/        | j0                        | j                  z
        }t-        | j                  j                  t/        | j0                        | j                  z
  dz         }n,| j                  j                  }| j                  j                  }t-        || j2                  dz         | _        t-        || j2                  d	z         | _
        | j4                  dkD  sJ | j                  dkD  sJ || _        |
| _	        | j                  | j                  d         }| j7                  |||
| j4                  |
      }| j2                  t        | j                  j                  | j                  j                  dz
        k  r| xj2                  dz  c_        | xj8                  dz  c_        |s|fS t;        |      S )a  
        Predict the sample from the previous timestep by reversing the SDE. This function propagates the sample with
        the SA-Solver.

        Args:
            model_output (`torch.Tensor`):
                The direct output from learned diffusion model.
            timestep (`int`):
                The current discrete timestep in the diffusion chain.
            sample (`torch.Tensor`):
                A current instance of a sample created by the diffusion process.
            generator (`torch.Generator`, *optional*):
                A random number generator.
            return_dict (`bool`):
                Whether or not to return a [`~schedulers.scheduling_utils.SchedulerOutput`] or `tuple`.

        Returns:
            [`~schedulers.scheduling_utils.SchedulerOutput`] or `tuple`:
                If return_dict is `True`, [`~schedulers.scheduling_utils.SchedulerOutput`] is returned, otherwise a
                tuple is returned where the first element is the sample tensor.

        NzaNumber of inference steps is 'None', you need to run 'set_timesteps' after creating the schedulerr   r   rV   )r  ru   r  r  r   r   r   )	generatorr   r    r   )r   r   r   r   r   )prev_sample)rk   r!   r}   r'  ru   r   r@   rq   r  r  this_corrector_orderr"   rp   r\   r=   r>   rr   r   r   r   r    rE   r$   r   ro   rt   this_predictor_orderr  rv   r   )ry   r   r   r   r*  r(  use_correctormodel_output_convertcurrent_taur,   r   r-  r,  r+  s                 r   stepzSASolverScheduler.step4  s0   < ##+s  ??"!!(+!+L0@0@0L#88f8U--(:(:2(>?K99"6 ,,??"// : F s4;;668S8SVW8WX[\\] 	>A$($6$6q1u$=Dq!$($6$6q1u$=Dq!	> "62!)2&&$$	
 ;;((#&t{{'B'BCDWZ^ZiZiDi#j #&t{{'B'BCDWZ^ZiZiDilmDm#n #';;#>#> #';;#>#> $'(<d>S>SVW>W$X!$'(<d>S>SVW>W$X!((1,,,((1,,,!mmD$6$6r$:;<<-++ = 
   3t{{'B'BDKKD_D_bcDc#dd!!Q&! 	A>!;77r   c                     |S )a?  
        Ensures interchangeability with schedulers that need to scale the denoising model input depending on the
        current timestep.

        Args:
            sample (`torch.Tensor`):
                The input sample.

        Returns:
            `torch.Tensor`:
                A scaled input sample.
        rY   )ry   r   r   r   s       r   scale_model_inputz#SASolverScheduler.scale_model_input  s	     r   original_samplesro   c                    | j                   j                  |j                        | _         | j                   j                  |j                        }|j                  |j                        }||   dz  }|j	                         }t        |j                        t        |j                        k  r=|j                  d      }t        |j                        t        |j                        k  r=d||   z
  dz  }|j	                         }t        |j                        t        |j                        k  r=|j                  d      }t        |j                        t        |j                        k  r=||z  ||z  z   }|S )N)r   r   rQ   rV   r   )rc   rx   r   r    flattenr   r   r   )ry   r4  r   ro   rc   sqrt_alpha_prodsqrt_one_minus_alpha_prodnoisy_sampless           r   	add_noisezSASolverScheduler.add_noise  sa    #1144<L<S<S4T,,//6F6L6L/MLL!1!8!89	(3s:)113/''(3/?/E/E+FF-77;O /''(3/?/E/E+FF &'	)B%Bs$J!$=$E$E$G!+112S9I9O9O5PP(A(K(KB(O% +112S9I9O9O5PP (*::=VY^=^^r   c                 .    | j                   j                  S N)r\   r8   r|   s    r   __len__zSASolverScheduler.__len__  s    {{...r   )r   )NN)333333?r>  r<  )NT)2__name__
__module____qualname____doc__r   name_compatiblesr   r
   r   intstrr   r   rl   ndarrayr   r   boolrz   propertyr}   r   r   r%   r   r   r&  r   r   r   r   r   r   r   r   r   r   r   r  r  r#  r'  r   r   r1  r3  	IntTensorr:  r=  ).0es   00r   r1   r1   O   s   AF %>>qAFF>LE $("%BF  ('+",1"%/"&,116*/*/&)%*5\M'+ *1S, S, S, 	S,
 S,  bjj$u+&= >?S, S, S, S, 8$S, S, %*S,  S, S,  S,  $D>!S," !)#S,$ "$%S,& "$'S,( UO)S,* "+S,,  }-S,. /S,0 1S, S,j     ! !(3 (O, O,U3PUP\P\K\E] O,d  D0 ELL RWR^R^ 4 TW \a\h\h . dg<?HM[`	F  $	]ll] 	] 
]~0*XkZ(}ll} 	}
 ||} } \\} 
}~C <<C \\	C
 LLC \\C C \\C 
CL(
1"  d8lld8 d8 	d8 d8 
%	&d8L %,,  ,, || ??	
 
4/c! ?s   J r1   )g+?r   )r   typingr   r   r   r   r   r   rl   r%   configuration_utilsr	   r
   utilsr   r   utils.torch_utilsr   scheduling_utilsr   r   r   scipy.statsr   r/   r1   rY   r   r   <module>rS     sN   $  9 9   A 1 , X X  !)4Xv/ v/r   