Skip to content

Commit ca51129

Browse files
added references
1 parent 4690112 commit ca51129

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

src/simple_regular_solve.jl

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleTauLeaping;
8282
end
8383

8484
function compute_hor(reactant_stoch, numjumps)
85+
# Compute the highest order of reaction (HOR) for each reaction j, as per Cao et al. (2006), Section IV.
86+
# HOR is the sum of stoichiometric coefficients of reactants in reaction j.
8587
hor = zeros(Int, numjumps)
8688
for j in 1:numjumps
8789
order = sum(stoch for (spec_idx, stoch) in reactant_stoch[j]; init=0)
@@ -94,7 +96,9 @@ function compute_hor(reactant_stoch, numjumps)
9496
end
9597

9698
function precompute_reaction_conditions(reactant_stoch, hor, numspecies, numjumps)
97-
# Initialize reaction_conditions as a vector of vectors of tuples
99+
# Precompute reaction conditions for each species i, storing reactions j where i is a reactant,
100+
# along with stoichiometry (nu_ij) and HOR (hor_j), to optimize compute_gi.
101+
# Reactant stoichiometry is used per Cao et al. (2006), Section IV, for g_i calculations.
98102
reaction_conditions = [Vector() for _ in 1:numspecies]
99103
for j in 1:numjumps
100104
for (spec_idx, stoch) in reactant_stoch[j]
@@ -107,6 +111,14 @@ function precompute_reaction_conditions(reactant_stoch, hor, numspecies, numjump
107111
end
108112

109113
function compute_gi(u, reaction_conditions, i)
114+
# Compute g_i for species i, bounding the relative change in propensity functions,
115+
# as per Cao et al. (2006), Section IV (between equations 27-28).
116+
# g_i is the maximum over all reactions j where species i is a reactant:
117+
# - HOR = 1: g_i = 1
118+
# - HOR = 2, nu_ij = 1: g_i = 2
119+
# - HOR = 2, nu_ij >= 2: g_i = x_i * (2/nu_ij + 1/(nu_ij - 1))
120+
# - HOR = 3, nu_ij = 1: g_i = 3
121+
# - HOR = 3, nu_ij >= 2: g_i = 1.5 * x_i * (2/nu_ij + 1/(nu_ij - 1))
110122
max_gi = 1
111123
for (j, nu_ij, hor_j) in reaction_conditions[i]
112124
if hor_j == 1
@@ -131,20 +143,25 @@ function compute_gi(u, reaction_conditions, i)
131143
end
132144

133145
function compute_tau_explicit(u, rate_cache, nu, p, t, epsilon, rate, dtmin, reaction_conditions, numjumps)
146+
# Compute the tau-leaping step-size using equation (8) from Cao et al. (2006):
147+
# tau = min_{i in I_rs} { max(epsilon * x_i / g_i, 1) / |mu_i(x)|, max(epsilon * x_i / g_i, 1)^2 / sigma_i^2(x) }
148+
# where mu_i(x) and sigma_i^2(x) are defined in equations (9a) and (9b):
149+
# mu_i(x) = sum_j nu_ij * a_j(x), sigma_i^2(x) = sum_j nu_ij^2 * a_j(x)
150+
# I_rs is the set of reactant species (assumed to be all species here, as critical reactions are not specified).
134151
rate(rate_cache, u, p, t)
135152
tau = Inf
136153
for i in 1:length(u)
137154
mu = zero(eltype(u))
138155
sigma2 = zero(eltype(u))
139156
for j in 1:size(nu, 2)
140-
mu += nu[i, j] * rate_cache[j]
141-
sigma2 += nu[i, j]^2 * rate_cache[j]
157+
mu += nu[i, j] * rate_cache[j] # Equation (9a)
158+
sigma2 += nu[i, j]^2 * rate_cache[j] # Equation (9b)
142159
end
143160
gi = compute_gi(u, reaction_conditions, i)
144-
bound = max(epsilon * u[i] / gi, 1.0)
145-
mu_term = abs(mu) > 0 ? bound / abs(mu) : Inf
146-
sigma_term = sigma2 > 0 ? bound^2 / sigma2 : Inf
147-
tau = min(tau, mu_term, sigma_term)
161+
bound = max(epsilon * u[i] / gi, 1.0) # max(epsilon * x_i / g_i, 1)
162+
mu_term = abs(mu) > 0 ? bound / abs(mu) : Inf # First term in equation (8)
163+
sigma_term = sigma2 > 0 ? bound^2 / sigma2 : Inf # Second term in equation (8)
164+
tau = min(tau, mu_term, sigma_term) # Equation (8)
148165
end
149166
return max(tau, dtmin)
150167
end
@@ -229,7 +246,7 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleAdaptiveTauLeaping;
229246
end
230247
u_new = u_current + du
231248
if any(<(0), u_new)
232-
# Halve tau to avoid negative populations, as per Cao et al. (2006, J. Chem. Phys., DOI: 10.1063/1.2159468)
249+
# Halve tau to avoid negative populations, as per Cao et al. (2006), Section 3.3
233250
tau /= 2
234251
continue
235252
end

0 commit comments

Comments
 (0)