Skip to content

Commit 1d1f4f8

Browse files
authored
Merge pull request #800 from SciML/noise_scaling_update
Noise scaling update
2 parents f712acf + c06098c commit 1d1f4f8

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

src/reactionsystem.jl

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,8 @@ function make_ReactionSystem_internal(rxs_and_eqs::Vector, iv, us_in, ps_in; spa
496496
(sym isa Symbolic) && findvars!(ps, us, sym, ivs, vars)
497497
end
498498

499-
# Will appear here: add stuff from nosie scaling.
499+
# Extract all quantities encountered in relevant `Reaction` metadata.
500+
has_noise_scaling(rx) && findvars!(ps, us, get_noise_scaling(rx), ivs, vars)
500501
end
501502

502503
# Extracts any species, variables, and parameters that occur in (non-reaction) equations.
@@ -1233,7 +1234,26 @@ function set_default_metadata(rs::ReactionSystem; default_reaction_metadata = [
12331234
updated_equations = map(eqtransform, get_eqs(rs))
12341235
@set! rs.eqs = updated_equations
12351236
@set! rs.rxs = Reaction[rx for rx in updated_equations if rx isa Reaction]
1236-
1237+
1238+
# Special routine to handle `Reaction` metadata that can contain new symbolic variables.
1239+
# Currently, `noise_scaling` is the only relevant metadata supported this way.
1240+
drm_dict = Dict(default_reaction_metadata)
1241+
if haskey(drm_dict, :noise_scaling)
1242+
# Finds parameters, species, and variables in the noise scaling term.
1243+
ns_expr = drm_dict[:noise_scaling]
1244+
ns_syms = [Symbolics.unwrap(sym) for sym in get_variables(ns_expr)]
1245+
ns_ps = Iterators.filter(ModelingToolkit.isparameter, ns_syms)
1246+
ns_sps = Iterators.filter(Catalyst.isspecies, ns_syms)
1247+
ns_vs = Iterators.filter(sym -> !Catalyst.isspecies(sym) &&
1248+
!ModelingToolkit.isparameter(sym), ns_syms)
1249+
# Adds parameters, species, and variables to the `ReactionSystem`.
1250+
@set! rs.ps = union(get_ps(rs), ns_ps)
1251+
sps_new = union(get_species(rs), ns_sps)
1252+
@set! rs.species = sps_new
1253+
vs_old = @view get_unknowns(rs)[length(get_species(rs))+1 : end]
1254+
@set! rs.unknowns = union(sps_new, vs_old, ns_vs)
1255+
end
1256+
12371257
# Updates reaction metadata for all its subsystems.
12381258
new_sub_systems = similar(get_systems(rs))
12391259
for (i, sub_system) in enumerate(get_systems(rs))

test/simulation_and_solving/simulate_SDEs.jl

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ using Catalyst, Statistics, StochasticDiffEq, Test
77
using StableRNGs
88
rng = StableRNG(123456)
99

10+
# Sets the default `t` to use.
11+
t = default_t()
12+
1013
# Fetch test functions and networks.
1114
include("../test_functions.jl")
1215
include("../test_networks.jl")
@@ -315,30 +318,61 @@ let
315318
end
316319
end
317320

321+
# Tests noise scaling is added properly for programmatically created system.
322+
# Tests noise scaling for interpolation into the `@reaction macro`.
323+
# Tests that species, variables, and parameters are extracted from noise scaling metadata when
324+
# `ReactionSystems`s are declared programmatically.
325+
let
326+
# Programmatically creates a model with noise scaling.
327+
t = default_t()
328+
@species X(t) H(t)
329+
@variables h(t)
330+
@parameters p d η
331+
rx1 = Reaction(p, nothing, [X]; metadata = [:noise_scaling => η*H + 1])
332+
rx2 = @reaction d, X --> 0, [noise_scaling=$h]
333+
@named rs = ReactionSystem([rx1, rx2], t)
334+
335+
# Checks that noise scaling has been added correctly.
336+
@test issetequal([X, H], species(rs))
337+
@test issetequal([X, H, h], unknowns(rs))
338+
@test issetequal([p, d, η], parameters(rs))
339+
@test isequal(get_noise_scaling(reactions(rs)[1]), η*H + 1)
340+
@test isequal(get_noise_scaling(reactions(rs)[2]), h)
341+
end
342+
318343
# Tests the `remake_noise_scaling` function.
344+
# Checks a parameter part of the initial system is added properly.
345+
# Checks that parameters, variables, and species not part of the original system are added properly.
319346
let
320347
# Creates noise scaling networks.
321348
noise_scaling_network1 = @reaction_network begin
349+
@parameters η1
322350
p, 0 --> X, [noise_scaling=2.0]
323351
d, X --> 0
324352
end
325-
noise_scaling_network2 = set_default_noise_scaling(noise_scaling_network1, 0.5)
326-
327-
# Checks that the two networks' reactions have the correct metadata.
328-
@test reactions(noise_scaling_network1)[1].metadata == [:noise_scaling => 2.0]
329-
@test reactions(noise_scaling_network1)[2].metadata == []
330-
@test reactions(noise_scaling_network2)[1].metadata == [:noise_scaling => 2.0]
331-
@test reactions(noise_scaling_network2)[2].metadata == [:noise_scaling => 0.5]
353+
@unpack p, d, η1, X = noise_scaling_network1
354+
@parameters η2
355+
@species Y(t)
356+
@variables V(t)
357+
358+
noise_scaling_network2 = set_default_noise_scaling(noise_scaling_network1, η1 + η2 + Y + V)
359+
@test isequal(reactions(noise_scaling_network2)[1].metadata, [:noise_scaling => 2.0])
360+
@test isequal(reactions(noise_scaling_network2)[2].metadata, [:noise_scaling => η1 + η2 + Y + V])
361+
@test issetequal([p, d, η1, η2], parameters(noise_scaling_network2))
362+
@test issetequal([X, Y], species(noise_scaling_network2))
363+
@test issetequal([X, Y, V], unknowns(noise_scaling_network2))
364+
@test issetequal([V], nonspecies(noise_scaling_network2))
332365
end
333366

334367
# Tests the `remake_noise_scaling` function on a hierarchical model.
335-
let
368+
# Checks that species, variables, and parameters not part of the original system is added properly.
369+
let
336370
# Creates hierarchical model.
337-
rn1 = @reaction_network begin
371+
rn1 = @reaction_network rn1 begin
338372
p, 0 --> X, [noise_scaling=2.0]
339373
d, X --> 0
340374
end
341-
rn2 = @reaction_network begin
375+
rn2 = @reaction_network rn2 begin
342376
k1, X1 --> X2, [noise_scaling=5.0]
343377
k2, X2 --> X1
344378
end
@@ -355,6 +389,7 @@ let
355389
end
356390

357391

392+
358393
### Other Tests ###
359394

360395
# Tests simulating a network without parameters.

0 commit comments

Comments
 (0)