Skip to content

Commit 2f793b1

Browse files
committed
Merge branch 'deficiency-one'
2 parents 134041d + 4aa5e97 commit 2f793b1

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

src/Catalyst.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export @reaction_network, @network_component, @reaction, @species
127127
include("network_analysis.jl")
128128
export reactioncomplexmap, reactioncomplexes, incidencemat
129129
export complexstoichmat
130-
export complexoutgoingmat, incidencematgraph, linkageclasses, deficiency, subnetworks
130+
export complexoutgoingmat, incidencematgraph, linkageclasses, stronglinkageclasses, terminallinkageclasses, deficiency, subnetworks
131131
export linkagedeficiencies, isreversible, isweaklyreversible
132132
export conservationlaws, conservedquantities, conservedequations, conservationlaw_constants
133133

src/network_analysis.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,3 +886,22 @@ function treeweight(t::SimpleDiGraph, g::SimpleDiGraph, distmx::Matrix)
886886
end
887887
prod
888888
end
889+
890+
### DEFICIENCY ONE
891+
892+
"""
893+
satisfiesdeficiencyone(rn::ReactionSystem)
894+
895+
Check if a reaction network obeys the conditions of the deficiency one theorem, which ensures that there is only one equilibrium for every positive stoichiometric compatibility class.
896+
"""
897+
898+
function satisfiesdeficiencyone(rn::ReactionSystem)
899+
δ = deficiency(rn)
900+
δ_l = linkagedeficiencies(rn)
901+
902+
complexes, D = reactioncomplexes(rn)
903+
lcs = linkageclasses(rn); tslcs = terminallinkageclasses(rn)
904+
905+
δ_l .<= 1 && sum(δ_l) = δ && length(lcs) == length(tslcs)
906+
end
907+

src/reactionsystem.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Base.@kwdef mutable struct NetworkProperties{I <: Integer, V <: BasicSymbolic{Re
7878
isempty::Bool = true
7979
netstoichmat::Union{Matrix{Int}, SparseMatrixCSC{Int, Int}} = Matrix{Int}(undef, 0, 0)
8080
conservationmat::Matrix{I} = Matrix{I}(undef, 0, 0)
81+
cyclemat::Matrix{I} = Matrix{I}(undef, 0, 0)
8182
col_order::Vector{Int} = Int[]
8283
rank::Int = 0
8384
nullity::Int = 0
@@ -93,6 +94,8 @@ Base.@kwdef mutable struct NetworkProperties{I <: Integer, V <: BasicSymbolic{Re
9394
complexoutgoingmat::Union{Matrix{Int}, SparseMatrixCSC{Int, Int}} = Matrix{Int}(undef, 0, 0)
9495
incidencegraph::Graphs.SimpleDiGraph{Int} = Graphs.DiGraph()
9596
linkageclasses::Vector{Vector{Int}} = Vector{Vector{Int}}(undef, 0)
97+
stronglinkageclasses::Vector{Vector{Int}} = Vector{Vector{Int}}(undef, 0)
98+
terminallinkageclasses::Vector{Vector{Int}} = Vector{Vector{Int}}(undef, 0)
9699
deficiency::Int = 0
97100
end
98101
#! format: on

test/network_analysis/network_properties.jl

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,81 @@ let
326326
@test Catalyst.iscomplexbalanced(rn, rates) == true
327327
end
328328

329+
### STRONG LINKAGE CLASS TESTS
330+
331+
let
332+
rn = @reaction_network begin
333+
(k1, k2), A <--> B + C
334+
k3, B + C --> D
335+
k4, D --> E
336+
(k5, k6), E <--> 2F
337+
k7, 2F --> D
338+
(k8, k9), D + E <--> G
339+
end
340+
341+
rcs, D = reactioncomplexes(rn)
342+
slcs = stronglinkageclasses(rn)
343+
tslcs = terminallinkageclasses(rn)
344+
@test length(slcs) == 3
345+
@test length(tslcs) == 2
346+
@test issubset([[1,2], [3,4,5], [6,7]], slcs)
347+
@test issubset([[3,4,5], [6,7]], tslcs)
348+
end
349+
350+
let
351+
rn = @reaction_network begin
352+
(k1, k2), A <--> B + C
353+
k3, B + C --> D
354+
k4, D --> E
355+
(k5, k6), E <--> 2F
356+
k7, 2F --> D
357+
(k8, k9), D + E --> G
358+
end
359+
360+
rcs, D = reactioncomplexes(rn)
361+
slcs = stronglinkageclasses(rn)
362+
tslcs = terminallinkageclasses(rn)
363+
@test length(slcs) == 4
364+
@test length(tslcs) == 2
365+
@test issubset([[1,2], [3,4,5], [6], [7]], slcs)
366+
@test issubset([[3,4,5], [7]], tslcs)
367+
end
368+
369+
let
370+
rn = @reaction_network begin
371+
(k1, k2), A <--> B + C
372+
(k3, k4), B + C <--> D
373+
k5, D --> E
374+
(k6, k7), E <--> 2F
375+
k8, 2F --> D
376+
(k9, k10), D + E <--> G
377+
end
378+
379+
rcs, D = reactioncomplexes(rn)
380+
slcs = stronglinkageclasses(rn)
381+
tslcs = terminallinkageclasses(rn)
382+
@test length(slcs) == 2
383+
@test length(tslcs) == 2
384+
@test issubset([[1,2,3,4,5], [6,7]], slcs)
385+
@test issubset([[1,2,3,4,5], [6,7]], tslcs)
386+
end
387+
388+
let
389+
rn = @reaction_network begin
390+
(k1, k2), A <--> 2B
391+
k3, A --> C + D
392+
(k4, k5), C + D <--> E
393+
k6, 2B --> F
394+
(k7, k8), F <--> 2G
395+
(k9, k10), 2G <--> H
396+
k11, H --> F
397+
end
398+
399+
rcs, D = reactioncomplexes(rn)
400+
slcs = stronglinkageclasses(rn)
401+
tslcs = terminallinkageclasses(rn)
402+
@test length(slcs) == 3
403+
@test length(tslcs) == 2
404+
@test issubset([[1,2], [3,4], [5,6,7]], slcs)
405+
@test issubset([[3,4], [5,6,7]], tslcs)
406+
end

0 commit comments

Comments
 (0)