It is possible to add metadata to symbolic variables. The following information can be added (note, it's possible to extend this to user-defined metadata as well)

## Input or output

Designate a variable as either an input or an output using the following

using ModelingToolkit
@variables u [input=true]
isinput(u)
true
@variables y [output=true]
isoutput(y)
true

## Bounds

Bounds are useful when parameters are to be optimized, or to express intervals of uncertainty.

@variables u [bounds=(-1,1)]
hasbounds(u)
true
getbounds(u)
(-1, 1)

## Mark input as a disturbance

Indicate that an input is not available for control, i.e., it's a disturbance input.

@variables u [input=true, disturbance=true]
isdisturbance(u)
true

## Mark parameter as tunable

Indicate that a parameter can be automatically tuned by automatic control tuning apps.

@parameters Kp [tunable=true]
istunable(Kp)
true

## Probability distributions

A probability distribution may be associated with a parameter to indicate either uncertainty about it's value, or as a prior distribution for Bayesian optimization.

using Distributions
d = Normal(10, 1)
@parameters m [dist=d]
hasdist(m)
getdist(m)

For systems that contain parameters with metadata like described above have some additional functions defined for convenience. In the example below, we define a system with tunable parameters and extract bounds vectors

@parameters t
Dₜ = Differential(t)
@variables x(t)=0 u(t)=0 [input=true] y(t)=0 [output=true]
@parameters T [tunable = true, bounds = (0, Inf)]
@parameters k [tunable = true, bounds = (0, Inf)]
eqs = [
Dₜ(x) ~ (-x + k*u) / T # A first-order system with time constant T and gain k
y ~ x
]
sys = ODESystem(eqs, t, name=:tunable_first_order)

\begin{align} \frac{dx(t)}{dt} =& \frac{k u\left( t \right) - x\left( t \right)}{T} \ y\left( t \right) =& x\left( t \right) \end{align}

p = tunable_parameters(sys) # extract all parameters marked as tunable
2-element Vector{Sym{Real, Base.ImmutableDict{DataType, Any}}}:
k
T
lb, ub = getbounds(p) # operating on a vector, we get lower and upper bound vectors
(lb = [0, 0], ub = [Inf, Inf])
b = getbounds(sys) # Operating on the system, we get a dict
Dict{Sym{Real, Base.ImmutableDict{DataType, Any}}, Tuple{Int64, Float64}} with 2 entries:
k => (0, Inf)
T => (0, Inf)

## Docstrings

ModelingToolkit.getboundsMethod
lb, ub = getbounds(p::AbstractVector)

Return vectors of lower and upper bounds of parameter vector p. Create parameters with bounds like this

@parameters p [bounds=(-1, 1)]
source
ModelingToolkit.getboundsMethod
getbounds(x)

Get the bounds associated with symbolc variable x. Create parameters with bounds like this

@parameters p [bounds=(-1, 1)]
source
ModelingToolkit.getboundsMethod
getbounds(sys::ModelingToolkit.AbstractSystem)

Returns a dict with pairs p => (lb, ub) mapping parameters of sys to lower and upper bounds. Create parameters with bounds like this

@parameters p [bounds=(-1, 1)]
source
ModelingToolkit.getdistMethod
getdist(x)

Get the probability distribution associated with symbolc variable x. If no distribution is associated with x, nothing is returned. Create parameters with associated distributions like this

using Distributions
d = Normal(0, 1)
@parameters u [dist=d]
hasdist(u) # true
getdist(u) # retrieve distribution
source
ModelingToolkit.istunableFunction
istunable(x, default = false)

Determine whether or not symbolic variable x is marked as a tunable for an automatic tuning algorithm.

default indicates whether variables without tunable metadata are to be considered tunable or not.

Create a tunable parameter by

@parameters u [tunable=true]
source
ModelingToolkit.tunable_parametersFunction
tunable_parameters(sys, p = parameters(sys); default=false)

Get all parameters of sys that are marked as tunable.

Keyword argument default indicates whether variables without tunable metadata are to be considered tunable or not.

Create a tunable parameter by

@parameters u [tunable=true]
source