Skip to contents

Shifts a square matrix left on the real axis so that its spectral abscissa (maximum real part of the eigenvalues) is strictly less than -margin. This is useful for ensuring that continuous-time drift matrices (e.g. in linear SDEs/state-space models) are Hurwitz-stable. If the matrix already satisfies the margin, it is returned unchanged.

Usage

ProjectToHurwitz(x, margin = 0.001)

Arguments

x

Numeric square matrix.

margin

Positive numeric. Target buffer inside the Hurwitz region; the result satisfies \(\max \Re\{\lambda_i(x^\star)\} \le -\text{margin}\) (default 1e-3).

Value

A numeric matrix of the same dimensions as x, shifted if necessary to satisfy the Hurwitz stability constraint.

Details

The projection is performed by subtracting a multiple of the identity: $$x^\star = x - (\alpha + \text{margin}) I,$$ where \(\alpha = \max \Re\{\lambda_i(x)\}\) is the spectral abscissa.

Author

Ivan Jacob Agaloos Pesigan

Examples

# Unstable (spectral abscissa >= 0):
x <- matrix(
  data = c(
    0.10, -0.40,
    0.50, 0.20
  ),
  nrow = 2
)
SpectralAbscissa(x = x) # >= 0
#> [1] 0.15
SpectralAbscissa(x = ProjectToHurwitz(x = x)) # <= -1e-3 (default margin)
#> [1] -0.001

# Already Hurwitz-stable is returned unchanged up to numerics:
x <- matrix(
  data = c(
    -0.50, -0.20,
     1.00, -0.30
  ),
  nrow = 2
)
SpectralAbscissa(x = x) # < 0
#> [1] -0.4
identical(ProjectToHurwitz(x = x), x)
#> [1] TRUE