private void hessenbergReduction(final RealMatrix matrixToReduce) { final int n = matrixToReduce.getHeight(); final double[][] V = matrixToReduce.blank().toDoubleArray(); final double[][] H = matrixToReduce.toDoubleArray(); final double[] ort = new double[matrixToReduce.getHeight()]; // This is derived from the Algol procedures hessenbergReduction and ortran, // by Martin and Wilkinson, Handbook for Auto. Comp., // Vol.ii-Linear Algebra, and the corresponding // Fortran subroutines in EISPACK. final int high = n - 1; for (int m = 1; m <= high - 1; m++) { // Scale column. double scale = 0.0; for (int i = m; i <= high; i++) scale = scale + Math.abs(H[i][m - 1]); if (scale != 0.0) { // Compute Householder transformation. double h = 0.0; for (int i = high; i >= m; i--) { ort[i] = H[i][m - 1] / scale; h += ort[i] * ort[i]; } double g = Math.sqrt(h); if (ort[m] > 0) g = -g; h = h - ort[m] * g; ort[m] = ort[m] - g; // Apply Householder similarity transformation // hessenbergMatrixElements = (I-u*u'/h)*hessenbergMatrixElements*(I-u*u')/h) for (int j = m; j < n; j++) { double f = 0.0; for (int i = high; i >= m; i--) f += ort[i] * H[i][j]; f = f / h; for (int i = m; i <= high; i++) H[i][j] -= f * ort[i]; } for (int i = 0; i <= high; i++) { double f = 0.0; for (int j = high; j >= m; j--) f += ort[j] * H[i][j]; f = f / h; for (int j = m; j <= high; j++) H[i][j] -= f * ort[j]; } ort[m] = scale * ort[m]; H[m][m - 1] = scale * g; } } // Accumulate transformations (Algol's ortran). for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) V[i][j] = (i == j ? 1.0 : 0.0); for (int m = high - 1; m >= 1; m--) if (H[m][m - 1] != 0.0) { for (int i = m + 1; i <= high; i++) ort[i] = H[i][m - 1]; for (int j = m; j <= high; j++) { double g = 0.0; for (int i = m; i <= high; i++) g += ort[i] * V[i][j]; // Double division avoids possible underflow g = (g / ort[m]) / H[m][m - 1]; for (int i = m; i <= high; i++) V[i][j] += g * ort[i]; } } this.matrix = new SimpleRealMatrix(V); this.hessenbergMatrix = new SimpleRealMatrix(H); }
/** * Check for symmetry, then construct the eigenvalue decomposition. Gives access to D and * matrixElements. * * @param matrixToDecompose Elements Square matrix */ public NonsymetricHessenbergReduction(final RealMatrix matrixToDecompose) { final int n = matrixToDecompose.getWidth(); // Reduce to Hessenberg form. hessenbergReduction(matrixToDecompose.getSubmatrix(0, n, 0, n)); }