Skip to content

Commit c843e48

Browse files
authored
Merge pull request #116 from isaacsas/faster-recursive-content
further optimize addreaction! for large systems
2 parents 6640558 + 2fae1e6 commit c843e48

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

src/maketype.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ function addreaction!(rn::DiffEqBase.AbstractReactionNetwork, rateexpr::ExprValu
285285
else # isa Expr
286286

287287
# mimicing ReactionStruct constructor for now, but this should be optimized...
288-
newdeps = unique!(recursive_content(rate_DE, species(rn), Vector{Symbol}()))
288+
newdeps = unique!(recursive_content(rate_DE, speciesmap(rn), Vector{Symbol}()))
289289
ismassaction = length(newdeps)==length(intersect!(dependents, newdeps)) ? true : false
290290
dependents = newdeps
291291
end

src/reaction_network.jl

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ end
7575
################# query-based macros:
7676

7777
"""
78-
@min_reaction_network
78+
@min_reaction_network
7979
8080
Generates a subtype of an `AbstractReactionNetwork` that only encodes a chemical
8181
reaction network. Use [`addodes!`](@ref), [`addsdes!`](@ref) or
@@ -160,10 +160,10 @@ function min_coordinate(name, ex::Expr, p, scale_noise)
160160

161161
# Build the type
162162
exprs = Vector{Expr}(undef,0)
163-
typeex,constructorex = maketype(DiffEqBase.AbstractReactionNetwork, name, nothing, nothing,
164-
nothing, nothing, nothing, nothing, nothing, nothing,
165-
nothing, nothing, syms, scale_noise; params=params,
166-
reactions=reactions, symjac=nothing, syms_to_ints=reactants,
163+
typeex,constructorex = maketype(DiffEqBase.AbstractReactionNetwork, name, nothing, nothing,
164+
nothing, nothing, nothing, nothing, nothing, nothing,
165+
nothing, nothing, syms, scale_noise; params=params,
166+
reactions=reactions, symjac=nothing, syms_to_ints=reactants,
167167
params_to_ints=parameters)
168168
push!(exprs,typeex)
169169
push!(exprs,constructorex)
@@ -213,7 +213,7 @@ function get_minnetwork(ex::Expr, p)
213213
end
214214

215215
#Generates a vector containing a number of reaction structures, each containing the infromation about one reaction.
216-
function get_reactions(ex::Expr, reactions = Vector{ReactionStruct}(undef,0))
216+
function get_reactions(ex::Expr, reactions = Vector{ReactionStruct}(undef,0))
217217
for line in ex.args
218218
(line.head != :tuple) && (continue)
219219
(rate,r_line) = line.args
@@ -253,8 +253,8 @@ struct ReactionStruct
253253
dependants::Vector{Symbol}
254254
is_pure_mass_action::Bool
255255

256-
function ReactionStruct(s::Vector{ReactantStruct}, p::Vector{ReactantStruct},
257-
ro::ExprValues, rde::ExprValues, rssa::ExprValues,
256+
function ReactionStruct(s::Vector{ReactantStruct}, p::Vector{ReactantStruct},
257+
ro::ExprValues, rde::ExprValues, rssa::ExprValues,
258258
dep::Vector{Symbol}, isma::Bool)
259259
new(s,p,ro,rde,rssa,dep,isma)
260260
end
@@ -331,6 +331,13 @@ function add_reactants!(ex::ExprValues, mult::Int, reactants::Vector{ReactantStr
331331
return reactants
332332
end
333333

334+
#For each reaction, sets its dependencies and whenever it is a pure mass action reaction.
335+
function update_reaction_info(reactions::Vector{ReactionStruct},syms::Vector{Symbol})
336+
for i = 1:length(reactions)
337+
reactions[i] = ReactionStruct(reactions[i],syms)
338+
end
339+
end
340+
334341
#From the vector with all reactions, generates a dictionary with all reactants. Each reactant will point to a number so that X --> means X will be replaced with u[1] in the equations.
335342
function get_reactants(reactions::Vector{ReactionStruct})
336343
reactants = OrderedDict{Symbol,Int}()
@@ -356,13 +363,6 @@ function get_parameters(p)
356363
return parameters
357364
end
358365

359-
#For each reaction, sets its dependencies and whenever it is a pure mass action reaction.
360-
function update_reaction_info(reactions::Vector{ReactionStruct},syms::Vector{Symbol})
361-
for i = 1:length(reactions)
362-
reactions[i] = ReactionStruct(reactions[i],syms)
363-
end
364-
end
365-
366366
#Produces an array of expressions. Each entry corresponds to a line in the function f, which constitutes the deterministic part of the system. The Expressions can be used for debugging, making LaTex code, or creating the real f function for simulating the network.
367367
function get_f(reactions::Vector{ReactionStruct}, reactants::OrderedDict{Symbol,Int})
368368
f = Vector{Expr}(undef,length(reactants))
@@ -376,11 +376,11 @@ function get_f(reactions::Vector{ReactionStruct}, reactants::OrderedDict{Symbol,
376376
end
377377
end
378378

379-
for line in f
379+
for line in f
380380
if length(line.args[2].args) == 1
381381
@assert line.args[2].args[1] == :+
382382
line.args[2] = 0
383-
else
383+
else
384384
line.args[2] = clean_subtractions(line.args[2])
385385
end
386386
end
@@ -575,14 +575,23 @@ end
575575

576576
#Parses an expression, and returns a set with all symbols in the expression, which is also a part of the provided vector with symbols (syms).
577577
function recursive_content(ex,syms::Vector{Symbol},content::Vector{Symbol})
578-
if typeof(ex)!=Expr
578+
if ex isa Symbol
579579
in(ex,syms) && push!(content,ex)
580-
else
580+
elseif ex isa Expr
581581
foreach(arg -> recursive_content(arg,syms,content), ex.args)
582582
end
583583
return content
584584
end
585585

586+
function recursive_content(ex,symsmap::OrderedDict{Symbol,Int},content::Vector{Symbol})
587+
if ex isa Symbol
588+
haskey(symsmap,ex) && push!(content,ex)
589+
elseif ex isa Expr
590+
foreach(arg -> recursive_content(arg,symsmap,content), ex.args)
591+
end
592+
return content
593+
end
594+
586595
#Makes the various jacobian elements required.
587596
function get_jacs(f_rhs::Vector{ExprValues}, syms::Vector{Symbol}, reactants::OrderedDict{Symbol,Int}, parameters::OrderedDict{Symbol,Int})
588597
symjac = calculate_symjac(deepcopy(f_rhs), syms)

0 commit comments

Comments
 (0)