Skip to content

Commit ecda156

Browse files
committed
Named state space sets
1 parent be41a0f commit ecda156

5 files changed

Lines changed: 46 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# v3.15
2+
3+
- New function `named_variables(ds)` for getting the variable names of an MTK-generated dynamical system.
4+
- `trajectory` function now automatically makes a named state space set if the dynamical system is MTK-generated.
5+
16
# v3.14.0
27

38
- `set_parameter!` and `current_parameter` will now throw an informative error message explicitly naming the parameter if the user tries to get/set a symbolic parameter that does not exist in the MTK-generated dynamical system.

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DynamicalSystemsBase"
22
uuid = "6e36e845-645a-534a-86f2-f5d4aa5a06b4"
33
repo = "https://github.com/JuliaDynamics/DynamicalSystemsBase.jl.git"
4-
version = "3.14.0"
4+
version = "3.15.0"
55

66
[deps]
77
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
@@ -21,7 +21,7 @@ OrdinaryDiffEqTsit5 = "1.1"
2121
Reexport = "1"
2222
Roots = "1, 2"
2323
SciMLBase = "1.19.5, 2"
24-
StateSpaceSets = "2"
24+
StateSpaceSets = "2.5"
2525
Statistics = "1"
2626
StochasticDiffEq = "6.66.0"
2727
SymbolicIndexingInterface = "0.3.4"

docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ initial_time
3030
isinplace(::DynamicalSystem)
3131
successful_step
3232
referrenced_sciml_model
33+
named_variables
3334
```
3435

3536
```@docs

src/core/dynamicalsystem_interface.jl

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ from an experimental measurement of a dynamical system with an unknown dynamic r
4444
4545
See also the DynamicalSystems.jl tutorial online for examples making dynamical systems.
4646
47-
## Integration with ModelingToolkit.jl
47+
## Integration with ModelingToolkit.jl (MTK)
4848
4949
Dynamical systems that have been constructed from `DEProblem`s that themselves
5050
have been constructed from ModelingToolkit.jl keep a reference to the symbolic
@@ -93,6 +93,7 @@ unless when developing new algorithm implementations that use dynamical systems.
9393
- [`isinplace`](@ref)
9494
- [`successful_step`](@ref)
9595
- [`referrenced_sciml_model`](@ref)
96+
- [`named_variables`](@ref)
9697
9798
### API - alter status
9899
@@ -126,7 +127,7 @@ errormsg(ds) = error("Not yet implemented for dynamical system of type $(nameof(
126127

127128
export current_state, initial_state, current_parameters, current_parameter, initial_parameters, isinplace,
128129
current_time, initial_time, successful_step, isdeterministic, isdiscretetime, dynamic_rule,
129-
reinit!, set_state!, set_parameter!, set_parameters!, step!, observe_state, referrenced_sciml_model
130+
reinit!, set_state!, set_parameter!, set_parameters!, step!, observe_state, referrenced_sciml_model, named_variables
130131

131132
###########################################################################################
132133
# Symbolic support
@@ -148,10 +149,27 @@ referrenced_sciml_model(::Nothing) = nothing
148149

149150
# return true if there is an actual referrenced system
150151
has_referrenced_model(prob::SciMLBase.DEProblem) = has_referrenced_model(referrenced_sciml_model(prob))
152+
has_referrenced_model(prob::DynamicalSystem) = has_referrenced_model(referrenced_sciml_model(prob))
151153
has_referrenced_model(::Nothing) = false
152154
has_referrenced_model(::SymbolicIndexingInterface.SymbolCache{Nothing, Nothing, Nothing}) = false
153155
has_referrenced_model(sys) = true
154156

157+
"""
158+
named_variables(ds::DynamicalSystem)
159+
160+
If `ds` is constructed via MTK, return a vector of the variable names (as symbols).
161+
Otherwise return `nothing`. If `X` is a `StateSpaceSet`, you can always do
162+
```julia
163+
X = StateSpaceSet(X; names = named_variables(ds))
164+
```
165+
in downstream functions to name a set coming from `ds` (if possible).
166+
"""
167+
function named_variables(ds::DynamicalSystem)
168+
mtk = referrenced_sciml_model(ds)
169+
isnothing(mtk) && return nothing
170+
return SymbolicIndexingInterface.getname.(SymbolicIndexingInterface.variable_symbols(mtk))
171+
end
172+
155173
###########################################################################################
156174
# API - obtaining information from the system
157175
###########################################################################################

src/core/trajectory.jl

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,15 @@ export trajectory
55
66
Evolve `ds` for a total time of `T` and return its trajectory `X`, sampled at equal time
77
intervals, and corresponding time vector. `X` is a `StateSpaceSet`.
8-
Optionally provide a starting state `u0` which is `current_state(ds)` by default.
9-
108
The returned time vector is `t = (t0+Ttr):Δt:(t0+Ttr+T)`.
119
12-
If time evolution diverged, or in general failed, before `T`,
10+
Optionally provide a starting state `u0` which is `current_state(ds)` by default.
11+
12+
If time evolution diverged or in general failed before `T`,
1313
the remaining of the trajectory is set to the last valid point.
1414
15-
`trajectory` is a very simple function provided for convenience.
16-
For continuous time systems, it doesn't play well with callbacks,
17-
use `DifferentialEquations.solve` if you want a trajectory/timeseries
18-
that works with callbacks, or in general you want more flexibility in the generated
19-
trajectory (but remember to convert the output of `solve` to a `StateSpaceSet`).
15+
The dimensions of `X` are automatically named if `ds` referrences an MTK model,
16+
see [`DynamicalSystem`](@ref).
2017
2118
## Keyword arguments
2219
@@ -32,17 +29,28 @@ trajectory (but remember to convert the output of `solve` to a `StateSpaceSet`).
3229
Defaults to `1:dimension(ds)` (all dynamic variables).
3330
Note: if you mix integer and symbolic indexing be sure to initialize the array
3431
as `Any` so that integers `1, 2, ...` are not converted to symbolic expressions.
32+
33+
## Description
34+
35+
`trajectory` is a very simple function provided for convenience.
36+
For continuous time systems, it doesn't play well with callbacks,
37+
use `DifferentialEquations.solve` if you want a trajectory
38+
that works with callbacks, or in general you want more flexibility in the generated
39+
trajectory (but remember to convert the output of `solve` to a `StateSpaceSet`).
3540
"""
3641
function trajectory(ds::DynamicalSystem, T, u0 = current_state(ds);
3742
save_idxs = nothing, t0 = initial_time(ds), kwargs...
3843
)
3944
accessor = svector_access(save_idxs)
4045
reinit!(ds, u0; t0)
4146
if isdiscretetime(ds)
42-
trajectory_discrete(ds, T; accessor, kwargs...)
47+
X, tvec = trajectory_discrete(ds, T; accessor, kwargs...)
4348
else
44-
trajectory_continuous(ds, T; accessor, kwargs...)
49+
X, tvec = trajectory_continuous(ds, T; accessor, kwargs...)
4550
end
51+
# name automatically if possible
52+
X = StateSpaceSet(X; names = named_variables(ds))
53+
return X, tvec
4654
end
4755

4856
function trajectory_discrete(ds, T;

0 commit comments

Comments
 (0)