Skip to content

Commit a345891

Browse files
committed
up
1 parent fe9e68a commit a345891

File tree

1 file changed

+0
-156
lines changed

1 file changed

+0
-156
lines changed

src/networkapi.jl

Lines changed: 0 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,159 +1656,3 @@ end
16561656
# Checks if a unit consist of exponents with base 1 (and is this unitless).
16571657
unitless_exp(u) = istree(u) && (operation(u) == ^) && (arguments(u)[1] == 1)
16581658

1659-
"""
1660-
iscomplexbalanced(rs::ReactionSystem, parametermap)
1661-
1662-
Constructively compute whether a network will have complex-balanced equilibrium
1663-
solutions, following the method in van der Schaft et al., [2015](https://link.springer.com/article/10.1007/s10910-015-0498-2#Sec3). Accepts a dictionary, vector, or tuple ofvariable-to-value mappings, e.g. [k1 => 1.0, k2 => 2.0,...].
1664-
"""
1665-
1666-
function iscomplexbalanced(rs::ReactionSystem, parametermap::Dict)
1667-
if length(parametermap) != numparams(rs)
1668-
error("Incorrect number of parameters specified.")
1669-
end
1670-
1671-
pmap = symmap_to_varmap(rs, parametermap)
1672-
pmap = Dict(ModelingToolkit.value(k) => v for (k,v) in pmap)
1673-
1674-
sm = speciesmap(rs)
1675-
cm = reactioncomplexmap(rs)
1676-
complexes, D = reactioncomplexes(rs)
1677-
rxns = reactions(rs)
1678-
nc = length(complexes); nr = numreactions(rs); nm = numspecies(rs)
1679-
1680-
if !all(r->ismassaction(r, rs), rxns)
1681-
error("The supplied ReactionSystem has reactions that are not ismassaction. Testing for being complex balanced is currently only supported for pure mass action networks.")
1682-
end
1683-
1684-
rates = [substitute(rate, pmap) for rate in reactionrates(rs)]
1685-
1686-
# Construct kinetic matrix, K
1687-
K = zeros(nr, nc)
1688-
for c in 1:nc
1689-
complex = complexes[c]
1690-
for (r, dir) in cm[complex]
1691-
rxn = rxns[r]
1692-
if dir == -1
1693-
K[r, c] = rates[r]
1694-
end
1695-
end
1696-
end
1697-
1698-
L = -D*K
1699-
S = netstoichmat(rs)
1700-
1701-
# Compute ρ using the matrix-tree theorem
1702-
g = incidencematgraph(rs)
1703-
R = ratematrix(rs, rates)
1704-
ρ = matrixtree(g, R)
1705-
1706-
# Determine if 1) ρ is positive and 2) D^T Ln ρ lies in the image of S^T
1707-
if all(>(0), ρ)
1708-
img = D'*log.(ρ)
1709-
if rank(S') == rank(hcat(S', img)) return true else return false end
1710-
else
1711-
return false
1712-
end
1713-
end
1714-
1715-
function iscomplexbalanced(rs::ReactionSystem, parametermap::Vector{Pair{Symbol, Float64}})
1716-
pdict = Dict(parametermap)
1717-
iscomplexbalanced(rs, pdict)
1718-
end
1719-
1720-
function iscomplexbalanced(rs::ReactionSystem, parametermap::Tuple{Pair{Symbol, Float64}})
1721-
pdict = Dict(parametermap)
1722-
iscomplexbalanced(rs, pdict)
1723-
end
1724-
1725-
iscomplexbalanced(rs::ReactionSystem, parametermap) = error("Parameter map must be a dictionary, tuple, or vector of symbol/value pairs.")
1726-
1727-
1728-
"""
1729-
ratematrix(rs::ReactionSystem, parametermap)
1730-
1731-
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.
1732-
"""
1733-
1734-
function ratematrix(rs::ReactionSystem, rates::Vector{Float64})
1735-
complexes, D = reactioncomplexes(rs)
1736-
n = length(complexes)
1737-
rxns = reactions(rs)
1738-
ratematrix = zeros(n, n)
1739-
1740-
for r in 1:length(rxns)
1741-
rxn = rxns[r]
1742-
s = findfirst(==(-1), @view D[:,r])
1743-
p = findfirst(==(1), @view D[:,r])
1744-
ratematrix[s, p] = rates[r]
1745-
end
1746-
ratematrix
1747-
end
1748-
1749-
function ratematrix(rs::ReactionSystem, parametermap::Dict{Symbol, Float64})
1750-
if length(parametermap) != numparams(rs)
1751-
error("The number of reaction rates must be equal to the number of parameters")
1752-
end
1753-
pmap = symmap_to_varmap(rs, parametermap)
1754-
rates = [substitute(rate, pmap) for rate in reactionrates(rs)]
1755-
ratematrix(rs, rates)
1756-
end
1757-
1758-
function ratematrix(rs::ReactionSystem, parametermap::Vector{Pair{Symbol, Float64}})
1759-
pdict = Dict(parametermap)
1760-
ratematrix(rs, pdict)
1761-
end
1762-
1763-
function ratematrix(rs::ReactionSystem, parametermap::Tuple{Pair{Symbol, Float64}})
1764-
pdict = Dict(parametermap)
1765-
ratematrix(rs, pdict)
1766-
end
1767-
1768-
ratematrix(rs::ReactionSystem, parametermap) = error("Parameter map must be a dictionary, tuple, or vector of symbol/value pairs.")
1769-
1770-
### BELOW: Helper functions for iscomplexbalanced
1771-
1772-
function matrixtree(g::SimpleDiGraph, distmx::Matrix)
1773-
n = nv(g)
1774-
if size(distmx) != (n, n)
1775-
error("Size of distance matrix is incorrect")
1776-
end
1777-
1778-
π = zeros(n)
1779-
1780-
if !Graphs.is_connected(g)
1781-
ccs = Graphs.connected_components(g)
1782-
for cc in ccs
1783-
sg, vmap = Graphs.induced_subgraph(g, cc)
1784-
distmx_s = distmx[cc, cc]
1785-
π_j = matrixtree(sg, distmx_s)
1786-
π[cc] = π_j
1787-
end
1788-
return π
1789-
end
1790-
1791-
# generate all spanning trees
1792-
ug = SimpleGraph(SimpleDiGraph(g))
1793-
trees = collect(Combinatorics.combinations(collect(edges(ug)), n-1))
1794-
trees = SimpleGraph.(trees)
1795-
trees = filter!(t->isempty(Graphs.cycle_basis(t)), trees)
1796-
1797-
# constructed rooted trees for every vertex, compute sum
1798-
for v in 1:n
1799-
rootedTrees = [reverse(Graphs.bfs_tree(t, v, dir=:in)) for t in trees]
1800-
π[v] = sum([treeweight(t, g, distmx) for t in rootedTrees])
1801-
end
1802-
1803-
# sum the contributions
1804-
return π
1805-
end
1806-
1807-
function treeweight(t::SimpleDiGraph, g::SimpleDiGraph, distmx::Matrix)
1808-
prod = 1
1809-
for e in edges(t)
1810-
s = Graphs.src(e); t = Graphs.dst(e)
1811-
prod *= distmx[s, t]
1812-
end
1813-
prod
1814-
end

0 commit comments

Comments
 (0)