The Schur Decomposition

The Schur decomposition of a square matrix writes the matrix as a product of matrices:

A = ZTZH,

where T is an upper triangular matrix called the Schur form, and Z is an orthogonal (unitary) matrix, the matrix of Schur vectors. The diagonal of T contains the eigenvalues of the original matrix.

For non-symmetric (non-Hermitian) matrices, the Schur decomposition is often preferred in favour of the full eigenvalue decomposition because the transformation matrices are orthogonal (unitary), and therefore generally better conditioned.

Real matrices may have complex eigenvalues. In this case, the matrix T is quasi-triangular, with 2x2 blocks on the diagonal corresponding to complex conjugate pairs of eigenvalues.

Working with Schur Decompositions

Schur decompositions of both real and complex matrices are represented by the SchurDecomposition<T> class. It has no constructors. Instead, it is created by calling the GetSchurDecomposition method on the matrix. This method has two overloads. The first overload has no arguments: The second overload takes a Boolean argument that specifies whether the contents of the matrix may be destroyed during the calculation of the eigenvalue decomposition.

C#
var A = Matrix.Create(new double[,]
  { { 2, 5, 8, 7 },
    { 5, 2, 2, 8 },
    { 7, 5, 6, 6 },
    { 5, 4, 4, 1 } });
var schur = A.GetSchurDecomposition();

The Decompose method performs the actual decomposition. This method makes a copy of the matrix if necessary. It then calls the appropriate LAPACK routine to perform the actual decomposition. This method is called by other methods as needed. You will rarely need to call it explicitly.

Once the decomposition is computed, a number of operations can be performed. However, unlike other decompositions, eigenvalue decompositions generally don't give an advantage when solving equations or computing the inverse. For these methods, the SchurDecomposition<T> class simply defers to corresponding method of the base matrix.

C#
var b = Matrix.CreateFromArray(4, 2, new double[] {
    8.70, -13.35, 1.89, -4.14,
    8.30, 2.13, 1.61, 5.00 }, MatrixElementOrder.ColumnMajor);
var x = schur.Solve(b);
var invA = schur.GetInverse();
var detA = schur.GetDeterminant();

Schur Decomposition Properties

Because real matrices may have complex eigenvalues, the Schur decomposition of a real matrix deserves some special attention.

Real matrices

The SchurForm property returns the SchurForm the upper triangular matrix T in the decomposition. The SchurVectors property returns the matrix of Schur vectors, the orthogonal matrix Z in the decomposition. The Eigenvalues property returns a vector containing the eigenvalues.

C#
var T = schur.SchurForm;
var Z = schur.SchurVectors;

A non-symmetric real matrix may have complex eigenvalues, which occur in complex conjugate pairs. In this case, the Eigenvalues returns only the real eigenvalues and the Schur form is quasi-triangular. To get all eigenvalues, use the ComplexEigenvalues property.

Complex matrices

The eigenvalues of a complex matrix are also complex. The Eigenvalues property returns a vector that always contains all the eigenvalues. The eigenvalues of a Hermitian matrix are real. This simply means that the imaginary component of the eigenvalue vector is identically zero.

The Schur form (the upper triangular matrix T in the decomposition) of a complex matrix is always upper triangular. The SchurForm property returns the Schur form. The SchurVectors property returns the matrix of Schur vectors, the unitary matrix Z in the decomposition.