
    i              	           d dl Z d dlmZ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	ed
eded   de
j6                  fdZ G d dee      Zy)    N)CallableListLiteralOptionalTupleUnion   )ConfigMixinregister_to_config)	deprecateis_scipy_available)randn_tensor   )KarrasDiffusionSchedulersSchedulerMixinSchedulerOutputnum_diffusion_timestepsmax_betaalpha_transform_type)cosineexpreturnc           
      $   |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 )aB  
    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`, defaults to `0.999`):
            The maximum beta to use; use values lower than 1 to avoid numerical instability.
        alpha_transform_type (`"cosine"` or `"exp"`, defaults to `"cosine"`):
            The type of noise schedule for `alpha_bar`. Choose from `cosine` or `exp`.

    Returns:
        `torch.Tensor`:
            The betas used by the scheduler to step the model outputs.
    r   c                 f    t        j                  | dz   dz  t         j                  z  dz        dz  S )NgMb?gT㥛 ?r	   )mathcospits    r/home/obispo/Crisostomo_bridge/mision_env/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    r   c                 2    t        j                  | dz        S )Ng      ()r   r   r   s    r    r!   z)betas_for_alpha_bar.<locals>.alpha_bar_fnB   s    88AI&&r"   z"Unsupported alpha_transform_type: r   dtype)
ValueErrorrangeappendmintorchtensorfloat32)r   r   r   r!   betasit1t2s           r    betas_for_alpha_barr1   #   s    0 x'	D 
	&	' =>R=STUUE*+ M((!e..S\"-R0@@@(KLM <<U]]33r"   c            0          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dWd,e
fd-ZdXd.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 	 dYd6e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(	 dZdLee
ej6                  f   dMeej6                     d2e
fdNZ)dO Z*	 	 d[d=ej6                  dLe
d1ej6                  dPed2ee+e,f   f
dQZ-d1ej6                  d2ej6                  fdRZ.dSej6                  dCej6                  dTej^                  d2ej6                  fdUZ0dV 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://huggingface.co/papers/2210.02303) 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$   r4   scaled_linear      ?r	   squaredcos_cap_v2z is not implemented for r6   r   dim)r7   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"   r7   cpu))configrJ   r   ImportErrorsumrI   rH   r&   r*   r+   r,   r-   r9   r1   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_outputsrB   
predict_x0lower_order_numslast_sample_step_index_begin_indexto)selfr:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rq   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.
        )rx   r{   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.
        ry   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`, defaults to `0`):
                The begin index for the scheduler.
        Nr   )r{   r   s     r    set_begin_indexz!SASolverScheduler.set_begin_index   s     (r"   rm   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   r9   r   NrX   leadingtrailingzY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.rS   )	in_sigmasrm   r6   )r   r%   r]   )0r*   searchsortedfliprj   r^   rM   r:   numpyitemrO   rn   r9   roundro   astypeint64arangerP   r&   arrayre   ri   rH   _convert_to_karras_sigma_to_tconcatenater,   rI   _convert_to_exponentialrJ   _convert_to_betarK   rL   interplenrp   rk   rz   rq   rm   rr   r?   r@   rt   rv   rw   rx   ry   )r{   rm   r   clipped_idxlast_timesteprq   
step_ratiork   
log_sigmassigmarc   
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!\:sampler   c                 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 )az  
        Apply dynamic thresholding to the predicted sample.

        "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

        Args:
            sample (`torch.Tensor`):
                The predicted sample to be thresholded.

        Returns:
            `torch.Tensor`:
                The thresholded sample.
        r   rU   )r)   rr   )r%   shaper*   r,   float64floatreshapern   prodabsquantiler^   rD   clamprE   	unsqueezerz   )r{   r   r%   
batch_sizechannelsremaining_dims
abs_sampless           r    _threshold_samplez#SASolverScheduler._threshold_sampleX  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 )a  
        Convert sigma values to corresponding timestep values through interpolation.

        Args:
            sigma (`np.ndarray`):
                The sigma value(s) to convert to timestep(s).
            log_sigmas (`np.ndarray`):
                The logarithm of the sigma schedule used for interpolation.

        Returns:
            `np.ndarray`:
                The interpolated timestep value(s) corresponding to the input sigma(s).
        g|=Nr   )axisr	   )rr   r   )	rn   ri   maximumnewaxiscumsumargmaxclipr   r   )r{   r   r   	log_sigmadistslow_idxhigh_idxlowhighwr   s              r    r   zSASolverScheduler._sigma_to_t  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 )a(  
        Convert sigma values to alpha_t and sigma_t values.

        Args:
            sigma (`torch.Tensor`):
                The sigma value(s) to convert.

        Returns:
            `Tuple[torch.Tensor, torch.Tensor]`:
                A tuple containing (alpha_t, sigma_t) values.
        r   r	   rS   )r^   rK   )r{   r   rg   rh   s       r    _sigma_to_alpha_sigma_tz)SASolverScheduler._sigma_to_alpha_sigma_t  sY     ;;&&%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 )a  
        Construct the noise schedule as proposed in [Elucidating the Design Space of Diffusion-Based Generative
        Models](https://huggingface.co/papers/2206.00364).

        Args:
            in_sigmas (`torch.Tensor`):
                The input sigma values to be converted.
            num_inference_steps (`int`):
                The number of inference steps to generate the noise schedule for.

        Returns:
            `torch.Tensor`:
                The converted sigma values following the Karras noise schedule.
        	sigma_minN	sigma_maxrX   r   g      @r   )hasattrr^   r   r   r   rn   r9   )
