Skip to content

Commit 9283fa6

Browse files
removed equilibrium_pair logic
1 parent f7f0780 commit 9283fa6

File tree

2 files changed

+41
-28
lines changed

2 files changed

+41
-28
lines changed

src/simple_regular_solve.jl

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,11 @@ struct ImplicitTauLeaping <: DiffEqBase.DEAlgorithm
5656
nc::Int # Critical reaction threshold
5757
nstiff::Float64 # Stiffness threshold for switching
5858
delta::Float64 # Partial equilibrium threshold
59-
equilibrium_pairs::Vector{Tuple{Int,Int}} # Reversible reaction pairs
6059
end
6160

6261
# Default constructor
63-
ImplicitTauLeaping(; epsilon=0.05, nc=10, nstiff=100.0, delta=0.05, equilibrium_pairs=[(1, 2)]) =
64-
ImplicitTauLeaping(epsilon, nc, nstiff, delta, equilibrium_pairs)
62+
ImplicitTauLeaping(; epsilon=0.05, nc=10, nstiff=100.0, delta=0.05) =
63+
ImplicitTauLeaping(epsilon, nc, nstiff, delta)
6564

6665
function DiffEqBase.solve(jump_prob::JumpProblem, alg::ImplicitTauLeaping; seed=nothing)
6766
# Boilerplate setup
@@ -91,7 +90,6 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::ImplicitTauLeaping; seed=
9190
nc = alg.nc
9291
nstiff = alg.nstiff
9392
delta = alg.delta
94-
equilibrium_pairs = alg.equilibrium_pairs
9593
t_end = tspan[2]
9694

9795
# Compute stoichiometry matrix from c function
@@ -108,17 +106,30 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::ImplicitTauLeaping; seed=
108106
end
109107
nu = compute_stoichiometry(c, u0, numjumps)
110108

