Skip to content

docs: improve documentation #3725

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 11, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/src/API/problems.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
```@meta
CollapsedDocStrings = true
```

# Building and solving numerical problems

Systems are numerically solved by building and solving the appropriate problem type.
7 changes: 0 additions & 7 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -42,13 +42,6 @@ If you use ModelingToolkit in your work, please cite the following:
for a summary of the changes. Some documentation pages may be broken while downstram
packages update to the new version.

!!! danger "Temporarily broken discrete systems"

ModelingToolkit's support for purely explicit systems of discrete update equations
(ones solved via `OrdinaryDiffEqFunctionMap.jl`) is temporarily broken. While such
systems can be created, simplfied and solved there are issues with the naming of
simplified unknowns and symbolic indexing of the problem/solution.

ModelingToolkit.jl is a symbolic-numeric modeling package. Thus it combines some
of the features from symbolic computing packages like SymPy or Mathematica with
the ideas of equation-based modeling systems like the causal Simulink and the
108 changes: 98 additions & 10 deletions src/systems/system.jl
Original file line number Diff line number Diff line change
@@ -826,9 +826,19 @@ end
"""
$(TYPEDSIGNATURES)

Convert a time-dependent system `sys` to a time-independent system of nonlinear
equations that solve for the steady state of the system where `D(x)` is zero for
each continuous variable `x`.
Given a time-dependent system `sys` of ODEs, convert it to a time-independent system of
nonlinear equations that solve for the steady-state of the unknowns. This is done by
replacing every derivative `D(x)` of an unknown `x` with zero. Note that this process
does not retain noise equations, brownian terms, jumps or costs associated with `sys`.
All other information such as defaults, guesses, observed and initialization equations
are retained. The independent variable of `sys` becomes a parameter of the returned system.

If `sys` is hierarchical (it contains subsystems) this transformation will be applied
recursively to all subsystems. The output system will be marked as `complete` if and only
if the input system is also `complete`. This also retains the `split` flag passed to
`complete`.

See also: [`complete`](@ref).
"""
function NonlinearSystem(sys::System)
if !is_time_dependent(sys)
@@ -837,6 +847,9 @@ function NonlinearSystem(sys::System)
eqs = equations(sys)
obs = observed(sys)
subrules = Dict([D(x) => 0.0 for x in unknowns(sys)])
for var in brownians(sys)
subrules[var] = 0.0
end
eqs = map(eqs) do eq
fast_substitute(eq, subrules)
end
@@ -856,30 +869,68 @@ end
########

"""
$(METHODLIST)
$(TYPEDSIGNATURES)

Construct a time-independent [`System`](@ref) for optimizing the specified scalar `cost`.
The system will have no equations.

Construct a [`System`](@ref) to solve an optimization problem with the given scalar cost.
Unknowns and parameters of the system are inferred from the cost and other values (such as
defaults) passed to it.

All keyword arguments are the same as those of the [`System`](@ref) constructor.
"""
function OptimizationSystem(cost; kwargs...)
return System(Equation[]; costs = [cost], kwargs...)
end

"""
$(TYPEDSIGNATURES)

Identical to the corresponding single-argument `OptimizationSystem` constructor, except
the unknowns and parameters are specified by passing arrays of symbolic variables to `dvs`
and `ps` respectively.
"""
function OptimizationSystem(cost, dvs, ps; kwargs...)
return System(Equation[], nothing, dvs, ps; costs = [cost], kwargs...)
end

"""
$(TYPEDSIGNATURES)

Construct a time-independent [`System`](@ref) for optimizing the specified multi-objective
`cost`. The cost will be reduced to a scalar using the `consolidate` function. This
defaults to summing the specified cost and that of all subsystems. The system will have no
equations.

Unknowns and parameters of the system are inferred from the cost and other values (such as
defaults) passed to it.

All keyword arguments are the same as those of the [`System`](@ref) constructor.
"""
function OptimizationSystem(cost::Array; kwargs...)
return System(Equation[]; costs = vec(cost), kwargs...)
end