r{   r   rm   r   r   rhorampmin_inv_rhomax_inv_rhork   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 )a  
        Construct an exponential noise schedule.

        Args:
            in_sigmas (`torch.Tensor`):
                The input sigma values to be converted.
            num_inference_steps (`int`):
                The number of inference steps to generate the noise schedule for.

        Returns:
            `torch.Tensor`:
                The converted sigma values following an exponential schedule.
        r   Nr   rX   r   )
r   r^   r   r   r   rn   r   r9   r   ri   )r{   r   rm   r   r   rk   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 )a  
        Construct a beta noise schedule as proposed in [Beta Sampling is All You
        Need](https://huggingface.co/papers/2407.12173).

        Args:
            in_sigmas (`torch.Tensor`):
                The input sigma values to be converted.
            num_inference_steps (`int`):
                The number of inference steps to generate the noise schedule for.
            alpha (`float`, *optional*, defaults to `0.6`):
                The alpha parameter for the beta distribution.
            beta (`float`, *optional*, defaults to `0.6`):
                The beta parameter for the beta distribution.

        Returns:
            `torch.Tensor`:
                The converted sigma values following a beta distribution schedule.
        r   Nr   rX   r   r   )r   r^   r   r   r   rn   r   r9   scipystatsr   ppf)
r{   r   rm   r   r   r   r   timestepr   rk   s
             r    r   z"SASolverScheduler._convert_to_beta  s    0 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)a=  
        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.

        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 argumentrq   1.0.0zPassing `timesteps` is deprecated and has no effect as model output conversion is now handled via an internal counter `self.step_index`)r7   r5   )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.)rW   zQ must be one of `epsilon`, `sample`, or `v_prediction` for the SASolverScheduler.)r   popr&   r   rk   r   r   r^   rF   rA   rN   rC   r   rg   rh   )r{   r   r   argskwargsr   r   rg   rh   x0_predr5   s              r    convert_model_outputz&SASolverScheduler.convert_model_output8  s   2 "$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   )r{   orderinterval_startinterval_ends       r    %get_coefficients_exponential_negativez7SASolverScheduler.get_coefficients_exponential_negative  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   )r{   r   r   r   tauinterval_end_covinterval_start_covs          r    %get_coefficients_exponential_positivez7SASolverScheduler.get_coefficients_exponential_positive  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   )r{   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'   ru   r   r   r(   )r{   r   r   r   r   r   coefficientslagrange_coefficientr.   coefficientjs              r    get_coefficients_fnz%SASolverScheduler.get_coefficients_fnD  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`r6   r   r   r&   r   rt   rk   r   r   r*   ri   
zeros_liker'   r(   r   ru   r   rf   rz   r%   ) r{   r   r   r   r   r   r   r   r   model_output_listrh   sigma_s0rg   alpha_s0rj   	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_updateX  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_outputrw   
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`r6   r  r  )r{   r  rw   r  r  r   r   r   r   r  r  rh   r  rg   r  rj   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"   r   schedule_timestepsc                    || j                   }||k(  j                         }t        |      dk(  rt        | j                         dz
  }|S t        |      dkD  r|d   j                         }|S |d   j                         }|S )a  
        Find the index for a given timestep in the schedule.

        Args:
            timestep (`int` or `torch.Tensor`):
                The timestep for which to find the index.
            schedule_timesteps (`torch.Tensor`, *optional*):
                The timestep schedule to search in. If `None`, uses `self.timesteps`.

        Returns:
            `int`:
                The index of the timestep in the schedule.
        r   r   )rq   nonzeror   r   )r{   r   r   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)z
        Initialize the step_index counter for the scheduler.

        Args:
            timestep (`int` or `torch.Tensor`):
                The current timestep for which to initialize the step index.
        N)
r   
isinstancer*   Tensorrz   rq   r   r$  rx   ry   )r{   r   s     r    _init_step_indexz"SASolverScheduler._init_step_index  sW     #(ELL1#;;t~~'<'<=#66x@D#00D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   rX   )r  rw   r  r  r   r   r   )	generatorr   r%   r	   )r   r   r   r   r   )prev_sample)rm   r&   r   r(  rw   r   rB   rs   r  r  this_corrector_orderr'   rr   r^   r?   r@   rt   r   r   r   r%   rG   r)   r   rq   rv   this_predictor_orderr  rx   r   )r{   r   r   r   r+  r)  use_correctormodel_output_convertcurrent_taur.   r   r.  r-  r,  s                 r    stepzSASolverScheduler.step  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.
        r[   )r{   r   r   r   s       r    scale_model_inputz#SASolverScheduler.scale_model_input  s	     r"   original_samplesrq   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 )a2  
        Add noise to the original samples according to the noise magnitude at each timestep (this is the forward
        diffusion process).

        Args:
            original_samples (`torch.Tensor`):
                The original samples to which noise will be added.
            noise (`torch.Tensor`):
                The noise to add to the samples.
            timesteps (`torch.IntTensor`):
                The timesteps indicating the noise level for each sample.

        Returns:
            `torch.Tensor`:
                The noisy samples.
        )r   r$   rS   rX   r   )re   rz   r   r%   flattenr   r   r   )r{   r5  r   rq   re   sqrt_alpha_prodsqrt_one_minus_alpha_prodnoisy_sampless           r    	add_noisezSASolverScheduler.add_noise  sa   2 #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^   r:   r~   s    r    __len__zSASolverScheduler.__len__0  s    {{...r"   )r   )NN)333333?r?  r=  )NT)2__name__
__module____qualname____doc__r   name_compatiblesr   r   r   intstrr   r   rn   ndarrayr   r   boolr|   propertyr   r   r   r*   r   r   r'  r   r   r   r   r   r   r   r   r   r   r   r  r  r$  r(  r   r   r2  r4  	IntTensorr;  r>  ).0es   00r    r3   r3   P   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) ) )X"J ,$ELL $RWR^R^ $N TW \a\h\h F dg..<?.HM.[`.	.h  $	YllY 	Y 
Yv0*XkZ(}ll} 	}
 ||} } \\} 
}~C <<C \\	C
 LLC \\C C \\C 
CN `d c5<</0 FNu||F\ 	 F1*  d8lld8 d8 	d8 d8 
%	&d8L %,,  (,,( ||( ??	(
 
(T/y$ ?s   Kr3   )g+?r   )r   typingr   r   r   r   r   r   r   rn   r*   configuration_utilsr
   r   utilsr   r   utils.torch_utilsr   scheduling_utilsr   r   r   scipy.statsr   rF  r   r'  r1   r3   r[   r"   r    <module>rT     s{   $  B B   A 1 , X X  5=*4 *4*4 "/2*4 \\	*4Za/ a/r"   