109+
# Detect reversible reaction pairs
110+
function find_reversible_pairs(nu)
111+
pairs = Vector{Tuple{Int,Int}}()
112+
for j in 1:numjumps
113+
for k in (j+1):numjumps
114+
if nu[:, j] == -nu[:, k]
115+
push!(pairs, (j, k))
116+
end
117+
end
118+
end
119+
return pairs
120+
end
121+
equilibrium_pairs = find_reversible_pairs(nu)
122+
111123
# Helper function to compute g_i (approximation from Cao et al., 2006)
112124
function compute_gi(u, nu, i)
113-
# Simplified g_i: highest order of reaction involving species i
114125
max_order = 1.0
115126
for j in 1:numjumps
116127
if abs(nu[i, j]) > 0
117-
# Approximate reaction order based on propensity (heuristic)
118128
rate(rate_cache, u, p, t[end])
119129
if rate_cache[j] > 0
120-
order = 1.0 # Assume first-order for simplicity
121-
if j == 1 # For SIR infection (S*I), assume second-order
130+
order = 1.0
131+
# Heuristic: if reaction involves multiple species, assume higher order
132+
if sum(abs.(nu[:, j])) > abs(nu[i, j])
122133
order = 2.0
123134
end
124135
max_order = max(max_order, order)
@@ -218,14 +229,15 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::ImplicitTauLeaping; seed=
218229
if norm(residual) < tol
219230
break
220231
end
221-
# Approximate Jacobian
232+
# Approximate Jacobian (diagonal approximation for simplicity)
222233
J = Diagonal(ones(length(u_new)))
223234
for j in 1:numjumps
224235
for i in 1:length(u_new)
225-
if j == 1 && i in [1, 2] # Infection: β*S*I
226-
J[i, i] += nu[i, j] * tau * p[1] * (i == 1 ? u_new[2] : u_new[1])
227-
elseif j == 2 && i == 2 # Recovery: ν*I
228-
J[i, i] += nu[i, j] * tau * p[2]
236+
# Heuristic derivative: assume linear or quadratic propensity
237+
rate(rate_new, u_new, p, t_prev + tau)
238+
if rate_new[j] > 0
239+
# Estimate derivative based on stoichiometry
240+
J[i, i] += nu[i, j] * tau * rate_new[j] / max(u_new[i], 1.0)
229241
end
230242
end
231243
end
@@ -266,7 +278,7 @@ function DiffEqBase.solve(jump_prob::JumpProblem, alg::ImplicitTauLeaping; seed=
266278
method = use_implicit ? :implicit : :explicit
267279

268280
# Check if tau1 is too small
269-
if tau1 < 10 / a0
281+
if a0 > 0 && tau1 < 10 / a0
270282
# Use SSA for a few steps
271283
steps = method == :implicit ? 10 : 100
272284
for _ in 1:steps

test/regular_jumps.jl

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,32 +40,33 @@ prob = DiscreteProblem([999, 1, 0], (0.0, 250.0))
4040
jump_prob = JumpProblem(prob, Direct(), rj; rng = rng)
4141
sol = solve(jump_prob, SimpleTauLeaping(); dt = 1.0)
4242

43+
# Decaying Dimerization Model
4344
# Parameters
4445
c1 = 1.0 # S1 -> 0
4546
c2 = 10.0 # S1 + S1 <- S2
4647
c3 = 1000.0 # S1 + S1 -> S2
4748
c4 = 0.1 # S2 -> S3
48-
p = (c1, c2, c3, c4)
49+
p_dim = (c1, c2, c3, c4)
4950

50-
regular_rate_implicit = (out, u, p, t) -> begin
51+
regular_rate_dim = (out, u, p, t) -> begin
5152
out[1] = p[1] * u[1] # S1 -> 0
5253
out[2] = p[2] * u[2] # S1 + S1 <- S2
5354
out[3] = p[3] * u[1] * (u[1] - 1) / 2 # S1 + S1 -> S2
5455
out[4] = p[4] * u[2] # S2 -> S3
5556
end
5657

57-
regular_c_implicit = (dc, u, p, t, counts, mark) -> begin
58-
dc .= 0.0
59-
dc[1] = -counts[1] - 2 * counts[3] + 2 * counts[2] # S1: -decay - 2*forward + 2*backward
60-
dc[2] = counts[3] - counts[2] - counts[4] # S2: +forward - backward - decay
61-
dc[3] = counts[4] # S3: +decay
58+
regular_c_dim = (du, u, p, t, counts, mark) -> begin
59+
du .= 0.0
60+
du[1] = -counts[1] - 2 * counts[3] + 2 * counts[2] # S1: -decay - 2*forward + 2*backward
61+
du[2] = counts[3] - counts[2] - counts[4] # S2: +forward - backward - decay
62+
du[3] = counts[4] # S3: +decay
6263
end
6364

64-
u0 = [10000.0, 0.0, 0.0] # S1, S2, S3
65-
tspan = (0.0, 4.0)
65+
u0_dim = [10000.0, 0.0, 0.0] # S1, S2, S3
66+
tspan_dim = (0.0, 4.0)
6667

67-
# Create JumpProblem with proper parameter passing
68-
prob_disc = DiscreteProblem(u0, tspan, p)
69-
rj = RegularJump(regular_rate_implicit, regular_c_implicit, 4)
70-
jump_prob = JumpProblem(prob_disc, Direct(), rj; rng=StableRNG(12345))
71-
sol = solve(jump_prob, ImplicitTauLeaping())
68+
prob_disc_dim = DiscreteProblem(u0_dim, tspan_dim, p_dim)
69+
rj_dim = RegularJump(regular_rate_dim, regular_c_dim, 4)
70+
jump_prob_dim = JumpProblem(prob_disc_dim, Direct(), rj_dim; rng=rng)
71+
72+
sol = solve(jump_prob_dim, ImplicitTauLeaping())

0 commit comments

Comments
 (0)