Skip to content

ltv_disc_tune

MATLAB equivalent: sidLTVdiscTune

ltv_disc_tune

Lambda tuning for LTV state-space identification (validation or frequency-based).

ltv_disc_tune

ltv_disc_tune(*args, method: str = 'validation', lambda_grid: ndarray | None = None, precondition: bool = False, algorithm: str = 'cosmic', segment_length: int | None = None, consistency_threshold: float = 0.9, coherence_threshold: float = 0.3) -> tuple

Tune the regularization parameter lambda for :func:sid.ltv_disc.

Two tuning strategies are available:

  • Validation (default) -- grid search over lambda evaluated by trajectory prediction RMSE on held-out state data.
  • Frequency -- compare the COSMIC frozen transfer function against a non-parametric :func:sid.freq_map estimate using a Mahalanobis-like consistency score. Selects the largest lambda whose posterior bands are consistent with the non-parametric bands.

Parameters:

Name Type Description Default
*args

Positional data arguments. Interpretation depends on method:

Validation method (4 positional args):

  • X_train -- Training state data, shape (N+1, p, L_train).
  • U_train -- Training input data, shape (N, q, L_train).
  • X_val -- Validation state data, shape (N+1, p, L_val).
  • U_val -- Validation input data, shape (N, q, L_val).

Frequency method (2 positional args):

  • X -- State data, shape (N+1, p, L) or list of arrays.
  • U -- Input data, shape (N, q, L) or list of arrays.
()
method str

'validation' (default) or 'frequency'.

'validation'
lambda_grid ndarray or None

Vector of candidate lambda values. Defaults:

  • Validation: logspace(-3, 15, 50)
  • Frequency: logspace(0, 10, 25)
None
precondition bool

Passed through to :func:sid.ltv_disc. Default is False.

False
algorithm str

Passed through to :func:sid.ltv_disc. Default is 'cosmic'.

'cosmic'
segment_length int or None

(Frequency only) Outer segment length for :func:sid.freq_map. Default: min(N // 4, 256).

None
consistency_threshold float

(Frequency only) Fraction of (omega, t) grid points required to be consistent. Default is 0.90.

0.9
coherence_threshold float

(Frequency only) Minimum coherence for a grid point to be included in the consistency test. Default is 0.3.

0.3

Returns:

Type Description
tuple

Return type depends on method:

Validation method -- (best_result, best_lambda, all_losses)

  • best_result (:class:~sid._results.LTVResult) -- Result at optimal lambda.
  • best_lambda (float) -- Optimal scalar lambda.
  • all_losses (ndarray, shape (n_grid,)) -- Trajectory RMSE at each grid lambda.

Frequency method -- (best_result, best_lambda, info_dict)

  • best_result (:class:~sid._results.LTVResult) -- Result at optimal lambda (with uncertainty).
  • best_lambda (float) -- Optimal scalar lambda.
  • info_dict (dict) -- Dictionary with keys:

  • 'lambda_grid' -- sorted lambda grid, shape (n_grid,).

  • 'fractions' -- consistency fraction per lambda, shape (n_grid,).
  • 'best_fraction' -- consistency fraction at selected lambda.
  • 'freq_map_results' -- list of :class:~sid._results.FreqMapResult, one per state channel.
  • 'chi2_threshold' -- chi-square threshold used (5.991).

Raises:

Type Description
SidError

If method is not 'validation' or 'frequency' (code: 'bad_method').

SidError

If the number of positional arguments is wrong for the chosen method (code: 'bad_args').

Examples:

Validation-based tuning:

>>> import numpy as np
>>> import sid
>>> best, lam, losses = sid.ltv_disc_tune(
...     X_train, U_train, X_val, U_val)

Frequency-based tuning (no validation data needed):

>>> best, lam, info = sid.ltv_disc_tune(
...     X, U, method='frequency')

Custom lambda grid:

>>> grid = np.logspace(-1, 12, 30)
>>> best, lam, losses = sid.ltv_disc_tune(
...     X_train, U_train, X_val, U_val, lambda_grid=grid)
Notes

Validation method algorithm:

  1. For each lambda in the grid, run :func:sid.ltv_disc on training data and compute the trajectory prediction RMSE on validation data.
  2. Select the lambda with minimum RMSE.
  3. Re-run :func:sid.ltv_disc at the optimal lambda.

Frequency method algorithm (SPEC.md S8.11):

  1. Run :func:sid.freq_map per state component (SISO) to obtain non-parametric frequency response estimates with uncertainty.
  2. For each lambda, run :func:sid.ltv_disc with uncertainty and compute the frozen transfer function via :func:sid.ltv_disc_frozen.
  3. Compute a Mahalanobis-like distance at each (omega, t) grid point: d^2 = |G_frozen - G_data|^2 / (std_frozen^2 + std_data^2).
  4. Count the fraction of grid points (above the coherence threshold) where d^2 < chi2_threshold (5.991 for 95% confidence, 2 DOF).
  5. Select the largest lambda achieving >= consistency_threshold fraction. Falls back to the lambda with the best fraction if none meet the threshold.

Specification: SPEC.md S8.4, S8.11

References

.. [1] Carvalho, Soares, Lourenco, Ventura. "COSMIC: fast closed-form identification from large-scale data for LTV systems." arXiv:2112.04355, 2022. .. [2] Ljung, L. "System Identification", 2nd ed., Prentice Hall, 1999.

See Also

sid.ltv_disc : LTV state-space identification. sid.ltv_disc_frozen : Frozen transfer function from LTV model. sid.freq_map : Time-varying frequency response estimation.

Changelog

2026-04-08 : First version (Python port) by Pedro Lourenco.