@@ -93,27 +93,44 @@ function compute_hor(reactant_stoch, numjumps)
9393 return hor
9494end
9595
96- function compute_gi (u, nu, hor, i)
96+ function precompute_reaction_conditions (reactant_stoch, hor, numspecies, numjumps)
97+ # Initialize reaction_conditions as a vector of vectors of tuples
98+ reaction_conditions = [Vector () for _ in 1 : numspecies]
99+ for j in 1 : numjumps
100+ for (spec_idx, stoch) in reactant_stoch[j]
101+ if stoch > 0 # Species is a reactant
102+ push! (reaction_conditions[spec_idx], (j, stoch, hor[j]))
103+ end
104+ end
105+ end
106+ return reaction_conditions
107+ end
108+
109+ function compute_gi (u, reaction_conditions, i)
97110 max_gi = 1
98- for j in 1 : size (nu, 2 )
99- if nu[i, j] < 0 # Species i is a substrate
100- if hor[j] == 1
101- max_gi = max (max_gi, 1 )
102- elseif hor[j] == 2 || hor[j] == 3
103- stoch = abs (nu[i, j])
104- if stoch >= 2
105- gi = 2 / stoch + 1 / (stoch - 1 )
106- max_gi = max (max_gi, ceil (Int, gi))
107- elseif stoch == 1
108- max_gi = max (max_gi, hor[j])
109- end
111+ for (j, nu_ij, hor_j) in reaction_conditions[i]
112+ if hor_j == 1
113+ max_gi = max (max_gi, 1 )
114+ elseif hor_j == 2
115+ if nu_ij == 1
116+ max_gi = max (max_gi, 2 )
117+ elseif nu_ij >= 2
118+ gi = u[i] * (2 / nu_ij + 1 / (nu_ij - 1 ))
119+ max_gi = max (max_gi, ceil (Int, gi))
120+ end
121+ elseif hor_j == 3
122+ if nu_ij == 1
123+ max_gi = max (max_gi, 3 )
124+ elseif nu_ij >= 2
125+ gi = 1.5 * u[i] * (2 / nu_ij + 1 / (nu_ij - 1 ))
126+ max_gi = max (max_gi, ceil (Int, gi))
110127 end
111128 end
112129 end
113130 return max_gi
114131end
115132
116- function compute_tau_explicit (u, rate_cache, nu, hor, p, t, epsilon, rate, dtmin)
133+ function compute_tau_explicit (u, rate_cache, nu, p, t, epsilon, rate, dtmin, reaction_conditions, numjumps )
117134 rate (rate_cache, u, p, t)
118135 tau = Inf
119136 for i in 1 : length (u)
@@ -123,7 +140,7 @@ function compute_tau_explicit(u, rate_cache, nu, hor, p, t, epsilon, rate, dtmin
123140 mu += nu[i, j] * rate_cache[j]
124141 sigma2 += nu[i, j]^ 2 * rate_cache[j]
125142 end
126- gi = compute_gi (u, nu, hor , i)
143+ gi = compute_gi (u, reaction_conditions , i)
127144 bound = max (epsilon * u[i] / gi, 1.0 )
128145 mu_term = abs (mu) > 0 ? bound / abs (mu) : Inf
129146 sigma_term = sigma2 > 0 ? bound^ 2 / sigma2 : Inf
@@ -168,16 +185,17 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleAdaptiveTauLeaping;
168185 t_end = tspan[2 ]
169186 epsilon = alg. epsilon
170187
171- # Extract stochiometry once from MassActionJump
188+ # Extract net stoichiometry for state updates
172189 nu = zeros (float (eltype (u0)), length (u0), numjumps)
173190 for j in 1 : numjumps
174191 for (spec_idx, stoch) in maj. net_stoch[j]
175192 nu[spec_idx, j] = stoch
176193 end
177194 end
178- # Extract reactant stochiometry for hor
195+ # Extract reactant stoichiometry for hor and gi
179196 reactant_stoch = maj. reactant_stoch
180197 hor = compute_hor (reactant_stoch, numjumps)
198+ reaction_conditions = precompute_reaction_conditions (reactant_stoch, hor, length (u0), numjumps)
181199
182200 # Set up saveat_times
183201 saveat_times = nothing
@@ -193,7 +211,7 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleAdaptiveTauLeaping;
193211
194212 while t_current < t_end
195213 rate (rate_cache, u_current, p, t_current)
196- tau = compute_tau_explicit (u_current, rate_cache, nu, hor, p, t_current, epsilon, rate, dtmin)
214+ tau = compute_tau_explicit (u_current, rate_cache, nu, p, t_current, epsilon, rate, dtmin, reaction_conditions, numjumps )
197215 tau = min (tau, t_end - t_current)
198216 if ! isempty (saveat_times) && save_idx <= length (saveat_times) && t_current + tau > saveat_times[save_idx]
199217 tau = saveat_times[save_idx] - t_current
@@ -222,7 +240,7 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleAdaptiveTauLeaping;
222240
223241 # Save state if at a saveat time or if saveat is empty
224242 if isempty (saveat_times) || (save_idx <= length (saveat_times) && t_new >= saveat_times[save_idx])
225- push! (usave, u_new)
243+ push! (usave, copy ( u_new) )
226244 push! (tsave, t_new)
227245 if ! isempty (saveat_times) && t_new >= saveat_times[save_idx]
228246 save_idx += 1
0 commit comments