ModelOrderReduction.AbstractDRProblemModelOrderReduction.AbstractReductionProblemModelOrderReduction.AbstractSVDModelOrderReduction.BalancedTruncationModelOrderReduction.FullOrderModelModelOrderReduction.OperatorInferenceModelModelOrderReduction.PODModelOrderReduction.RSVDModelOrderReduction.SVDModelOrderReduction.SourceFieldModelOrderReduction.TSVDModelOrderReduction.baltruncModelOrderReduction.deimModelOrderReduction.opinfModelOrderReduction.podModelOrderReduction.quadratic_monomialsModelOrderReduction.reduce!ModelOrderReduction.reduced_dynamicsModelOrderReduction.separate_terms
ModelOrderReduction.POD — Type
POD(snapshots; min_renergy = 1.0, min_nmodes = 1,
max_nmodes = length(snapshots[1])) -> POD
POD(snapshots, nmodes::Int) -> PODProper orthogonal decomposition reduction problem built from state snapshots. Call reduce! with an SVD backend to compute its basis and spectrum.
Arguments
snapshots::AbstractMatrix{T}: a state-by-snapshot matrix, where each column is a state snapshot.snapshots::AbstractVector{<:AbstractVector{T}}: a vector of state snapshots.nmodes::Int: the fixed number of retained modes. This positional form disables energy-based truncation.
Keywords
min_renergy::T = 1.0: minimum captured relative spectral energy when selecting modes.min_nmodes::Int = 1: lower bound on the number of retained modes.max_nmodes::Int = length(snapshots[1]): upper bound on the number of retained modes.
Fields
snapshots::S: the input snapshot data.min_renergy::T: the minimum relative spectral energy used for truncation.min_nmodes::Int: the lower bound on the number of retained modes.max_nmodes::Int: the upper bound on the number of retained modes.nmodes::Int: the selected number of retained modes.rbasis::Union{Missing, Matrix{T}}: the reduced basis afterreduce!, ormissingbefore reduction.renergy::T: the captured relative spectral energy.spectrum::Union{Missing, Vector{T}}: the singular-value spectrum afterreduce!, ormissingbefore reduction.
Throws
AssertionError: if the snapshots are not vector-valued or the truncation bounds are invalid.
Returns
POD: an initialized reduction problem. The basis and spectrum are populated byreduce!.
Examples
julia> using ModelOrderReduction
julia> pod = POD([3.0 0.0; 0.0 1.0], 1);
julia> pod.nmodes
1ModelOrderReduction.reduce! — Function
reduce!(pod::POD, alg::SVD) -> nothingCompute the reduced basis and full singular-value spectrum for pod using dense SVD.
Arguments
pod::POD: reduction problem to update in place.alg::SVD: dense singular value decomposition backend.
Returns
nothing:podis updated in place.
Examples
julia> using ModelOrderReduction
julia> pod = POD([3.0 0.0; 0.0 1.0], 1);
julia> reduce!(pod, SVD()); size(pod.rbasis)
(2, 1)reduce!(pod::POD, alg::TSVD) -> nothingCompute the reduced basis and truncated singular-value spectrum for pod using a truncated SVD.
Arguments
pod::POD: reduction problem to update in place.alg::TSVD: truncated singular value decomposition backend.
Returns
nothing:podis updated in place.
Throws
- An exception propagated by
TSVD.tsvdif the snapshot matrix is not accepted by the truncated SVD backend.
Examples
julia> using ModelOrderReduction
julia> pod = POD([3.0 0.0; 0.0 1.0], 1);
julia> reduce!(pod, TSVD()); pod.nmodes
1reduce!(pod::POD, alg::RSVD) -> nothingCompute the reduced basis and approximate singular-value spectrum for pod using a randomized SVD.
Arguments
pod::POD: reduction problem to update in place.alg::RSVD: randomized singular value decomposition backend.
Returns
nothing:podis updated in place.
Throws
- An exception propagated by
RandomizedLinAlg.rsvdif the snapshot matrix is not accepted by the randomized SVD backend.
Examples
julia> using ModelOrderReduction
julia> pod = POD([3.0 0.0; 0.0 1.0], 1);
julia> reduce!(pod, RSVD()); pod.nmodes
1ModelOrderReduction.SVD — Type
SVD(; kwargs...) -> SVDDense singular value decomposition backend for reduce!.
Keywords
kwargs...: keyword arguments forwarded toLinearAlgebra.svd.
Fields
kwargs: the named tuple of keyword arguments forwarded to the decomposition.
Examples
julia> using ModelOrderReduction
julia> SVD() isa SVD
trueModelOrderReduction.TSVD — Type
TSVD(; kwargs...) -> TSVDTruncated singular value decomposition backend for reduce!. Use this backend when only the requested reduced modes should be computed.
Keywords
kwargs...: keyword arguments forwarded toTSVD.tsvd.
Fields
kwargs: the named tuple of keyword arguments forwarded to the decomposition.
Examples
julia> using ModelOrderReduction
julia> TSVD() isa TSVD
trueModelOrderReduction.RSVD — Type
RSVD([p::Int = 0]) -> RSVDRandomized singular value decomposition backend for reduce!.
Arguments
p::Int = 0: number of oversampling vectors used byRandomizedLinAlg.rsvd.
Fields
p::Int: the oversampling parameter.
Throws
MethodError: ifpis not anInt.
Examples
julia> using ModelOrderReduction
julia> RSVD(2).p
2ModelOrderReduction.deim — Function
deim(
sys::ModelingToolkit.System,
snapshot::AbstractMatrix,
pod_dim::Integer;
deim_dim::Integer = pod_dim,
name::Symbol = Symbol(nameof(sys), :_deim),
snapshot_times = nothing,
kwargs...
) -> ModelingToolkit.SystemReduce a first-order ModelingToolkit.System with Proper Orthogonal Decomposition (POD) and the Discrete Empirical Interpolation Method (DEIM).
The rows of snapshot follow ModelingToolkit.unknowns(sys) and each column is one time instance. The state basis is the POD basis of snapshot, and the DEIM basis is the POD basis of the nonlinear terms evaluated at the snapshot columns. Both bases are computed with TSVD.
sys may contain algebraic equations or array equations. It is structurally simplified as needed, which may scalarize the equations offline, but the returned system always has one array differential equation for the reduced state and one reconstruction observed equation per source field. The reduced equation is array linear algebra in the reduced state: the projected matrices, the stencil rows of the state basis, and the full-grid reconstruction coefficients are array parameters of the reduced system, and only the DEIM-sampled nonlinear terms are scalar expressions. Unknowns eliminated during simplification are reconstructed by a least-squares fit to snapshot. Terms that are linear in the unknowns with numeric coefficients are projected exactly; every other state-dependent term is interpolated by DEIM. Pass MethodOfLines symbolic_discretize systems before structural simplification so every element of each field is available for reconstruction.
Nonlinear terms are evaluated at the numeric parameter defaults of sys. Use the problem/solution method for problem-specific parameter values. The reduced state and its derivative at the first snapshot column are stored as initial conditions.
The reduced system inherits the time span of sys, so a problem can be built from it without repeating one. Passing a time span explicitly still overrides it, and a source system without one produces a reduced system without one.
Construct a DAEProblem with build_initializeprob = false from the returned system to keep array code generation, or call ModelingToolkit.mtkcompile on it and construct an ODEProblem to generate scalar code for the reduced equation. Reconstruct fields with SymbolicIndexingInterface.observed(reduced_system, field).
Arguments
sys::ModelingToolkit.System: first-order source system without subsystems.snapshot::AbstractMatrix: state-by-time snapshot matrix forsys.pod_dim::Integer: number of POD state modes to retain.
Keywords
deim_dim::Integer = pod_dim: number of DEIM modes for the nonlinear terms.name::Symbol = Symbol(nameof(sys), :_deim): name of the reduced system.snapshot_times = nothing: time of each snapshot column; required when the equations depend on the independent variable.kwargs...: keyword arguments forwarded toSymbolics.substitute.
Returns
ModelingToolkit.System: the completed reduced system.
Throws
DimensionMismatch: ifsnapshotdoes not have one row per unknown ofsys, or ifsnapshot_timesdoes not have one entry per column.ArgumentError: ifsysdoes not simplify to an explicit first-order ODE, or if a nonlinear term cannot be evaluated numerically.
Examples
reduced_system = deim(source_system, snapshots, 4; deim_dim = 6)deim(
prob::Union{SciMLBase.AbstractODEProblem, SciMLBase.AbstractDAEProblem},
sol,
pod_dim::Integer;
deim_dim::Integer = pod_dim,
name::Union{Nothing, Symbol} = nothing,
kwargs...
) -> ModelingToolkit.SystemReduce the symbolic system behind prob with POD-DEIM, using one of its saved solutions sol as the training snapshot.
prob must have been constructed from a ModelingToolkit.System, such as the array-form DAEProblem returned by MethodOfLines. The saved states are the snapshot columns, the saved times supply the independent variable for time-dependent terms, and the parameter values of prob are used for training and become the defaults of the reduced system. The reduced system also inherits the time span of prob, which is the interval it was trained on, so a problem can be built from it without repeating one. sol may be the SciMLBase.PDETimeSeriesSolution returned by MethodOfLines or its underlying SciMLBase.AbstractODESolution. See the system method for the reduction itself and for how to construct problems from the returned system.
Arguments
prob: symbolic first-order problem whose function stores aModelingToolkit.System.sol: saved solution obtained fromprob.pod_dim::Integer: number of POD state modes to retain.
Keywords
deim_dim::Integer = pod_dim: number of DEIM modes for the nonlinear terms.name::Union{Nothing, Symbol} = nothing: name of the reduced system. The default appends_deimto the name of the full system.kwargs...: keyword arguments forwarded toSymbolics.substitute.
Returns
ModelingToolkit.System: the completed reduced system.
Throws
ArgumentError: ifprobhas no symbolic system, ifsolwas not obtained fromprobor does not start at the beginning ofprob, or if the system does not simplify to an explicit first-order ODE.DimensionMismatch: if the saved states do not match the unknowns of the system.
Examples
full_problem = discretize(pde_system, discretization; fallback = false)
full_solution = solve(full_problem)
reduced_system = deim(full_problem, full_solution, 4)
reduced_problem = DAEProblem(reduced_system, nothing; build_initializeprob = false)ModelOrderReduction.pod — Function
pod(
sys::ModelingToolkit.System,
snapshot::AbstractMatrix,
pod_dim::Integer;
name::Symbol = Symbol(nameof(sys), :_pod),
snapshot_times = nothing,
kwargs...
) -> ModelingToolkit.SystemReduce a first-order ModelingToolkit.System with Proper Orthogonal Decomposition (POD) Galerkin projection, without Discrete Empirical Interpolation (DEIM).
The rows of snapshot follow ModelingToolkit.unknowns(sys) and each column is one time instance. The state basis is the POD basis of snapshot, computed with TSVD.
When the source system is an explicit first-order model whose differential equations are written in terms of the source field variables (including array equations), the reduced dynamics are assembled by substituting $\mathbf y = V\hat{\mathbf y}$ into those equations and left-multiplying by $V^T$. The state basis and its transpose are array parameters, so the generated residual is array linear algebra whose symbolic size does not grow with the full-order grid. When the source has already been scalarized, the same Galerkin projection is applied to the compiled residual; the online nonlinear cost then scales with the full-order dimension (use deim to hyper-reduce it).
sys may contain algebraic equations or array equations. It is structurally simplified as needed. The returned system always has one array differential equation for the reduced state and one reconstruction observed equation per source field. Unknowns eliminated during simplification are reconstructed by a least-squares fit to snapshot.
The reduced system inherits the time span of sys, so a problem can be built from it without repeating one. Passing a time span explicitly still overrides it, and a source system without one produces a reduced system without one.
Construct a DAEProblem with build_initializeprob = false from the returned system to keep array code generation, or call ModelingToolkit.mtkcompile on it and construct an ODEProblem to generate scalar code for the reduced equation. Reconstruct fields with SymbolicIndexingInterface.observed(reduced_system, field).
Arguments
sys::ModelingToolkit.System: first-order source system without subsystems.snapshot::AbstractMatrix: state-by-time snapshot matrix forsys.pod_dim::Integer: number of POD state modes to retain.
Keywords
name::Symbol = Symbol(nameof(sys), :_pod): name of the reduced system.snapshot_times = nothing: time of each snapshot column; required when the equations depend on the independent variable.kwargs...: keyword arguments forwarded toSymbolics.substitute.
Returns
ModelingToolkit.System: the completed reduced system.
Throws
DimensionMismatch: ifsnapshotdoes not have one row per unknown ofsys, or ifsnapshot_timesdoes not have one entry per column.ArgumentError: ifsysdoes not simplify to an explicit first-order ODE, or if a residual term cannot be evaluated numerically.
Examples
reduced_system = pod(source_system, snapshots, 4)pod(
prob::Union{SciMLBase.AbstractODEProblem, SciMLBase.AbstractDAEProblem},
sol,
pod_dim::Integer;
name::Union{Nothing, Symbol} = nothing,
kwargs...
) -> ModelingToolkit.SystemReduce the symbolic system behind prob with POD Galerkin projection, using one of its saved solutions sol as the training snapshot.
prob must have been constructed from a ModelingToolkit.System, such as the array-form DAEProblem returned by MethodOfLines. The saved states are the snapshot columns, the saved times supply the independent variable for time-dependent terms, and the parameter values of prob are used for training and become the defaults of the reduced system. The reduced system also inherits the time span of prob, which is the interval it was trained on, so a problem can be built from it without repeating one. sol may be the SciMLBase.PDETimeSeriesSolution returned by MethodOfLines or its underlying SciMLBase.AbstractODESolution. See the system method for the reduction itself and for how to construct problems from the returned system.
Arguments
prob: symbolic first-order problem whose function stores aModelingToolkit.System.sol: saved solution obtained fromprob.pod_dim::Integer: number of POD state modes to retain.
Keywords
name::Union{Nothing, Symbol} = nothing: name of the reduced system. The default appends_podto the name of the full system.kwargs...: keyword arguments forwarded toSymbolics.substitute.
Returns
ModelingToolkit.System: the completed reduced system.
Throws
ArgumentError: ifprobhas no symbolic system, ifsolwas not obtained fromprobor does not start at the beginning ofprob, or if the system does not simplify to an explicit first-order ODE.DimensionMismatch: if the saved states do not match the unknowns of the system.
Examples
full_problem = discretize(pde_system, discretization; fallback = false)
full_solution = solve(full_problem)
reduced_system = pod(full_problem, full_solution, 4)
reduced_problem = DAEProblem(
reduced_system, nothing; build_initializeprob = false
)ModelOrderReduction.baltrunc — Function
baltrunc(A, B, C, D = nothing; n = nothing, atol = 0, rtol = 1e-3,
residual = false) -> BalancedTruncationBalanced truncation of a continuous-time linear time-invariant system
\[\dot x = A x + B u,\qquad y = C x + D u.\]
The square-root method balances the controllability and observability Gramians and truncates states with small Hankel singular values. If n is omitted, the reduced order keeps singular values at least atol and at least rtol times the largest singular value.
When residual = true, truncated states are eliminated by residualization (singular perturbation) so that the static gain is matched.
Only real floating-point systems are supported. A must be Hurwitz.
Arguments
A::AbstractMatrix: state matrix.B::AbstractVecOrMat: input matrix (vectors are treated as single-input).C::AbstractMatrix: output matrix.D: feedthrough matrix. Defaults to a zero matrix conforming to(C, B).
Keywords
n = nothing: reduced order. Whennothing, choose the order fromatol/rtol.atol = 0: absolute Hankel-singular-value cutoff.rtol = 1e-3: relative Hankel-singular-value cutoff.residual = false: use residualization instead of plain truncation.
Returns
BalancedTruncation: reduced matrices, retained Hankel singular values, and projectors.
Throws
ArgumentError: if the system dimensions are inconsistent,Ais not square,Ais not Hurwitz, no positive Hankel singular values remain, ornis invalid.
Examples
julia> using ModelOrderReduction
julia> A = [-1.0 0.0; 0.0 -2.0]; B = reshape([1.0, 1.0], 2, 1); C = [1.0 1.0];
julia> bt = baltrunc(A, B, C; n = 1);
julia> size(bt.A)
(1, 1)References
- Moore, B. C. (1981). Principal component analysis in linear systems. IEEE Transactions on Automatic Control.
- Antoulas, A. C. (2005). Approximation of Large-Scale Dynamical Systems. SIAM.
ModelOrderReduction.BalancedTruncation — Type
struct BalancedTruncation{T<:AbstractFloat}Reduced continuous-time LTI model produced by baltrunc.
The reduced dynamics are
\[\dot x_r = A_r x_r + B_r u,\qquad y = C_r x_r + D_r u,\]
with reconstruction $x \approx T_r x_r$ and reduction $x_r = S x$ for plain truncation. When residualization is used, $T_r$ is still the balanced truncation map for the retained states; the static contribution of the discarded states is folded into $(A_r, B_r, C_r, D_r)$ rather than into $T_r$.
Fields
A::Matrix{T} where T<:AbstractFloat: reduced state matrix $A_r$B::Matrix{T} where T<:AbstractFloat: reduced input matrix $B_r$C::Matrix{T} where T<:AbstractFloat: reduced output matrix $C_r$D::Matrix{T} where T<:AbstractFloat: feedthrough matrix $D_r$hsv::Vector{T} where T<:AbstractFloat: retained Hankel singular valuesTr::Matrix{T} where T<:AbstractFloat: right projector $T_r$ with $x \approx T_r x_r$ under plain truncationS::Matrix{T} where T<:AbstractFloat: left projector $S$ with $x_r = S x$
ModelOrderReduction.opinf — Function
opinf(X, Xdot; nmodes, basis = nothing, linear = true, quadratic = false,
inputs = nothing, constant = false, λ = 0) -> OperatorInferenceModelLearn a polynomial reduced model by Operator Inference.
Snapshot matrix X and derivative matrix Xdot store one snapshot per column (state dimension × number of snapshots). A POD basis with nmodes columns is computed from X unless basis is provided. The projected least-squares problem
\[\min_O \| D O^\top - \dot X_r^\top \|_F^2 + \lambda \|O\|_F^2\]
is solved for the selected operator blocks.
Arguments
X::AbstractMatrix: state snapshots as columns.Xdot::AbstractMatrix: time-derivative snapshots as columns, conforming toX.
Keywords
nmodes::Integer: number of POD modes. Required whenbasisis omitted.basis = nothing: optional orthonormal basis $V$. When provided,nmodesdefaults tosize(basis, 2).linear = true: infer a linear operator $A$.quadratic = false: infer a quadratic operator $H$ on unique monomials.inputs = nothing: optional input snapshots as an(input dimension × snapshots)matrix, or a length-snapshotsvector for a single input.constant = false: infer a constant forcing term $c$.λ = 0: Tikhonov regularization weight applied isotropically to all operator coefficients. When positive, the ridge problem is solved via an augmented QR factorization.
Returns
OperatorInferenceModel: inferred basis and operator blocks.
Throws
ArgumentError/DimensionMismatch: if sizes are inconsistent, the basis is not orthonormal, or no operator block is requested.
Examples
julia> using ModelOrderReduction, LinearAlgebra
julia> Atrue = [-1.0 0.0; 0.0 -2.0];
julia> X = reduce(hcat, [[exp(-t), exp(-2t)] for t in 0:0.05:3]);
julia> Xdot = Atrue * X;
julia> model = opinf(X, Xdot; basis = Matrix{Float64}(I, 2, 2));
julia> model.A ≈ Atrue
trueReferences
- Peherstorfer, B. & Willcox, K. (2016). Data-driven operator inference for nonintrusive projection-based model reduction. CMAME.
- Qian, E., Kramer, B., Peherstorfer, B. & Willcox, K. (2020). Lift & Learn.
opinf(
X::AbstractVector{<:AbstractVector},
Xdot::AbstractVector{<:AbstractVector};
kwargs...
)
Operator Inference from a vector-of-snapshots representation, matching the POD snapshot convention.
ModelOrderReduction.OperatorInferenceModel — Type
struct OperatorInferenceModel{T<:AbstractFloat}Reduced model learned by opinf.
With reduced coordinates $x_r = V^\top x$, the inferred dynamics are
\[\dot x_r = c + A x_r + B u + H\,\mathrm{quad}(x_r),\]
where $\mathrm{quad}$ stacks the unique quadratic monomials $x_i x_j$ for $1 \le i \le j \le r$ in row-major lower-triangular order $(x_1^2, x_1 x_2, \ldots, x_1 x_r, x_2^2, \ldots, x_r^2)$.
Fields
basis::Matrix{T} where T<:AbstractFloat: POD / trial basis $V$ with orthonormal columnsA::Union{Nothing, Matrix{T}} where T<:AbstractFloat: linear operator $A$, ornothingif not inferredH::Union{Nothing, Matrix{T}} where T<:AbstractFloat: quadratic operator $H$ withsize(H, 2) == r(r + 1) ÷ 2, ornothingB::Union{Nothing, Matrix{T}} where T<:AbstractFloat: input operator $B$, ornothingif not inferredc::Union{Nothing, Vector{T}} where T<:AbstractFloat: constant term $c$, ornothingif not inferred
ModelOrderReduction.reduced_dynamics — Function
reduced_dynamics(
model::OperatorInferenceModel{T},
xr::AbstractVector
) -> Any
reduced_dynamics(
model::OperatorInferenceModel{T},
xr::AbstractVector,
u::Union{Nothing, AbstractVector}
) -> Any
Evaluate the reduced right-hand side of model at reduced state xr with optional input u.
ModelOrderReduction.quadratic_monomials — Function
quadratic_monomials(
x::AbstractArray{T, 1}
) -> AbstractVector
Allocate and return the unique quadratic monomials of x.