-
-
Notifications
You must be signed in to change notification settings - Fork 82
Add API functions for the other kinds of matrixes that a CRN ODE system can be factored into #1134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 22 commits
e3c9d33
17d1cd5
9e23705
f8df438
389d09a
7d6cbf5
4922561
536a50d
835b4ff
b89329a
4a691b4
211ac81
3bdf298
3128628
b921fed
c82c80e
fcab9c3
cf89a29
77b606f
e5eec18
6e68436
7487e0d
b3dce88
b777518
a782851
32deeea
3f1d1ca
ce8e110
8551454
a6d924a
b8e3255
2d1c9c8
aa12d24
b823256
bfe849f
6c25931
5c9bf74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -192,6 +192,122 @@ function complexstoichmat(::Type{Matrix{Int}}, rn::ReactionSystem, rcs) | |
| Z | ||
| end | ||
|
|
||
| @doc raw""" | ||
| laplacianmat(rn::ReactionSystem, pmap=Dict(); sparse=false) | ||
|
|
||
| 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. | ||
| Returns a symbolic matrix by default, but will return a numerical matrix if parameter values are specified via pmap. | ||
| """ | ||
| function laplacianmat(rn::ReactionSystem, pmap = Dict(); sparse = false) | ||
| D = incidencemat(rn; sparse); K = fluxmat(rn, pmap; sparse) | ||
| D*K | ||
| end | ||
|
|
||
| @doc raw""" | ||
| fluxmat(rn::ReactionSystem, pmap = Dict(); sparse=false) | ||
|
|
||
| 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). | ||
| 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`. | ||
| """ | ||
| function fluxmat(rn::ReactionSystem, pmap::Dict = Dict(); sparse=false) | ||
| rates = reactionrates(rn) | ||
|
|
||
| !isempty(pmap) && (rates = substitutevals(rn, pmap, parameters(rn), rates)) | ||
vyudu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| rcmap = reactioncomplexmap(rn); nc = length(rcmap); nr = length(rates) | ||
vyudu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| mtype = eltype(rates) <: Symbolics.BasicSymbolic ? Num : eltype(rates) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it has to, doesn't seem like it's actually possible to have zeros in this matrix if the eltype is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't it by type There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that better than being There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't want to return mixtures of Nums and non-Nums across different methods, so we should not re-wrap internal symbolics. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually this creates some issues for the sparse method (can't really do any arithmetic with a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you want to internally use Num I guess that is ok, but yeah, we should unwrap before returning to users for consistency. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about returning a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually that doesn't work, nevermind, when you find the Laplacian matrix (D*K) type inference infers its eltype as Any anyway. Since it's the sparse matrix support that's causing the issue I think it might just be better to not allow the sparse kwarg for now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, I guess just stick with |
||
| if sparse | ||
| return fluxmat(SparseMatrixCSC{mtype, Int}, rcmap, rates) | ||
| else | ||
| return fluxmat(Matrix{mtype}, rcmap, rates) | ||
| end | ||
| end | ||
|
|
||
| function fluxmat(::Type{SparseMatrixCSC{T, Int}}, rcmap, rates) where T | ||
| Is = Int[] | ||
| Js = Int[] | ||
| Vs = T[] | ||
| for (i, (complex, rxs)) in enumerate(rcmap) | ||
| for (rx, dir) in rxs | ||
| dir == -1 && begin | ||
| push!(Is, rx) | ||
| push!(Js, i) | ||
| push!(Vs, rates[rx]) | ||
| end | ||
| end | ||
| end | ||
| Z = sparse(Is, Js, Vs, length(rates), length(rcmap)) | ||
| end | ||
|
|
||
| function fluxmat(::Type{Matrix{T}}, rcmap, rates) where T | ||
| nr = length(rates); nc = length(rcmap) | ||
| K = zeros(T, nr, nc) | ||
| for (i, (complex, rxs)) in enumerate(rcmap) | ||
| for (rx, dir) in rxs | ||
| dir == -1 && (K[rx, i] = rates[rx]) | ||
| end | ||
| end | ||
| K | ||
| end | ||
|
|
||
| function fluxmat(rn::ReactionSystem, pmap::Vector; sparse = false) | ||
| pdict = Dict(pmap) | ||
| fluxmat(rn, pdict; sparse) | ||
| end | ||
|
|
||
| function fluxmat(rn::ReactionSystem, pmap::Tuple; sparse = false) | ||
| pdict = Dict(pmap) | ||
| fluxmat(rn, pdict; sparse) | ||
| end | ||
|
|
||
| # 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. | ||
| function substitutevals(rn::ReactionSystem, map::Dict, syms, symexprs) | ||
| length(map) != length(syms) && error("Incorrect number of parameter-value pairs were specified.") | ||
| map = symmap_to_varmap(rn, map) | ||
| map = Dict(ModelingToolkit.value(k) => v for (k, v) in map) | ||
| vals = [substitute(expr, map) for expr in symexprs] | ||
| end | ||
|
|
||
| """ | ||
| massactionvector(rn::ReactionSystem, scmap = Dict(); combinatoric_ratelaws = true) | ||
|
|
||
| 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)``. | ||
| 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. | ||
| If the `combinatoric_ratelaws` option is set, will include prefactors for that (see [introduction to Catalyst's rate laws](@ref introduction_to_catalyst_ratelaws). | ||
| """ | ||
| function massactionvector(rn::ReactionSystem, scmap::Dict = Dict(); combinatoric_ratelaws = true) | ||
| r = numreactions(rn); rxs = reactions(rn) | ||
| sm = speciesmap(rn); specs = species(rn) | ||
|
|
||
| if !all(r -> ismassaction(r, rn), rxs) | ||
| error("The supplied ReactionSystem has reactions that are not ismassaction. The mass action vector is only defined for pure mass action networks.") | ||
| end | ||
|
|
||
| !isempty(scmap) && (specs = substitutevals(rn, scmap, specs, specs)) | ||
|
|
||
| vtype = eltype(specs) <: Symbolics.BasicSymbolic ? Num : eltype(specs) | ||
| Φ = Vector{vtype}() | ||
| rcmap = reactioncomplexmap(rn) | ||
| for comp in keys(reactioncomplexmap(rn)) | ||
| subs = map(ce -> getfield(ce, :speciesid), comp) | ||
| stoich = map(ce -> getfield(ce, :speciesstoich), comp) | ||
| maprod = prod(vtype[specs[s]^α for (s, α) in zip(subs, stoich)]) | ||
| combinatoric_ratelaws && (maprod /= prod(map(factorial, stoich))) | ||
| push!(Φ, maprod) | ||
| end | ||
|
|
||
| Φ | ||
| end | ||
|
|
||
| function massactionvector(rn::ReactionSystem, scmap::Tuple; combinatoric_ratelaws = true) | ||
| sdict = Dict(scmap) | ||
| massactionvector(rn, sdict; combinatoric_ratelaws) | ||
| end | ||
|
|
||
| function massactionvector(rn::ReactionSystem, scmap::Vector; combinatoric_ratelaws = true) | ||
| sdict = Dict(scmap) | ||
| massactionvector(rn, sdict; combinatoric_ratelaws) | ||
| end | ||
|
|
||
| @doc raw""" | ||
| complexoutgoingmat(network::ReactionSystem; sparse=false) | ||
|
|
||
|
|
@@ -787,7 +903,7 @@ function isdetailedbalanced(rs::ReactionSystem, parametermap::Dict; abstol=0, re | |
| elseif !isreversible(rs) | ||
| return false | ||
| elseif !all(r -> ismassaction(r, rs), reactions(rs)) | ||
| error("The supplied ReactionSystem has reactions that are not ismassaction. Testing for being complex balanced is currently only supported for pure mass action networks.") | ||
| error("The supplied ReactionSystem has reactions that are not ismassaction. Testing for being detailed balanced is currently only supported for pure mass action networks.") | ||
| end | ||
|
|
||
| isforestlike(rs) && deficiency(rs) == 0 && return true | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.