Skip to content

Commit 2d4c263

Browse files
committed
Merge branch 'master' of https://github.com/SciML/Catalyst.jl into graph-docs
comment out HC
2 parents fbdc21d + 51b9d0b commit 2d4c263

File tree

8 files changed

+789
-601
lines changed

8 files changed

+789
-601
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ RuntimeGeneratedFunctions = "0.5.12"
6767
SciMLBase = "2.57.2"
6868
Setfield = "1"
6969
# StructuralIdentifiability = "0.5.8"
70-
SymbolicUtils = "< 3.8"
70+
SymbolicUtils = "3.8.1"
7171
Symbolics = "6.22"
7272
Unitful = "1.12.4"
7373
julia = "1.10"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ be found in its corresponding research paper, [Catalyst: Fast and flexible model
7272
- Model steady states can be [computed through homotopy continuation](https://docs.sciml.ai/Catalyst/stable/steady_state_functionality/homotopy_continuation/) using [HomotopyContinuation.jl](https://github.com/JuliaHomotopyContinuation/HomotopyContinuation.jl) (which can find *all* steady states of systems with multiple ones), by [forward ODE simulations](https://docs.sciml.ai/Catalyst/stable/steady_state_functionality/nonlinear_solve/#steady_state_solving_simulation) using [SteadyStateDiffEq.jl](https://github.com/SciML/SteadyStateDiffEq.jl), or by [numerically solving steady-state nonlinear equations](https://docs.sciml.ai/Catalyst/stable/steady_state_functionality/nonlinear_solve/#steady_state_solving_nonlinear) using [NonlinearSolve.jl](https://github.com/SciML/NonlinearSolve.jl).
7373
- [BifurcationKit.jl](https://github.com/bifurcationkit/BifurcationKit.jl) can be used to [compute bifurcation diagrams](https://docs.sciml.ai/Catalyst/stable/steady_state_functionality/bifurcation_diagrams/) of model steady states (including finding periodic orbits).
7474
- [DynamicalSystems.jl](https://github.com/JuliaDynamics/DynamicalSystems.jl) can be used to compute model [basins of attraction](https://docs.sciml.ai/Catalyst/stable/steady_state_functionality/dynamical_systems/#dynamical_systems_basins_of_attraction), [Lyapunov spectrums](https://docs.sciml.ai/Catalyst/stable/steady_state_functionality/dynamical_systems/#dynamical_systems_lyapunov_exponents), and other dynamical system properties.
75-
- [StructuralIdentifiability.jl](https://github.com/SciML/StructuralIdentifiability.jl) can be used to [perform structural identifiability analysis](https://docs.sciml.ai/Catalyst/stable/inverse_problems/structural_identifiability/).
7675
- [Optimization.jl](https://github.com/SciML/Optimization.jl), [DiffEqParamEstim.jl](https://github.com/SciML/DiffEqParamEstim.jl), and [PEtab.jl](https://github.com/sebapersson/PEtab.jl) can all be used to [fit model parameters to data](https://sebapersson.github.io/PEtab.jl/stable/Define_in_julia/).
7776
- [GlobalSensitivity.jl](https://github.com/SciML/GlobalSensitivity.jl) can be used to perform [global sensitivity analysis](https://docs.sciml.ai/Catalyst/stable/inverse_problems/global_sensitivity_analysis/) of model behaviors.
7877
- [SciMLSensitivity.jl](https://github.com/SciML/SciMLSensitivity.jl) can be used to compute local sensitivities of functions containing forward model simulations.
78+
<!-- - [StructuralIdentifiability.jl](https://github.com/SciML/StructuralIdentifiability.jl) can be used to [perform structural identifiability analysis](https://docs.sciml.ai/Catalyst/stable/inverse_problems/structural_identifiability/). -->
7979

8080
#### Features of packages built upon Catalyst
8181
- Catalyst [`ReactionSystem`](@ref)s can be [imported from SBML files](https://docs.sciml.ai/Catalyst/stable/model_creation/model_file_loading_and_export/#Loading-SBML-files-using-SBMLImporter.jl-and-SBMLToolkit.jl) via [SBMLImporter.jl](https://github.com/sebapersson/SBMLImporter.jl) and [SBMLToolkit.jl](https://github.com/SciML/SBMLToolkit.jl), and [from BioNetGen .net files](https://docs.sciml.ai/Catalyst/stable/model_creation/model_file_loading_and_export/#file_loading_rni_net) and various stoichiometric matrix network representations using [ReactionNetworkImporters.jl](https://github.com/SciML/ReactionNetworkImporters.jl).

docs/src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ etc).
4141
- Model steady states can be [computed through homotopy continuation](@ref homotopy_continuation) using [HomotopyContinuation.jl](https://github.com/JuliaHomotopyContinuation/HomotopyContinuation.jl) (which can find *all* steady states of systems with multiple ones), by [forward ODE simulations](@ref steady_state_solving_simulation) using [SteadyStateDiffEq.jl)](https://github.com/SciML/SteadyStateDiffEq.jl), or by [numerically solving steady-state nonlinear equations](@ref steady_state_solving_nonlinear) using [NonlinearSolve.jl](https://github.com/SciML/NonlinearSolve.jl).
4242
[BifurcationKit.jl](https://github.com/bifurcationkit/BifurcationKit.jl) can be used to compute bifurcation diagrams of model steady states (including finding periodic orbits).
4343
- [DynamicalSystems.jl](https://github.com/JuliaDynamics/DynamicalSystems.jl) can be used to compute model [basins of attraction](@ref dynamical_systems_basins_of_attraction), [Lyapunov spectrums](@ref dynamical_systems_lyapunov_exponents), and other dynamical system properties.
44-
<!--- [StructuralIdentifiability.jl](https://github.com/SciML/StructuralIdentifiability.jl) can be used to perform structural identifiability analysis.-->
4544
- [Optimization.jl](https://github.com/SciML/Optimization.jl), [DiffEqParamEstim.jl](https://github.com/SciML/DiffEqParamEstim.jl), and [PEtab.jl](https://github.com/sebapersson/PEtab.jl) can all be used to [fit model parameters to data](https://sebapersson.github.io/PEtab.jl/stable/Define_in_julia/).
4645
- [GlobalSensitivity.jl](https://github.com/SciML/GlobalSensitivity.jl) can be used to perform [global sensitivity analysis](@ref global_sensitivity_analysis) of model behaviors.
4746
- [SciMLSensitivity.jl](https://github.com/SciML/SciMLSensitivity.jl) can be used to compute local sensitivities of functions containing forward model simulations.
47+
<!--- [StructuralIdentifiability.jl](https://github.com/SciML/StructuralIdentifiability.jl) can be used to perform structural identifiability analysis.-->
4848

4949
#### [Features of packages built upon Catalyst](@id doc_index_features_other_packages)
5050
- Catalyst [`ReactionSystem`](@ref)s can be [imported from SBML files](@ref model_file_import_export_sbml) via [SBMLImporter.jl](https://github.com/sebapersson/SBMLImporter.jl) and [SBMLToolkit.jl](https://github.com/SciML/SBMLToolkit.jl), and [from BioNetGen .net files](@ref model_file_import_export_sbml_rni_net) and various stoichiometric matrix network representations using [ReactionNetworkImporters.jl](https://github.com/SciML/ReactionNetworkImporters.jl).

src/Catalyst.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ export @reaction_network, @network_component, @reaction, @species
115115
# Network analysis functionality.
116116
include("network_analysis.jl")
117117
export reactioncomplexmap, reactioncomplexes, incidencemat
118-
export complexstoichmat
119-
export complexoutgoingmat, incidencematgraph, linkageclasses, stronglinkageclasses,
118+
export complexstoichmat, laplacianmat, fluxmat, massactionvector, complexoutgoingmat
119+
export incidencematgraph, linkageclasses, stronglinkageclasses,
120120
terminallinkageclasses, deficiency, subnetworks
121121
export linkagedeficiencies, isreversible, isweaklyreversible
122122
export conservationlaws, conservedquantities, conservedequations, conservationlaw_constants

src/network_analysis.jl

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,143 @@ function complexstoichmat(::Type{Matrix{Int}}, rn::ReactionSystem, rcs)
192192
Z
193193
end
194194

195+
@doc raw"""
196+
laplacianmat(rn::ReactionSystem, pmap=Dict(); sparse=false)
197+
198+
Return the negative of the graph Laplacian of the reaction network. The ODE system of a chemical reaction network can be factorized as ``\frac{dx}{dt} = Y A_k Φ(x)``, where ``Y`` is the [`complexstoichmat`](@ref) and ``A_k`` is the negative of the graph Laplacian, and ``Φ`` is the [`massactionvector`](@ref). ``A_k`` is an n-by-n matrix, where n is the number of complexes, where ``A_{ij} = k_{ij}`` if a reaction exists between the two complexes and 0 otherwise.
199+
Returns a symbolic matrix by default, but will return a numerical matrix if parameter values are specified via pmap.
200+
201+
**Warning**: Unlike other Catalyst functions, the `laplacianmat` function will return a `Matrix{Num}` in the symbolic case. This is to allow easier computation of the matrix decomposition of the ODEs, and to ensure that multiplying the sparse form of the matrix will work.
202+
"""
203+
function laplacianmat(rn::ReactionSystem, pmap::Dict = Dict(); sparse = false)
204+
D = incidencemat(rn; sparse)
205+
K = fluxmat(rn, pmap; sparse)
206+
D * K
207+
end
208+
209+
Base.zero(::Type{Union{R, Symbolics.BasicSymbolic{Real}}}) where R <: Real = zero(R)
210+
Base.one(::Type{Union{R, Symbolics.BasicSymbolic{Real}}}) where R <: Real = one(R)
211+
212+
@doc raw"""
213+
fluxmat(rn::ReactionSystem, pmap = Dict(); sparse=false)
214+
215+
Return an r×c matrix ``K`` such that, if complex ``j`` is the substrate complex of reaction ``i``, then ``K_{ij} = k``, the rate constant for this reaction. Mostly a helper function for the network Laplacian, [`laplacianmat`](@ref). Has the useful property that ``\frac{dx}{dt} = S*K*Φ(x)``, where S is the [`netstoichmat`](@ref) or net stoichiometry matrix and ``Φ(x)`` is the [`massactionvector`](@ref).
216+
Returns a symbolic matrix by default, but will return a numerical matrix if rate constants are specified as a `Tuple`, `Vector`, or `Dict` of symbol-value pairs via `pmap`.
217+
218+
**Warning**: Unlike other Catalyst functions, the `fluxmat` function will return a `Matrix{Num}` in the symbolic case. This is to allow easier computation of the matrix decomposition of the ODEs, and to ensure that multiplying the sparse form of the matrix will work.
219+
"""
220+
function fluxmat(rn::ReactionSystem, pmap::Dict = Dict(); sparse=false)
221+
rates = if isempty(pmap)
222+
reactionrates(rn)
223+
else
224+
substitutevals(rn, pmap, parameters(rn), reactionrates(rn))
225+
end
226+
227+
rcmap = reactioncomplexmap(rn)
228+
nc = length(rcmap)
229+
nr = length(rates)
230+
mtype = eltype(rates) <: Symbolics.BasicSymbolic ? Num : eltype(rates)
231+
if sparse
232+
return fluxmat(SparseMatrixCSC{mtype, Int}, rcmap, rates)
233+
else
234+
return fluxmat(Matrix{mtype}, rcmap, rates)
235+
end
236+
end
237+
238+
function fluxmat(::Type{SparseMatrixCSC{T, Int}}, rcmap, rates) where T
239+
Is = Int[]
240+
Js = Int[]
241+
Vs = T[]
242+
for (i, (complex, rxs)) in enumerate(rcmap)
243+
for (rx, dir) in rxs
244+
dir == -1 && begin
245+
push!(Is, rx)
246+
push!(Js, i)
247+
push!(Vs, rates[rx])
248+
end
249+
end
250+
end
251+
Z = sparse(Is, Js, Vs, length(rates), length(rcmap))
252+
end
253+
254+
function fluxmat(::Type{Matrix{T}}, rcmap, rates) where T
255+
nr = length(rates)
256+
nc = length(rcmap)
257+
K = zeros(T, nr, nc)
258+
for (i, (complex, rxs)) in enumerate(rcmap)
259+
for (rx, dir) in rxs
260+
dir == -1 && (K[rx, i] = rates[rx])
261+
end
262+
end
263+
K
264+
end
265+
266+
function fluxmat(rn::ReactionSystem, pmap::Vector)
267+
pdict = Dict(pmap)
268+
fluxmat(rn, pdict)
269+
end
270+
271+
function fluxmat(rn::ReactionSystem, pmap::Tuple)
272+
pdict = Dict(pmap)
273+
fluxmat(rn, pdict)
274+
end
275+
276+
# Helper to substitute values into a (vector of) symbolic expressions. The syms are the symbols to substitute and the symexprs are the expressions to substitute into.
277+
function substitutevals(rn::ReactionSystem, map::Dict, syms, symexprs)
278+
length(map) != length(syms) && error("Incorrect number of parameter-value pairs were specified.")
279+
map = symmap_to_varmap(rn, map)
280+
map = Dict(ModelingToolkit.value(k) => v for (k, v) in map)
281+
vals = [substitute(expr, map) for expr in symexprs]
282+
end
283+
284+
"""
285+
massactionvector(rn::ReactionSystem, scmap = Dict(); combinatoric_ratelaws = true)
286+
287+
Return the vector whose entries correspond to the "mass action products" of each complex. For example, given the complex A + B, the corresponding entry of the vector would be ``A*B``, and for the complex 2X + Y, the corresponding entry would be ``X^2*Y``. The ODE system of a chemical reaction network can be factorized as ``\frac{dx}{dt} = Y A_k Φ(x)``, where ``Y`` is the [`complexstoichmat`](@ref) and ``A_k`` is the negative of the [`laplacianmat`](@ref). This utility returns ``Φ(x)``.
288+
Returns a symbolic vector by default, but will return a numerical vector if species concentrations are specified as a tuple, vector, or dictionary via scmap.
289+
If the `combinatoric_ratelaws` option is set, will include prefactors for that (see [introduction to Catalyst's rate laws](@ref introduction_to_catalyst_ratelaws). Will default to the default for the system.
290+
291+
**Warning**: Unlike other Catalyst functions, the `massactionvector` function will return a `Vector{Num}` in the symbolic case. This is to allow easier computation of the matrix decomposition of the ODEs.
292+
"""
293+
function massactionvector(rn::ReactionSystem, scmap::Dict = Dict(); combinatoric_ratelaws = Catalyst.get_combinatoric_ratelaws(rn))
294+
r = numreactions(rn)
295+
rxs = reactions(rn)
296+
sm = speciesmap(rn)
297+
298+
specs = if isempty(scmap)
299+
species(rn)
300+
else
301+
substitutevals(rn, scmap, species(rn), species(rn))
302+
end
303+
304+
if !all(r -> ismassaction(r, rn), rxs)
305+
error("The supplied ReactionSystem has reactions that are not ismassaction. The mass action vector is only defined for pure mass action networks.")
306+
end
307+
308+
vtype = eltype(specs) <: Symbolics.BasicSymbolic ? Num : eltype(specs)
309+
Φ = Vector{vtype}()
310+
rcmap = reactioncomplexmap(rn)
311+
for comp in keys(reactioncomplexmap(rn))
312+
subs = map(ce -> getfield(ce, :speciesid), comp)
313+
stoich = map(ce -> getfield(ce, :speciesstoich), comp)
314+
maprod = prod(vtype[specs[s]^α for (s, α) in zip(subs, stoich)])
315+
combinatoric_ratelaws && (maprod /= prod(map(factorial, stoich)))
316+
push!(Φ, maprod)
317+
end
318+
319+
Φ
320+
end
321+
322+
function massactionvector(rn::ReactionSystem, scmap::Tuple; combinatoric_ratelaws = Catalyst.get_combinatoric_ratelaws(rn))
323+
sdict = Dict(scmap)
324+
massactionvector(rn, sdict; combinatoric_ratelaws)
325+
end
326+
327+
function massactionvector(rn::ReactionSystem, scmap::Vector; combinatoric_ratelaws = Catalyst.get_combinatoric_ratelaws(rn))
328+
sdict = Dict(scmap)
329+
massactionvector(rn, sdict; combinatoric_ratelaws)
330+
end
331+
195332
@doc raw"""
196333
complexoutgoingmat(network::ReactionSystem; sparse=false)
197334
@@ -787,7 +924,7 @@ function isdetailedbalanced(rs::ReactionSystem, parametermap::Dict; abstol=0, re
787924
elseif !isreversible(rs)
788925
return false
789926
elseif !all(r -> ismassaction(r, rs), reactions(rs))
790-
error("The supplied ReactionSystem has reactions that are not ismassaction. Testing for being complex balanced is currently only supported for pure mass action networks.")
927+
error("The supplied ReactionSystem has reactions that are not ismassaction. Testing for being detailed balanced is currently only supported for pure mass action networks.")
791928
end
792929

793930
isforestlike(rs) && deficiency(rs) == 0 && return true

0 commit comments

Comments
 (0)