@@ -92,27 +92,44 @@ function compute_hor(reactant_stoch, numjumps)
9292 return hor
9393end
9494
95- function compute_gi (u, nu, hor, i)
95+ function precompute_reaction_conditions (reactant_stoch, hor, numspecies, numjumps)
96+ # Initialize reaction_conditions as a vector of vectors of tuples
97+ reaction_conditions = [Vector () for _ in 1 : numspecies]
98+ for j in 1 : numjumps
99+ for (spec_idx, stoch) in reactant_stoch[j]
100+ if stoch > 0 # Species is a reactant
101+ push! (reaction_conditions[spec_idx], (j, stoch, hor[j]))
102+ end
103+ end
104+ end
105+ return reaction_conditions
106+ end
107+
108+ function compute_gi (u, reaction_conditions, i)
96109 max_gi = 1
97- for j in 1 : size (nu, 2 )
98- if nu[i, j] < 0 # Species i is a substrate
99- if hor[j] == 1
100- max_gi = max (max_gi, 1 )
101- elseif hor[j] == 2 || hor[j] == 3
102- stoch = abs (nu[i, j])
103- if stoch >= 2
104- gi = 2 / stoch + 1 / (stoch - 1 )
105- max_gi = max (max_gi, ceil (Int, gi))
106- elseif stoch == 1
107- max_gi = max (max_gi, hor[j])
108- end
110+ for (j, nu_ij, hor_j) in reaction_conditions[i]
111+ if hor_j == 1
112+ max_gi = max (max_gi, 1 )
113+ elseif hor_j == 2
114+ if nu_ij == 1
115+ max_gi = max (max_gi, 2 )
116+ elseif nu_ij >= 2
117+ gi = u[i] * (2 / nu_ij + 1 / (nu_ij - 1 ))
118+ max_gi = max (max_gi, ceil (Int, gi))
119+ end
120+ elseif hor_j == 3
121+ if nu_ij == 1
122+ max_gi = max (max_gi, 3 )
123+ elseif nu_ij >= 2
124+ gi = 1.5 * u[i] * (2 / nu_ij + 1 / (nu_ij - 1 ))
125+ max_gi = max (max_gi, ceil (Int, gi))
109126 end
110127 end
111128 end
112129 return max_gi
113130end
114131
115- function compute_tau_explicit (u, rate_cache, nu, hor, p, t, epsilon, rate, dtmin)
132+ function compute_tau_explicit (u, rate_cache, nu, p, t, epsilon, rate, dtmin, reaction_conditions, numjumps )
116133 rate (rate_cache, u, p, t)
117134 tau = Inf
118135 for i in 1 : length (u)
@@ -122,7 +139,7 @@ function compute_tau_explicit(u, rate_cache, nu, hor, p, t, epsilon, rate, dtmin
122139 mu += nu[i, j] * rate_cache[j]
123140 sigma2 += nu[i, j]^ 2 * rate_cache[j]
124141 end
125- gi = compute_gi (u, nu, hor , i)
142+ gi = compute_gi (u, reaction_conditions , i)
126143 bound = max (epsilon * u[i] / gi, 1.0 )
127144 mu_term = abs (mu) > 0 ? bound / abs (mu) : Inf
128145 sigma_term = sigma2 > 0 ? bound^ 2 / sigma2 : Inf
@@ -167,16 +184,17 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleAdaptiveTauLeaping;
167184 t_end = tspan[2 ]
168185 epsilon = alg. epsilon
169186
170- # Extract stochiometry once from MassActionJump
187+ # Extract net stoichiometry for state updates
171188 nu = zeros (float (eltype (u0)), length (u0), numjumps)
172189 for j in 1 : numjumps
173190 for (spec_idx, stoch) in maj. net_stoch[j]
174191 nu[spec_idx, j] = stoch
175192 end
176193 end
177- # Extract reactant stochiometry for hor
194+ # Extract reactant stoichiometry for hor and gi
178195 reactant_stoch = maj. reactant_stoch
179196 hor = compute_hor (reactant_stoch, numjumps)
197+ reaction_conditions = precompute_reaction_conditions (reactant_stoch, hor, length (u0), numjumps)
180198
181199 # Set up saveat_times
182200 saveat_times = nothing
@@ -192,7 +210,7 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleAdaptiveTauLeaping;
192210
193211 while t_current < t_end
194212 rate (rate_cache, u_current, p, t_current)
195- tau = compute_tau_explicit (u_current, rate_cache, nu, hor, p, t_current, epsilon, rate, dtmin)
213+ tau = compute_tau_explicit (u_current, rate_cache, nu, p, t_current, epsilon, rate, dtmin, reaction_conditions, numjumps )
196214 tau = min (tau, t_end - t_current)
197215 if ! isempty (saveat_times) && save_idx <= length (saveat_times) && t_current + tau > saveat_times[save_idx]
198216 tau = saveat_times[save_idx] - t_current
@@ -221,7 +239,7 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::SimpleAdaptiveTauLeaping;
221239
222240 # Save state if at a saveat time or if saveat is empty
223241 if isempty (saveat_times) || (save_idx <= length (saveat_times) && t_new >= saveat_times[save_idx])
224- push! (usave, u_new)
242+ push! (usave, copy ( u_new) )
225243 push! (tsave, t_new)
226244 if ! isempty (saveat_times) && t_new >= saveat_times[save_idx]
227245 save_idx += 1
0 commit comments