/** * Extracts the column of A and copies it into u while computing the magnitude of the * largest element and returning it. * * <pre> * u[ (offsetU+row0+i)*2 ] = A.getReal(row0+i,col) * u[ (offsetU+row0+i)*2 + 1] = A.getImag(row0+i,col) * </pre> * * @param A Complex matrix * @param row0 First row in A to be copied * @param row1 Last row in A + 1 to be copied * @param col Column in A * @param u Output array storage * @param offsetU first index in U * @return magnitude of largest element */ public static double extractColumnAndMax(ZMatrixRMaj A, int row0, int row1, int col, double[] u, int offsetU) { int indexU = (offsetU + row0) * 2; // find the largest value in this column // this is used to normalize the column and mitigate overflow/underflow double max = 0; int indexA = A.getIndex(row0, col); double[] h = A.data; for (int i = row0; i < row1; i++, indexA += A.numCols * 2) { // copy the householder vector to an array to reduce cache misses // big improvement on larger matrices and a relatively small performance hit on small matrices. double realVal = u[indexU++] = h[indexA]; double imagVal = u[indexU++] = h[indexA + 1]; double magVal = realVal * realVal + imagVal * imagVal; if (max < magVal) { max = magVal; } } return(Math.Sqrt(max)); }
/** * Extracts a house holder vector from the column of A and stores it in u * @param A Complex matrix with householder vectors stored in the lower left triangle * @param row0 first row in A (implicitly assumed to be r + i0) * @param row1 last row + 1 in A * @param col Column in A * @param u Output array storage * @param offsetU first index in U */ public static void extractHouseholderColumn(ZMatrixRMaj A, int row0, int row1, int col, double[] u, int offsetU) { int indexU = (row0 + offsetU) * 2; u[indexU++] = 1; u[indexU++] = 0; for (int row = row0 + 1; row < row1; row++) { int indexA = A.getIndex(row, col); u[indexU++] = A.data[indexA]; u[indexU++] = A.data[indexA + 1]; } }
/** * <p> * Extracts a submatrix from 'src' and inserts it in a submatrix in 'dst'. * </p> * <p> * s<sub>i-y0 , j-x0</sub> = o<sub>ij</sub> for all y0 ≤ i < y1 and x0 ≤ j < x1 <br> * <br> * where 's<sub>ij</sub>' is an element in the submatrix and 'o<sub>ij</sub>' is an element in the * original matrix. * </p> * * @param src The original matrix which is to be copied. Not modified. * @param srcX0 Start column. * @param srcX1 Stop column+1. * @param srcY0 Start row. * @param srcY1 Stop row+1. * @param dst Where the submatrix are stored. Modified. * @param dstY0 Start row in dst. * @param dstX0 start column in dst. */ public static void extract(ZMatrixRMaj src, int srcY0, int srcY1, int srcX0, int srcX1, ZMatrixRMaj dst, int dstY0, int dstX0) { int numRows = srcY1 - srcY0; int stride = (srcX1 - srcX0) * 2; for (int y = 0; y < numRows; y++) { int indexSrc = src.getIndex(y + srcY0, srcX0); int indexDst = dst.getIndex(y + dstY0, dstX0); System.Array.Copy(src.data, indexSrc, dst.data, indexDst, stride); } }
/** * <p> * Extracts the diagonal elements 'src' write it to the 'dst' vector. 'dst' * can either be a row or column vector. * <p> * * @param src Matrix whose diagonal elements are being extracted. Not modified. * @param dst A vector the results will be written into. Modified. */ public static void extractDiag(ZMatrixRMaj src, ZMatrixRMaj dst) { int N = Math.Min(src.numRows, src.numCols); // reshape if it's not the right size if (!MatrixFeatures_ZDRM.isVector(dst) || dst.numCols * dst.numCols != N) { dst.reshape(N, 1); } for (int i = 0; i < N; i++) { int index = src.getIndex(i, i); dst.data[i * 2] = src.data[index]; dst.data[i * 2 + 1] = src.data[index + 1]; } }
public override /**/ double quality() { return(SpecializedOps_ZDRM.qualityTriangular(R)); } /** * 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 written to. Modified. */ //@Override public override void solve(ZMatrixRMaj B, ZMatrixRMaj 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; Y.reshape(numRows, 1); Z.reshape(numRows, 1); // 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++) { int indexB = B.getIndex(i, colB); Y.data[i * 2] = B.data[indexB]; Y.data[i * 2 + 1] = B.data[indexB + 1]; } // Solve Qa=b // a = Q'b CommonOps_ZDRM.mult(Qt, Y, Z); // solve for Rx = b using the standard upper triangular solver TriangularSolver_ZDRM.solveU(R.data, Z.data, numCols); // save the results for (int i = 0; i < numCols; i++) { X.set(i, colB, Z.data[i * 2], Z.data[i * 2 + 1]); } } }
/** * Finds the magnitude of the largest element in the row * @param A Complex matrix * @param row Row in A * @param col0 First column in A to be copied * @param col1 Last column in A + 1 to be copied * @return magnitude of largest element */ public static double computeRowMax(ZMatrixRMaj A, int row, int col0, int col1) { double max = 0; int indexA = A.getIndex(row, col0); double[] h = A.data; for (int i = col0; i < col1; i++) { double realVal = h[indexA++]; double imagVal = h[indexA++]; double magVal = realVal * realVal + imagVal * imagVal; if (max < magVal) { max = magVal; } } return(Math.Sqrt(max)); }
/** * Converts the columns in a matrix into a set of vectors. * * @param A Matrix. Not modified. * @param v Optional storage for columns. * @return An array of vectors. */ public static ZMatrixRMaj[] columnsToVector(ZMatrixRMaj A, ZMatrixRMaj[] v) { ZMatrixRMaj[] ret; if (v == null || v.Count() < A.numCols) { ret = new ZMatrixRMaj[A.numCols]; } else { ret = v; } for (int i = 0; i < ret.Count(); i++) { if (ret[i] == null) { ret[i] = new ZMatrixRMaj(A.numRows, 1); } else { ret[i].reshape(A.numRows, 1); } ZMatrixRMaj u = ret[i]; int indexU = 0; for (int j = 0; j < A.numRows; j++) { int indexA = A.getIndex(j, i); u.data[indexU++] = A.data[indexA++]; u.data[indexU++] = A.data[indexA]; } } return(ret); }