Skip to content

Commit 7f90698

Browse files
Merge pull request #3558 from hersle/observed_variables
Add getter for observed variables
2 parents 520811e + efea3d7 commit 7f90698

File tree

14 files changed

+47
-18
lines changed

14 files changed

+47
-18
lines changed

docs/src/tutorials/acausal_components.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ sol = solve(prob)
320320
plot(sol)
321321
```
322322

323+
By default, this plots only the unknown variables that had to be solved for.
323324
However, what if we wanted to plot the timeseries of a different variable? Do
324325
not worry, that information was not thrown away! Instead, transformations
325326
like `structural_simplify` simply change unknown variables into observables which are
@@ -346,3 +347,9 @@ or we can plot the timeseries of the resistor's voltage:
346347
```@example acausal
347348
plot(sol, idxs = [rc_model.resistor.v])
348349
```
350+
351+
Although it may be more confusing than helpful here, we can of course also plot all unknown and observed variables together:
352+
353+
```@example acausal
354+
plot(sol, idxs = [unknowns(rc_model); observables(rc_model)])
355+
```

src/ModelingToolkit.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ import Symbolics: rename, get_variables!, _solve, hessian_sparsity,
8585
substituter, scalarize, getparent, hasderiv, hasdiff
8686

8787
import DiffEqBase: @add_kwonly
88-
export independent_variables, unknowns, parameters, full_parameters, continuous_events,
89-
discrete_events
88+
export independent_variables, unknowns, observables, parameters, full_parameters,
89+
continuous_events, discrete_events
9090
@reexport using Symbolics
9191
@reexport using UnPack
9292
RuntimeGeneratedFunctions.init(@__MODULE__)

src/systems/abstractsystem.jl

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ function has_observed_with_lhs(sys, sym)
430430
if has_index_cache(sys) && (ic = get_index_cache(sys)) !== nothing
431431
return haskey(ic.observed_syms_to_timeseries, sym)
432432
else
433-
return any(isequal(sym), [eq.lhs for eq in observed(sys)])
433+
return any(isequal(sym), observables(sys))
434434
end
435435
end
436436

@@ -489,7 +489,7 @@ function _all_ts_idxs!(ts_idxs, ::ScalarSymbolic, sys, sym::Symbol)
489489
if has_index_cache(sys) && (ic = get_index_cache(sys)) !== nothing
490490
return _all_ts_idxs!(ts_idxs, sys, ic.symbol_to_variable[sym])
491491
elseif is_variable(sys, sym) || is_independent_variable(sys, sym) ||
492-
any(isequal(sym), [getname(eq.lhs) for eq in observed(sys)])
492+
any(isequal(sym), getname.(observables(sys)))
493493
push!(ts_idxs, ContinuousTimeseries())
494494
elseif is_timeseries_parameter(sys, sym)
495495
push!(ts_idxs, timeseries_parameter_index(sys, s).timeseries_idx)
@@ -579,7 +579,7 @@ SymbolicIndexingInterface.constant_structure(::AbstractSystem) = true
579579

580580
function SymbolicIndexingInterface.all_variable_symbols(sys::AbstractSystem)
581581
syms = variable_symbols(sys)
582-
obs = getproperty.(observed(sys), :lhs)
582+
obs = observables(sys)
583583
return isempty(obs) ? syms : vcat(syms, obs)
584584
end
585585

@@ -1411,6 +1411,7 @@ _nonum(@nospecialize x) = x isa Num ? x.val : x
14111411
$(TYPEDSIGNATURES)
14121412
14131413
Get the unknown variables of the system `sys` and its subsystems.
1414+
These must be explicitly solved for, unlike `observables(sys)`.
14141415
14151416
See also [`ModelingToolkit.get_unknowns`](@ref).
14161417
"""
@@ -1677,6 +1678,14 @@ function controls(sys::AbstractSystem)
16771678
isempty(systems) ? ctrls : [ctrls; reduce(vcat, namespace_controls.(systems))]
16781679
end
16791680

1681+
"""
1682+
$(TYPEDSIGNATURES)
1683+
1684+
Get the observed equations of the system `sys` and its subsystems.
1685+
These can be expressed in terms of `unknowns(sys)`, and do not have to be explicitly solved for.
1686+
1687+
See also [`observables`](@ref) and [`ModelingToolkit.get_observed()`](@ref).
1688+
"""
16801689
function observed(sys::AbstractSystem)
16811690
obs = get_observed(sys)
16821691
systems = get_systems(sys)
@@ -1686,6 +1695,19 @@ function observed(sys::AbstractSystem)
16861695
init = Equation[])]
16871696
end
16881697

1698+
"""
1699+
$(TYPEDSIGNATURES)
1700+
1701+
Get the observed variables of the system `sys` and its subsystems.
1702+
These can be expressed in terms of `unknowns(sys)`, and do not have to be explicitly solved for.
1703+
It is equivalent to all left hand sides of `observed(sys)`.
1704+
1705+
See also [`observed`](@ref).
1706+
"""
1707+
function observables(sys::AbstractSystem)
1708+
return map(eq -> eq.lhs, observed(sys))
1709+
end
1710+
16891711
Base.@deprecate default_u0(x) defaults(x) false
16901712
Base.@deprecate default_p(x) defaults(x) false
16911713

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,7 @@ function InitializationProblem{iip, specialize}(sys::AbstractSystem,
14961496
@warn errmsg
14971497
end
14981498

1499-
uninit = setdiff(unknowns(sys), [unknowns(isys); getfield.(observed(isys), :lhs)])
1499+
uninit = setdiff(unknowns(sys), [unknowns(isys); observables(isys)])
15001500

15011501
# TODO: throw on uninitialized arrays
15021502
filter!(x -> !(x isa Symbolics.Arr), uninit)

src/systems/diffeqs/odesystem.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct ODESystem <: AbstractODESystem
4747
var_to_name::Any
4848
"""Control parameters (some subset of `ps`)."""
4949
ctrls::Vector
50-
"""Observed variables."""
50+
"""Observed equations."""
5151
observed::Vector{Equation}
5252
"""System of constraints that must be satisfied by the solution to the system."""
5353
constraintsystem::Union{Nothing, ConstraintsSystem}
@@ -532,7 +532,7 @@ function build_explicit_observed_function(sys, ts;
532532

533533
vs = ModelingToolkit.vars(ts; op)
534534
namespace_subs = Dict()
535-
ns_map = Dict{Any, Any}(renamespace(sys, eq.lhs) => eq.lhs for eq in observed(sys))
535+
ns_map = Dict{Any, Any}(renamespace(sys, obs) => obs for obs in observables(sys))
536536
for sym in unknowns(sys)
537537
ns_map[renamespace(sys, sym)] = sym
538538
if iscall(sym) && operation(sym) === getindex

src/systems/diffeqs/sdesystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct SDESystem <: AbstractODESystem
4848
var_to_name::Any
4949
"""Control parameters (some subset of `ps`)."""
5050
ctrls::Vector
51-
"""Observed variables."""
51+
"""Observed equations."""
5252
observed::Vector{Equation}
5353
"""
5454
Time-derivative matrix. Note: this field will not be defined until

src/systems/jumps/jumpsystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct JumpSystem{U <: ArrayPartition} <: AbstractTimeDependentSystem
5959
ps::Vector
6060
"""Array variables."""
6161
var_to_name::Any
62-
"""Observed variables."""
62+
"""Observed equations."""
6363
observed::Vector{Equation}
6464
"""The name of the system."""
6565
name::Symbol

src/systems/nonlinear/nonlinearsystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct NonlinearSystem <: AbstractTimeIndependentSystem
3232
ps::Vector
3333
"""Array variables."""
3434
var_to_name::Any
35-
"""Observed variables."""
35+
"""Observed equations."""
3636
observed::Vector{Equation}
3737
"""
3838
Jacobian matrix. Note: this field will not be defined until

src/systems/optimization/constraints_system.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct ConstraintsSystem <: AbstractTimeIndependentSystem
3333
ps::Vector
3434
"""Array variables."""
3535
var_to_name::Any
36-
"""Observed variables."""
36+
"""Observed equations."""
3737
observed::Vector{Equation}
3838
"""
3939
Jacobian matrix. Note: this field will not be defined until

src/systems/optimization/optimizationsystem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct OptimizationSystem <: AbstractOptimizationSystem
3131
ps::Vector
3232
"""Array variables."""
3333
var_to_name::Any
34-
"""Observed variables."""
34+
"""Observed equations."""
3535
observed::Vector{Equation}
3636
"""List of constraint equations of the system."""
3737
constraints::Vector{Union{Equation, Inequality}}

0 commit comments

Comments
 (0)