/** * Reads in a ZMatrixRMaj from the IO stream where the user specifies the matrix dimensions. * * @param numRows Number of rows in the matrix * @param numCols Number of columns in the matrix * @return DMatrixRMaj * @throws IOException */ public ZMatrixRMaj readComplex(int numRows, int numCols) { ZMatrixRMaj A = new ZMatrixRMaj(numRows, numCols); int wordsCol = numCols * 2; for (int i = 0; i < numRows; i++) { List <string> words = extractWords(); if (words == null) { throw new IOException("Too few rows found. expected " + numRows + " actual " + i); } if (words.Count != wordsCol) { throw new IOException("Unexpected number of words in column. Found " + words.Count + " expected " + wordsCol); } for (int j = 0; j < wordsCol; j += 2) { double real = double.Parse(words[j]); double imaginary = double.Parse(words[j + 1]); A.set(i, j, real, imaginary); } } return(A); }
/** * Computes the householder vector used in QR decomposition. * * u = x / max(x) * u(0) = u(0) + |u| * u = u / u(0) * * @param x Input vector. Unmodified. * @return The found householder reflector vector */ public static ZMatrixRMaj householderVector(ZMatrixRMaj x) { ZMatrixRMaj u = (ZMatrixRMaj)x.copy(); double max = CommonOps_ZDRM.elementMaxAbs(u); CommonOps_ZDRM.elementDivide(u, max, 0, u); double nx = NormOps_ZDRM.normF(u); Complex_F64 c = new Complex_F64(); u.get(0, 0, c); double realTau, imagTau; if (c.getMagnitude() == 0) { realTau = nx; imagTau = 0; } else { realTau = c.real / c.getMagnitude() * nx; imagTau = c.imaginary / c.getMagnitude() * nx; } u.set(0, 0, c.real + realTau, c.imaginary + imagTau); CommonOps_ZDRM.elementDivide(u, u.getReal(0, 0), u.getImag(0, 0), u); return(u); }
/** * <p> * Creates an identity matrix of the specified size.<br> * <br> * a<sub>ij</sub> = 0+0i if i ≠ j<br> * a<sub>ij</sub> = 1+0i if i = j<br> * </p> * * @param width The width and height of the identity matrix. * @return A new instance of an identity matrix. */ public static ZMatrixRMaj identity(int width) { ZMatrixRMaj A = new ZMatrixRMaj(width, width); for (int i = 0; i < width; i++) { A.set(i, i, 1, 0); } return(A); }
public static ZMatrixRMaj diag(ZMatrixRMaj output, int N, double[] data) { output = UtilEjml.reshapeOrDeclare(output, N, N); int index = 0; for (int i = 0; i < N; i++) { output.set(i, i, data[index++], data[index++]); } return(output); }
/** * <p> * Creates a matrix with diagonal elements set to 1 and the rest 0.<br> * <br> * a<sub>ij</sub> = 0+0i if i ≠ j<br> * a<sub>ij</sub> = 1+0i if i = j<br> * </p> * * @param width The width of the identity matrix. * @param height The height of the identity matrix. * @return A new instance of an identity matrix. */ public static ZMatrixRMaj identity(int width, int height) { ZMatrixRMaj A = new ZMatrixRMaj(width, height); int m = Math.Min(width, height); for (int i = 0; i < m; i++) { A.set(i, i, 1, 0); } return(A); }
/** * <p>Performs an "in-place" conjugate transpose.</p> * * @see #transpose(ZMatrixRMaj) * * @param mat The matrix that is to be transposed. Modified. */ public static void transposeConjugate(ZMatrixRMaj mat) { if (mat.numCols == mat.numRows) { TransposeAlgs_ZDRM.squareConjugate(mat); } else { ZMatrixRMaj b = new ZMatrixRMaj(mat.numCols, mat.numRows); transposeConjugate(mat, b); mat.reshape(b.numRows, b.numCols); mat.set(b); } }
/** * Assigns the provided square matrix to be a random Hermitian matrix with elements from min to max value. * * @param A The matrix that is to be modified. Must be square. Modified. * @param min Minimum value an element can have. * @param max Maximum value an element can have. * @param rand Random number generator. */ public static void fillHermitian(ZMatrixRMaj A, double min, double max, IMersenneTwister rand) { if (A.numRows != A.numCols) { throw new ArgumentException("A must be a square matrix"); } double range = max - min; int length = A.numRows; for (int i = 0; i < length; i++) { A.set(i, i, rand.NextDouble() * range + min, 0); for (int j = i + 1; j < length; j++) { double real = rand.NextDouble() * range + min; double imaginary = rand.NextDouble() * range + min; A.set(i, j, real, imaginary); A.set(j, i, real, -imaginary); } } }
/** * <p> * Creates a new square matrix whose diagonal elements are specified by data and all * the other elements are zero.<br> * <br> * a<sub>ij</sub> = 0 if i ≤ j<br> * a<sub>ij</sub> = diag[i] if i = j<br> * </p> * * @param data Contains the values of the diagonal elements of the resulting matrix. * @return A new complex matrix. */ public static ZMatrixRMaj diag(double[] data) { if (data.Length % 2 == 1) { throw new ArgumentException("must be an even number of arguments"); } int N = data.Length / 2; ZMatrixRMaj m = new ZMatrixRMaj(N, N); int index = 0; for (int i = 0; i < N; i++) { m.set(i, i, data[index++], data[index++]); } return(m); }
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]); } } }