Skip to content

Commit 7e7fb17

Browse files
authored
Merge pull request #943 from SciML/s/param
Use metadata to denote parameters
2 parents b2ce1b3 + cc33ce3 commit 7e7fb17

File tree

12 files changed

+75
-93
lines changed

12 files changed

+75
-93
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ SciMLBase = "1.3"
6565
Setfield = "0.7"
6666
SpecialFunctions = "0.7, 0.8, 0.9, 0.10, 1.0"
6767
StaticArrays = "0.10, 0.11, 0.12, 1.0"
68-
SymbolicUtils = "0.8.3, 0.9, 0.10"
69-
Symbolics = "0.1.8"
68+
SymbolicUtils = "0.10"
69+
Symbolics = "0.1.14"
7070
UnPack = "0.1, 1.0"
7171
Unitful = "1.1"
7272
julia = "1.2"

docs/src/tutorials/tearing_parallelism.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function connect_heat(ps...)
3737
end
3838

3939
# Basic electric components
40-
const t = Sym{ModelingToolkit.Parameter{Real}}(:t)
40+
@parameters t
4141
const D = Differential(t)
4242
function Pin(;name)
4343
@variables v(t) i(t)

src/parameters.jl

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,35 @@
1-
import SymbolicUtils: symtype, term
2-
struct Parameter{T} end
1+
import SymbolicUtils: symtype, term, hasmetadata
2+
struct MTKParameterCtx end
33

4+
isparameter(x::Num) = isparameter(value(x))
5+
isparameter(x::Symbolic) = getmetadata(x, MTKParameterCtx, false)
46
isparameter(x) = false
5-
isparameter(::Sym{<:Parameter}) = true
6-
isparameter(::Sym{<:FnType{<:Any, <:Parameter}}) = true
77

8-
SymbolicUtils.@number_methods(Sym{Parameter{Real}},
9-
term(f, a),
10-
term(f, a, b), skipbasics)
8+
"""
9+
toparam(s::Sym)
1110
12-
SymbolicUtils.symtype(s::Symbolic{Parameter{T}}) where T = T
13-
SymbolicUtils.similarterm(t::Term{<:Parameter}, f, args) = Term(f, args)
11+
Maps the variable to a paramter.
12+
"""
13+
toparam(s::Symbolic) = setmetadata(s, MTKParameterCtx, true)
14+
toparam(s::Num) = Num(toparam(value(s)))
1415

15-
Base.convert(::Type{Num}, x::Symbolic{Parameter{T}}) where {T<:Number} = Num(x)
16+
"""
17+
tovar(s::Sym)
18+
19+
Maps the variable to a state.
20+
"""
21+
tovar(s::Symbolic) = setmetadata(s, MTKParameterCtx, false)
22+
tovar(s::Num) = Num(tovar(value(s)))
1623

1724
"""
1825
$(SIGNATURES)
1926
2027
Define one or more known variables.
2128
"""
2229
macro parameters(xs...)
23-
esc(_parse_vars(:parameters, Parameter{Real}, xs))
30+
Symbolics._parse_vars(:parameters,
31+
Real,
32+
xs,
33+
x -> x isa Array ? toparam.(x) : toparam(x)
34+
) |> esc
2435
end

src/structural_transformation/pantelides.jl

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,6 @@
22
### Reassemble: structural information -> system
33
###
44

5-
# Naive subtree matching, we can make the dict have levels
6-
# Going forward we should look into storing the depth in Terms
7-
function walk_and_substitute(expr, substitution_dict)
8-
if haskey(substitution_dict, expr)
9-
return substitution_dict[expr]
10-
elseif istree(expr)
11-
return similarterm(
12-
expr,
13-
walk_and_substitute(operation(expr), substitution_dict),
14-
map(x->walk_and_substitute(x, substitution_dict), arguments(expr))
15-
)
16-
else
17-
@assert !(expr isa Equation) "RHS cannot contain equations"
18-
return expr
19-
end
20-
end
21-
225
function pantelides_reassemble(sys, eqassoc, assign)
236
s = structure(sys)
247
@unpack fullvars, varassoc = s
@@ -74,7 +57,7 @@ function pantelides_reassemble(sys, eqassoc, assign)
7457
end
7558
rhs = ModelingToolkit.expand_derivatives(D(eq.rhs))
7659
substitution_dict = Dict(x.lhs => x.rhs for x in out_eqs if x !== nothing && x.lhs isa Symbolic)
77-
sub_rhs = walk_and_substitute(rhs, substitution_dict)
60+
sub_rhs = substitute(rhs, substitution_dict)
7861
out_eqs[e] = lhs ~ sub_rhs
7962
end
8063

