Solve

All algorithms have been combined under a single API to match the interface of other SciML packages. Thus, you can simply define a Problem, and then seamlessly switch between solvers.

All of the above methods return a DataDrivenSolution if not enforced otherwise.

Common Options

Many of the algorithms implemented directly in DataDrivenDiffEq share common options. These can be passed into the solve call via keyword arguments and get collected into the CommonOptions struct, which is given below.

DataDrivenDiffEq.DataDrivenCommonOptionsType
struct DataDrivenCommonOptions{T, K}

Common options for all methods provided via DataDrivenDiffEq.

Fields

  • maxiters: Maximum iterations Default: 100

  • abstol: Absolute tolerance Default: sqrt(eps())

  • reltol: Relative tolerance Default: sqrt(eps())

  • progress: Show a progress meter Default: false

  • verbose: Display log - Not implemented right now Default: false

  • denoise: Denoise the data using the optimal threshold method. Default: false

  • normalize: Normalize the data, see DataNormalization Default: DataNormalization()

  • data_processing: Data processing pipeline, see DataProcessing Default: DataProcessing()

  • roundingmode: Rounding mode for the parameters Default: RoundToZero

  • digits: Digits for the parameters - used for rounding. Default: 10

  • selector: Model selection criteria - used for model selection within each algorithm Default: bic

  • generate_symbolic_parameters: Enables the use of symbolic parameters for the result. If false, the numerical value is used. Default: true

  • eval_expresssion: Evaluate the expression, see Symbolics.build_function Default: false

  • kwargs: Additional kwargs Default: (;)

Note

The keyword argument eval_expression controls the function creation behavior. eval_expression=true means that eval is used, so normal world-age behavior applies (i.e. the functions cannot be called from the function that generates them). If eval_expression=false, then construction via GeneralizedGenerated.jl is utilized to allow for same world-age evaluation. However, this can cause Julia to segfault on sufficiently large basis functions. By default eval_expression=false.

Denoising happens before normalization!

source
Info

The keyword argument eval_expression controls the function creation behavior. eval_expression=true means that eval is used, so normal world-age behavior applies (i.e. the functions cannot be called from the function that generates them). If eval_expression=false, then construction via GeneralizedGenerated.jl is utilized to allow for same world-age evaluation. However, this can cause Julia to segfault on sufficiently large basis functions. By default eval_expression=false.

Solving the Problem

After defining a problem, we choose a method to solve it. Depending on the input arguments and the type of problem, the function will return a result derived from the algorithm of choice. Different options can be provided, depending on the inference method, for options like rounding, normalization, or the progress bar. An optional Basis can be used for lifting the measurements.

solution = solve(DataDrivenProblem, [basis], solver; kwargs...)

If no Basis is supported, a unit basis is derived from the problem data containing the states and controls of the system.

Or more concrete examples:

# Use a Koopman based inference without a basis
res = solve(problem, DMDSVD(); options = DataDrivenCommonOptions(), kwargs...)
# Use a sparse identification
res = solve(problem, basis, STLSQ(); options = DataDrivenCommonOptions(), kwargs...)

As we can see above, the use of a Basis is optional to invoke the estimation process. Internally, a linear Basis will be generated based on the DataDrivenProblem containing the states and control inputs.

The DataDrivenSolutionres contains a result which is the inferred system and a Basis.

Model Selection

Most estimation and model inference algorithms require hyperparameters, e.g., the sparsity controlling penalty, train-test splits. To account for this, the keyword selector can be passed to the DataDrivenCommonOptions. This allows the user to control the selection criteria and returns the minimum selector.

Common choices for selector are rss, bic, aic, aicc, and r2. Given that each subresult of the algorithm extends the StatsBase API, we can also use different schemes like:

options = DataDrivenCommonOptions(selector = (x) -> rss(x) / nobs(x))

Which results in the mean squared error of the system.