/** * Compute the eigenvalue of square matrix. * * @param matrix Input matrix A. * @return A pair of column vectors A and B s.t. each row of A + Bi is a eigenvalue of the * underlying matrix * @throws UnsupportedOperationException if unable to compute */ public Pair compute(Matrix matrix) { Throw.when() .isNull(() -> matrix, () -> "No input matrix.") .isFalse( () -> matrix.getRowCount() == matrix.getColCount(), () -> "Input matrix is not square."); switch (matrix.getRowCount()) { case 0: return Pair.EMPTY; case 1: return Pair.of(Matrices.scalar(matrix.get(0, 0)), Matrices.zeros(1)); case 2: return DoubleShift.of(matrix, 0).eig(); default: break; } return this.findEig(this.qrImpl.compute(new DefaultMatrix(matrix), null, false)); }
/** * Find eigen-values of a square matrix in Schur form. * * @param schur Input matrix in Schur form * @return A pair of column vectors A and B s.t. each row of A + Bi is a eigenvalue of the * underlying matrix */ protected Pair findEig(Matrix schur) { int n = schur.getRowCount() - 1; int k = 0; double[] re = new double[schur.getRowCount()]; double[] im = new double[schur.getRowCount()]; while (k < n) { if (Math.abs(schur.get(k + 1, k)) < QRStep.EPSILON) { re[k] = schur.get(k, k); k++; } else { Pair eig = DoubleShift.of(schur, k).eig(); re[k] = eig.getLeft().get(0, 0); re[k + 1] = eig.getLeft().get(1, 0); im[k] = eig.getRight().get(0, 0); im[k + 1] = eig.getRight().get(1, 0); k += 2; } } if (k < schur.getRowCount()) { re[k] = schur.get(k, k); } return Pair.of(new ColumnVector(re), new ColumnVector(im)); }