public override /**/ double quality() { return(SpecializedOps_DDRM.qualityTriangular(QR)); } /** * Solves for X using the QR decomposition. * * @param B A matrix that is n by m. Not modified. * @param X An n by m matrix where the solution is writen to. Modified. */ public override void solve(DMatrixRMaj B, DMatrixRMaj X) { if (X.numRows != numCols) { throw new ArgumentException("Unexpected dimensions for X"); } else if (B.numRows != numRows || B.numCols != X.numCols) { throw new ArgumentException("Unexpected dimensions for B"); } int BnumCols = B.numCols; // solve each column one by one for (int colB = 0; colB < BnumCols; colB++) { // make a copy of this column in the vector for (int i = 0; i < numRows; i++) { a[i] = B.data[i * BnumCols + colB]; } // Solve Qa=b // a = Q'b // a = Q_{n-1}...Q_2*Q_1*b // // Q_n*b = (I-gamma*u*u^T)*b = b - u*(gamma*U^T*b) for (int n = 0; n < numCols; n++) { u[n] = 1; double ub = a[n]; // U^T*b for (int i = n + 1; i < numRows; i++) { ub += (u[i] = QR.unsafe_get(i, n)) * a[i]; } // gamma*U^T*b ub *= gammas[n]; for (int i = n; i < numRows; i++) { a[i] -= u[i] * ub; } } // solve for Rx = b using the standard upper triangular solver TriangularSolver_DDRM.solveU(QR.data, a, numCols); // save the results for (int i = 0; i < numCols; i++) { X.data[i * X.numCols + colB] = a[i]; } } }
/** * <p> * Checks to see if a matrix is lower triangular or Hessenberg. A Hessenberg matrix of degree N * has the following property:<br> * <br> * a<sub>ij</sub> ≤ 0 for all i < j+N<br> * <br> * A triangular matrix is a Hessenberg matrix of degree 0. * </p> * * @param A Matrix being tested. Not modified. * @param hessenberg The degree of being hessenberg. * @param tol How close to zero the lower left elements need to be. * @return If it is an upper triangular/hessenberg matrix or not. */ public static bool isLowerTriangle(DMatrixRMaj A, int hessenberg, double tol) { for (int i = 0; i < A.numRows - hessenberg - 1; i++) { for (int j = i + hessenberg + 1; j < A.numCols; j++) { if (!(Math.Abs(A.unsafe_get(i, j)) <= tol)) { return(false); } } } return(true); }
/** * <p> * Checks to see if a matrix is upper triangular or Hessenberg. A Hessenberg matrix of degree N * has the following property:<br> * <br> * a<sub>ij</sub> ≤ 0 for all i < j+N<br> * <br> * A triangular matrix is a Hessenberg matrix of degree 0. * </p> * * @param A Matrix being tested. Not modified. * @param hessenberg The degree of being hessenberg. * @param tol How close to zero the lower left elements need to be. * @return If it is an upper triangular/hessenberg matrix or not. */ public static bool isUpperTriangle(DMatrixRMaj A, int hessenberg, double tol) { for (int i = hessenberg + 1; i < A.numRows; i++) { int maxCol = Math.Min(i - hessenberg, A.numCols); for (int j = 0; j < maxCol; j++) { if (!(Math.Abs(A.unsafe_get(i, j)) <= tol)) { return(false); } } } return(true); }
/** * Returns the R matrix. */ public DMatrixRMaj getR() { DMatrixRMaj R = new DMatrixRMaj(QR.numRows, QR.numCols); int N = Math.Min(QR.numCols, QR.numRows); for (int i = 0; i < N; i++) { for (int j = i; j < QR.numCols; j++) { R.unsafe_set(i, j, QR.unsafe_get(i, j)); } } return(R); }