package util.linalg;
/**
* An implementation of the hessenberg decomposition
* which decomposes a square matrix A into
* U * H * Ut where H is a upper hessenberg matrix
* and U is a orthonormal matrix. Upper hessenberg
* matrices are upper triangular matrices with
* nonzero values in the band directly below
* the diagonal. The implementation uses householder
* matrices to zero elements.
* @author Andrew Guillory gtg008g@mail.gatech.edu
* @version 1.0
*/
public class HessenbergDecomposition {
/**
* The orthonormal matrix
*/
private RectangularMatrix u;
/**
* The upper hessenberg matrix
*/
private RectangularMatrix h;
/**
* Make a new hessenberg decomposition of
* the given matrix.
* @param a the matrix to decompose
*/
public HessenbergDecomposition(Matrix a) {
h = new RectangularMatrix(a);
u = RectangularMatrix.eye(a.m());
decompose();
}
/**
* Perform the decomposition in place on
* h by zeroing out
* the sub sub diagonal elements in the first
* n - 2 columns of the matrix.
*/
private void decompose() {
// the first n - 2 columns
for (int i = 0; i < h.n() - 2; i++) {
// extract the column
Vector c = h.getColumn(i);
// the vector we want to reflect
// the k+1:n elements of the column
// into (r, 0, 0, ...) for some r
Vector v = c.get(i+1, c.size());
HouseholderReflection hr = new HouseholderReflection(v);
// apply to the h matrix from the left and from the right
hr.applyLeft(h, i+1, h.m(), i, h.n());
hr.applyRight(h, 0, h.m(), i+1, h.n());
// accumulate the u from the right
hr.applyRight(u, 0, u.m(), i+1, u.n());
}
}
/**
* Get the upper hessenberg matrix h
* @return the matrix h
*/
public RectangularMatrix getH() {
return h;
}
/**
* Get the orthonormal matrix u
* @return the matrix u
*/
public RectangularMatrix getU() {
return u;
}
}