a
    d5                     @   s   d dl Z d dlZd dlZddlmZ ddlmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZ edd	Zed
dZG dd dejjZdd ZdZdZdZdddZdddZG dd deZdd ZdS )    N   )
find_event)_interp_evaluate_interp_fit)_compute_error_ratio_select_initial_step_optimal_step_size)Perturb)AdaptiveStepsizeEventODESolver_ButcherTableauzalpha, beta, c_sol, c_error_RungeKuttaStatez y1, f1, t0, t1, dt, interp_coeffc                   @   s$   e Zd Zedd Zedd ZdS )_UncheckedAssignc                 C   s   || _ ||j|< |S N)indexdata)ctxZscratchvaluer    r   d/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchdiffeq/_impl/rk_common.pyforward   s    
z_UncheckedAssign.forwardc                 C   s   ||| j  d fS r   )r   )r   Zgrad_scratchr   r   r   backward$   s    z_UncheckedAssign.backwardN)__name__
__module____qualname__staticmethodr   r   r   r   r   r   r      s   
r   c                 C   sx  | |j}| |j}| |j}tjg |jt|jd R |j|jd}t	||d}t
t|j|jD ]\}\}	}
|	dkr|}tj}n||	|  }tj}|tj|dd|d f |
|  dd| }| |||d	}t	||d|d f}qp|jd d
kr&|jdd |jd k sH|tj|||j  dd| }|}|d }tj|||j  dd}||||fS )a  Take an arbitrary Runge-Kutta step and estimate error.
    Args:
        func: Function to evaluate like `func(t, y)` to compute the time derivative of `y`.
        y0: Tensor initial value for the state.
        f0: Tensor initial value for the derivative, computed from `func(t0, y0)`.
        t0: float64 scalar Tensor giving the initial time.
        dt: float64 scalar Tensor giving the size of the desired time step.
        t1: float64 scalar Tensor giving the end time; equal to t0 + dt. This is used (rather than t0 + dt) to ensure
            floating point accuracy when needed.
        tableau: _ButcherTableau describing how to take the Runge-Kutta step.
    Returns:
        Tuple `(y1, f1, y1_error, k)` giving the estimated function value after
        the Runge-Kutta step at `t1 = t0 + dt`, the derivative of the state at `t1`,
        estimated error at `t1`, and a list of Runge-Kutta coefficients `k` used for
        calculating these terms.
    r   dtypedevice.r   g      ?.NZdimperturbr   .r   )tor   torchemptyshapelenalphar   r   apply	enumeratezipbetar	   PREVNONEsumview_asc_solallc_error)funcy0f0t0dtt1tableaukiZalpha_iZbeta_iZtir"   yify1f1y1_errorr   r   r   _runge_kutta_step)   s(    ,0."rC   gUUUUUU?gUUUUUU?gUUUUUU?Fc                 C   s   |}|d u r&| |||rt jnt jd}|d }| || |||  }	| || |||	  }
| ||||
  |rrt jnt jd}|d|	|
   | | t S )Nr!   g      ?   )r	   NEXTr/   r.   
_one_sixth)r5   r8   r9   r:   r6   r7   r"   k1Zhalf_dtk2k3k4r   r   r   rk4_step_func_   s    "rK   c                 C   s   |}|du r&| |||rt jnt jd}| ||t  ||| t  }| ||t  ||||t    }	| ||||| |	   |rt jnt jd}
|d||	   |
 | d S )z)Smaller error with slightly more compute.Nr!      g      ?)r	   rE   r/   
_one_third_two_thirdsr.   )r5   r8   r9   r:   r6   r7   r"   rG   rH   rI   rJ   r   r   r   rk4_alt_step_funcj   s    "*rO   c                       st   e Zd ZU eed< eed< ejed< dddddddejf fd	d
	Z	dd Z
