ltv_disc¶
MATLAB equivalent:
sidLTVdisc
ltv_disc ¶
Discrete-time LTV state-space identification via the COSMIC algorithm.
ltv_disc ¶
ltv_disc(X: ndarray | list, U: ndarray | list, *, lambda_: float | ndarray | str = 'auto', lambda_grid: ndarray | None = None, precondition: bool = False, algorithm: str = 'cosmic', uncertainty: bool = False, noise_cov: ndarray | str = 'estimate', covariance_mode: str = 'diagonal') -> LTVResult
Identify a discrete-time LTV state-space model from trajectory data.
Estimates time-varying system matrices A(k) and B(k) for the model
.. math::
x(k+1) = A(k)\,x(k) + B(k)\,u(k), \quad k = 0, \ldots, N-1
using the COSMIC algorithm (Carvalho et al., 2022), which solves a regularized least-squares problem balancing data fidelity against temporal smoothness of the system matrices. The closed-form block-tridiagonal solver has O(N (p+q)^3) complexity.
This is an open-source replacement for proprietary LTV identification routines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray or list of ndarray
|
State trajectory data. Accepted formats:
|
required |
U
|
ndarray or list of ndarray
|
Input trajectory data, matching format of X:
|
required |
lambda_
|
float, ndarray, or ``'auto'``
|
Regularization strength. Options:
Must be positive (scalar or all elements). |
'auto'
|
lambda_grid
|
ndarray or None
|
Candidate lambda values for L-curve auto-selection. Only used
when |
None
|
precondition
|
bool
|
Apply block-diagonal preconditioning. Currently disabled in
v1.0. Default is |
False
|
algorithm
|
str
|
Identification algorithm. Only |
'cosmic'
|
uncertainty
|
bool
|
Compute Bayesian posterior uncertainty for A(k), B(k). Doubles
computation cost. Default is |
False
|
noise_cov
|
ndarray or ``'estimate'``
|
Measurement noise covariance. Options:
|
'estimate'
|
covariance_mode
|
str
|
How to estimate noise covariance when noise_cov is
|
'diagonal'
|
Returns:
| Type | Description |
|---|---|
LTVResult
|
Frozen dataclass with fields:
|
Raises:
| Type | Description |
|---|---|
SidError
|
If data contains NaN/Inf (code: |
SidError
|
If data dimensions are inconsistent (code: |
SidError
|
If trajectories are too short, N < 2 (code: |
SidError
|
If lambda is invalid (code: |
SidError
|
If algorithm is unsupported (code: |
SidError
|
If noise_cov is invalid (code: |
SidError
|
If covariance_mode is invalid (code: |
Examples:
Basic identification with automatic lambda:
>>> import numpy as np
>>> import sid
>>> N = 100; p = 2; q = 1
>>> rng = np.random.default_rng(0)
>>> X = rng.standard_normal((N + 1, p))
>>> U = rng.standard_normal((N, q))
>>> result = sid.ltv_disc(X, U)
>>> result.a.shape
(2, 2, 100)
Manual uniform lambda:
With uncertainty estimation:
Variable-length trajectories:
>>> X_list = [rng.standard_normal((51, 2)), rng.standard_normal((31, 2))]
>>> U_list = [rng.standard_normal((50, 1)), rng.standard_normal((30, 1))]
>>> result = sid.ltv_disc(X_list, U_list, lambda_=1e3)
Notes
Algorithm:
- Validate and orient input data; detect variable-length mode.
- Build per-step data matrices D(k), X_lead(k) from trajectories (SPEC.md S8.3.2).
- If
lambda_='auto', run L-curve selection over a grid of candidate values. - Build block-tridiagonal terms S(k), Theta(k) (SPEC.md S8.3.3).
- COSMIC forward-backward pass: forward pass computes Lbd(k) and Y(k), backward pass recovers C(k) = [A(k)'; B(k)'] (SPEC.md S8.3.4).
- Extract A(k), B(k) from C(k).
- Evaluate total cost = fidelity + regularization.
- If uncertainty requested: backward recursion on P(k), noise covariance estimation, and standard deviation extraction (SPEC.md S8.9).
Specification: SPEC.md S8 -- Discrete-Time LTV State-Space Identification
References
.. [1] Carvalho, Soares, Lourenco, Ventura. "COSMIC: fast closed-form identification from large-scale data for LTV systems." arXiv:2112.04355, 2022.
See Also
sid.ltv_disc_tune : Tune lambda via cross-validation. sid.ltv_disc_frozen : Identify with frozen (constant) segments. sid.freq_map : Time-varying frequency response estimation.
Changelog
2026-04-08 : First version (Python port) by Pedro Lourenco.