/** * Only eigenvalues of a symmetric real matrix are computed. * * @param A a symmetric real matrix * @return a 1D {@code double} array containing the eigenvalues in decreasing order (absolute * value) */ public static double[] computeEigenvalues(Matrix A) { SparseMatrix S = (SparseMatrix) decompose(A, false)[1]; int m = S.getRowDimension(); int n = S.getColumnDimension(); int len = m >= n ? n : m; double[] s = ArrayOperator.allocateVector(len, 0); for (int i = 0; i < len; i++) { s[i] = S.getEntry(i, i); } return s; }
/** * Build the diagonal matrix containing all eigenvalues. * * @param s eigenvalues * @param m number of rows * @param n number of columns * @return a diagonal matrix containing all eigenvalues */ private static Matrix buildD(double[] s, int m, int n) { TreeMap<Pair<Integer, Integer>, Double> map = new TreeMap<Pair<Integer, Integer>, Double>(); for (int i = 0; i < m; i++) { if (i < n) map.put(Pair.of(i, i), s[i]); } return SparseMatrix.createSparseMatrix(map, m, n); }
/** * Unpack Q and T from the result of tridiagonalization. * * @param A tridiagonalization result * @param a diagonal * @param b superdiagonal * @param computeV if V is to be computed * @return a {@code Matrix} array [Q, T] */ private static Matrix[] unpack(Matrix A, double[] a, double[] b, boolean computeV) { Matrix[] QT = new Matrix[3]; int m = A.getRowDimension(); int n = A.getColumnDimension(); DenseMatrix Q = null; if (computeV) { Q = new DenseMatrix(m, m, 0); double[][] QData = Q.getData(); double s = 0; double[] y = null; for (int i = 0; i < m; i++) { // Compute U^T * e_i y = QData[i]; y[i] = 1; for (int j = 0; j < n - 2; j++) { s = 0; for (int k = j + 1; k < m; k++) { s += A.getEntry(k, j) * y[k]; } for (int k = j + 1; k < m; k++) { y[k] -= A.getEntry(k, j) * s; } } } /*fprintf("Q:\n"); disp(Q);*/ } TreeMap<Pair<Integer, Integer>, Double> map = new TreeMap<Pair<Integer, Integer>, Double>(); for (int i = 0; i < m; i++) { if (i < n) map.put(Pair.of(i, i), a[i]); if (i < n - 1) { map.put(Pair.of(i, i + 1), b[i]); map.put(Pair.of(i + 1, i), b[i]); } } Matrix T = SparseMatrix.createSparseMatrix(map, m, n); /*fprintf("T:\n"); printMatrix(T); T = new SparseMatrix(m, n); for (int i = 0; i < m; i++) { if (i < n) T.setEntry(i, i, a[i]); if (i < n - 1) { T.setEntry(i, i + 1, b[i]); T.setEntry(i + 1, i, b[i]); } }*/ if (computeV) { /*fprintf("T:\n"); printMatrix(T);*/ /*fprintf("A:\n"); printMatrix(A); fprintf("Q'Q:\n"); disp(Q.transpose().mtimes(Q));*/ /*fprintf("QTQ':\n"); disp(Q.mtimes(T).mtimes(Q.transpose()));*/ } QT[0] = Q; QT[1] = T; return QT; }