(self, rk_state)
return rk_state
Take an adaptive Runge-Kutta step to integrate the ODE.
Take an adaptive Runge-Kutta step to integrate the ODE.
Take an adaptive Runge - Kutta step to integrate the ODE .
def _adaptive_step(self, rk_state):
        """Take an adaptive Runge-Kutta step to integrate the ODE."""
        y0, f0, _, t0, dt, interp_coeff = rk_state
        t1 = t0 + dt
        # dtypes: self.y0.dtype (probably float32); self.dtype (probably float64)
        # used for state and timelike objects respectively.
        # Then:
        # y0.dtype == self.y0.dtype
        # f0.dtype == self.y0.dtype
        # t0.dtype == self.dtype
        # dt.dtype == self.dtype
        # for coeff in interp_coeff: coeff.dtype == self.y0.dtype

        ########################################################
        #                      Assertions                      #
        ########################################################
        assert t0 + dt > t0, 'underflow in dt {}'.format(dt.item())
        assert torch.isfinite(y0).all(), 'non-finite values in state `y`: {}'.format(y0)

        ########################################################
        #     Make step, respecting prescribed grid points     #
        ########################################################

        on_step_t = False
        if len(self.step_t):
            next_step_t = self.step_t[self.next_step_index]
            on_step_t = t0 < next_step_t < t0 + dt
            if on_step_t:
                t1 = next_step_t
                dt = t1 - t0

        on_jump_t = False
        if len(self.jump_t):
            next_jump_t = self.jump_t[self.next_jump_index]
            on_jump_t = t0 < next_jump_t < t0 + dt
            if on_jump_t:
                on_step_t = False
                t1 = next_jump_t
                dt = t1 - t0

        # Must be arranged as doing all the step_t handling, then all the jump_t handling, in case we
        # trigger both. (i.e. interleaving them would be wrong.)

        y1, f1, y1_error, k = _runge_kutta_step(self.func, y0, f0, t0, dt, t1, tableau=self.tableau)
        # dtypes:
        # y1.dtype == self.y0.dtype
        # f1.dtype == self.y0.dtype
        # y1_error.dtype == self.dtype
        # k.dtype == self.y0.dtype

        ########################################################
        #                     Error Ratio                      #
        ########################################################
        error_ratio = _compute_error_ratio(y1_error, self.rtol, self.atol, y0, y1, self.norm)
        accept_step = error_ratio <= 1
        # dtypes:
        # error_ratio.dtype == self.dtype

        ########################################################
        #                   Update RK State                    #
        ########################################################
        if accept_step:
            t_next = t1
            y_next = y1
            interp_coeff = self._interp_fit(y0, y_next, k, dt)
            if on_step_t:
                if self.next_step_index != len(self.step_t) - 1:
                    self.next_step_index += 1
            if on_jump_t:
                if self.next_jump_index != len(self.jump_t) - 1:
                    self.next_jump_index += 1
                # We've just passed a discontinuity in f; we should update f to match the side of the discontinuity
                # we're now on.
                f1 = self.func(t_next, y_next, perturb=Perturb.NEXT)
            f_next = f1
        else:
            t_next = t0
            y_next = y0
            f_next = f0
        dt_next = _optimal_step_size(dt, error_ratio, self.safety, self.ifactor, self.dfactor, self.order)
        rk_state = _RungeKuttaState(y_next, f_next, t0, t_next, dt_next, interp_coeff)
        return rk_state
def _adaptive_step ( self , rk_state ) : y0 , f0 , _ , t0 , dt , interp_coeff = rk_state t1 = t0 + dt # dtypes: self.y0.dtype (probably float32); self.dtype (probably float64) # used for state and timelike objects respectively. # Then: # y0.dtype == self.y0.dtype # f0.dtype == self.y0.dtype # t0.dtype == self.dtype # dt.dtype == self.dtype # for coeff in interp_coeff: coeff.dtype == self.y0.dtype ######################################################## #                      Assertions                      # ######################################################## assert t0 + dt > t0 , 'underflow in dt {}' . format ( dt . item ( ) ) assert torch . isfinite ( y0 ) . all ( ) , 'non-finite values in state `y`: {}' . format ( y0 ) ######################################################## #     Make step, respecting prescribed grid points     # ######################################################## on_step_t = False if len ( self . step_t ) : next_step_t = self . step_t [ self . next_step_index ] on_step_t = t0 < next_step_t < t0 + dt if on_step_t : t1 = next_step_t dt = t1 - t0 on_jump_t = False if len ( self . jump_t ) : next_jump_t = self . jump_t [ self . next_jump_index ] on_jump_t = t0 < next_jump_t < t0 + dt if on_jump_t : on_step_t = False t1 = next_jump_t dt = t1 - t0 # Must be arranged as doing all the step_t handling, then all the jump_t handling, in case we # trigger both. (i.e. interleaving them would be wrong.) y1 , f1 , y1_error , k = _runge_kutta_step ( self . func , y0 , f0 , t0 , dt , t1 , tableau = self . tableau ) # dtypes: # y1.dtype == self.y0.dtype # f1.dtype == self.y0.dtype # y1_error.dtype == self.dtype # k.dtype == self.y0.dtype ######################################################## #                     Error Ratio                      # ######################################################## error_ratio = _compute_error_ratio ( y1_error , self . rtol , self . atol , y0 , y1 , self . norm ) accept_step = error_ratio <= 1 # dtypes: # error_ratio.dtype == self.dtype ######################################################## #                   Update RK State                    # ######################################################## if accept_step : t_next = t1 y_next = y1 interp_coeff = self . _interp_fit ( y0 , y_next , k , dt ) if on_step_t : if self . next_step_index != len ( self . step_t ) - 1 : self . next_step_index += 1 if on_jump_t : if self . next_jump_index != len ( self . jump_t ) - 1 : self . next_jump_index += 1 # We've just passed a discontinuity in f; we should update f to match the side of the discontinuity # we're now on. f1 = self . func ( t_next , y_next , perturb = Perturb . NEXT ) f_next = f1 else : t_next = t0 y_next = y0 f_next = f0 dt_next = _optimal_step_size ( dt , error_ratio , self . safety , self . ifactor , self . dfactor , self . order ) rk_state = _RungeKuttaState ( y_next , f_next , t0 , t_next , dt_next , interp_coeff ) return rk_state