Skip to content

Commit

Permalink
Merge pull request SciML#2432 from AayushSabharwal/as/states-unknowns
Browse files Browse the repository at this point in the history
refactor: rename states to unknowns, and related changes
  • Loading branch information
ChrisRackauckas authored Jan 30, 2024
2 parents 882f721 + ff1382a commit 74cada4
Show file tree
Hide file tree
Showing 78 changed files with 666 additions and 667 deletions.
14 changes: 7 additions & 7 deletions docs/src/basics/AbstractSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Generally, it follows the order of:

1. Equations
2. Independent Variables
3. Dependent Variables (or States)
3. Dependent Variables (or Unknowns)
4. Parameters

All other pieces are handled via keyword arguments. `AbstractSystem`s share the
Expand All @@ -37,19 +37,19 @@ same keyword arguments, which are:
## Composition and Accessor Functions

Each `AbstractSystem` has lists of variables in context, such as distinguishing
parameters vs states. In addition, an `AbstractSystem` can also hold other
`AbstractSystem` types. Direct accessing of the values, such as `sys.states`,
gives the immediate list, while the accessor functions `states(sys)` gives the
parameters vs unknowns. In addition, an `AbstractSystem` can also hold other
`AbstractSystem` types. Direct accessing of the values, such as `sys.unknowns`,
gives the immediate list, while the accessor functions `unknowns(sys)` gives the
total set, which includes that of all systems held inside.

The values which are common to all `AbstractSystem`s are:

- `equations(sys)`: All equations that define the system and its subsystems.
- `states(sys)`: All the states in the system and its subsystems.
- `unknowns(sys)`: All the unknowns in the system and its subsystems.
- `parameters(sys)`: All parameters of the system and its subsystems.
- `nameof(sys)`: The name of the current-level system.
- `get_eqs(sys)`: Equations that define the current-level system.
- `get_states(sys)`: States that are in the current-level system.
- `get_unknowns(sys)`: Unknowns that are in the current-level system.
- `get_ps(sys)`: Parameters that are in the current-level system.
- `get_systems(sys)`: Subsystems of the current-level system.

Expand Down Expand Up @@ -129,7 +129,7 @@ pairs `var=>value`, which allows the user to designate the values without having
to know the order that ModelingToolkit is internally using.

For the value maps, the parameters are allowed to be functions of each other,
and value maps of states can be functions of the parameters, i.e. you can do:
and value maps of unknowns can be functions of the parameters, i.e. you can do:

```
u0 = [
Expand Down
18 changes: 9 additions & 9 deletions docs/src/basics/Composition.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ an optional forcing function, and allowing the user to specify the
forcing later. Here, the library author defines a component named
`decay`. The user then builds two `decay` components and connects them,
saying the forcing term of `decay1` is a constant while the forcing term
of `decay2` is the value of the state variable `x`.
of `decay2` is the value of the unknown variable `x`.

```@example composition
using ModelingToolkit
Expand Down Expand Up @@ -70,18 +70,18 @@ subsystems. A model is the composition of itself and its subsystems.
For example, if we have:

```julia
@named sys = compose(ODESystem(eqs, indepvar, states, ps), subsys)
@named sys = compose(ODESystem(eqs, indepvar, unknowns, ps), subsys)
```

the `equations` of `sys` is the concatenation of `get_eqs(sys)` and
`equations(subsys)`, the states are the concatenation of their states,
`equations(subsys)`, the unknowns are the concatenation of their unknowns,
etc. When the `ODEProblem` or `ODEFunction` is generated from this
system, it will build and compile the functions associated with this
composition.

