This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

Notebooks · lib/are

The algebraic Riccati equation, by the Schur method

The continuous-time algebraic Riccati equation

A^T P + P A - P B R^-1 B^T P + W = 0

is quadratic in P, and the thing you want is not just any solution but the one that stabilizes: the symmetric P for which A - B R^-1 B^T P has every eigenvalue in the left half plane. This module computes it the way SLICOT's SB02MD does, which is Laub's method of 1979.

The idea is that the quadratic equation is a linear one in disguise. Build the 2n by 2n Hamiltonian

H = [[A, -B R^-1 B^T], [-W, -A^T]]

and the stabilizing P is read off its stable invariant subspace. If the columns of [X1; X2] are a basis for the eigenvectors of H belonging to the eigenvalues with negative real part, then P = X2 X1^-1. A Hamiltonian's spectrum is symmetric about the imaginary axis, so exactly n of its 2n eigenvalues are stable, and the subspace has exactly the right dimension.

Nothing here forms an eigenvector. lib/schur reduces H to real Schur form, reorders the stable blocks to the top left, and the first n columns of the orthogonal factor are an orthonormal basis for that subspace — better conditioned than eigenvectors, and available whether or not H is diagonalizable.

are_sign solves the same equation by a completely different route, Roberts's matrix sign function, and the two are checked against each other. Two unrelated algorithms landing on the same matrix is a much stronger argument than either one looking right on its own.

They do not land on it equally well, and the test below measures the gap. Over the systems it tries, the Schur method's relative residual stays under 4 × 10−15 while the sign function's reaches 7 × 10−13, and where the two answers differ it is the sign function that has moved. Its last step solves an overdetermined system through its normal equations, which squares the condition number; that is the price of not computing a Schur form, and it is why SB02MD is the Schur one.

Used with import are.

Look inside this program

  • Atlas

    The program’s map: every function and which calls which.

  • There’s no recorded run of this program yet.

Shift+Enter in a cell runs it and moves to the next. Running a cell runs every cell above it too, as one program.

[1]lines 46–488