/** Return the Householder vectors @return Lower trapezoidal matrix whose columns define the reflections */ public CoreMatrix getH() { CoreMatrix X = new CoreMatrix(m, n); double[,] H = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i >= j) { H[i, j] = QR[i, j]; } else { H[i, j] = 0.0; } } } return X; }
/* ------------------------ Constructor * ------------------------ */ /** Check for symmetry, then construct the eigenvalue decomposition @param A Square matrix @return Structure to access D and V. */ public EigenvalueDecomposition(CoreMatrix Arg) { double[,] A = Arg.getArray(); n = Arg.getColumnDimension(); V = new double[n, n]; d = new double[n]; e = new double[n]; issymmetric = true; for (int j = 0; (j < n) & issymmetric; j++) { for (int i = 0; (i < n) & issymmetric; i++) { issymmetric = (A[i, j] == A[j, i]); } } if (issymmetric) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { V[i, j] = A[i, j]; } } // Tridiagonalize. tred2(); // Diagonalize. tql2(); } else { H = new double[n, n]; ort = new double[n]; for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { H[i, j] = A[i, j]; } } // Reduce to Hessenberg form. orthes(); // Reduce Hessenberg to real Schur form. hqr2(); } }
/** Return the block diagonal eigenvalue matrix @return D */ public CoreMatrix getD() { CoreMatrix X = new CoreMatrix(n, n); double[,] D = X.getArray(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { D[i, j] = 0.0; } D[i, i] = d[i]; if (e[i] > 0) { D[i, i + 1] = e[i]; } else if (e[i] < 0) { D[i, i - 1] = e[i]; } } return X; }
/** Return lower triangular factor @return L */ public CoreMatrix getL() { CoreMatrix X = new CoreMatrix(m, n); double[,] L = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i > j) { L[i, j] = LU[i, j]; } else if (i == j) { L[i, j] = 1.0; } else { L[i, j] = 0.0; } } } return X; }
/** Return upper triangular factor @return U */ public CoreMatrix getU() { CoreMatrix X = new CoreMatrix(n, n); double[,] U = X.getArray(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i <= j) { U[i, j] = LU[i, j]; } else { U[i, j] = 0.0; } } } return X; }
/** Get a subCoreMatrix. @param i0 Initial row index @param i1 Final row index @param j0 Initial column index @param j1 Final column index @return A(i0:i1,j0:j1) @exception Exception SubCoreMatrix indices */ public CoreMatrix getMatrix(int i0, int i1, int j0, int j1) { CoreMatrix X = new CoreMatrix(i1 - i0 + 1, j1 - j0 + 1); double[,] B = X.getArray(); try { for (int i = i0; i <= i1; i++) { for (int j = j0; j <= j1; j++) { B[i - i0, j - j0] = A[i, j]; } } } catch (Exception) { throw new Exception("SubCoreMatrix indices"); } return X; }
/** Generate identity CoreMatrix @param m Number of rows. @param n Number of colums. @return An m-by-n CoreMatrix with ones on the diagonal and zeros elsewhere. */ public static CoreMatrix identity(int m, int n) { CoreMatrix A = new CoreMatrix(m, n); double[,] X = A.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { X[i, j] = (i == j ? 1.0 : 0.0); } } return A; }
/** Element-by-element left division, C = A.\B @param B another CoreMatrix @return A.\B */ public CoreMatrix arrayLeftDivide(CoreMatrix B) { checkCoreMatrixDimensions(B); CoreMatrix X = new CoreMatrix(m, n); double[,] C = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { C[i, j] = B.A[i, j] / A[i, j]; } } return X; }
/** Multiply a CoreMatrix by a scalar, C = s*A @param s scalar @return s*A */ public CoreMatrix times(double s) { CoreMatrix X = new CoreMatrix(m, n); double[,] C = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { C[i, j] = s * A[i, j]; } } return X; }
/** CoreMatrix transpose. @return A' */ public CoreMatrix transpose() { CoreMatrix X = new CoreMatrix(n, m); double[,] C = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { C[j, i] = A[i, j]; } } return X; }
/** Unary minus @return -A */ public CoreMatrix uminus() { CoreMatrix X = new CoreMatrix(m, n); double[,] C = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { C[i, j] = -A[i, j]; } } return X; }
/** Get a subCoreMatrix. @param r Array of row indices. @param i0 Initial column index @param i1 Final column index @return A(r(:),j0:j1) @exception Exception SubCoreMatrix indices */ public CoreMatrix getMatrix(int[] r, int j0, int j1) { CoreMatrix X = new CoreMatrix(r.Length, j1 - j0 + 1); double[,] B = X.getArray(); try { for (int i = 0; i < r.Length; i++) { for (int j = j0; j <= j1; j++) { B[i, j - j0] = A[r[i], j]; } } } catch (Exception) { throw new Exception("SubCoreMatrix indices"); } return X; }
/** Get a subCoreMatrix. @param i0 Initial row index @param i1 Final row index @param c Array of column indices. @return A(i0:i1,c(:)) @exception Exception SubCoreMatrix indices */ public CoreMatrix getMatrix(int i0, int i1, int[] c) { CoreMatrix X = new CoreMatrix(i1 - i0 + 1, c.Length); double[,] B = X.getArray(); try { for (int i = i0; i <= i1; i++) { for (int j = 0; j < c.Length; j++) { B[i - i0, j] = A[i, c[j]]; } } } catch (Exception) { throw new Exception("SubCoreMatrix indices"); } return X; }
/** Get a subCoreMatrix. @param r Array of row indices. @param c Array of column indices. @return A(r(:),c(:)) @exception Exception SubCoreMatrix indices */ public CoreMatrix getMatrix(int[] r, int[] c) { CoreMatrix X = new CoreMatrix(r.Length, c.Length); double[,] B = X.getArray(); try { for (int i = 0; i < r.Length; i++) { for (int j = 0; j < c.Length; j++) { B[i, j] = A[r[i], c[j]]; } } } catch (Exception) { throw new Exception("SubCoreMatrix indices"); } return X; }
/** Return the upper triangular factor @return R */ public CoreMatrix getR() { CoreMatrix X = new CoreMatrix(n, n); double[,] R = X.getArray(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i < j) { R[i, j] = QR[i, j]; } else if (i == j) { R[i, j] = Rdiag[i]; } else { R[i, j] = 0.0; } } } return X; }
/** Linear algebraic CoreMatrix multiplication, A * B @param B another CoreMatrix @return CoreMatrix product, A * B @exception IllegalArgumentException CoreMatrix inner dimensions must agree. */ public CoreMatrix times(CoreMatrix B) { if (B.m != n) { throw new Exception("CoreMatrix inner dimensions must agree."); } CoreMatrix X = new CoreMatrix(m, B.n); double[,] C = X.getArray(); double[] Bcolj = new double[n]; for (int j = 0; j < B.n; j++) { for (int k = 0; k < n; k++) { Bcolj[k] = B.A[k, j]; } for (int i = 0; i < m; i++) { double[] Arowi = new double[n]; for (int z = 0; z < n; z++) Arowi[z] = A[i, z]; double s = 0; for (int k = 0; k < n; k++) { s += Arowi[k] * Bcolj[k]; } C[i, j] = s; } } return X; }
/** Generate and return the (economy-sized) orthogonal factor @return Q */ public CoreMatrix getQ() { CoreMatrix X = new CoreMatrix(m, n); double[,] Q = X.getArray(); for (int k = n - 1; k >= 0; k--) { for (int i = 0; i < m; i++) { Q[i, k] = 0.0; } Q[k, k] = 1.0; for (int j = k; j < n; j++) { if (QR[k, k] != 0) { double s = 0.0; for (int i = k; i < m; i++) { s += QR[i, k] * Q[i, j]; } s = -s / QR[k, k]; for (int i = k; i < m; i++) { Q[i, j] += s * QR[i, k]; } } } } return X; }
/* ------------------------ Public Methods * ------------------------ */ /** Construct a CoreMatrix from a copy of a 2-D array. @param A Two-dimensional array of doubles. @exception IllegalArgumentException All rows must have the same length */ public static CoreMatrix constructWithCopy(double[,] A) { int m = A.GetLength(0); int n = A.GetLength(1); CoreMatrix X = new CoreMatrix(m, n); double[,] C = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { C[i, j] = A[i, j]; } } return X; }