"""
$(TYPEDSIGNATURES)

Identical to the corresponding single-argument `OptimizationSystem` constructor, except
the unknowns and parameters are specified by passing arrays of symbolic variables to `dvs`
and `ps` respectively.
"""
function OptimizationSystem(cost::Array, dvs, ps; kwargs...)
return System(Equation[], nothing, dvs, ps; costs = vec(cost), kwargs...)
end

"""
$(METHODLIST)
$(TYPEDSIGNATURES)

Construct a [`System`](@ref) to solve a system of jump equations.
Construct a [`System`](@ref) to solve a system of jump equations. `jumps` is an array of
jumps, expressed using `JumpProcesses.MassActionJump`, `JumpProcesses.ConstantRateJump`
and `JumpProcesses.VariableRateJump`. It can also include standard equations to simulate
jump-diffusion processes. `iv` should be the independent variable of the system.

All keyword arguments are the same as those of the [`System`](@ref) constructor.
"""
function JumpSystem(jumps, iv; kwargs...)
mask = isa.(jumps, Equation)
@@ -888,17 +939,42 @@ function JumpSystem(jumps, iv; kwargs...)
return System(eqs, iv; jumps, kwargs...)
end

"""
$(TYPEDSIGNATURES)

Identical to the 2-argument `JumpSystem` constructor, but uses the explicitly provided
`dvs` and `ps` for unknowns and parameters of the system.
"""
function JumpSystem(jumps, iv, dvs, ps; kwargs...)
mask = isa.(jumps, Equation)
eqs = Vector{Equation}(jumps[mask])
jumps = jumps[.!mask]
return System(eqs, iv, dvs, ps; jumps, kwargs...)
end

# explicitly write the docstring to avoid mentioning `parameter_dependencies`.
"""
$(METHODLIST)

Construct a system of equations with associated noise terms.
SDESystem(eqs::Vector{Equation}, noise, iv; is_scalar_noise = false, kwargs...)

Construct a system of equations with associated noise terms. Instead of specifying noise
using [`@brownians`](@ref) variables, it is specified using a noise matrix `noise`. `iv` is
the independent variable of the system.

In the general case, `noise` should be a `N x M` matrix where `N` is the number of
equations (`length(eqs)`) and `M` is the number of independent random variables.
`noise[i, j]` is the diffusion term for equation `i` and random variable `j`. If the noise
is diagonal (`N == M` and `noise[i, j] == 0` for all `i != j`) it can be specified as a
`Vector` of length `N` corresponding to the diagonal of the noise matrix. As a special
case, if all equations have the same noise then all rows of `noise` are identical. This
is known as "scalar noise". In this case, `noise` can be a `Vector` corresponding to the
repeated row and `is_scalar_noise` must be `true`.

Note that systems created in this manner cannot be used hierarchically. This should only
be used to construct flattened systems. To use such a system hierarchically, it must be
converted to use brownian variables using [`noise_to_brownians`](@ref). [`mtkcompile`](@ref)
will automatically perform this conversion.

All keyword arguments are the same as those of the [`System`](@ref) constructor.
"""
function SDESystem(eqs::Vector{Equation}, noise, iv; is_scalar_noise = false,
parameter_dependencies = Equation[], kwargs...)
@@ -912,6 +988,13 @@ function SDESystem(eqs::Vector{Equation}, noise, iv; is_scalar_noise = false,
@set sys.parameter_dependencies = parameter_dependencies
end

"""
SDESystem(eqs::Vector{Equation}, noise, iv, dvs, ps; is_scalar_noise = false, kwargs...)


Identical to the 3-argument `SDESystem` constructor, but uses the explicitly provided
`dvs` and `ps` for unknowns and parameters of the system.
"""
function SDESystem(
eqs::Vector{Equation}, noise, iv, dvs, ps; is_scalar_noise = false,
parameter_dependencies = Equation[], kwargs...)
@@ -925,6 +1008,11 @@ function SDESystem(
@set sys.parameter_dependencies = parameter_dependencies
end

"""
$(TYPEDSIGNATURES)

Attach the given noise matrix `noise` to the system `sys`.
"""
function SDESystem(sys::System, noise; kwargs...)
SDESystem(equations(sys), noise, get_iv(sys); kwargs...)
end