def test_constraints(): k = 1e23, 3.0, 4.0 y0 = [.7, .0, .0] x0, xend = 0, 5 kwargs = dict(atol=1e-8, rtol=1e-8, method='bdf') f, j = _get_f_j(k) args = f, j, y0, x0, xend def _check(xout, yout, info): yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, atol=40*kwargs['atol'], rtol=40*kwargs['rtol']) assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] is True assert xout[-1] == xend xout1, yout1, info1 = integrate_adaptive(*args, **kwargs) xout2, yout2, info2 = integrate_adaptive(*args, constraints=[1.0, 1.0, 1.0], **kwargs) _check(xout1, yout1, info1) _check(xout2, yout2, info2) assert info2['n_steps'] < info1['n_steps'] - 2 # <-- thanks to constraints with pytest.raises(Exception): integrate_adaptive(*args, constraints=[42.0, 17.0, 1984], **kwargs) # incorrect values for constraints
def test_integrate_adaptive_tstop0(): k = k0, k1, k2 = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] atol, rtol = 1e-8, 1e-8 kwargs = dict(dx0=1e-10, atol=atol, rtol=rtol) f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, x0=0, xend=3, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, rtol=10*rtol, atol=10*atol) xout, yout, info = integrate_adaptive(f, j, y0, x0=0, xend=0, **kwargs) assert xout == [0] assert np.allclose(yout, y0)
def integrate_ivp(u0=1.0, v0=0.0, mu=1.0, tend=10.0, dt0=1e-8, nt=0, nsteps=600, t0=0.0, atol=1e-8, rtol=1e-8, plot=False, savefig='None', method='bdf', dpi=100, verbose=False): """ Example program integrating an IVP problem of van der Pol oscillator """ f, j = get_f_and_j(mu) if nt > 1: tout = np.linspace(t0, tend, nt) yout, nfo = integrate_predefined( f, j, [u0, v0], tout, dt0, atol, rtol, nsteps=nsteps, check_indexing=False, method=method) else: tout, yout, nfo = integrate_adaptive( f, j, [u0, v0], t0, tend, dt0, atol, rtol, nsteps=nsteps, check_indexing=False, method=method) # dfdt[:] also for len == 1 if verbose: print(nfo) if plot: import matplotlib.pyplot as plt plt.plot(tout, yout[:, 1], 'g--') plt.plot(tout, yout[:, 0], 'k-', linewidth=2) if savefig == 'None': plt.show() else: plt.savefig(savefig, dpi=dpi)
def test_set_max_steps_between_jac(): k = 1e23, 3.0, 4.0 y0 = [.7, .0, .0] x0, xend = 0, 5 kwargs = dict(atol=1e-8, rtol=1e-8, method='bdf', dx_max_cb=lambda x, y: 1e-3, nsteps=xend * 1050) f, j = _get_f_j(k) xout, yout, info = integrate_adaptive( f, j, y0, x0, xend, max_steps_between_jac= 5, # 1e6=>6, 100=>49, 50 => 92, 25=>137, 10=>270, 5=>276, 2=>284, 1=>292 **kwargs) assert info['njev'] > 200 yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, atol=40 * kwargs['atol'], rtol=40 * kwargs['rtol']) assert info['n_steps'] > 1000 assert info['nfev'] > 0 assert info['success'] is True assert xout[-1] == xend
def test_adaptive_nderiv(): def f(t, y, fout): fout[0] = y[0] kwargs = dict(dx0=1e-4, atol=1e-4, rtol=1e-12, method='adams', nderiv=4) xout, yout, info = integrate_adaptive(f, None, [1], 0, 2, **kwargs) discrepancy = np.exp(xout) - yout[:, 0].flatten() assert np.allclose(discrepancy, 0, atol=1e-3)
def test_roots_adaptive(): def f(t, y, fout): fout[0] = y[0] def roots(t, y, out): out[0] = y[0] - exp(1) kwargs = dict(dx0=1e-12, atol=1e-12, rtol=1e-12, method='adams', roots=roots, nroots=1) xout, yout, info = integrate_adaptive(f, None, [1], 0, 2, **kwargs) assert len(info['root_indices']) == 1 assert np.min(np.abs(xout - 1)) < 1e-11
def test_return_on_root(): def f(t, y, fout): fout[0] = y[0] def roots(t, y, out): out[0] = y[0] - exp(1) kwargs = dict(dx0=1e-12, atol=1e-12, rtol=1e-12, method='adams', roots=roots, nroots=1, return_on_root=True) xout, yout, info = integrate_adaptive(f, None, [1], 0, 2, **kwargs) assert len(info['root_indices']) == 1 assert abs(xout[-1] - 1) < 1e-11 assert abs(yout[-1, 0] - exp(1)) < 1e-11
def test_roots_adaptive(): def f(t, y, fout): fout[0] = y[0] def roots(t, y, out): out[0] = y[0] - exp(1) kwargs = dict(dx0=1e-12, atol=1e-12, rtol=1e-12, method='adams', roots=roots, nroots=1) xout, yout, info = integrate_adaptive(f, None, [1], 0, 2, **kwargs) assert len(info['root_indices']) == 1 assert info['n_root_evals'] > 10 assert np.min(np.abs(xout - 1)) < 1e-11
def test_sparse_jac_adaptive(): k = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] atol, rtol = 1e-8, 1e-8 f, _, j_sparse, nnz = _get_f_j(k, with_sparse=True) kwargs = dict(atol=atol, rtol=rtol, method='bdf', linear_solver='klu', nnz=nnz) xout, yout, info = integrate_adaptive(f, j_sparse, y0, 0, 10, **kwargs) yref = decay_get_Cref(k, y0, xout - xout[0]) assert info['success'] assert info['njev'] > 0 assert np.allclose(yout, yref, rtol=10*rtol, atol=10*atol)
def integrate_ivp(u0=1.0, v0=0.0, mu=1.0, tend=10.0, dt0=1e-8, nt=0, nsteps=600, t0=0.0, atol=1e-8, rtol=1e-8, plot=False, savefig='None', method='bdf', dpi=100, verbose=False): """ Example program integrating an IVP problem of van der Pol oscillator """ f, j = get_f_and_j(mu) if nt > 1: tout = np.linspace(t0, tend, nt) yout, nfo = integrate_predefined(f, j, [u0, v0], tout, dt0, atol, rtol, nsteps=nsteps, check_indexing=False, method=method) else: tout, yout, nfo = integrate_adaptive( f, j, [u0, v0], t0, tend, dt0, atol, rtol, nsteps=nsteps, check_indexing=False, method=method) # dfdt[:] also for len == 1 if verbose: print(nfo) if plot: import matplotlib.pyplot as plt plt.plot(tout, yout[:, 1], 'g--') plt.plot(tout, yout[:, 0], 'k-', linewidth=2) if savefig == 'None': plt.show() else: plt.savefig(savefig, dpi=dpi)
def test_dx0cb(): k = 1e23, 3.0, 4.0 y0 = [.7, .0, .0] x0, xend = 0, 5 kwargs = dict(atol=1e-8, rtol=1e-8, method='bdf', dx0cb=lambda x, y: y[0]*1e-30) f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, x0, xend, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, atol=40*kwargs['atol'], rtol=40*kwargs['rtol']) assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] is True assert xout[-1] == xend
def test_return_on_root(): def f(t, y, fout): fout[0] = y[0] def roots(t, y, out): out[0] = y[0] - exp(1) kwargs = dict(dx0=1e-12, atol=1e-12, rtol=1e-12, method='adams', roots=roots, nroots=1, return_on_root=True, return_on_error=True) xout, yout, info = integrate_adaptive(f, None, [1], 0, 2, **kwargs) assert len(info['root_indices']) == 1 assert abs(xout[-1] - 1) < 1e-11 assert abs(yout[-1, 0] - exp(1)) < 1e-11 assert info['success']
def test_dx_max_cb(): k = 1e23, 3.0, 4.0 y0 = [.7, .0, .0] x0, xend = 0, 5 kwargs = dict(atol=1e-8, rtol=1e-8, method='bdf', dx_max_cb=lambda x, y: 1e-3, nsteps=xend*1050) f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, x0, xend, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, atol=40*kwargs['atol'], rtol=40*kwargs['rtol']) assert info['n_steps'] > 1000 assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] is True assert xout[-1] == xend
def test_adaptive_ew_ele(): k = 2.0, 3.0, 4.0 y0 = [0.7, 0., 0.] atol, rtol = 1e-8, 1e-8 kwargs = dict(dx0=1e-10, atol=atol, rtol=rtol, method='bdf', ew_ele=True) f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, 0, 10, **kwargs) yref = decay_get_Cref(k, y0, xout - xout[0]) assert np.allclose(yout, yref, rtol=10 * rtol, atol=10 * atol) assert yout.shape[0] == xout.size assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] abs_ew_ele = np.abs(np.prod(info['ew_ele'], axis=1)) assert np.all(abs_ew_ele < 1)
def test_derivative_3(): def f(t, y, fout): fout[0] = y[1] fout[1] = -y[0] kwargs = dict(dx0=0.0, atol=1e-13, rtol=1e-13, nderiv=2, method='adams', iter_type='newton') xout, yout, info = integrate_adaptive(f, None, [0, 1], 0, 4*pi, **kwargs) assert yout.shape[1:] == (3, 2) sinx, cosx = np.sin(xout), np.cos(xout) ref = np.empty((len(xout), 3, 2)) ref[:, 0, 0], ref[:, 0, 1] = sinx, cosx ref[:, 1, 0], ref[:, 1, 1] = cosx, -sinx ref[:, 2, 0], ref[:, 2, 1] = -sinx, -cosx discrepancy = yout[7:, ...] - ref[7:, ...] assert np.allclose(discrepancy, 0, rtol=1e-6, atol=1e-6)
def test_jtimes_adaptive(linear_solver, with_jac): g = 9.81 y0 = [1000.0, 0.0] atol, rtol = 1e-8, 1e-8 f, jac, jtimes = _gravity_f_j_jtimes(g) if not with_jac: jac = None kwargs = dict(atol=atol, rtol=rtol, method='bdf', linear_solver=linear_solver, jtimes=jtimes) tout, yout, info = integrate_adaptive(f, jac, y0, 0, 10, **kwargs) yref = gravity_analytic(g, y0, tout) assert np.allclose(yout, yref, rtol=10*rtol, atol=10*atol) assert info['success'] assert info['njvev'] > 0 if not with_jac: assert info['njev'] == 0
def test_quads_adaptive(): k = 0.7 def f(t, y, fout): fout[0] = -0.7*y[0] def quads(t, y, out): out[0] = t*y[0] out[1] = y[0]**2 kwargs = dict(dx0=1e-12, atol=1e-12, rtol=1e-12, method='adams', quads=quads, nquads=2) A, t0, duration = 42, 0, 4 t, yout, info = integrate_adaptive(f, None, [A, 0, 0], t0, t0 + duration, **kwargs) assert np.allclose(yout[:, 0], 42*np.exp(-k*t)) q0 = A/k**2 + (-A*k**2*t - A*k)*np.exp(-k*t)/k**3 q1 = (1.0/2.0)*A**2/k - 1.0/2.0*A**2*np.exp(-2*k*t)/k assert np.allclose(info['quads'][:, 0], q0) assert np.allclose(info['quads'][:, 1], q1)
def test_adaptive_return_on_error(): k = k0, k1, k2 = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] atol, rtol = 1e-8, 1e-8 kwargs = dict(x0=0, xend=3, dx0=1e-10, atol=atol, rtol=rtol, method='bdf') f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, nsteps=7, return_on_error=True, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, rtol=10*rtol, atol=10*atol) assert xout.size == 8 assert xout[-1] > 1e-6 assert yout.shape[0] == xout.size assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] is False assert xout[-1] < kwargs['xend'] # obviously not strict
def test_adaptive_autorestart(): k = k0, k1, k2 = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] atol, rtol = 1e-8, 1e-8 kwargs = dict(x0=0, xend=3, dx0=1e-10, atol=atol, rtol=rtol, method='BDF', nsteps=62, return_on_error=True, autorestart=10) f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, rtol=10*rtol, atol=10*atol) assert xout[-1] > 1e-6 assert yout.shape[0] == xout.size assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] assert xout[-1] == kwargs['xend']
def test_adaptive_autorestart(): k = k0, k1, k2 = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] atol, rtol = 1e-8, 1e-8 kwargs = dict(x0=0, xend=3, dx0=1e-10, atol=atol, rtol=rtol, method='BDF', nsteps=62, return_on_error=True, autorestart=10, autonomous_exprs=True) f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, rtol=10*rtol, atol=10*atol) assert xout[-1] > 1e-6 assert yout.shape[0] == xout.size assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] assert xout[-1] == kwargs['xend']
def test_adaptive_return_on_error(): k = k0, k1, k2 = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] atol, rtol = 1e-8, 1e-8 kwargs = dict(x0=0, xend=3, dx0=1e-10, atol=atol, rtol=rtol, method='bdf') f, j = _get_f_j(k) xout, yout, info = integrate_adaptive(f, j, y0, nsteps=7, return_on_error=True, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, rtol=10*rtol, atol=10*atol) assert xout.size == 8 assert 1e-6 < xout[-1] < 1 assert yout.shape[0] == xout.size assert info['nfev'] > 0 assert info['njev'] > 0 assert info['success'] == False # noqa assert xout[-1] < kwargs['xend'] # obviously not strict
def test_integrate_adaptive(method, forgiveness, banded): use_jac = method in requires_jac k = k0, k1, k2 = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] if config['SUNDIALS_PRECISION'] == "single": atol, rtol = 1e-4, 1e-4 else: atol, rtol = 1e-8, 1e-8 kwargs = dict(x0=0, xend=3, dx0=1e-10, atol=atol, rtol=rtol, method=method, iter_type='newton') f, j = _get_f_j(k) if not use_jac: j = None else: if banded: j = bandify(j, 1, 0) kwargs['lband'] = 1 kwargs['uband'] = 0 # Run twice to catch possible side-effects: if method == 'bdf': kwargs['stab_lim_det'] = True xout, yout, info = integrate_adaptive(f, j, y0, **kwargs) xout, yout, info = integrate_adaptive(f, j, y0, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, rtol=forgiveness * rtol, atol=forgiveness * atol) assert info['nfev'] > 0 if method in requires_jac: assert info['njev'] > 0 assert np.allclose(info['atol'], [atol]) and np.isclose(info['rtol'], rtol) with pytest.raises(RuntimeError) as excinfo: kw = kwargs.copy() kw['atol'], kw['rtol'] = 1e-36, 1e-36 integrate_adaptive(f, j, y0, **kw) assert 'acc' in str(excinfo.value).lower() with pytest.raises(RuntimeError) as excinfo: integrate_adaptive(f, j, y0, nsteps=7, **kwargs) assert 'maximum' in str(excinfo.value).lower() assert '7' in str(excinfo.value).lower()
def test_integrate_adaptive(method, forgiveness, banded): use_jac = method in requires_jac k = k0, k1, k2 = 2.0, 3.0, 4.0 y0 = [0.7, 0.3, 0.5] atol, rtol = 1e-8, 1e-8 kwargs = dict(x0=0, xend=3, dx0=1e-10, atol=atol, rtol=rtol, method=method, iter_type='newton') f, j = _get_f_j(k) if not use_jac: j = None else: if banded: j = bandify(j, 1, 0) kwargs['lband'] = 1 kwargs['uband'] = 0 # Run twice to catch possible side-effects: xout, yout, info = integrate_adaptive(f, j, y0, **kwargs) xout, yout, info = integrate_adaptive(f, j, y0, **kwargs) yref = decay_get_Cref(k, y0, xout) assert np.allclose(yout, yref, rtol=forgiveness*rtol, atol=forgiveness*atol) assert info['nfev'] > 0 if method in requires_jac: assert info['njev'] > 0 with pytest.raises(RuntimeError) as excinfo: kw = kwargs.copy() kw['atol'], kw['rtol'] = 1e-36, 1e-36 integrate_adaptive(f, j, y0, **kw) assert 'acc' in str(excinfo.value).lower() with pytest.raises(RuntimeError) as excinfo: integrate_adaptive(f, j, y0, nsteps=7, **kwargs) assert 'maximum' in str(excinfo.value).lower() assert '7' in str(excinfo.value).lower()