Skip to content

Commit 2be692b

Browse files
committed
feat: add default_target_function
Create a default target function as described in Eq. 3 from the QN paper (https://doi.org/10.1186/1752-0509-1-4).
1 parent 8ca5401 commit 2be692b

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

src/GraphDynamicalSystems.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export QualitativeNetwork,
2323
get_domain,
2424
target_functions,
2525
interpret,
26-
create_qn_system
26+
create_qn_system,
27+
default_target_function
2728

2829
end

src/qualitative_networks.jl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,57 @@ function build_qn_grammar(
158158
return g
159159
end
160160

161+
"""
162+
$TYPEDSIGNATURES
163+
164+
Construct a default target function for an entity in a QN from a list of
165+
`activators` and `inhibitors`.
166+
167+
Follows the definition given in Eq. 3 of ["Qualitative networks: a symbolic
168+
approach to analyze biological signaling
169+
networks"](https://doi.org/10.1186/1752-0509-1-4).
170+
171+
## Examples
172+
173+
Say we have a component `X` and it has an lower bound on its state value of 0,
174+
an upper bound of 4, activators `A`, `B`, `C`, and inhibitors `D`, `E`, `F`,
175+
then the following example constructs an expression for its default target
176+
function.
177+
178+
```jldoctest
179+
julia> default_target_function(0, 4, [:A, :B, :C], [:D, :E, :F])
180+
:(max(0, (A + B + C) / 3 - (D + E + F) / 3))
181+
```
182+
183+
"""
184+
function default_target_function(
185+
lower_bound::Integer,
186+
upper_bound::Integer,
187+
activators::AbstractVector = [],
188+
inhibitors::AbstractVector = [],
189+
)
190+
sum_only_or_nothing = x -> if length(x) == 0
191+
nothing
192+
elseif length(x) == 1
193+
:($(only(x)))
194+
elseif length(x) > 1
195+
:($(Expr(:call, :+, x...)) / $(length(x)))
196+
end
197+
198+
expr_activators = sum_only_or_nothing(activators)
199+
expr_inhibitors = sum_only_or_nothing(inhibitors)
200+
201+
if isnothing(expr_activators) && isnothing(expr_inhibitors)
202+
error("Constructing a default target function for a QN with no \
203+
activators or inhibitors.")
204+
elseif isnothing(expr_activators) # no activators, special case mentioned in paper
205+
return :($upper_bound - $expr_inhibitors)
206+
elseif isnothing(expr_inhibitors)
207+
return :($expr_activators)
208+
else
209+
return :(max($lower_bound, $expr_activators - $expr_inhibitors))
210+
end
211+
end
161212

162213
struct Entity{I}
163214
target_function::Any

test/qn_test.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,32 @@ end
112112

113113
basins = basins_of_attraction(mapper, grid)
114114
end
115+
116+
@testitem "Construct default target functions" begin
117+
lower_bound = 0
118+
upper_bound = 4
119+
activators = [:A, :B, :C]
120+
inhibitors = [:D, :E, :F]
121+
122+
@test default_target_function(lower_bound, upper_bound, activators, inhibitors) ==
123+
:(max($lower_bound, (A + B + C) / 3 - (D + E + F) / 3))
124+
125+
activators = [:A, :B]
126+
inhibitors = [:D]
127+
128+
@test default_target_function(lower_bound, upper_bound, activators, inhibitors) ==
129+
:(max($lower_bound, (A + B) / 2 - D))
130+
131+
activators = []
132+
inhibitors = [:D]
133+
134+
@test default_target_function(lower_bound, upper_bound, activators, inhibitors) ==
135+
:($upper_bound - D)
136+
137+
activators = [:A]
138+
inhibitors = []
139+
140+
@test default_target_function(lower_bound, upper_bound, activators, inhibitors) == :(A)
141+
142+
@test_throws r"no activators or inhibitors" default_target_function(0, 4)
143+
end

0 commit comments

Comments
 (0)