Skip to content

Commit 0b72d4c

Browse files
added references
1 parent b5f77f5 commit 0b72d4c

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
@@ -81,6 +81,8 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleTauLeaping;
8181
end
8282

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

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

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

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

0 commit comments

Comments
 (0)