src/structural_transformation/tearing.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function tearing_reassemble(sys; simplify=false)
5050
var = fullvars[iv]
5151
rhs = value(solve_for(eq, var; simplify=simplify, check=false))
5252
# if we don't simplify the rhs and the `eq` is not solved properly
53-
(!simplify && var in vars(rhs)) && (rhs = SymbolicUtils.polynormalize(rhs))
53+
(!simplify && occursin(rhs, var)) && (rhs = SymbolicUtils.polynormalize(rhs))
5454
# Since we know `eq` is linear wrt `var`, so the round off must be a
5555
# linear term. We can correct the round off error by a linear
5656
# correction.

src/systems/abstractsystem.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,8 @@ end
271271
function renamespace(namespace, x)
272272
if x isa Num
273273
renamespace(namespace, value(x))
274-
elseif istree(x)
275-
renamespace(namespace, operation(x))(arguments(x)...)
276-
elseif x isa Sym
277-
Sym{symtype(x)}(renamespace(namespace,nameof(x)))
274+
elseif x isa Symbolic
275+
rename(x, renamespace(namespace, getname(x)))
278276
else
279277
Symbol(namespace,:₊,x)
280278
end
@@ -311,8 +309,7 @@ function namespace_expr(O,name,iv) where {T}
311309
if istree(O)
312310
renamed = map(a->namespace_expr(a,name,iv), arguments(O))
313311
if operation(O) isa Sym
314-
renamed_op = rename(operation(O),renamespace(name,nameof(operation(O))))
315-
Term{_symparam(O)}(renamed_op,renamed)
312+
renamed_op = rename(O,renamespace(name, getname(O)))
316313
else
317314
similarterm(O,operation(O),renamed)
318315
end

src/systems/diffeqs/odesystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ iv_from_nested_derivative(x::Term) = operation(x) isa Differential ? iv_from_nes
106106
iv_from_nested_derivative(x::Sym) = x
107107
iv_from_nested_derivative(x) = missing
108108

109-
vars(x::Sym) = [x]
109+
vars(x::Sym) = Set([x])
110110
vars(exprs::Symbolic) = vars([exprs])
111111
vars(exprs) = foldl(vars!, exprs; init = Set())
112112
vars!(vars, eq::Equation) = (vars!(vars, eq.lhs); vars!(vars, eq.rhs); vars)

src/utils.jl

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,6 @@ function states_to_sym(states::Set)
7272
end
7373
states_to_sym(states) = states_to_sym(Set(states))
7474

75-
"""
76-
toparam(s::Sym) -> Sym{<:Parameter}
77-
78-
Maps the variable to a paramter.
79-
"""
80-
toparam(s::Sym) = Sym{Parameter{symtype(s)}}(s.name)
81-
toparam(s::Sym{<:Parameter}) = s
82-
83-
"""
84-
tovar(s::Sym) -> Sym{Real}
85-
tovar(s::Sym{<:Parameter}) -> Sym{Real}
86-
87-
Maps the variable to a state.
88-
"""
89-
tovar(s::Sym{<:Parameter}) = Sym{symtype(s)}(s.name)
90-
tovar(s::Sym) = s
91-
9275
function todict(d)
9376
eltype(d) <: Pair || throw(ArgumentError("The variable-value mapping must be a Dict."))
9477
d isa Dict ? d : Dict(d)

test/rc_model.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ using Test
22
using ModelingToolkit, OrdinaryDiffEq
33

44
# Basic electric components
5-
const t = Sym{ModelingToolkit.Parameter{Real}}(:t)
5+
@parameters t
66
function Pin(;name)
77
@variables v(t) i(t)
88
ODESystem(Equation[], t, [v, i], [], name=name, defaults=[v=>1.0, i=>1.0])

test/reactionsystem_components.jl

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ using ModelingToolkit, LinearAlgebra, OrdinaryDiffEq, Test
22
MT = ModelingToolkit
33

44
# Repressilator model
5-
@parameters t α₀ α K n δ β μ
5+
@parameters t α₀ α K n δ β μ
66
@variables m(t) P(t) R(t)
7-
rxs = [Reaction(α₀, nothing, [m]),
7+
rxs = [
8+
Reaction(α₀, nothing, [m]),
89
Reaction/ (1 + (R/K)^n), nothing, [m]),
910
Reaction(δ, [m], nothing),
1011
Reaction(β, [m], [m,P]),
11-
Reaction(μ, [P], nothing)
12-
]
12+
Reaction(μ, [P], nothing)
13+
]
1314

