Skip to content

Commit 69725c9

Browse files
committed
added network_analysis
1 parent a345891 commit 69725c9

File tree

2 files changed

+107
-1658
lines changed

2 files changed

+107
-1658
lines changed

src/network_analysis.jl

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,3 +769,110 @@ function iscomplexbalanced(rs::ReactionSystem, parametermap::Dict)
769769
# Determine if 1) ρ is positive and 2) D^T Ln ρ lies in the image of S^T
770770
if all(>(0), ρ)
771771
img = D'*log.(ρ)
772+
if rank(S') == rank(hcat(S', img)) return true else return false end
773+
else
774+
return false
775+
end
776+
end
777+
778+
function iscomplexbalanced(rs::ReactionSystem, parametermap::Vector{Pair{Symbol, Float64}})
779+
pdict = Dict(parametermap)
780+
iscomplexbalanced(rs, pdict)
781+
end
782+
783+
function iscomplexbalanced(rs::ReactionSystem, parametermap::Tuple{Pair{Symbol, Float64}})
784+
pdict = Dict(parametermap)
785+
iscomplexbalanced(rs, pdict)
786+
end
787+
788+
iscomplexbalanced(rs::ReactionSystem, parametermap) = error("Parameter map must be a dictionary, tuple, or vector of symbol/value pairs.")
789+
790+
791+
"""
792+
ratematrix(rs::ReactionSystem, parametermap)
793+
794+
Given a reaction system with n complexes, outputs an n-by-n matrix where R_{ij} is the rate constant of the reaction between complex i and complex j.
795+
"""
796+
797+
function ratematrix(rs::ReactionSystem, rates::Vector{Float64})
798+
complexes, D = reactioncomplexes(rs)
799+
n = length(complexes)
800+
rxns = reactions(rs)
801+
ratematrix = zeros(n, n)
802+
803+
for r in 1:length(rxns)
804+
rxn = rxns[r]
805+
s = findfirst(==(-1), @view D[:,r])
806+
p = findfirst(==(1), @view D[:,r])
807+
ratematrix[s, p] = rates[r]
808+
end
809+
ratematrix
810+
end
811+
812+
function ratematrix(rs::ReactionSystem, parametermap::Dict{Symbol, Float64})
813+
if length(parametermap) != numparams(rs)
814+
error("The number of reaction rates must be equal to the number of parameters")
815+
end
816+
pmap = symmap_to_varmap(rs, parametermap)
817+
rates = [substitute(rate, pmap) for rate in reactionrates(rs)]
818+
ratematrix(rs, rates)
819+
end
820+
821+
function ratematrix(rs::ReactionSystem, parametermap::Vector{Pair{Symbol, Float64}})
822+
pdict = Dict(parametermap)
823+
ratematrix(rs, pdict)
824+
end
825+
826+
function ratematrix(rs::ReactionSystem, parametermap::Tuple{Pair{Symbol, Float64}})
827+
pdict = Dict(parametermap)
828+
ratematrix(rs, pdict)
829+
end
830+
831+
ratematrix(rs::ReactionSystem, parametermap) = error("Parameter map must be a dictionary, tuple, or vector of symbol/value pairs.")
832+
833+
### BELOW: Helper functions for iscomplexbalanced
834+
835+
function matrixtree(g::SimpleDiGraph, distmx::Matrix)
836+
n = nv(g)
837+
if size(distmx) != (n, n)
838+
error("Size of distance matrix is incorrect")
839+
end
840+
841+
π = zeros(n)
842+
843+
if !Graphs.is_connected(g)
844+
ccs = Graphs.connected_components(g)
845+
for cc in ccs
846+
sg, vmap = Graphs.induced_subgraph(g, cc)
847+
distmx_s = distmx[cc, cc]
848+
π_j = matrixtree(sg, distmx_s)
849+
π[cc] = π_j
850+
end
851+
return π
852+
end
853+
854+
# generate all spanning trees
855+
ug = SimpleGraph(SimpleDiGraph(g))
856+
trees = collect(Combinatorics.combinations(collect(edges(ug)), n-1))
857+
trees = SimpleGraph.(trees)
858+
trees = filter!(t->isempty(Graphs.cycle_basis(t)), trees)
859+
860+
# constructed rooted trees for every vertex, compute sum
861+
for v in 1:n
862+
rootedTrees = [reverse(Graphs.bfs_tree(t, v, dir=:in)) for t in trees]
863+
π[v] = sum([treeweight(t, g, distmx) for t in rootedTrees])
864+
end
865+
866+
# sum the contributions
867+
return π
868+
end
869+
870+
function treeweight(t::SimpleDiGraph, g::SimpleDiGraph, distmx::Matrix)
871+
prod = 1
872+
for e in edges(t)
873+
s = Graphs.src(e); t = Graphs.dst(e)
874+
prod *= distmx[s, t]
875+
end
876+
prod
877+
end
878+

0 commit comments

Comments
 (0)