Skip to content

Commit ed3771a

Browse files
feat: add dump_variable_metadata, dump_parameters, dump_variables
Also make `istunable` default to `true` for parameters without tunable metadata. `tunable_parameters` is also updated accordingly
1 parent 932adeb commit ed3771a

File tree

3 files changed

+104
-11
lines changed

3 files changed

+104
-11
lines changed

src/systems/abstractsystem.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,3 +2146,23 @@ function process_parameter_dependencies(pdeps, ps)
21462146
end
21472147
return pdeps, ps
21482148
end
2149+
2150+
function dump_parameters(sys::AbstractSystem)
2151+
defs = defaults(sys)
2152+
map(dump_variable_metadata.(parameters(sys))) do meta
2153+
if haskey(defs, meta.var)
2154+
meta = merge(meta, (; default = defs[meta.var]))
2155+
end
2156+
meta
2157+
end
2158+
end
2159+
2160+
function dump_unknowns(sys::AbstractSystem)
2161+
defs = defaults(sys)
2162+
map(dump_variable_metadata.(unknowns(sys))) do meta
2163+
if haskey(defs, meta.var)
2164+
meta = merge(meta, (; default = defs[meta.var]))
2165+
end
2166+
meta
2167+
end
2168+
end

src/variables.jl

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,57 @@ Symbolics.option_to_metadata_type(::Val{:irreducible}) = VariableIrreducible
1515
Symbolics.option_to_metadata_type(::Val{:state_priority}) = VariableStatePriority
1616
Symbolics.option_to_metadata_type(::Val{:misc}) = VariableMisc
1717

18+
function dump_variable_metadata(var)
19+
uvar = unwrap(var)
20+
vartype, name = get(uvar.metadata, VariableSource, (:unknown, :unknown))
21+
shape = Symbolics.shape(var)
22+
if shape == ()
23+
shape = nothing
24+
end
25+
unit = get(uvar.metadata, VariableUnit, nothing)
26+
connect = get(uvar.metadata, VariableConnectType, nothing)
27+
noise = get(uvar.metadata, VariableNoiseType, nothing)
28+
input = isinput(uvar) || nothing
29+
output = isoutput(uvar) || nothing
30+
irreducible = get(uvar.metadata, VariableIrreducible, nothing)
31+
state_priority = get(uvar.metadata, VariableStatePriority, nothing)
32+
misc = get(uvar.metadata, VariableMisc, nothing)
33+
bounds = hasbounds(uvar) ? getbounds(uvar) : nothing
34+
desc = getdescription(var)
35+
if desc == ""
36+
desc = nothing
37+
end
38+
guess = getguess(uvar)
39+
disturbance = isdisturbance(uvar) || nothing
40+
tunable = istunable(uvar, isparameter(uvar))
41+
dist = getdist(uvar)
42+
type = symtype(uvar)
43+
44+
meta = (
45+
var = var,
46+
vartype,
47+
name,
48+
shape,
49+
unit,
50+
connect,
51+
noise,
52+
input,
53+
output,
54+
irreducible,
55+
state_priority,
56+
misc,
57+
bounds,
58+
desc,
59+
guess,
60+
disturbance,
61+
tunable,
62+
dist,
63+
type,
64+
)
65+
66+
return NamedTuple(k => v for (k, v) in pairs(meta) if v !== nothing)
67+
end
68+
1869
abstract type AbstractConnectType end
1970
struct Equality <: AbstractConnectType end # Equality connection
2071
struct Flow <: AbstractConnectType end # sum to 0
@@ -243,7 +294,7 @@ Symbolics.option_to_metadata_type(::Val{:tunable}) = VariableTunable
243294
istunable(x::Num, args...) = istunable(Symbolics.unwrap(x), args...)
244295

245296
"""
246-
istunable(x, default = false)
297+
istunable(x, default = true)
247298
248299
Determine whether symbolic variable `x` is marked as a tunable for an automatic tuning algorithm.
249300
@@ -257,7 +308,7 @@ Create a tunable parameter by
257308
258309
See also [`tunable_parameters`](@ref), [`getbounds`](@ref)
259310
"""
260-
function istunable(x, default = false)
311+
function istunable(x, default = true)
261312
p = Symbolics.getparent(x, nothing)
262313
p === nothing || (x = p)
263314
Symbolics.getmetadata(x, VariableTunable, default)
@@ -302,7 +353,7 @@ end
302353
## System interface
303354