1415
specs = [m,P,R]
1516
pars = [α₀,α,K,n,δ,β,μ]
@@ -19,31 +20,31 @@ pars = [α₀,α,K,n,δ,β,μ]
1920
@named os₁ = convert(ODESystem, rs)
2021
@named os₂ = convert(ODESystem, rs)
2122
@named os₃ = convert(ODESystem, rs)
22-
connections = [os₁.R ~ os₃.P,
23+
connections = [os₁.R ~ os₃.P,
2324
os₂.R ~ os₁.P,
2425
os₃.R ~ os₂.P]
2526
@named connected = ODESystem(connections, t, [], [], systems=[os₁,os₂,os₃])
2627
oderepressilator = structural_simplify(connected)
2728

28-
pvals = [os₁.α₀ => 5e-4,
29-
os₁.α => .5,
30-
os₁.K => 40.0,
31-
os₁.n => 2,
32-
os₁.δ => (log(2)/120),
29+
pvals = [os₁.α₀ => 5e-4,
30+
os₁.α => .5,
31+
os₁.K => 40.0,
32+
os₁.n => 2,
33+
os₁.δ => (log(2)/120),
3334
os₁.β => (20*log(2)/120),
3435
os₁.μ => (log(2)/600),
35-
os₂.α₀ => 5e-4,
36-
os₂.α => .5,
37-
os₂.K => 40.0,
38-
os₂.n => 2,
39-
os₂.δ => (log(2)/120),
36+
os₂.α₀ => 5e-4,
37+
os₂.α => .5,
38+
os₂.K => 40.0,
39+
os₂.n => 2,
40+
os₂.δ => (log(2)/120),
4041
os₂.β => (20*log(2)/120),
4142
os₂.μ => (log(2)/600),
42-
os₃.α₀ => 5e-4,
43-
os₃.α => .5,
44-
os₃.K => 40.0,
45-
os₃.n => 2,
46-
os₃.δ => (log(2)/120),
43+
os₃.α₀ => 5e-4,
44+
os₃.α => .5,
45+
os₃.K => 40.0,
46+
os₃.n => 2,
47+
os₃.δ => (log(2)/120),
4748
os₃.β => (20*log(2)/120),
4849
os₃.μ => (log(2)/600)]
4950
u₀ = [os₁.m => 0.0, os₁.P => 20.0, os₂.m => 0.0, os₂.P => 0.0, os₃.m => 0.0, os₃.P => 0.0]
@@ -58,8 +59,8 @@ function repress!(f, y, p, t)
5859
f[2] = α / (1 + (y[4] / K)^n) - δ * y[2] + α₀
5960
f[3] = α / (1 + (y[5] / K)^n) - δ * y[3] + α₀
6061
f[4] = β * y[1] - μ * y[4]
61-
f[5] = β * y[2] - μ * y[5]
62-
f[6] = β * y[3] - μ * y[6]
62+
f[5] = β * y[2] - μ * y[5]
63+
f[6] = β * y[3] - μ * y[6]
6364
nothing
6465
end
6566
ps = (α₀=5e-4, α=.5, K=40.0, n=2, δ=(log(2)/120), β=(20*log(2)/120), μ=(log(2)/600))
@@ -77,10 +78,10 @@ i = indexof(os₁.P, states(oderepressilator))
7778
# @named rs₁ = ReactionSystem(rxs, t, specs, pars)
7879
# @named rs₂ = ReactionSystem(rxs, t, specs, pars)
7980
# @named rs₃ = ReactionSystem(rxs, t, specs, pars)
80-
# connections = [rs₁.R ~ rs₃.P,
81+
# connections = [rs₁.R ~ rs₃.P,
8182
# rs₂.R ~ rs₁.P,
8283
# rs₃.R ~ rs₂.P]
8384
# @named csys = ODESystem(connections, t, [], [])
8485
# @named repressilator = ReactionSystem(t; systems=[csys,rs₁,rs₂,rs₃])
8586
# @named oderepressilator2 = convert(ODESystem, repressilator)
86-
# sys2 = structural_simplify(oderepressilator2) # FAILS currently
87+
# sys2 = structural_simplify(oderepressilator2) # FAILS currently

0 commit comments

Comments
 (0)