Skip to content

Commit 8b1bdb1

Browse files
committed
improved noise scaling
1 parent c15f84e commit 8b1bdb1

File tree

3 files changed

+66
-8
lines changed

3 files changed

+66
-8
lines changed

src/networkapi.jl

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,9 @@ end
504504

505505
# convert symbol of the form :sys.a.b.c to a symbolic a.b.c
506506
function _symbol_to_var(sys, sym)
507-
if hasproperty(sys, sym)
507+
if sym isa Num
508+
return sym
509+
elseif hasproperty(sys, sym)
508510
var = getproperty(sys, sym, namespace = false)
509511
else
510512
strs = split(String(sym), "") # need to check if this should be split of not!!!
@@ -563,25 +565,39 @@ pmap = symmap_to_varmap(sys, [:β => 1.0, :ν => 1.0, :subsys₊k => 1.0])
563565
Notes:
564566
- Any `Symbol`, `sym`, within `symmap` must be a valid field of `sys`. i.e.
565567
`sys.sym` must be defined.
568+
- The function works even if symbols and symbolics are mixed, e.g.
569+
```julia
570+
sir = @reaction_network sir begin
571+
β, S + I --> 2I
572+
ν, I --> R
573+
end
574+
@unpack S = sir
575+
mixed_u0map = [S => 1.0, :I => 1.0, :R => 1.0]
576+
u0map = symmap_to_varmap(sir, mixed_u0map)
577+
```
578+
566579
"""
567580
function symmap_to_varmap(sys, symmap::Tuple)
568581
if all(p -> p isa Pair{Symbol}, symmap)
569582
return ((_symbol_to_var(sys, sym) => val for (sym, val) in symmap)...,)
570583
else # if not all entries map a symbol to value pass through
571-
return symmap
584+
return symmapAny
572585
end
573586
end
574587

575-
function symmap_to_varmap(sys, symmap::AbstractArray{Pair{Symbol, T}}) where {T}
588+
function symmap_to_varmap(sys, symmap::AbstractArray{Pair{Any, T}}) where {T}
576589
[_symbol_to_var(sys, sym) => val for (sym, val) in symmap]
577590
end
578591

579-
function symmap_to_varmap(sys, symmap::Dict{Symbol, T}) where {T}
592+
function symmap_to_varmap(sys, symmap::Dict{Any, T}) where {T}
580593
Dict(_symbol_to_var(sys, sym) => val for (sym, val) in symmap)
581594
end
582595

583-
# don't permute any other types and let varmap_to_vars handle erroring
596+
# don't permute any other types and let varmap_to_vars handle erroring.
597+
# If all keys are `Num`, conversion not needed.
584598
symmap_to_varmap(sys, symmap) = symmap
599+
symmap_to_varmap(sys, symmap::AbstractArray{Pair{Num, T}}) where {T} = symmap
600+
symmap_to_varmap(sys, symmap::Dict{Num, T}) where {T} = symmap
585601
#error("symmap_to_varmap requires a Dict, AbstractArray or Tuple to map Symbols to values.")
586602

587603
######################## reaction complexes and reaction rates ###############################

src/reaction_network.jl

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem)))
369369
parameters_declared = extract_syms(options, :parameters)
370370
variables = extract_syms(options, :variables)
371371

372+
# Handles a (potential) noise scaling parameter.
373+
#nosie_scaling_p_args = handle_noise_scaling_ps!(parameters_declared, options)
374+
372375
# handle independent variables
373376
if haskey(options, :ivs)
374377
ivs = Tuple(extract_syms(options, :ivs))
@@ -391,7 +394,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem)))
391394
declared_syms)
392395
species = vcat(species_declared, species_extracted)
393396
parameters = vcat(parameters_declared, parameters_extracted)
394-
397+
395398
# Checks for input errors.
396399
(sum(length.([reaction_lines, option_lines])) != length(ex.args)) &&
397400
error("@reaction_network input contain $(length(ex.args) - sum(length.([reaction_lines,option_lines]))) malformed lines.")
@@ -414,6 +417,7 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem)))
414417
push!(rxexprs.args, get_rxexprs(reaction))
415418
end
416419

420+
# Returns the rephrased expression.
417421
quote
418422
$ps
419423
$ivexpr
@@ -556,8 +560,22 @@ function get_pexpr(parameters_extracted, options)
556560
pexprs = (haskey(options, :parameters) ? options[:parameters] :
557561
(isempty(parameters_extracted) ? :() : :(@parameters)))
558562
foreach(p -> push!(pexprs.args, p), parameters_extracted)
563+
append!(pexprs.args, get_noise_scaling_pexpr(options))
559564
pexprs
560565
end
566+
# Extracts any decalred nosie scaling parameters.
567+
function get_noise_scaling_pexpr(options)
568+
haskey(options, :noise_scaling_parameters) || return []
569+
ns_expr = options[:noise_scaling_parameters]
570+
for idx = length(ns_expr.args):-1:3
571+
if ns_expr.args[idx] isa Symbol
572+
insert!(ns_expr.args, idx+1, :([noisescalingparameter=true]))
573+
elseif (ns_expr.args[idx] isa Expr) && (ns_expr.args[idx].head == :ref)
574+
insert!(ns_expr.args, idx+1, :([noisescalingparameter=true]))
575+
end
576+
end
577+
return ns_expr.args[3:end]
578+
end
561579

562580
# Creates the reaction vector declaration statement.
563581
function get_rxexprs(rxstruct)
@@ -811,6 +829,21 @@ function recursive_expand_functions!(expr::ExprValues)
811829
expr
812830
end
813831

832+
### Option Handling ###
833+
834+
# Extracts any potential nosie scaling parameters and add them to teh decalred parameters.
835+
function add_noise_scaling_ps!(parameters_declared, options)
836+
haskey(options, :noise_scaling_parameters) || return
837+
for arg in options[:noise_scaling_parameters].args[end:-1:3]
838+
if arg isa Symbol
839+
push!(parameters_declared, arg)
840+
elseif arg isa Expr
841+
push!(parameters_declared, arg.args[1])
842+
end
843+
end
844+
end
845+
846+
814847
# ### Old functions (for deleting).
815848

816849
# function get_rx_species_deletethis(rxs, ps)

src/reactionsystem.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ drop_dynamics(s) = isconstant(s) || isbc(s) || (!isspecies(s))
5858

5959
# Denotes that a parameter controls the scaling of noise in the CLE.
6060
struct NoiseScalingParameter end
61-
Symbolics.option_to_metadata_type(::Val{:isnoisescalingparameter}) = NoiseScalingParameter
61+
Symbolics.option_to_metadata_type(::Val{:noisescalingparameter}) = NoiseScalingParameter
6262

6363
isnoisescalingparameter(s::Num) = isnoisescalingparameter(MT.value(s))
6464
function isnoisescalingparameter(s)
@@ -1546,7 +1546,16 @@ end
15461546

15471547
# Extracts any noise scaling parameters from a reaction system.
15481548
function get_noise_scaling(rs::ReactionSystem)
1549-
return nothing
1549+
ns_params = filter(p -> isnoisescalingparameter(p), parameters(rs))
1550+
if isempty(ns_params)
1551+
return nothing
1552+
elseif length(ns_params) == 1
1553+
return Num(ns_params[1])
1554+
elseif length(ns_params) == length(reactions(rs))
1555+
return ns_params
1556+
else
1557+
error("The system have $(length(ns_params)) noise scaling parameters. This number should be equal to 0, 1, or the number of reactions ($(length(reactions(rs)))).")
1558+
end
15501559
end
15511560

15521561
"""

0 commit comments

Comments
 (0)