The new equations within the higher level system can access the variables
in the lower level system by namespacing via the `nameof(subsys)`. For
example, let's say there is a variable `x` in `states` and a variable
example, let's say there is a variable `x` in `unknowns` and a variable
`x` in `subsys`. We can declare that these two variables are the same
by specifying their equality: `x ~ subsys.x` in the `eqs` for `sys`.
This algebraic relationship can then be simplified by transformations
Expand Down Expand Up @@ -133,7 +133,7 @@ sys = ODESystem(
sys.y = u * 1.1
```

In a hierarchical system, variables of the subsystem get namespaced by the name of the system they are in. This prevents naming clashes, but also enforces that every state and parameter is local to the subsystem it is used in. In some cases it might be desirable to have variables and parameters that are shared between subsystems, or even global. This can be accomplished as follows.
In a hierarchical system, variables of the subsystem get namespaced by the name of the system they are in. This prevents naming clashes, but also enforces that every unknown and parameter is local to the subsystem it is used in. In some cases it might be desirable to have variables and parameters that are shared between subsystems, or even global. This can be accomplished as follows.

```julia
@parameters t a b c d e f
Expand Down Expand Up @@ -186,12 +186,12 @@ i.e. equations which result in `0~0` expressions, in over-specified systems.

Model inheritance can be done in two ways: implicitly or explicitly. First, one
can use the `extend` function to extend a base model with another set of
equations, states, and parameters. An example can be found in the
equations, unknowns, and parameters. An example can be found in the
[acausal components tutorial](@ref acausal).

The explicit way is to shadow variables with equality expressions. For example,
let's assume we have three separate systems which we want to compose to a single
one. This is how one could explicitly forward all states and parameters to the
one. This is how one could explicitly forward all unknowns and parameters to the
higher level system:

```@example compose
Expand Down Expand Up @@ -225,7 +225,7 @@ sir = compose(ODESystem([
reqn.γ => γ], name = :sir), seqn, ieqn, reqn)
```

Note that the states are forwarded by an equality relationship, while
Note that the unknowns are forwarded by an equality relationship, while
the parameters are forwarded through a relationship in their default
values. The user of this model can then solve this model simply by
specifying the values at the highest level:
Expand Down Expand Up @@ -266,7 +266,7 @@ more efficient and more stable.
## Components with discontinuous dynamics

When modeling, e.g., impacts, saturations or Coulomb friction, the dynamic
equations are discontinuous in either the state or one of its derivatives. This
equations are discontinuous in either the unknown or one of its derivatives. This
causes the solver to take very small steps around the discontinuity, and
sometimes leads to early stopping due to `dt <= dt_min`. The correct way to
handle such dynamics is to tell the solver about the discontinuity by a
Expand Down
4 changes: 2 additions & 2 deletions docs/src/basics/ContextualVariables.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ the `@variable` which is defined by
@variables x y(x)
```

This is used for the “normal” variable of a given system, like the states of a
This is used for the “normal” variable of a given system, like the unknowns of a
differential equation or objective function. All the macros below support
the same syntax as `@variables`.

## Parameters

All modeling projects have some form of parameters. `@parameters` marks a variable
as being the parameter of some system, which allows automatic detection algorithms
to ignore such variables when attempting to find the states of a system.
to ignore such variables when attempting to find the unknowns of a system.

## Constants

Expand Down
12 changes: 6 additions & 6 deletions docs/src/basics/Events.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ event conditions, and the second vector of equations describes the effect on the
state. Each affect equation must be of the form

```julia
single_state_variable ~ expression_involving_any_variables_or_parameters
single_unknown_variable ~ expression_involving_any_variables_or_parameters
```

or
Expand Down Expand Up @@ -151,13 +151,13 @@ of one or more equations, an affect is defined as a `tuple`:
[x ~ 0] => (affect!, [v, x], [p, q], ctx)
```

where, `affect!` is a Julia function with the signature: `affect!(integ, u, p, ctx)`; `[u,v]` and `[p,q]` are the symbolic states (variables) and parameters
where, `affect!` is a Julia function with the signature: `affect!(integ, u, p, ctx)`; `[u,v]` and `[p,q]` are the symbolic unknowns (variables) and parameters
that are accessed by `affect!`, respectively; and `ctx` is any context that is
passed to `affect!` as the `ctx` argument.

`affect!` receives a [DifferentialEquations.jl
integrator](https://docs.sciml.ai/DiffEqDocs/stable/basics/integrator/)
as its first argument, which can then be used to access states and parameters
as its first argument, which can then be used to access unknowns and parameters
that are provided in the `u` and `p` arguments (implemented as `NamedTuple`s).
The integrator can also be manipulated more generally to control solution
behavior, see the [integrator
Expand All @@ -167,7 +167,7 @@ documentation. In affect functions, we have that
```julia
function affect!(integ, u, p, ctx)
# integ.t is the current time
# integ.u[u.v] is the value of the state `v` above
# integ.u[u.v] is the value of the unknown `v` above
# integ.p[p.q] is the value of the parameter `q` above
end
```
Expand Down Expand Up @@ -222,8 +222,8 @@ where conditions are symbolic expressions that should evaluate to `true` when an
individual affect should be executed. Here `affect1` and `affect2` are each
either a vector of one or more symbolic equations, or a functional affect, just
as for continuous events. As before, for any *one* event the symbolic affect
equations can either all change states (i.e. variables) or all change
parameters, but one cannot currently mix state and parameter changes within one
equations can either all change unknowns (i.e. variables) or all change
parameters, but one cannot currently mix unknown variable and parameter changes within one
individual event.

### Example: Injecting cells into a population
Expand Down
2 changes: 1 addition & 1 deletion docs/src/basics/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ julia> ModelingToolkit.missing_variable_defaults(sys, [1,2,3])
x3ˍtt(t) => 3
```

## Change the state vector type
## Change the unknown variable vector type

Use the `u0_constructor` keyword argument to map an array to the desired
container type. For example:
Expand Down
6 changes: 3 additions & 3 deletions docs/src/basics/Linearization.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ matrices, simplified_sys = linearize(sys, [r], [y]) # Linearize from r to y
matrices
```

The named tuple `matrices` contains the matrices of the linear statespace representation, while `simplified_sys` is an `ODESystem` that, among other things, indicates the state order in the linear system through
The named tuple `matrices` contains the matrices of the linear statespace representation, while `simplified_sys` is an `ODESystem` that, among other things, indicates the unknown variable order in the linear system through

```@example LINEARIZE
using ModelingToolkit: inputs, outputs
[states(simplified_sys); inputs(simplified_sys); outputs(simplified_sys)]
[unknowns(simplified_sys); inputs(simplified_sys); outputs(simplified_sys)]
```

## Operating point

The operating point to linearize around can be specified with the keyword argument `op` like this: `op = Dict(x => 1, r => 2)`. The operating point may include specification of state variables, input variables and parameters. For variables that are not specified in `op`, the default value specified in the model will be used if available, if no value is specified, an error is thrown.
The operating point to linearize around can be specified with the keyword argument `op` like this: `op = Dict(x => 1, r => 2)`. The operating point may include specification of unknown variables, input variables and parameters. For variables that are not specified in `op`, the default value specified in the model will be used if available, if no value is specified, an error is thrown.

## Batch linearization and algebraic variables

Expand Down
10 changes: 5 additions & 5 deletions docs/src/basics/MTKModel_Connector.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ModelingToolkit.Model

## Components

Components are models from various domains. These models contain states and their
Components are models from various domains. These models contain unknowns and their
equations.

### [Defining components with `@mtkmodel`](@id mtkmodel)
Expand All @@ -25,11 +25,11 @@ equations.

- `@components`: for listing sub-components of the system
- `@equations`: for the list of equations
- `@extend`: for extending a base system and unpacking its states
- `@extend`: for extending a base system and unpacking its unknowns
- `@icon` : for embedding the model icon
- `@parameters`: for specifying the symbolic parameters
- `@structural_parameters`: for specifying non-symbolic parameters
- `@variables`: for specifying the states
- `@variables`: for specifying the unknowns

Let's explore these in more detail with the following example:

Expand Down Expand Up @@ -171,7 +171,7 @@ getdefault(model_c4.model_a.k_array[2])
Connectors are special models that can be used to connect different components together.
MTK provides 3 distinct connectors:

- `DomainConnector`: A connector which has only one state which is of `Flow` type,
- `DomainConnector`: A connector which has only one unknown which is of `Flow` type,
specified by `[connect = Flow]`.
- `StreamConnector`: A connector which has atleast one stream variable, specified by
`[connect = Stream]`. A `StreamConnector` must have exactly one flow variable.
Expand Down Expand Up @@ -228,7 +228,7 @@ end
`structure` stores metadata that describes composition of a model. It includes:

- `:components`: List of sub-components in the form of [[name, sub_component_name],...].
- `:extend`: The list of extended states, name given to the base system, and name of the base system.
- `:extend`: The list of extended unknowns, name given to the base system, and name of the base system.
- `:structural_parameters`: Dictionary of structural parameters mapped to their default values.
- `:parameters`: Dictionary of symbolic parameters mapped to their metadata. For
parameter arrays, length is added to the metadata as `:size`.
Expand Down
12 changes: 6 additions & 6 deletions docs/src/examples/modelingtoolkitize_index_reduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ traced_sys = modelingtoolkitize(pendulum_prob)
pendulum_sys = structural_simplify(dae_index_lowering(traced_sys))
prob = ODAEProblem(pendulum_sys, [], tspan)
sol = solve(prob, Tsit5(), abstol = 1e-8, reltol = 1e-8)
plot(sol, idxs = states(traced_sys))
plot(sol, idxs = unknowns(traced_sys))
```

## Explanation
Expand Down Expand Up @@ -81,7 +81,7 @@ However, one will quickly be greeted with the unfortunate message:
└ @ OrdinaryDiffEq C:\Users\accou\.julia\packages\OrdinaryDiffEq\yCczp\src\initdt.jl:76
┌ Warning: Automatic dt set the starting dt as NaN, causing instability.
└ @ OrdinaryDiffEq C:\Users\accou\.julia\packages\OrdinaryDiffEq\yCczp\src\solve.jl:485
┌ Warning: NaN dt detected. Likely a NaN value in the state, parameters, or derivative value caused this outcome.
┌ Warning: NaN dt detected. Likely a NaN value in the unknowns, parameters, or derivative value caused this outcome.
└ @ SciMLBase C:\Users\accou\.julia\packages\SciMLBase\DrPil\src\integrator_interface.jl:325
```

Expand Down Expand Up @@ -154,17 +154,17 @@ prob = ODEProblem(pendulum_sys, Pair[], tspan)
sol = solve(prob, Rodas4())
using Plots
plot(sol, idxs = states(traced_sys))
plot(sol, idxs = unknowns(traced_sys))
```

Note that plotting using `states(traced_sys)` is done so that any
Note that plotting using `unknowns(traced_sys)` is done so that any
variables which are symbolically eliminated, or any variable reordering
done for enhanced parallelism/performance, still show up in the resulting
plot and the plot is shown in the same order as the original numerical
code.

Note that we can even go a bit further. If we use the `ODAEProblem`
constructor, we can remove the algebraic equations from the states of the
constructor, we can remove the algebraic equations from the unknowns of the
system and fully transform the index-3 DAE into an index-0 ODE which can
be solved via an explicit Runge-Kutta method:

Expand All @@ -173,7 +173,7 @@ traced_sys = modelingtoolkitize(pendulum_prob)
pendulum_sys = structural_simplify(dae_index_lowering(traced_sys))
prob = ODAEProblem(pendulum_sys, Pair[], tspan)
sol = solve(prob, Tsit5(), abstol = 1e-8, reltol = 1e-8)
plot(sol, idxs = states(traced_sys))
plot(sol, idxs = unknowns(traced_sys))
```

And there you go: this has transformed the model from being too hard to
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/perturbation.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ using ModelingToolkit, DifferentialEquations

@named sys = ODESystem(eqs, t)
sys = structural_simplify(sys)
states(sys)
unknowns(sys)
```

```julia
Expand Down
10 changes: 5 additions & 5 deletions docs/src/examples/spring_mass.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ We can take a look at the equations in the model using the `equations` function.
equations(model)
```

The states of this model are:
The unknowns of this model are:

```@example component
states(model)
unknowns(model)
```

And the parameters of this model are:
Expand All @@ -162,7 +162,7 @@ sys = structural_simplify(model)
equations(sys)
```

We are left with only 4 equations involving 4 state variables (`mass.pos[1]`,
We are left with only 4 equations involving 4 unknown variables (`mass.pos[1]`,
`mass.pos[2]`, `mass.v[1]`, `mass.v[2]`). We can solve the system by converting
it to an `ODEProblem`. Some observed variables are not expanded by default. To
view the complete equations, one can do
Expand All @@ -179,13 +179,13 @@ sol = solve(prob, Rosenbrock23())
plot(sol)
```

What if we want the timeseries of a different variable? That information is not lost! Instead, `structural_simplify` simply changes state variables into `observed` variables.
What if we want the timeseries of a different variable? That information is not lost! Instead, `structural_simplify` simply changes unknown variables into `observed` variables.

```@example component
observed(sys)
```

These are explicit algebraic equations which can be used to reconstruct the required variables on the fly. This leads to dramatic computational savings since implicitly solving an ODE scales as O(n^3), so fewer states are significantly better!
These are explicit algebraic equations which can be used to reconstruct the required variables on the fly. This leads to dramatic computational savings since implicitly solving an ODE scales as O(n^3), so fewer unknowns are significantly better!

We can access these variables using the solution object. For example, let's retrieve the x-position of the mass over time:

Expand Down
2 changes: 1 addition & 1 deletion docs/src/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ contributors to the library.
## Observables and Variable Elimination

In the variable “elimination” algorithms, what is actually done is that variables
are removed from being states and equations are moved into the `observed` category
are removed from being unknowns and equations are moved into the `observed` category
of the system. The `observed` equations are explicit algebraic equations which
are then substituted out to completely eliminate these variables from the other
equations, allowing the system to act as though these variables no longer exist.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/systems/JumpSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ JumpSystem
## Composition and Accessor Functions

- `get_eqs(sys)` or `equations(sys)`: The equations that define the jump system.
- `get_states(sys)` or `states(sys)`: The set of states in the jump system.
- `get_unknowns(sys)` or `unknowns(sys)`: The set of unknowns in the jump system.
- `get_ps(sys)` or `parameters(sys)`: The parameters of the jump system.
- `get_iv(sys)`: The independent variable of the jump system.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/systems/NonlinearSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ NonlinearSystem
## Composition and Accessor Functions

- `get_eqs(sys)` or `equations(sys)`: The equations that define the nonlinear system.
- `get_states(sys)` or `states(sys)`: The set of states in the nonlinear system.
- `get_unknowns(sys)` or `unknowns(sys)`: The set of unknowns in the nonlinear system.
- `get_ps(sys)` or `parameters(sys)`: The parameters of the nonlinear system.
- `get_u0_p(sys, u0map, parammap)` Numeric arrays for the initial condition and parameters given `var => value` maps.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/systems/ODESystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ODESystem
## Composition and Accessor Functions

- `get_eqs(sys)` or `equations(sys)`: The equations that define the ODE.
- `get_states(sys)` or `states(sys)`: The set of states in the ODE.
- `get_unknowns(sys)` or `unknowns(sys)`: The set of unknowns in the ODE.
- `get_ps(sys)` or `parameters(sys)`: The parameters of the ODE.
- `get_iv(sys)`: The independent variable of the ODE.
- `get_u0_p(sys, u0map, parammap)` Numeric arrays for the initial condition and parameters given `var => value` maps.
Expand Down
Loading

0 comments on commit 74cada4

Please sign in to comment.