Skip to content

Commit c9e4643

Browse files
authored
Add QN-specific reinit! function (#15)
This fix allows the use of `Attractors.jl` to find steady states in QNs.
1 parent 2c14a15 commit c9e4643

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ HerbSearch = "3008d8e8-f9aa-438a-92ed-26e9c7b4829f"
1616
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
1717
MetaGraphsNext = "fa8bd995-216d-47f1-8a91-f3b68fbeb377"
1818
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
19+
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
1920
SoleLogics = "b002da8f-3cb3-4d91-bbe3-2953433912b5"
21+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2022
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2123

2224
[compat]
@@ -32,6 +34,8 @@ HerbSearch = "0.4.1"
3234
MLStyle = "0.4.17"
3335
MetaGraphsNext = "0.7"
3436
Random = "1.10"
37+
SciMLBase = "2.74.1"
3538
SoleLogics = "0.12.0"
39+
StaticArrays = "1.9.12"
3640
Statistics = "1.10"
3741
julia = "1.6"

src/qualitative_networks.jl

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import DynamicalSystemsBase: get_state, set_state!
22

33
using AbstractTrees: Leaves
4-
using DynamicalSystemsBase: ArbitrarySteppable
4+
using DynamicalSystemsBase: ArbitrarySteppable, current_parameters, initial_state
55
using HerbConstraints: addconstraint!, DomainRuleNode, VarNode, Ordered, Forbidden
66
using HerbCore: AbstractGrammar, RuleNode, get_rule
77
using HerbGrammar: add_rule!, rulenode2expr, @csgrammar
88
using HerbSearch: rand
99
using MLStyle: @match
1010
using MetaGraphsNext: MetaGraph, SimpleDiGraph, add_edge!, nv, labels
11+
import SciMLBase
12+
using StaticArrays: MVector
1113

1214
base_qn_grammar = @csgrammar begin
1315
Val = Val + Val
@@ -202,11 +204,11 @@ with an [`ArbitrarySteppable`](https://juliadynamics.github.io/DynamicalSystems.
202204
from [`DynamicalSystems`](https://juliadynamics.github.io/DynamicalSystems.jl/stable/).
203205
See [`aqn`](@ref) for an example.
204206
"""
205-
struct QualitativeNetwork
207+
struct QualitativeNetwork{N,C}
206208
"Graph containing the topology and target functions of the network"
207209
graph::MetaGraph
208210
"State of the network"
209-
state::AbstractVector{Int}
211+
state::MVector{C,Int}
210212
"The maximum activation level/state value of any component"
211213
N::Int
212214

@@ -215,7 +217,7 @@ struct QualitativeNetwork
215217
error("All values in state must be <= N (N=$N)")
216218
end
217219

218-
return new(g, s, N)
220+
return new{N,length(s)}(g, s, N)
219221
end
220222
end
221223

@@ -306,7 +308,7 @@ end
306308
"""
307309
$(TYPEDSIGNATURES)
308310
"""
309-
function limit_change(prev_value, next_value, N::Int)
311+
function limit_change(prev_value, next_value, N::Integer)
310312
if next_value > prev_value
311313
limited_value = min(prev_value + 1, N)
312314
elseif next_value < prev_value
@@ -315,7 +317,7 @@ function limit_change(prev_value, next_value, N::Int)
315317
limited_value = next_value
316318
end
317319

318-
return round(Int, limited_value)
320+
return limited_value
319321
end
320322

321323
"""
@@ -335,6 +337,17 @@ extract_state(model::QN) = model.state
335337
extract_parameters(model::QN) = model.graph
336338
reset_model!(model::QN, u, _) = model.state .= u
337339

340+
function SciMLBase.reinit!(
341+
ds::ArbitrarySteppable{<:AbstractVector{<:Real},<:QualitativeNetwork},
342+
u::AbstractVector{<:Real} = initial_state(ds);
343+
p = current_parameters(ds),
344+
t0 = 0, # t0 is not used but required for downstream.
345+
)
346+
ds.reinit(ds.model, u, p)
347+
ds.t[] = 0
348+
return ds
349+
end
350+
338351
"""
339352
$(TYPEDSIGNATURES)
340353

test/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[deps]
22
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
3+
Attractors = "f3fd9213-ca85-4dba-9dfd-7fc91308fec7"
34
DynamicalSystemsBase = "6e36e845-645a-534a-86f2-f5d4aa5a06b4"
45
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
56
HerbCore = "2b23ba43-8213-43cb-b5ea-38c12b45bd45"

test/test-qn.jl

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
using Attractors: AttractorsViaRecurrences, basins_of_attraction
12
using DynamicalSystemsBase: step!, get_state, set_state!
23
using Graphs: ne, nv
34
using Random: seed!
45

6+
seed!(42)
7+
58
@testset "QN Grammar Creation" begin
69
entities = [:a, :b, :c]
710
constants = [i for i = 1:10]
@@ -65,11 +68,22 @@ end
6568
end
6669

6770
@testset "Async QN" begin
68-
seed!(42)
69-
7071
for i = 1:100
7172
async_qn = aqn(network, N + i)
7273
step!(async_qn, 10)
7374
@test all(get_state(async_qn.model) .<= N + i)
7475
end
7576
end
77+
78+
@testset "Get attractors" begin
79+
n_entities = 3
80+
qn = sample_qualitative_network(n_entities, 2)
81+
82+
async_qn = aqn(qn, 1)
83+
84+
grid = Tuple(range(0, 1) for _ = 1:n_entities)
85+
86+
mapper = AttractorsViaRecurrences(async_qn, grid)
87+
88+
basins = basins_of_attraction(mapper, grid)
89+
end

0 commit comments

Comments
 (0)