def __init__(self, fun, get_energy_gradient, t0, y0, t_bound, max_step=np.inf, rtol=1e-3, atol=1e-6, ls_ctol=1e-4, ls_max_iter=10, ls_dec_scale=0.5, vectorized=False, line_search_class=None, **extraneous): warn_extraneous(extraneous) super(RungeKutta_LS, self).__init__(fun, t0, y0, t_bound, vectorized, support_complex=True) self.y_old = None self.max_step = validate_max_step(max_step) self.rtol, self.atol = validate_tol(rtol, atol, self.n) self.f = self.fun(self.t, self.y) self.h_abs = select_initial_step(self.fun, self.t, self.y, self.f, self.direction, self.order, self.rtol, self.atol) self.K = np.empty((self.n_stages + 1, self.n), dtype=self.y.dtype) self.ls_ctol = ls_ctol self.ls_max_iter = ls_max_iter self.ls_dec_scale = ls_dec_scale self.get_energy_gradient = get_energy_gradient self.line_search_class = line_search_class
def __init__(self, fun, t0, y0, t_bound, max_step=np.inf, rtol=1e-7, atol=1e-12, safety_factor=0.9, min_step_change=0.333, max_step_change=6.0, beta_stabilizer=0.00, max_nsteps=100000, vectorized=False, **extraneous): warn_extraneous(extraneous) super().__init__(fun, t0, y0, t_bound, vectorized, support_complex=True) self.y_old = None self.max_step = validate_max_step(max_step) self.beta_stabilizer = validate_beta_stabilizer(beta_stabilizer) self.max_nsteps = validate_max_nsteps(max_nsteps) self.safety_factor = validate_safety_factor(safety_factor) self.rtol, self.atol = validate_tol(rtol, atol, self.n) self.min_step_change = min_step_change self.max_step_change = max_step_change self.order = 8 self.f = self.fun(self.t, self.y) self.h_abs = select_initial_step(self.fun, self.t, self.y, self.f, self.direction, self.order, self.rtol, self.atol) self.nfev += 2 self.n_steps = 0 self.n_accepted = 0 self.n_rejected = 0 self.factor_old = 1e-4 # Lund-stabilization factor self.K = np.zeros((16, self.n)) self.interpolation = np.zeros((8, self.n))
def __init__(self, *args, **kwargs): self.options = VariableStepOptions( **{k: kwargs.pop(k) for k in variable_step_options if k in kwargs}) h = kwargs.pop("first_step", None) super().__init__(*args, **kwargs) validate_max_step(self.options.max_step) validate_tol(self.options.rtol, self.options.atol, self.y.size) if h is None: h = select_initial_step( self.rhs, self.t, self.y, self.f, 1, self.error_estimator_order, self.options.rtol, self.options.atol, ) self.h = np.array(h, dtype=float)
def __init__(self, fun, t0, y0, t_bound, max_step=np.inf, rtol=1e-3, atol=1e-6, vectorized=False, first_step=None, const_jac=False, rho_jac=None, **extraneous): warn_extraneous(extraneous) super(SSV2stab, self).__init__( fun, t0, y0, t_bound, vectorized, support_complex=False) if first_step is None: self.absh = None else: self.absh = validate_first_step(first_step, t0, t_bound) self.hold = None if not isinstance(const_jac, bool): raise TypeError('`const_jac` should be True or False') if rho_jac is not None: if not callable(rho_jac): raise TypeError( '`rho_jac` should be None or a function: ' '`sprad = rho_jac(t, y)`') elif not isinstance(rho_jac(self.t, self.y), float): raise TypeError('`rho_jac` should return a float') elif rho_jac(self.t, self.y) <= 0: raise ValueError('`rho_jac` should return a positive float') self.const_jac = const_jac self.rho_jac = rho_jac self.max_step = validate_max_step(max_step) self.rtol, self.atol = validate_tol(rtol, atol, self.y) self.uround = np.nextafter(np.finfo(self.y.dtype).epsneg, 1) self.sqrtu = sqrt(self.uround) self.sqrtmin = sqrt(np.finfo(self.y.dtype).tiny) self.W = np.empty((4, self.n), self.y.dtype) self.V = None # eigenvector for spectral radius estimation. It # was WORK(5) in Fortran. Init in self._rho(). # reset counters nrejct[()] = 0 nfesig[()] = 0 maxm[()] = 0 self.nstsig = 0 self.mlim = 0 # added, for stiffness warning # Initialize on the first call. mmax = int(round(sqrt(self.rtol/(10.0 * self.uround)))) self.mmax = max(mmax, 2) self.newspc = True self.jacatt = False self.W[0] = self.y self.W[1] = self.fun(self.t, self.y) # evaluate max_step = min(self.max_step, abs(self.t_bound - self.t)) self.max_step = min(max_step, sqrt(np.finfo(self.y.dtype).max)) hmin = abs(self.t) if self.t_bound != np.inf: hmin = max(hmin, abs(self.max_step)) self.hmin = max(self.sqrtmin, 10.0 * self.uround * hmin)
def __init__(self, fun, t0, y0, t_bound, max_step=np.inf, rtol=1e-7, atol=1e-12, safety_factor=0.9, min_step_change=0.333, max_step_change=6.0, beta_stabilizer=0.00, max_nsteps=100000, vectorized=False, **extraneous): warn_extraneous(extraneous) super().__init__(fun, t0, y0, t_bound, vectorized, support_complex=True) self.y_old = None self.max_step = validate_max_step(max_step) self.beta_stabilizer = validate_beta_stabilizer(beta_stabilizer) self.max_nsteps = validate_max_nsteps(max_nsteps) self.safety_factor = validate_safety_factor(safety_factor) self.rtol, self.atol = validate_tol(rtol, atol, self.n) self.min_step_change = min_step_change self.max_step_change = max_step_change self.order = 8 self.f = self.fun(self.t, self.y) self.h_abs = select_initial_step( self.fun, self.t, self.y, self.f, self.direction, self.order, self.rtol, self.atol, ) self.nfev += 2 self.n_steps = 0 self.n_accepted = 0 self.n_rejected = 0 self.factor_old = 1e-4 # Lund-stabilization factor self.K = np.zeros((16, self.n)) self.interpolation = np.zeros((8, self.n))
def __init__(self, fun, t0, y0, t_bound, max_step=np.inf, rtol=1e-3, atol=1e-6, vectorized=False, first_step=None, nfev_stiff_detect=5000, sc_params=None, **extraneous): warn_extraneous(extraneous) super(RungeKutta, self).__init__(fun, t0, y0, t_bound, vectorized, support_complex=True) self.max_step = validate_max_step(max_step) self.rtol, self.atol = validate_tol(rtol, atol, self.y) self.f = self.fun(self.t, self.y) if self.f.dtype != self.y.dtype: raise TypeError('dtypes of solution and derivative do not match') self.error_exponent = -1 / (self.error_estimator_order + 1) self._init_stiffness_detection(nfev_stiff_detect) self.h_min_a, self.h_min_b = self._init_min_step_parameters() self._init_sc_control(sc_params) # size of first step: if first_step is None: b = self.t + self.direction * min(abs(self.t_bound - self.t), self.max_step) self.h_abs = abs( h_start(self.fun, self.t, b, self.y, self.f, self.error_estimator_order, self.rtol, self.atol)) else: self.h_abs = validate_first_step(first_step, t0, t_bound) self.K = np.empty((self.n_stages + 1, self.n), self.y.dtype) self.FSAL = 1 if self.E[self.n_stages] else 0 self.h_previous = None self.y_old = None NFS[()] = 0 # global failed step counter
def __init__(self, fun, t0, y0, t_bound, max_step=np.inf, rtol=1e-3, atol=1e-6, min_step=0, vectorized=False, first_step=None, **extraneous): warn_extraneous(extraneous) super(RungeKutta, self).__init__(fun, t0, y0, t_bound, vectorized, support_complex=True) self.min_step_user = min_step self.y_old = None self.max_step = validate_max_step(max_step) self.rtol, self.atol = validate_tol(rtol, atol, self.n) self.f = self.fun(self.t, self.y) if first_step is None: self.h_abs = select_initial_step( self.fun, self.t, self.y, self.f, self.direction, self.order, self.rtol, self.atol) else: self.h_abs = validate_first_step(first_step, t0, t_bound) self.K = np.empty((self.n_stages + 1, self.n), dtype=self.y.dtype)
def __init__(self, fun, t0, y0, t_bound, max_step=np.inf, rtol=1e-3, atol=1e-6, vectorized=False, first_step=None, k_max=12, **extraneous): if not (isinstance(k_max, int) and k_max > 0 and k_max < 13): raise ValueError("`k_max` should be an integer between 1 and 12.") warn_extraneous(extraneous) super(SWAG, self).__init__( fun, t0, y0, t_bound, vectorized, support_complex=True) self.max_step = validate_max_step(max_step) self.rtol, self.atol = validate_tol(rtol, atol, self.y) # starting step size self.yp = self.fun(self.t, self.y) # initial evaluation if first_step is None: b = self.t + copysign(min(abs(self.t_bound - self.t), self.max_step), self.direction) self.h = h_start(self.fun, self.t, b, self.y, self.yp, 1, self.rtol, self.atol) else: h_abs = validate_first_step(first_step, t0, t_bound) self.h = copysign(h_abs, self.direction) # constants small = np.nextafter(np.finfo(self.y.dtype).epsneg, 1) self.twou = 2.0 * small self.fouru = 4.0 * small self.two = (2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0) self.gstr = (0.5, 0.0833, 0.0417, 0.0264, 0.0188, 0.0143, 0.0114, 0.00936, 0.00789, 0.00679, 0.00592, 0.00524, 0.00468) iq = np.arange(1, k_max + 2) self.iqq = 1.0 / (iq * (iq + 1)) # added self.k_max = k_max # added self.eps = 1.0 # tolerances in wt self.p5eps = 0.5 # tolerances in wt # allocate arrays self.phi = np.empty((self.n, k_max + 2), self.y.dtype, 'F') self.psi = np.empty(k_max) self.alpha = np.empty(k_max) self.beta = np.empty(k_max) self.sig = np.empty(k_max + 1) self.v = np.empty(k_max) self.w = np.empty(k_max) self.g = np.empty(k_max + 1) self.gi = np.empty(k_max - 1) self.iv = np.zeros(max(0, k_max - 2), np.short) # Tolerances are dealt with like in scipy: wt is like scipy's scale # and will be update each step. This is only the initial value: self.wt = self.atol + self.rtol * 0.5*( np.abs(self.y) + np.abs(self.y - self.h*self.yp)) # initialization # from *** block 0 *** of dsteps.f, under IF START: _round = 0.0 if self.y.size: # to pass scipy's unit tests _round = self.twou * norm(self.y / self.wt) if self.p5eps < 100.0 * _round: # The compensated summation of the original code that would be # executed if nornd == False has been removed. Instead, this # warning is given to the user. warn("Numerical rounding may limit the accuracy " "at this tolerance.") self.phi[:, 0] = self.yp self.phi[:, 1] = 0.0 self.sig[0] = 1.0 self.g[0] = 1.0 self.g[1] = 0.5 self.hold = 0.0 self.k = 1 self.kold = 0 self.kprev = 0 self.phase1 = True self.ivc = 0 self.kgi = 0 self.ns = 0 # from ddes.f, for stiffness detection self.kle4 = 0
def __init__(self, fun, t0, y0, t_bound, max_step=np.inf, rtol=1e-3, atol=1e-6, jac=None, jac_sparsity=None, vectorized=False, first_step=None, mass=None, bPrint=False, newton_tol=None, constant_dt=False, bPrintProgress=False, **extraneous): warn_extraneous(extraneous) super(RadauDAE, self).__init__(fun, t0, y0, t_bound, vectorized) self.y_old = None self.max_step = validate_max_step(max_step) self.rtol, self.atol = validate_tol(rtol, atol, self.n) self.f = self.fun(self.t, self.y) # Select initial step assuming the same order which is used to control # the error. if first_step is None: self.h_abs = select_initial_step(self.fun, self.t, self.y, self.f, self.direction, 3, self.rtol, self.atol) else: self.h_abs = validate_first_step(first_step, t0, t_bound) self.h_abs_old = None self.error_norm_old = None if newton_tol is None: self.newton_tol = max(10 * EPS / rtol, min(0.03, rtol**0.5)) else: self.newton_tol = newton_tol self.sol = None self.constant_dt = constant_dt self.jac_factor = None self.jac, self.J = self._validate_jac(jac, jac_sparsity) self.nlusove = 0 self.bPrintProgress = bPrintProgress global BPRINT BPRINT = bPrint if BPRINT: zzzjac = self.jac def debugJacprint(t, y, f): print('\tupdating jacobian') return zzzjac(t, y, f) self.jac = debugJacprint if issparse(self.J): def lu(A): self.nlu += 1 return splu(A) def solve_lu(LU, b): self.nlusove += 1 return LU.solve(b) I = eye(self.n, format='csc') else: def lu(A): self.nlu += 1 return lu_factor(A, overwrite_a=True) def solve_lu(LU, b): self.nlusove += 1 return lu_solve(LU, b, overwrite_b=True) I = np.identity(self.n) self.lu = lu self.solve_lu = solve_lu self.I = I if not (mass is None): if issparse(mass): self.mass_matrix = csc_matrix(mass) self.index_algebraic_vars = np.where( np.all(self.mass_matrix.toarray() == 0, axis=1))[0] # TODO: avoid the toarray() else: self.mass_matrix = mass self.index_algebraic_vars = np.where( np.all(self.mass_matrix == 0, axis=1))[0] self.nvars_algebraic = self.index_algebraic_vars.size else: self.mass_matrix = None self.index_algebraic_vars = None self.nvars_algebraic = 0 self.current_jac = True self.LU_real = None self.LU_complex = None self.Z = None self.info = { 'cond': { 'LU_real': [], 'LU_complex': [], 't': [], 'h': [] } }