o
    io                     @   s   d dl Z d dlmZmZ d dlZdejdejdededejf
dd	Zddejdejdejdejdede	dejfddZ
ddejdejdejdejdede	de	dejfddZddedededeeejef gef fddZdS )    N)UnionCallablestsolver_ordertau_treturnc                 C   s   d|d  }||  }t j|| j| jd}|| | | | |    }|d|d }|d  }	|	d|	d }
|dkrJ|
|t|  }
t 	|d dkdd}|
 | 
 }
|
| S )u  Compute (1 + tau^2) * integral of exp((1 + tau^2) * x) * x^p dx from s to t with exp((1 + tau^2) * t) factored out, using integration by parts.

    Integral of exp((1 + tau^2) * x) * x^p dx
        = product_terms[p] - (p / (1 + tau^2)) * integral of exp((1 + tau^2) * x) * x^(p-1) dx,
    with base case p=0 where integral equals product_terms[0].

    where
        product_terms[p] = x^p * exp((1 + tau^2) * x) / (1 + tau^2).

    Construct a recursive coefficient matrix following the above recursive relation to compute all integral terms up to p = (solver_order - 1).
    Return coefficients used by the SA-Solver in data prediction mode.

    Args:
        s: Start time s.
        t: End time t.
        solver_order: Current order of the solver.
        tau_t: Stochastic strength parameter in the SDE.

    Returns:
        Exponential coefficients used in data prediction, with exp((1 + tau^2) * t) factored out, ordered from p=0 to p=solver_order−1, shape (solver_order,).
          )dtypedevicer         ?g      )torcharanger   r   exp	unsqueezelgammamathlogwheretril)r   r   r   r   tau_mulhpproduct_terms_factoredrecursive_depth_matlog_factorialrecursive_coeff_matsigns r   9/mnt/c/Users/fbmor/ComfyUI/comfy/k_diffusion/sa_solver.pycompute_exponential_coeffs
   s   r!   F
sigma_nextcurr_lambdaslambda_slambda_tis_corrector_stepc                 C   s   d|d  }|| }| |   }|r(|d| |  }	|| |    |	 }
n|d| |d   |d |  }
|| |    |
 }	t|
|	gS )z`Compute simple order-2 b coefficients from SA-Solver paper (Appendix D. Implementation Details).r	   r
   g      ?)r   expm1negr   stack)r"   r#   r$   r%   r   r&   r   r   alpha_tb_1b_2r   r   r    (compute_simple_stochastic_adams_b_coeffs5   s    r.   simple_order_2c                 C   sj   |j d }|r|dkrt| |||||S t||||}tj||ddj}	tj|	|}
| |  }||
 S )a  Compute b_i coefficients for the SA-Solver (see eqs. 15 and 18).

    The solver order corresponds to the number of input lambdas (half-logSNR points).

    Args:
        sigma_next: Sigma at end time t.
        curr_lambdas: Lambda time points used to construct the Lagrange basis, shape (N,).
        lambda_s: Lambda at start time s.
        lambda_t: Lambda at end time t.
        tau_t: Stochastic strength parameter in the SDE.
        simple_order_2: Whether to enable the simple order-2 scheme.
        is_corrector_step: Flag for corrector step in simple order-2 mode.

    Returns:
        b_i coefficients for the SA-Solver, shape (N,), where N is the solver order.
    r   r
   T)
increasing)	shaper.   r!   r   vanderTlinalgsolver   )r"   r#   r$   r%   r   r/   r&   num_timestepsexp_integral_coeffsvandermonde_matrix_Tlagrange_integralsr+   r   r   r    !compute_stochastic_adams_b_coeffsE   s   
r:   r   start_sigma	end_sigmaetac                    s(   dt tjtf dtf fdd}|S )a  Return a function that controls the stochasticity of SA-Solver.

    When eta = 0, SA-Solver runs as ODE. The official approach uses
    time t to determine the SDE interval, while here we use sigma instead.

    See:
        https://github.com/scxue/SA-Solver/blob/main/README.md
    sigmar   c                    s<   dkrdS t | tjr|  } |   kr krS  dS )Nr   g        )
isinstancer   Tensoritem)r>   r<   r=   r;   r   r    tau_funcq   s
   z'get_tau_interval_func.<locals>.tau_func)r   r   r@   float)r;   r<   r=   rC   r   rB   r    get_tau_interval_funcg   s   $
rE   )F)FF)r   )r   typingr   r   r   r@   intrD   r!   boolr.   r:   rE   r   r   r   r    <module>   s   $2+64"