304355
"""
305-
tunable_parameters(sys, p = parameters(sys); default=false)
356+
tunable_parameters(sys, p = parameters(sys); default=true)
306357
307358
Get all parameters of `sys` that are marked as `tunable`.
308359
@@ -316,7 +367,7 @@ Create a tunable parameter by
316367
317368
See also [`getbounds`](@ref), [`istunable`](@ref)
318369
"""
319-
function tunable_parameters(sys, p = parameters(sys); default = false)
370+
function tunable_parameters(sys, p = parameters(sys); default = true)
320371
filter(x -> istunable(x, default), p)
321372
end
322373

test/test_variable_metadata.jl

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,52 +4,72 @@ using ModelingToolkit
44
@variables u [bounds = (-1, 1)]
55
@test getbounds(u) == (-1, 1)
66
@test hasbounds(u)
7+
@test ModelingToolkit.dump_variable_metadata(u).bounds == (-1, 1)
78

89
@variables y
910
@test !hasbounds(y)
11+
@test !haskey(ModelingToolkit.dump_variable_metadata(y), :bounds)
1012

1113
# Guess
1214
@variables y [guess = 0]
1315
@test getguess(y) === 0
1416
@test hasguess(y) === true
17+
@test ModelingToolkit.dump_variable_metadata(y).guess == 0
1518

1619
@variables y
1720
@test hasguess(y) === false
21+
@test !haskey(ModelingToolkit.dump_variable_metadata(y), :guess)
1822

1923
# Disturbance
2024
@variables u [disturbance = true]
2125
@test isdisturbance(u)
26+
@test ModelingToolkit.dump_variable_metadata(u).disturbance
2227

2328
@variables y
2429
@test !isdisturbance(y)
30+
@test !haskey(ModelingToolkit.dump_variable_metadata(y), :disturbance)
2531

2632
# Tunable
2733
@parameters u [tunable = true]
2834
@test istunable(u)
35+
@test ModelingToolkit.dump_variable_metadata(u).tunable
36+
37+
@parameters u2 [tunable = false]
38+
@test !istunable(u2)
39+
@test !ModelingToolkit.dump_variable_metadata(u2).tunable
2940

3041
@parameters y
31-
@test !istunable(y)
42+
@test istunable(y)
43+
@test ModelingToolkit.dump_variable_metadata(y).tunable
3244

3345
# Distributions
3446
struct FakeNormal end
3547
d = FakeNormal()
3648
@parameters u [dist = d]
3749
@test hasdist(u)
3850
@test getdist(u) == d
51+
@test ModelingToolkit.dump_variable_metadata(u).dist == d
3952

4053
@parameters y
4154
@test !hasdist(y)
55+
@test !haskey(ModelingToolkit.dump_variable_metadata(y), :dist)
4256

4357
## System interface
4458
@parameters t
4559
Dₜ = Differential(t)
4660
@variables x(t)=0 [bounds = (-10, 10)] u(t)=0 [input = true] y(t)=0 [output = true]
47-
@parameters T [tunable = true, bounds = (0, Inf)]
61+
@parameters T [bounds = (0, Inf)]
4862
@parameters k [tunable = true, bounds = (0, Inf)]
49-
@parameters k2
63+
@parameters k2 [tunable = false]
5064
eqs = [Dₜ(x) ~ (-k2 * x + k * u) / T
5165
y ~ x]
5266
sys = ODESystem(eqs, t, name = :tunable_first_order)
67+
unk_meta = ModelingToolkit.dump_unknowns(sys)
68+
@test length(unk_meta) == 3
69+
@test all(iszero, meta.default for meta in unk_meta)
70+
param_meta = ModelingToolkit.dump_parameters(sys)
71+
@test length(param_meta) == 3
72+
@test all(!haskey(meta, :default) for meta in param_meta)
5373

5474
p = tunable_parameters(sys)
5575
sp = Set(p)
@@ -68,21 +88,23 @@ b = getbounds(sys)
6888
b = getbounds(sys, unknowns(sys))
6989
@test b[x] == (-10, 10)
7090

71-
p = tunable_parameters(sys, default = true)
91+
p = tunable_parameters(sys, default = false)
7292
sp = Set(p)
7393
@test k sp
74-
@test T sp
75-
@test k2 sp
76-
@test length(p) == 3
94+
@test T sp
95+
@test k2 sp
96+
@test length(p) == 1
7797

7898
## Descriptions
7999
@variables u [description = "This is my input"]
80100
@test getdescription(u) == "This is my input"
81101
@test hasdescription(u)
102+
@test ModelingToolkit.dump_variable_metadata(u).desc == "This is my input"
82103

83104
@variables u
84105
@test getdescription(u) == ""
85106
@test !hasdescription(u)
107+
@test !haskey(ModelingToolkit.dump_variable_metadata(u), :desc)
86108

87109
@parameters t
88110
@variables u(t) [description = "A short description of u"]

0 commit comments

Comments
 (0)