3333"""
3434$(TYPEDEF)
3535
36- Defines a jump process with a rate (i.e. hazard, intensity, or propensity) that
37- may explicitly depend on time. More precisely, one where the rate function is
38- allowed to change *between* the occurrence of jumps. For detailed examples and
39- usage information see the
36+ Defines a jump process with a rate (i.e. hazard, intensity, or propensity) that may
37+ explicitly depend on time. More precisely, one where the rate function is allowed to change
38+ *between* the occurrence of jumps. For detailed examples and usage information see the
4039- [Tutorial](https://docs.sciml.ai/JumpProcesses/stable/tutorials/discrete_stochastic_example/)
4140
41+ Note that two types of `VariableRateJump`s are currently supported, with different
42+ performance charactertistics.
43+ - A general `VariableRateJump` or `VariableRateJump` will refer to one in which only `rate`
44+ and `affect` functions are specified.
45+
46+ * These are the most general in what they can represent, but require the use of an
47+ `ODEProblem` or `SDEProblem` whose underlying timestepper handles their evolution in
48+ time (via the callback interface).
49+ * This is the least performant jump type in simulations.
50+
51+ - Bounded `VariableRateJump`s require passing the keyword arguments `urate` and
52+ `rateinterval`, corresponding to functions `urate(u, p, t)` and `rateinterval(u, p, t)`,
53+ see below. These must calculate a time window over which the rate function is bounded by a
54+ constant (as long as any components of the state on which the upper bound function depends
55+ do not change). One can also optionally provide a lower bound function, `lrate(u, p, t)`
56+ via the `lrate` keyword argument, that can lead to increased performance.
57+
58+ * Bounded `VariableRateJump`s can currently be used in the `Coevolve` aggregator, and
59+ can therefore be efficiently simulated in pure-jump `DiscreteProblem`s using the
60+ `SSAStepper` time-stepper.
61+ * These can be substantially more performant than general `VariableRateJump`s without
62+ the rate bound functions.
63+
64+ The additional user provided functions leveraged by bounded `VariableRateJumps`, `urate(u,
65+ p, t)`, `rateinterval(u, p, t)`, and the optional `lrate(u, p, t)` require that
66+ - For `s` in `[t, t + rateinterval(u, p, t)]`, we should have that `lrate(u, p, t) <=
67+ rate(u, p, s) <= urate(u, p, t)` provided any components of `u` on which these functions
68+ depend remain unchanged.
69+
4270## Fields
4371
4472$(FIELDS)
4573
4674## Examples
47- Suppose `u[1]` gives the amount of particles and `t*p[1]` the probability per
48- time each particle can decay away. A corresponding `VariableRateJump` for this
49- jump process is
75+ Suppose `u[1]` gives the amount of particles and `t*p[1]` the probability per time each
76+ particle can decay away. A corresponding `VariableRateJump` for this jump process is
5077```julia
5178rate(u,p,t) = t*p[1]*u[1]
5279affect!(integrator) = integrator.u[1] -= 1
5380vrj = VariableRateJump(rate, affect!)
5481```
5582
56- In case we want to use the `Coevolve` aggregator, we need to pass the rate
57- boundaries and interval for which the rates apply. The `Coevolve` aggregator
58- allow us to perform discrete steps with `SSAStepper()`.
83+ In case we want to use the `Coevolve` aggregator, we need to pass the rate boundaries and
84+ interval for which the rates apply. The `Coevolve` aggregator allow us to perform discrete
85+ steps with `SSAStepper()`.
5986```julia
60- L (u,p,t) = (1/ p[1])* 2
61- rate(u,p,t) = t* p[1]* u[1]
87+ rateinterval (u,p,t) = (1 / p[1]) * 2
88+ rate(u,p,t) = t * p[1] * u[1]
6289lrate(u, p, t) = rate(u, p, t)
63- urate(u,p,t) = rate(u, p, t + L (u,p,t))
90+ urate(u,p,t) = rate(u, p, t + rateinterval (u,p,t))
6491affect!(integrator) = integrator.u[1] -= 1
65- vrj = VariableRateJump(rate, affect!; lrate=lrate, urate=urate, L=L)
92+ vrj = VariableRateJump(rate, affect!; lrate = lrate, urate = urate,
93+ rateinterval = rateinterval)
6694```
6795
6896## Notes
69- - When using the `Coevolve` aggregator, `DiscreteProblem` can be used.
70- Otherwise, `ODEProblem` or `SDEProblem` must be used to be correctly simulated.
71- - **When not using the `Coevolve` aggregator, `VariableRateJump`s result in
72- `integrator`s storing an effective state type that wraps the main state
73- vector.** See [`ExtendedJumpArray`](@ref) for details on using this object. Note
74- that the presence of *any* `VariableRateJump`s will result in all
75- `ConstantRateJump`, `VariableRateJump` and callback `affect!` functions
76- receiving an integrator with `integrator.u` an [`ExtendedJumpArray`](@ref).
77- - Salis H., Kaznessis Y., Accurate hybrid stochastic simulation of a system of
78- coupled chemical or biochemical reactions, Journal of Chemical Physics, 122
79- (5), DOI:10.1063/1.1835951 is used for calculating jump times with
80- `VariableRateJump`s within ODE/SDE integrators.
97+ - When using the `Coevolve` aggregator, `DiscreteProblem` can be used. Otherwise,
98+ `ODEProblem` or `SDEProblem` must be used to be correctly simulated.
99+ - **When not using the `Coevolve` aggregator, `VariableRateJump`s result in `integrator`s
100+ storing an effective state type that wraps the main state vector.** See
101+ [`ExtendedJumpArray`](@ref) for details on using this object. Note that the presence of
102+ *any* `VariableRateJump`s will result in all `ConstantRateJump`, `VariableRateJump` and
103+ callback `affect!` functions receiving an integrator with `integrator.u` an
104+ [`ExtendedJumpArray`](@ref).
105+ - Salis H., Kaznessis Y., Accurate hybrid stochastic simulation of a system of coupled
106+ chemical or biochemical reactions, Journal of Chemical Physics, 122 (5),
107+ DOI:10.1063/1.1835951 is used for calculating jump times with `VariableRateJump`s within
108+ ODE/SDE integrators.
81109"""
82110struct VariableRateJump{R, F, R2, R3, R4, I, T, T2} <: AbstractJump
83111 """ Function `rate(u,p,t)` that returns the jump's current rate given state
@@ -86,21 +114,29 @@ struct VariableRateJump{R, F, R2, R3, R4, I, T, T2} <: AbstractJump
86114 """ Function `affect!(integrator)` that updates the state for one occurrence
87115 of the jump given `integrator`."""
88116 affect!:: F
89- """ When planning to use the `Coevolve` aggregator, function `lrate(u, p,
90- t)` that computes the lower bound of the rate in interval `t` to `t + L` at time
91- `t` given state `u`, parameters `p`. This is not required if using another
92- aggregator."""
117+ """ Optional function `lrate(u, p, t)` that computes a lower bound on the rate in the
118+ interval `t` to `t + rateinterval(u, p, t)` at time `t` given state `u` and parameters
119+ `p`. The bound should hold over this time interval as long as components of `u` for
120+ which the rate functions are dependent do not change. When using aggregators that
121+ support bounded `VariableRateJump`s, currently only `Coevolve`, providing a lower-bound
122+ can lead to improved performance.
123+ """
93124 lrate:: R2
94- """ When planning to use the `Coevolve` aggregator, function `urate(u, p,
95- t)` that computes the upper bound of the rate in interval `t` to `t + L` at time
96- `t` given state `u`, parameters `p`. This is not required if using another
97- aggregator."""
125+ """ Optional function `urate(u, p, t)` for general `VariableRateJump`s, but is required
126+ to define a bounded `VariableRateJump`, which can be used with supporting aggregators,
127+ currently only `Coevolve`, and offers improved computational performance. Computes an
128+ upper bound for the rate in the interval `t` to `t + rateinterval(u, p, t)` at time `t`
129+ given state `u` and parameters `p`. The bound should hold over this time interval as
130+ long as components of `u` for which the rate functions are dependent do not change. """
98131 urate:: R3
99- """ When planning to use the `Coevolve` aggregator, function `L(u, p,
100- t)` that computes the interval length `L` starting at time `t` given state
101- `u`, parameters `p` for which the rate is bounded between `lrate` and
102- `urate`. This is not required if using another aggregator."""
103- L:: R4
132+ """ Optional function `rateinterval(u, p, t)` for general `VariableRateJump`s, but is
133+ required to define a bounded `VariableRateJump`, which can be used with supporting
134+ aggregators, currently only `Coevolve`, and offers improved computational performance.
135+ Computes the time interval from time `t` over which the `urate` and `lrate` bounds will
136+ hold, `t` to `t + rateinterval(u, p, t)`, given state `u` and parameters `p`. The bound
137+ should hold over this time interval as long as components of `u` for which the rate
138+ functions are dependent do not change. """
139+ rateinterval:: R4
104140 idxs:: I
105141 rootfind:: Bool
106142 interp_points:: Int
@@ -109,22 +145,33 @@ struct VariableRateJump{R, F, R2, R3, R4, I, T, T2} <: AbstractJump
109145 reltol:: T2
110146end
111147
148+ """
149+ ```
150+ function VariableRateJump(rate, affect!; lrate = nothing, urate = nothing,
151+ rateinterval = nothing, rootfind = true,
152+ idxs = nothing,
153+ save_positions = (false, true),
154+ interp_points = 10,
155+ abstol = 1e-12, reltol = 0)
156+ ```
157+ """
112158function VariableRateJump (rate, affect!;
113159 lrate = nothing , urate = nothing ,
114- L = nothing , rootfind = true ,
160+ rateinterval = nothing , rootfind = true ,
115161 idxs = nothing ,
116162 save_positions = (false , true ),
117163 interp_points = 10 ,
118164 abstol = 1e-12 , reltol = 0 )
119- if ! (urate != = nothing && L != = nothing ) && ! (urate === nothing && L === nothing )
120- error (" Either `urate` and `L` must be nothing, or both of them must be defined." )
165+ if ! (urate != = nothing && rateinterval != = nothing ) &&
166+ ! (urate === nothing && rateinterval === nothing )
167+ error (" `urate` and `rateinterval` must both be `nothing`, or must both be defined." )
121168 end
122169
123170 if (urate != = nothing && lrate === nothing )
124171 lrate = (u, p, t) -> zero (typeof (t))
125172 end
126173
127- VariableRateJump (rate, affect!, lrate, urate, L , idxs, rootfind,
174+ VariableRateJump (rate, affect!, lrate, urate, rateinterval , idxs, rootfind,
128175 interp_points, save_positions, abstol, reltol)
129176end
130177
0 commit comments