def test_jump(self): n = 10 τ = 10 width = 10**np.random.uniform(-7,0)*τ factor = np.random.random(n) times = sorted(np.random.uniform(0,τ,5)) past = Past(n, [ (time,np.random.random(n),0.1*np.random.random(n)) for time in times ]) jump_time = np.random.uniform(past[-2][0],past[-1][0]) jump_size = np.random.random(n) # Use a derivative for which it is clear how a jump affects it: f = lambda: [ factor[i]*y(i) + y(i,t-τ) for i in range(n) ] self.DDE = dde_integrator(f,past) state = self.DDE.get_recent_state(jump_time+width) derivative = self.DDE.eval_f(jump_time+width,state) self.DDE.apply_jump(jump_size,jump_time,width) assert self.DDE[-1][0] == jump_time+width assert_allclose( self.DDE[-1][1], state+jump_size ) assert_allclose( self.DDE[-1][2], derivative+factor*jump_size )
def __init__(self, f, past, helpers=(), control_pars=(), n_basic=None): self.past = past self.t, self.y, self.diff = self.past[-1] self.n = len(self.y) self.n_basic = n_basic or self.n self.last_garbage = -1 self.old_new_y = None self.parameters = [] from jitcdde._jitcdde import t, y, current_y, past_y, anchors Y = sympy.DeferredVector("Y") substitutions = list(helpers[::-1]) + [(y(i), Y[i]) for i in range(self.n)] past_calls = 0 f_wc = [] for entry in f(): new_entry = entry.subs(substitutions).simplify(ratio=1.0) past_calls += new_entry.count(anchors) f_wc.append(new_entry) F = sympy.lambdify([t, Y] + list(control_pars), f_wc, [{ anchors.__name__: self.get_past_anchors, past_y.__name__: self.get_past_value }, "math"]) self.f = lambda *args: np.array(F(*args)).flatten() self.anchor_mem = (len(past) - 1) * np.ones(past_calls, dtype=int)
def __init__(self, f, past, helpers = (), control_pars = (), n_basic = None, tangent_indices = (), ): self.past = past self.t, self.y, self.diff = self.past[-1] self.n = len(self.y) self.n_basic = n_basic or self.n self.tangent_indices = tangent_indices self.last_garbage = -1 self.old_new_y = None self.parameters = [] from jitcdde._jitcdde import t, y, past_y, anchors from sympy import DeferredVector, sympify, lambdify Y = DeferredVector("Y") substitutions = list(reversed(helpers)) + [(y(i),Y[i]) for i in range(self.n)] past_calls = 0 f_wc = [] for entry in f(): new_entry = sympify(entry).subs(substitutions).simplify(ratio=1.0) past_calls += new_entry.count(anchors) f_wc.append(new_entry) F = lambdify( [t, Y] + list(control_pars), f_wc, [ { anchors.name: self.get_past_anchors, past_y .name: interpolate }, "math" ] ) self.f = lambda *args: np.array(F(*args)).flatten() # storage of search positions (cursors) for lookup of anchors corresponding to a given time (see `get_past_anchors`) # Note that this approach is tailored to mimic the C implementation (using linked lists) as good as possible and therefore is rather clunky in Python. self.anchor_mem = (len(past)-1)*np.ones(past_calls, dtype=int)
def __init__(self, f, past, helpers = (), control_pars = (), n_basic = None, tangent_indices = (), ): self.past = past self.t, self.y, self.diff = self.past[-1] self.n = len(self.y) self.n_basic = n_basic or self.n self.tangent_indices = tangent_indices self.last_garbage = -1 self.old_new_y = None self.parameters = [] from jitcdde._jitcdde import t, y, past_y, anchors from sympy import DeferredVector, sympify, lambdify Y = DeferredVector("Y") substitutions = list(reversed(helpers)) + [(y(i),Y[i]) for i in range(self.n)] past_calls = 0 f_wc = [] for entry in f(): new_entry = sympify(entry).subs(substitutions).simplify(ratio=1.0) past_calls += new_entry.count(anchors) f_wc.append(new_entry) F = lambdify( [t, Y] + list(control_pars), f_wc, [ { anchors.name: self.get_past_anchors, past_y .name: interpolate }, "math" ] ) self.f = lambda *args: np.array(F(*args)).flatten() # storage of search positions (cursors) for lookup of anchors corresponding to a given time (see `get_past_anchors`) # Note that this approach is tailored to mimic the C implementation (using linked lists) as good as possible and therefore is rather clunky in Python. self.anchor_mem = (len(past)-1)*np.ones(past_calls, dtype=int)
def f_alt(): yield 0.25 * delayed_y / (1.0 + delayed_y**p) - 0.1*y(0,t)
def f(): yield 0.25 * y(0,t-tau) / (1.0 + y(0,t-tau)**p) - 0.1*y(0,t)
self.assertEqual(self.DDE.t, 0.0) self.DDE.get_next_step(1.0) self.assertEqual(self.DDE.y[0], y0) self.assertEqual(self.DDE.diff[0], dy0) self.assertEqual(self.DDE.t, 0.0) self.assertAlmostEqual(self.DDE.error[0], expected_error) self.DDE.accept_step() self.assertAlmostEqual(self.DDE.y[0], expected_y) self.assertEqual(self.DDE.t, 1.0) delayed_y = sympy.Symbol("delayed_y") f_alt_helpers = [(delayed_y, y(0,t-tau))] def f_alt(): yield 0.25 * delayed_y / (1.0 + delayed_y**p) - 0.1*y(0,t) class integration_test_with_helpers(integration_test): def setUp(self): self.DDE = dde_integrator(f_alt, past_generator(), f_alt_helpers) class double_integration_test(unittest.TestCase): def test_integration(self): past = past_generator() double_past = [] for entry in past: double_past += [( entry[0], np.hstack((entry[1],entry[1])),
def f_alt(): yield 0.25 * delayed_y / (1.0 + delayed_y**p) - 0.1*y(0,t)
def f(): yield 0.25 * y(0,t-tau) / (1.0 + y(0,t-tau)**p) - 0.1*y(0,t)
self.assertEqual(self.DDE.t, 0.0) self.DDE.get_next_step(1.0) self.assertEqual(self.DDE.y[0], y0) self.assertEqual(self.DDE.diff[0], dy0) self.assertEqual(self.DDE.t, 0.0) self.assertAlmostEqual(self.DDE.error[0], expected_error) self.DDE.accept_step() self.assertAlmostEqual(self.DDE.y[0], expected_y) self.assertEqual(self.DDE.t, 1.0) delayed_y = symengine.Symbol("delayed_y") f_alt_helpers = [(delayed_y, y(0,t-tau))] def f_alt(): yield 0.25 * delayed_y / (1.0 + delayed_y**p) - 0.1*y(0,t) class integration_test_with_helpers(integration_test): def setUp(self): self.DDE = dde_integrator(f_alt, past_generator(), f_alt_helpers) class double_integration_test(unittest.TestCase): def test_integration(self): past = past_generator() double_past = [] for entry in past: double_past += [( entry[0], np.hstack((entry[1],entry[1])),