@@ -13,8 +13,10 @@ $(TYPEDEF)
13
13
14
14
Defines a collection of jump processes to associate with another problem type.
15
15
- [Documentation Page](https://docs.sciml.ai/JumpProcesses/stable/jump_types/)
16
- - [Tutorial Page](https://docs.sciml.ai/JumpProcesses/stable/tutorials/discrete_stochastic_example/)
17
- - [FAQ Page](https://docs.sciml.ai/JumpProcesses/stable/tutorials/discrete_stochastic_example/#FAQ)
16
+ - [Tutorial
17
+ Page](https://docs.sciml.ai/JumpProcesses/stable/tutorials/discrete_stochastic_example/)
18
+ - [FAQ
19
+ Page](https://docs.sciml.ai/JumpProcesses/stable/tutorials/discrete_stochastic_example/#FAQ)
18
20
19
21
### Constructors
20
22
@@ -44,20 +46,21 @@ then be passed within a single [`JumpSet`](@ref) or as subsequent sequential arg
44
46
$(FIELDS)
45
47
46
48
## Keyword Arguments
47
- - `rng`, the random number generator to use. Defaults to Julia's built-in
48
- generator.
49
- - `save_positions=(true,true)`, specifies whether to save the system's state (before, after)
50
- the jump occurs.
49
+ - `rng`, the random number generator to use. Defaults to Julia's built-in generator.
50
+ - `save_positions=(true,true)` when including variable rates and `(false,true)` for constant
51
+ rates, specifies whether to save the system's state (before, after) the jump occurs.
51
52
- `spatial_system`, for spatial problems the underlying spatial structure.
52
53
- `hopping_constants`, for spatial problems the spatial transition rate coefficients.
53
- - `use_vrj_bounds = true`, set to false to disable handling bounded `VariableRateJump`s
54
- with a supporting aggregator (such as `Coevolve`). They will then be handled via the
55
- continuous integration interface, and treated like general `VariableRateJump`s.
54
+ - `use_vrj_bounds = true`, set to false to disable handling bounded `VariableRateJump`s with
55
+ a supporting aggregator (such as `Coevolve`). They will then be handled via the continuous
56
+ integration interface, and treated like general `VariableRateJump`s.
57
+ - `vr_aggregator`, indicates the aggregator to use for sampling variable rate jumps. Current
58
+ default is `VR_FRM`.
56
59
57
60
Please see the [tutorial
58
- page](https://docs.sciml.ai/JumpProcesses/stable/tutorials/discrete_stochastic_example/) in the
59
- DifferentialEquations.jl [docs](https://docs.sciml.ai/JumpProcesses/stable/) for usage examples and
60
- commonly asked questions.
61
+ page](https://docs.sciml.ai/JumpProcesses/stable/tutorials/discrete_stochastic_example/) in
62
+ the DifferentialEquations.jl [docs](https://docs.sciml.ai/JumpProcesses/stable/) for usage
63
+ examples and commonly asked questions.
61
64
"""
62
65
mutable struct JumpProblem{iip, P, A, C, J <: Union{Nothing, AbstractJumpAggregator} , J2,
63
66
J3, J4, R, K} <: DiffEqBase.AbstractJumpProblem{P, J}
213
216
make_kwarg (; kwargs... ) = kwargs
214
217
215
218
function JumpProblem (prob, aggregator:: AbstractAggregatorAlgorithm , jumps:: JumpSet ;
219
+ vr_aggregator:: VariableRateAggregator = VR_FRM (),
216
220
save_positions = prob isa DiffEqBase. AbstractDiscreteProblem ?
217
221
(false , true ) : (true , true ),
218
222
rng = DEFAULT_RNG, scale_rates = true , useiszero = true ,
@@ -270,9 +274,9 @@ function JumpProblem(prob, aggregator::AbstractAggregatorAlgorithm, jumps::JumpS
270
274
271
275
# handle any remaining vrjs
272
276
if length (cvrjs) > 0
273
- new_prob = extend_problem (prob, cvrjs; rng)
274
- variable_jump_callback = build_variable_callback ( CallbackSet (), 0 , cvrjs ... ; rng)
275
- cont_agg = cvrjs
277
+ # Handle variable rate jumps based on vr_aggregator
278
+ new_prob, variable_jump_callback, cont_agg = configure_jump_problem (prob,
279
+ vr_aggregator, jumps, cvrjs; rng)
276
280
else
277
281
new_prob = prob
278
282
variable_jump_callback = CallbackSet ()
@@ -293,163 +297,6 @@ function JumpProblem(prob, aggregator::AbstractAggregatorAlgorithm, jumps::JumpS
293
297
solkwargs)
294
298
end
295
299
296
- # extends prob.u0 to an ExtendedJumpArray with Njumps integrated intensity values,
297
- # of type prob.tspan
298
- function extend_u0 (prob, Njumps, rng)
299
- ttype = eltype (prob. tspan)
300
- u0 = ExtendedJumpArray (prob. u0, [- randexp (rng, ttype) for i in 1 : Njumps])
301
- return u0
302
- end
303
-
304
- function extend_problem (prob:: DiffEqBase.AbstractDiscreteProblem , jumps; rng = DEFAULT_RNG)
305
- error (" General `VariableRateJump`s require a continuous problem, like an ODE/SDE/DDE/DAE problem. To use a `DiscreteProblem` bounded `VariableRateJump`s must be used. See the JumpProcesses docs." )
306
- end
307
-
308
- function extend_problem (prob:: DiffEqBase.AbstractODEProblem , jumps; rng = DEFAULT_RNG)
309
- _f = SciMLBase. unwrapped_f (prob. f)
310
-
311
- if isinplace (prob)
312
- jump_f = let _f = _f
313
- function (du:: ExtendedJumpArray , u:: ExtendedJumpArray , p, t)
314
- _f (du. u, u. u, p, t)
315
- update_jumps! (du, u, p, t, length (u. u), jumps... )
316
- end
317
- end
318
- else
319
- jump_f = let _f = _f
320
- function (u:: ExtendedJumpArray , p, t)
321
- du = ExtendedJumpArray (_f (u. u, p, t), u. jump_u)
322
- update_jumps! (du, u, p, t, length (u. u), jumps... )
323
- return du
324
- end
325
- end
326
- end
327
-
328
- u0 = extend_u0 (prob, length (jumps), rng)
329
- f = ODEFunction {isinplace(prob)} (jump_f; sys = prob. f. sys,
330
- observed = prob. f. observed)
331
- remake (prob; f, u0)
332
- end
333
-
334
- function extend_problem (prob:: DiffEqBase.AbstractSDEProblem , jumps; rng = DEFAULT_RNG)
335
- _f = SciMLBase. unwrapped_f (prob. f)
336
-
337
- if isinplace (prob)
338
- jump_f = let _f = _f
339
- function (du:: ExtendedJumpArray , u:: ExtendedJumpArray , p, t)
340
- _f (du. u, u. u, p, t)
341
- update_jumps! (du, u, p, t, length (u. u), jumps... )
342
- end
343
- end
344
- else
345
- jump_f = let _f = _f
346
- function (u:: ExtendedJumpArray , p, t)
347
- du = ExtendedJumpArray (_f (u. u, p, t), u. jump_u)
348
- update_jumps! (du, u, p, t, length (u. u), jumps... )
349
- return du
350
- end
351
- end
352
- end
353
-
354
- if prob. noise_rate_prototype === nothing
355
- jump_g = function (du, u, p, t)
356
- prob. g (du. u, u. u, p, t)
357
- end
358
- else
359
- jump_g = function (du, u, p, t)
360
- prob. g (du, u. u, p, t)
361
- end
362
- end
363
-
364
- u0 = extend_u0 (prob, length (jumps), rng)
365
- f = SDEFunction {isinplace(prob)} (jump_f, jump_g; sys = prob. f. sys,
366
- observed = prob. f. observed)
367
- remake (prob; f, g = jump_g, u0)
368
- end
369
-
370
- function extend_problem (prob:: DiffEqBase.AbstractDDEProblem , jumps; rng = DEFAULT_RNG)
371
- _f = SciMLBase. unwrapped_f (prob. f)
372
-
373
- if isinplace (prob)
374
- jump_f = let _f = _f
375
- function (du:: ExtendedJumpArray , u:: ExtendedJumpArray , h, p, t)
376
- _f (du. u, u. u, h, p, t)
377
- update_jumps! (du, u, p, t, length (u. u), jumps... )
378
- end
379
- end
380
- else
381
- jump_f = let _f = _f
382
- function (u:: ExtendedJumpArray , h, p, t)
383
- du = ExtendedJumpArray (_f (u. u, h, p, t), u. jump_u)
384
- update_jumps! (du, u, p, t, length (u. u), jumps... )
385
- return du
386
- end
387
- end
388
- end
389
-
390
- u0 = extend_u0 (prob, length (jumps), rng)
391
- f = DDEFunction {isinplace(prob)} (jump_f; sys = prob. f. sys,
392
- observed = prob. f. observed)
393
- remake (prob; f, u0)
394
- end
395
-
396
- # Not sure if the DAE one is correct: Should be a residual of sorts
397
- function extend_problem (prob:: DiffEqBase.AbstractDAEProblem , jumps; rng = DEFAULT_RNG)
398
- _f = SciMLBase. unwrapped_f (prob. f)
399
-
400
- if isinplace (prob)
401
- jump_f = let _f = _f
402
- function (out, du:: ExtendedJumpArray , u:: ExtendedJumpArray , h, p, t)
403
- _f (out, du. u, u. u, h, p, t)
404
- update_jumps! (out, u, p, t, length (u. u), jumps... )
405
- end
406
- end
407
- else
408
- jump_f = let _f = _f
409
- function (du, u:: ExtendedJumpArray , h, p, t)
410
- out = ExtendedJumpArray (_f (du. u, u. u, h, p, t), u. jump_u)
411
- update_jumps! (du, u, p, t, length (u. u), jumps... )
412
- return du
413
- end
414
- end
415
- end
416
-
417
- u0 = extend_u0 (prob, length (jumps), rng)
418
- f = DAEFunction {isinplace(prob)} (jump_f, sys = prob. f. sys,
419
- observed = prob. f. observed)
420
- remake (prob; f, u0)
421
- end
422
-
423
- function wrap_jump_in_callback (idx, jump; rng = DEFAULT_RNG)
424
- condition = function (u, t, integrator)
425
- u. jump_u[idx]
426
- end
427
- affect! = function (integrator)
428
- jump. affect! (integrator)
429
- integrator. u. jump_u[idx] = - randexp (rng, typeof (integrator. t))
430
- nothing
431
- end
432
- new_cb = ContinuousCallback (condition, affect!;
433
- idxs = jump. idxs,
434
- rootfind = jump. rootfind,
435
- interp_points = jump. interp_points,
436
- save_positions = jump. save_positions,
437
- abstol = jump. abstol,
438
- reltol = jump. reltol)
439
- return new_cb
440
- end
441
-
442
- function build_variable_callback (cb, idx, jump, jumps... ; rng = DEFAULT_RNG)
443
- idx += 1
444
- new_cb = wrap_jump_in_callback (idx, jump; rng)
445
- build_variable_callback (CallbackSet (cb, new_cb), idx, jumps... ; rng = DEFAULT_RNG)
446
- end
447
-
448
- function build_variable_callback (cb, idx, jump; rng = DEFAULT_RNG)
449
- idx += 1
450
- CallbackSet (cb, wrap_jump_in_callback (idx, jump; rng))
451
- end
452
-
453
300
aggregator (jp:: JumpProblem{iip, P, A, C, J} ) where {iip, P, A, C, J} = A
454
301
455
302
@inline function extend_tstops! (tstops,
@@ -458,17 +305,6 @@ aggregator(jp::JumpProblem{iip, P, A, C, J}) where {iip, P, A, C, J} = A
458
305
push! (tstops, jp. jump_callback. discrete_callbacks[1 ]. condition. next_jump_time)
459
306
end
460
307
461
- @inline function update_jumps! (du, u, p, t, idx, jump)
462
- idx += 1
463
- du[idx] = jump. rate (u. u, p, t)
464
- end
465
-
466
- @inline function update_jumps! (du, u, p, t, idx, jump, jumps... )
467
- idx += 1
468
- du[idx] = jump. rate (u. u, p, t)
469
- update_jumps! (du, u, p, t, idx, jumps... )
470
- end
471
-
472
308
# ## Displays
473
309
num_constant_rate_jumps (aggregator:: AbstractSSAJumpAggregator ) = length (aggregator. rates)
474
310
0 commit comments