dd Zdd Zdd Zdd Z  ZS )RKAdaptiveStepsizeODESolverorderr;   midNg?g      $@g?ic                    sr  t t| jf |d| t|j}j || _tj|| d| _	tj|| d| _
|d u rfd ntj|| d| _tj|| d| _tj|	| d| _tj|
| d| _tj|tj d| _|| _|d u rd ntj|| d| _|d u rd ntj|| d| _t| jjj jd fdd| jjD | jjj jd| jjj jdd| _| jj jd| _d S )N)r   r6   r   r   r   c                    s   g | ]}|j  jd qS )rS   )r$   r   ).0br   r6   r   r   
<listcomp>       z8RKAdaptiveStepsizeODESolver.__init__.<locals>.<listcomp>)r)   r-   r2   r4   )superrP   __init__r%   Zpromote_typesr   r   r5   Z	as_tensorrtolatol
first_stepsafetyifactordfactorint32max_num_stepsstep_tjump_tr   r;   r)   r$   r-   r2   r4   rR   )selfr5   r6   r[   r\   r]   rc   rd   r^   r_   r`   rb   r   kwargs	__class__rV   r   rZ   z   s(    
z$RKAdaptiveStepsizeODESolver.__init__c              
   C   s  |d }|  |d | j}| jd u rRt| j |d | j| jd | j| j| j|d}n| j}t| j||d |d || jgd | _	| j
d u rtjg | j| jjd}nt| j
|}|| j}| jd u rtjg | j| jjd}nt| j|}|| j}t||gjddd }|dk r"td|| _
|| _tt| j
 |d t| j
d | _tt| j |d t| jd | _d S )	Nr   r   )r7      r   T)Zreturn_countszG`step_t` and `jump_t` must not have any repeated elements between them.)r5   r6   r]   r   rQ   r[   r\   normr   rk_staterc   r%   Ztensorr   r   _sort_tvalsr$   rd   catuniqueany
ValueErrorminbisecttolistr(   next_step_indexnext_jump_index)re   tr8   r7   r]   rc   rd   countsr   r   r   _before_integrate   s.    
 &

(z-RKAdaptiveStepsizeODESolver._before_integratec                 C   s^   d}|| j jkrD|| jk s,J d|| j| | j | _ |d7 }qt| j j| j j| j j|S )zBInterpolate through the next time point, integrating as necessary.r   max_num_steps exceeded ({}>={})r   )rk   r:   rb   format_adaptive_stepr   interp_coeffr8   )re   Znext_tn_stepsr   r   r   _advance   s    
z$RKAdaptiveStepsizeODESolver._advancec                    s   | j j j jdkr& j j j jfS d}t| j j j j}|t| j j j jkr| jk szJ d| j  j  _ |d7 }qB fdd}t|| j j	 j j| j
S )z9Returns t, state(t) such that event_fn(t, state(t)) == 0.r   ry   r   c                    s   t  jj jj jj| S r   )r   rk   r|   r8   r:   )rv   re   r   r   <lambda>   rX   zBRKAdaptiveStepsizeODESolver._advance_until_event.<locals>.<lambda>)rk   r:   r@   r%   signrb   rz   r{   r   r8   r\   )re   Zevent_fnr}   Zsign0Z	interp_fnr   r   r   _advance_until_event   s    
z0RKAdaptiveStepsizeODESolver._advance_until_eventc              	   C   s  |\}}}}}}|| }|| |ks6J d | t| sRJ d |d}	t| jr| j| j }
||
  k o|| k n  }	|	r|
}|| }d}t| jr| j| j	 }||  k o|| k n  }|rd}	|}|| }t
| j|||||| jd\}}}}t|| j| j||| j}|dk}|r|}|}| ||||}|	rl| jt| jd krl|  jd7  _|r| j	t| jd kr|  j	d7  _	| j||tjd}|}n|}|}|}t||| j| j| j| j}t||||||}|S )z7Take an adaptive Runge-Kutta step to integrate the ODE.zunderflow in dt {}z"non-finite values in state `y`: {}F)r;   r   r!   )rz   itemr%   isfiniter3   r(   rc   rt   rd   ru   rC   r5   r;   r   r[   r\   rj   r   r	   rE   r   r^   r_   r`   rQ   r   )re   rk   r6   r7   _r8   r9   r|   r:   Z	on_step_tZnext_step_tZ	on_jump_tZnext_jump_tr@   rA   rB   r<   Zerror_ratioZaccept_stepZt_nextZy_nextZf_nextZdt_nextr   r   r   r{      sP    

"
z*RKAdaptiveStepsizeODESolver._adaptive_stepc                 C   sN   | |}|tj||| j  dd| }|d }|d }t||||||S )zEFit an interpolating polynomial to the results of a Runge-Kutta step.r   r    r   r#   )Ztype_asr%   r0   rR   r1   r   )re   r6   r@   r<   r9   Zy_midr7   rA   r   r   r   r   '  s
    
"z'RKAdaptiveStepsizeODESolver._interp_fit)r   r   r   int__annotations__r   r%   ZTensorfloat64rZ   rx   r~   r   r{   r   __classcell__r   r   rg   r   rP   u   s"   

%	SrP   c                 C   s   | | |k } t | jS r   )r%   sortvalues)Ztvalsr8   r   r   r   rl   0  s    rl   )NF)NF)rr   collectionsr%   Zevent_handlingr   Zinterpr   r   miscr   r   r   r	   Zsolversr
   
namedtupler   r   ZautogradZFunctionr   rC   rM   rN   rF   rK   rO   rP   rl   r   r   r   r   <module>   s&   1

 <