Skip to content

Commit

Permalink
Merge pull request #973 from SciML/test_expansion
Browse files Browse the repository at this point in the history
Expand tests
  • Loading branch information
TorkelE authored Jul 16, 2024
2 parents cae7118 + ff6aa63 commit df6befd
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 9 deletions.
15 changes: 9 additions & 6 deletions src/network_analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,8 @@ end
iscomplexbalanced(rs::ReactionSystem, parametermap)
Constructively compute whether a network will have complex-balanced equilibrium
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 of variable-to-value mappings, e.g. [k1 => 1.0, k2 => 2.0,...].
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 of variable-to-value mappings, e.g. [k1 => 1.0, k2 => 2.0,...].
"""

function iscomplexbalanced(rs::ReactionSystem, parametermap::Dict)
Expand Down Expand Up @@ -795,12 +796,12 @@ function iscomplexbalanced(rs::ReactionSystem, parametermap::Dict)
end
end

function iscomplexbalanced(rs::ReactionSystem, parametermap::Vector{Pair{Symbol, Float64}})
function iscomplexbalanced(rs::ReactionSystem, parametermap::Vector{<:Pair})
pdict = Dict(parametermap)
iscomplexbalanced(rs, pdict)
end

function iscomplexbalanced(rs::ReactionSystem, parametermap::Tuple{Pair{Symbol, Float64}})
function iscomplexbalanced(rs::ReactionSystem, parametermap::Tuple)
pdict = Dict(parametermap)
iscomplexbalanced(rs, pdict)
end
Expand All @@ -812,7 +813,9 @@ end
"""
ratematrix(rs::ReactionSystem, parametermap)
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. Accepts a dictionary, vector, or tuple of variable-to-value mappings, e.g. [k1 => 1.0, k2 => 2.0,...].
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. Accepts a dictionary, vector, or tuple
of variable-to-value mappings, e.g. [k1 => 1.0, k2 => 2.0,...].
"""

function ratematrix(rs::ReactionSystem, rates::Vector{Float64})
Expand Down Expand Up @@ -842,12 +845,12 @@ function ratematrix(rs::ReactionSystem, parametermap::Dict)
ratematrix(rs, rates)
end

function ratematrix(rs::ReactionSystem, parametermap::Vector{Pair{Symbol, Float64}})
function ratematrix(rs::ReactionSystem, parametermap::Vector{<:Pair})
pdict = Dict(parametermap)
ratematrix(rs, pdict)
end

function ratematrix(rs::ReactionSystem, parametermap::Tuple{Pair{Symbol, Float64}})
function ratematrix(rs::ReactionSystem, parametermap::Tuple)
pdict = Dict(parametermap)
ratematrix(rs, pdict)
end
Expand Down
10 changes: 10 additions & 0 deletions test/miscellaneous_tests/stability_computation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,13 @@ let
u = [1.0]
@test_throws Exception steady_state_stability(u, rn, p; tol = 1e2)
end

# Test that stability computation for non-autonomous (t-dependent) systems throws error.
let
rn = @reaction_network begin
(p + 1/(1+t),d), 0 <--> X
end
p = [:p => 1.0, :d => 1.0]
u = [1.0]
@test_throws Exception steady_state_stability(u, rn, p)
end
134 changes: 133 additions & 1 deletion test/network_analysis/network_properties.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
### Prepares Tests ###

# Fetch packages.
using Catalyst, LinearAlgebra, Test, StableRNGs
using Catalyst, LinearAlgebra, Test, SparseArrays

# Sets stable rng number.
using StableRNGs
rng = StableRNG(514)

### Basic Tests ###

# Tests basic `ReactionComplex` properties.
let
rcs1 = Catalyst.ReactionComplex([1, 2], [1, 3])
rcs2 = Catalyst.ReactionComplex([1, 2], [1, 3])
rcs3 = Catalyst.ReactionComplex([3], [2])
@test rcs1 == rcs2
@test rcs2 != rcs3
@test length(rcs1) == 2
@test length(rcs3) == 1
end

# Tests network analysis functions on MAPK network (by comparing to manually computed outputs).
let
MAPK = @reaction_network MAPK begin
Expand Down Expand Up @@ -203,6 +216,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == false
end

let
rn = @reaction_network begin
k1, A --> B
Expand All @@ -215,6 +229,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == false
end

let
rn = @reaction_network begin
k1, A --> B
Expand All @@ -229,6 +244,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == false
end

let
rn = @reaction_network begin
(k2, k1), A <--> 2B
Expand All @@ -244,6 +260,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == true
end

let
rn = @reaction_network begin
(k2, k1), A + E <--> AE
Expand All @@ -257,6 +274,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == false
end

let
rn = @reaction_network begin
(k2, k1), A + E <--> AE
Expand All @@ -270,6 +288,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == true
end

let
rn = @reaction_network begin (k2, k1), A + B <--> 2A end
rev = true
Expand All @@ -280,6 +299,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == true
end

let
rn = @reaction_network begin
k1, A + B --> 3A
Expand All @@ -295,6 +315,7 @@ let
rates = Dict(zip(parameters(rn), k))
@test Catalyst.iscomplexbalanced(rn, rates) == true
end

let
rn = @reaction_network begin
(k2, k1), A + E <--> AE
Expand Down Expand Up @@ -409,3 +430,114 @@ let
@test issubset([[1,2], [3,4], [5,6,7]], slcs)
@test issubset([[3,4], [5,6,7]], tslcs)
end

### Other Network Properties Tests ###

# Tests outgoing complexes matrices (1).
# Checks using dense and sparse representation.
let
# Declares network.
rs = @reaction_network begin
k1, X1 + X2 --> X3 + X4
(k2,k2), X3 + X4 <--> X1
k3, X1 --> X2
k4, X1 + X2 --> X2
end

# Compares to manually computed matrix.
cmplx_out_mat = [
-1 0 0 0 -1;
0 -1 0 0 0;
0 0 -1 -1 0;
0 0 0 0 0;
]
complexoutgoingmat(rs) == cmplx_out_mat
complexoutgoingmat(rs; sparse = true) == sparse(cmplx_out_mat)
end

# Tests outgoing complexes matrices (2).
# Checks using dense and sparse representation.
let
# Declares network.
rs = @reaction_network begin
k1, X1 --> X2
k2, X2 --> X3
k3, X3 --> X4
k4, X3 --> X5
k5, X2 --> X1
k6, X1 --> X2
end

# Compares to manually computed matrix.
cmplx_out_mat = [
-1 0 0 0 0 -1;
0 -1 0 0 -1 0;
0 0 -1 -1 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
]
complexoutgoingmat(rs)
complexoutgoingmat(rs; sparse = true) == sparse(cmplx_out_mat)
end

# Tests that `iscomplexbalanced` works for different rate inputs.
# Tests that non-valid rate input yields and error
let
# Declares network.
rn = @reaction_network begin
k1, 3A + 2B --> 3C
k2, B + 4D --> 2E
k3, 2E --> 3C
(k4, k5), B + 4D <--> 3A + 2B
k6, F --> B + 4D
k7, 3C --> F
end

# Declares rate alternatives.
k = rand(rng, numparams(rn))
rates_vec = Pair.(parameters(rn), k)
rates_tup = Tuple(rates_vec)
rates_dict = Dict(rates_vec)
rates_invalid = k

# Tests that inputs are handled correctly.
@test Catalyst.iscomplexbalanced(rn, rates_vec) == Catalyst.iscomplexbalanced(rn, rates_tup)
@test Catalyst.iscomplexbalanced(rn, rates_tup) == Catalyst.iscomplexbalanced(rn, rates_dict)
@test_throws Exception Catalyst.iscomplexbalanced(rn, k)
end

# Tests rate matrix computation for various input types.
let
# Declares network and its known rate matrix.
rn = @reaction_network begin
(k2, k1), A1 <--> A2 + A3
k3, A2 + A3 --> A4
k4, A4 --> A5
(k6, k5), A5 <--> 2A6
k7, 2A6 --> A4
k8, A4 + A5 --> A7
end
rate_mat = [
0.0 1.0 0.0 0.0 0.0 0.0 0.0;
2.0 0.0 3.0 0.0 0.0 0.0 0.0;
0.0 0.0 0.0 4.0 0.0 0.0 0.0;
0.0 0.0 0.0 0.0 5.0 0.0 0.0;
0.0 0.0 7.0 6.0 0.0 0.0 0.0;
0.0 0.0 0.0 0.0 0.0 0.0 8.0;
0.0 0.0 0.0 0.0 0.0 0.0 0.0;
]

# Declares rate alternatives.
rate_vals = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
rates_vec = Pair.(parameters(rn), rate_vals)
rates_tup = Tuple(rates_vec)
rates_dict = Dict(rates_vec)
rates_invalid = reshape(rate_vals, 1, 8)

# Tests that all input types generates the correct rate matrix.
Catalyst.ratematrix(rn, rate_vals) == rate_mat
Catalyst.ratematrix(rn, rates_vec) == rate_mat
Catalyst.ratematrix(rn, rates_tup) == rate_mat
Catalyst.ratematrix(rn, rates_dict) == rate_mat
@test_throws Exception Catalyst.iscomplexbalanced(rn, rates_invalid)
end
2 changes: 2 additions & 0 deletions test/reactionsystem_core/reaction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ end
# Tests creation.
# Tests basic accessor functions.
# Tests that repeated metadata entries are not permitted.
# Tests that attempting to access non-existent metadata throws an error.
let
@parameters k
@species X(t) X2(t)
Expand All @@ -135,6 +136,7 @@ let
@test Catalyst.hasmetadata(r, :noise_scaling)
@test !Catalyst.hasmetadata(r, :nonexisting_metadata)
@test Catalyst.getmetadata(r, :noise_scaling) == 0.0
@test_throws Exception Catalyst.getmetadata(r, :misc)

metadata_repeated = [:noise_scaling => 0.0, :noise_scaling => 1.0, :metadata_entry => "unused"]
@test_throws Exception Reaction(k, [X], [X2], [2], [1]; metadata=metadata_repeated)
Expand Down
Loading

0 comments on commit df6befd

Please sign in to comment.