/** * <p> * Adjusts the matrices so that the singular values are in descending order. * </p> * * <p> * In most implementations of SVD the singular values are automatically arranged in in descending * order. In EJML this is not the case since it is often not needed and some computations can * be saved by not doing that. * </p> * * @param U Matrix. Modified. * @param tranU is U transposed or not. * @param W Diagonal matrix with singular values. Modified. * @param V Matrix. Modified. * @param tranV is V transposed or not. */ // TODO the number of copies can probably be reduced here public static void descendingOrder(DMatrixRMaj U, bool tranU, DMatrixRMaj W, DMatrixRMaj V, bool tranV) { int numSingular = Math.Min(W.numRows, W.numCols); checkSvdMatrixSize(U, tranU, W, V, tranV); for (int i = 0; i < numSingular; i++) { double bigValue = -1; int bigIndex = -1; // find the smallest singular value in the submatrix for (int j = i; j < numSingular; j++) { double v = W.get(j, j); if (v > bigValue) { bigValue = v; bigIndex = j; } } // only swap if the current index is not the smallest if (bigIndex == i) { continue; } if (bigIndex == -1) { // there is at least one uncountable singular value. just stop here break; } double tmp = W.get(i, i); W.set(i, i, bigValue); W.set(bigIndex, bigIndex, tmp); if (V != null) { swapRowOrCol(V, tranV, i, bigIndex); } if (U != null) { swapRowOrCol(U, tranU, i, bigIndex); } } }
public override bool setA(DMatrixRMaj A) { _setA(A); if (!decomposition.decompose(A)) { return(false); } rank = decomposition.getRank(); R.reshape(numRows, numCols); decomposition.getR(R, false); // extract the r11 triangle sub matrix R11.reshape(rank, rank); CommonOps_DDRM.extract(R, 0, rank, 0, rank, R11, 0, 0); if (norm2Solution && rank < numCols) { // extract the R12 sub-matrix W.reshape(rank, numCols - rank); CommonOps_DDRM.extract(R, 0, rank, rank, numCols, W, 0, 0); // W=inv(R11)*R12 TriangularSolver_DDRM.solveU(R11.data, 0, R11.numCols, R11.numCols, W.data, 0, W.numCols, W.numCols); // set the identity matrix in the upper portion W.reshape(numCols, W.numCols, true); for (int i = 0; i < numCols - rank; i++) { for (int j = 0; j < numCols - rank; j++) { if (i == j) { W.set(i + rank, j, -1); } else { W.set(i + rank, j, 0); } } } } return(true); }
/** * Reads in a DMatrixRMaj 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 DMatrixRMaj readReal(int numRows, int numCols) { DMatrixRMaj A = new DMatrixRMaj(numRows, numCols); 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 != numCols) { throw new IOException("Unexpected number of words in column. Found " + words.Count + " expected " + numCols); } for (int j = 0; j < numCols; j++) { A.set(i, j, double.Parse(words[j])); } } return(A); }
/** * Computes the best fit set of polynomial coefficients to the provided observations. * * @param samplePoints where the observations were sampled. * @param observations A set of observations. */ public void fit(double[] samplePoints, double[] observations) { // Create a copy of the observations and put it into a matrix y.reshape(observations.Length, 1, false); Array.Copy(observations, 0, y.data, 0, observations.Length); // reshape the matrix to avoid unnecessarily declaring new memory // save values is set to false since its old values don't matter A.reshape(y.numRows, coef.numRows, false); // set up the A matrix for (int i = 0; i < observations.Length; i++) { double obs = 1; for (int j = 0; j < coef.numRows; j++) { A.set(i, j, obs); obs *= samplePoints[i]; } } // process the A matrix and see if it failed if (!solver.setA(A)) { throw new InvalidOperationException("Solver failed"); } // solver the the coefficients solver.solve(y, coef); }
/** * Returns the Q matrix. */ public DMatrixRMaj getQ() { DMatrixRMaj Q = CommonOps_DDRM.identity(QR.numRows); DMatrixRMaj Q_k = new DMatrixRMaj(QR.numRows, QR.numRows); DMatrixRMaj u = new DMatrixRMaj(QR.numRows, 1); DMatrixRMaj temp = new DMatrixRMaj(QR.numRows, QR.numRows); int N = Math.Min(QR.numCols, QR.numRows); // compute Q by first extracting the householder vectors from the columns of QR and then applying it to Q for (int j = N - 1; j >= 0; j--) { CommonOps_DDRM.extract(QR, j, QR.numRows, j, j + 1, u, j, 0); u.set(j, 1.0); // A = (I - γ*u*u<sup>T</sup>)*A<br> CommonOps_DDRM.setIdentity(Q_k); CommonOps_DDRM.multAddTransB(-gammas[j], u, u, Q_k); CommonOps_DDRM.mult(Q_k, Q, temp); Q.set(temp); } return(Q); }
/** * <p> * Puts all the real eigenvectors into the columns of a matrix. If an eigenvalue is imaginary * then the corresponding eigenvector will have zeros in its column. * </p> * * @param eig An eigenvalue decomposition which has already decomposed a matrix. * @return An m by m matrix containing eigenvectors in its columns. */ public static DMatrixRMaj createMatrixV(EigenDecomposition_F64 <DMatrixRMaj> eig) { int N = eig.getNumberOfEigenvalues(); DMatrixRMaj V = new DMatrixRMaj(N, N); for (int i = 0; i < N; i++) { Complex_F64 c = eig.getEigenvalue(i); if (c.isReal()) { DMatrixRMaj v = eig.getEigenVector(i); if (v != null) { for (int j = 0; j < N; j++) { V.set(j, i, v.get(j, 0)); } } } } return(V); }
/** * Adds a new sample of the raw data to internal data structure for later processing. All the samples * must be added before computeBasis is called. * * @param sampleData Sample from original raw data. */ public void addSample(double[] sampleData) { if (A.getNumCols() != sampleData.Length) { throw new ArgumentException("Unexpected sample size"); } if (sampleIndex >= A.getNumRows()) { throw new ArgumentException("Too many samples"); } for (int i = 0; i < sampleData.Length; i++) { A.set(sampleIndex, i, sampleData[i]); } sampleIndex++; }
public static DMatrixRMaj createQ(double T, double var) { DMatrixRMaj Q = new DMatrixRMaj(9, 9); double a00 = (1.0 / 4.0) * T * T * T * T * var; double a01 = (1.0 / 2.0) * T * T * T * var; double a02 = (1.0 / 2.0) * T * T * var; double a11 = T * T * var; double a12 = T * var; double a22 = var; for (int i = 0; i < 3; i++) { Q.set(i, i, a00); Q.set(i, 3 + i, a01); Q.set(i, 6 + i, a02); Q.set(3 + i, 3 + i, a11); Q.set(3 + i, 6 + i, a12); Q.set(6 + i, 6 + i, a22); } for (int y = 1; y < 9; y++) { for (int x = 0; x < y; x++) { Q.set(y, x, Q.get(x, y)); } } return(Q); }
/** * Makes a draw on the distribution. The results are added to parameter 'x' */ public void next(DMatrixRMaj x) { for (int i = 0; i < r.numRows; i++) { r.set(i, 0, (double)rand.NextGaussian()); } CommonOps_DDRM.multAdd(A, r, x); }
public void deriv(DMatrixRMaj x, DMatrixRMaj deriv) { double[] dataX = x.data; int length = x.numRows; for (int j = 0; j < length; j++) { double v = dataX[j]; double dA = 1; double dB = v; double dC = v * v; deriv.set(0, j, dA); deriv.set(1, j, dB); deriv.set(2, j, dC); } }
/** * Extracts the tridiagonal matrix found in the decomposition. * * @param T If not null then the results will be stored here. Otherwise a new matrix will be created. * @return The extracted T matrix. */ public DMatrixRMaj getT(DMatrixRMaj T) { T = UtilDecompositons_DDRM.checkZeros(T, N, N); T.data[0] = QT.data[0]; T.data[1] = QT.data[1]; for (int i = 1; i < N - 1; i++) { T.set(i, i, QT.get(i, i)); T.set(i, i + 1, QT.get(i, i + 1)); T.set(i, i - 1, QT.get(i - 1, i)); } T.data[(N - 1) * N + N - 1] = QT.data[(N - 1) * N + N - 1]; T.data[(N - 1) * N + N - 2] = QT.data[(N - 2) * N + N - 1]; return(T); }
//@Override public void predict() { // x = F x CommonOps_DDRM.mult(F, x, a); x.set(a); // P = F P F' + Q CommonOps_DDRM.mult(F, P, b); CommonOps_DDRM.multTransB(b, F, P); CommonOps_DDRM.addEquals(P, Q); }
public static DMatrixRMaj createH() { DMatrixRMaj H = new DMatrixRMaj(measDOF, 9); for (int i = 0; i < measDOF; i++) { H.set(i, i, 1.0); } return(H); }
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; // get the pivots and transpose them int[] pivots = decomposition.getColPivots(); // solve each column one by one for (int colB = 0; colB < BnumCols; colB++) { x_basic.reshape(numRows, 1); Y.reshape(numRows, 1); // make a copy of this column in the vector for (int i = 0; i < numRows; i++) { Y.data[i] = B.get(i, colB); } // Solve Q*a=b => a = Q'*b CommonOps_DDRM.multTransA(Q, Y, x_basic); // solve for Rx = b using the standard upper triangular solver TriangularSolver_DDRM.solveU(R11.data, x_basic.data, rank); // finish the basic solution by filling in zeros x_basic.reshape(numCols, 1, true); for (int i = rank; i < numCols; i++) { x_basic.data[i] = 0; } if (norm2Solution && rank < numCols) { upgradeSolution(x_basic); } // save the results for (int i = 0; i < numCols; i++) { X.set(pivots[i], colB, x_basic.data[i]); } } }
/** * <p> * Creates a randomly generated set of orthonormal vectors. At most it can generate the same * number of vectors as the dimension of the vectors. * </p> * * <p> * This is done by creating random vectors then ensuring that they are orthogonal * to all the ones previously created with reflectors. * </p> * * <p> * NOTE: This employs a brute force O(N<sup>3</sup>) algorithm. * </p> * * @param dimen dimension of the space which the vectors will span. * @param numVectors How many vectors it should generate. * @param rand Used to create random vectors. * @return Array of N random orthogonal vectors of unit length. */ // is there a faster algorithm out there? This one is a bit sluggish public static DMatrixRMaj[] span(int dimen, int numVectors, IMersenneTwister rand) { if (dimen < numVectors) { throw new ArgumentException("The number of vectors must be less than or equal to the dimension"); } DMatrixRMaj[] u = new DMatrixRMaj[numVectors]; u[0] = RandomMatrices_DDRM.rectangle(dimen, 1, -1, 1, rand); NormOps_DDRM.normalizeF(u[0]); for (int i = 1; i < numVectors; i++) { // Console.WriteLine(" i = "+i); DMatrixRMaj a = new DMatrixRMaj(dimen, 1); DMatrixRMaj r = null; for (int j = 0; j < i; j++) { // Console.WriteLine("j = "+j); if (j == 0) { r = RandomMatrices_DDRM.rectangle(dimen, 1, -1, 1, rand); } // find a vector that is normal to vector j // u[i] = (1/2)*(r + Q[j]*r) a.set(r); VectorVectorMult_DDRM.householder(-2.0, u[j], r, a); CommonOps_DDRM.add(r, a, a); CommonOps_DDRM.scale(0.5, a); // UtilEjml.print(a); DMatrixRMaj t = a; a = r; r = t; // normalize it so it doesn't get too small double val = NormOps_DDRM.normF(r); if (val == 0 || double.IsNaN(val) || double.IsInfinity(val)) { throw new InvalidOperationException("Failed sanity check"); } CommonOps_DDRM.divide(r, val); } u[i] = r; } return(u); }
/** * Sets the provided square matrix to be aJava.Util.Random symmetric matrix whose values are selected from an uniform distribution * from min to max, inclusive. * * @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 randJava.Util.Random number generator. */ public static void symmetric(DMatrixRMaj A, double min, double max, Java.Util.Random 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++) { for (int j = i; j < length; j++) { double val = rand.NextDouble() * range + min; A.set(i, j, val); A.set(j, i, val); } } }
public DMatrixRMaj extract() { DMatrixRMaj ret = new DMatrixRMaj(row1 - row0, col1 - col0); for (int i = 0; i < ret.numRows; i++) { for (int j = 0; j < ret.numCols; j++) { ret.set(i, j, get(i, j)); } } return(ret); }
/** * Updates the Q matrix to take in account the inserted matrix. * * @param rowIndex where the matrix has been inserted. */ private void updateInsertQ(int rowIndex) { Qm.set(Q); Q.reshape(m_m, m_m, false); for (int i = 0; i < rowIndex; i++) { for (int j = 0; j < m_m; j++) { double sum = 0; for (int k = 0; k < m; k++) { sum += Qm.data[i * m + k] * U_tran.data[j * m_m + k + 1]; } Q.data[i * m_m + j] = sum; } } for (int j = 0; j < m_m; j++) { Q.data[rowIndex * m_m + j] = U_tran.data[j * m_m]; } for (int i = rowIndex + 1; i < m_m; i++) { for (int j = 0; j < m_m; j++) { double sum = 0; for (int k = 0; k < m; k++) { sum += Qm.data[(i - 1) * m + k] * U_tran.data[j * m_m + k + 1]; } Q.data[i * m_m + j] = sum; } } }
/** * Multiplied a transpose orthogonal matrix Q by the specified rotator. This is used * to update the U and V matrices. Updating the transpose of the matrix is faster * since it only modifies the rows. * * * @param Q Orthogonal matrix * @param m Coordinate of rotator. * @param n Coordinate of rotator. * @param c cosine of rotator. * @param s sine of rotator. */ protected void updateRotator(DMatrixRMaj Q, int m, int n, double c, double s) { int rowA = m * Q.numCols; int rowB = n * Q.numCols; // for( int i = 0; i < Q.numCols; i++ ) { // double a = Q.get(rowA+i); // double b = Q.get(rowB+i); // Q.set( rowA+i, c*a + s*b); // Q.set( rowB+i, -s*a + c*b); // } // Console.WriteLine("------ AFter Update Rotator "+m+" "+n); // Q.print(); // Console.WriteLine(); int endA = rowA + Q.numCols; for (; rowA != endA; rowA++, rowB++) { double a = Q.get(rowA); double b = Q.get(rowB); Q.set(rowA, c * a + s * b); Q.set(rowB, -s * a + c * b); } }
/** * Creates a random vector that is inside the specified span. * * @param span The span the random vector belongs in. * @param rand RNG * @return A random vector within the specified span. */ public static DMatrixRMaj insideSpan(DMatrixRMaj[] span, double min, double max, IMersenneTwister rand) { DMatrixRMaj A = new DMatrixRMaj(span.Length, 1); DMatrixRMaj B = new DMatrixRMaj(span[0].getNumElements(), 1); for (int i = 0; i < span.Length; i++) { B.set(span[i]); double val = rand.NextDouble() * (max - min) + min; CommonOps_DDRM.scale(val, B); CommonOps_DDRM.add(A, B, A); } return(A); }
/** * <p> * Computes the F norm of the difference between the two Matrices:<br> * <br> * Sqrt{∑<sub>i=1:m</sub> ∑<sub>j=1:n</sub> ( a<sub>ij</sub> - b<sub>ij</sub>)<sup>2</sup>} * </p> * <p> * This is often used as a cost function. * </p> * * @see NormOps_DDRM#fastNormF * * @param a m by n matrix. Not modified. * @param b m by n matrix. Not modified. * * @return The F normal of the difference matrix. */ public static double diffNormF(DMatrixD1 a, DMatrixD1 b) { if (a.numRows != b.numRows || a.numCols != b.numCols) { throw new ArgumentException("Both matrices must have the same shape."); } int size = a.getNumElements(); DMatrixRMaj diff = new DMatrixRMaj(size, 1); for (int i = 0; i < size; i++) { diff.set(i, b.get(i) - a.get(i)); } return(NormOps_DDRM.normF(diff)); }
/** * <p> * A diagonal matrix where real diagonal element contains a real eigenvalue. If an eigenvalue * is imaginary then zero is stored in its place. * </p> * * @param eig An eigenvalue decomposition which has already decomposed a matrix. * @return A diagonal matrix containing the eigenvalues. */ public static DMatrixRMaj createMatrixD(EigenDecomposition_F64 <DMatrixRMaj> eig) { int N = eig.getNumberOfEigenvalues(); DMatrixRMaj D = new DMatrixRMaj(N, N); for (int i = 0; i < N; i++) { Complex_F64 c = eig.getEigenvalue(i); if (c.isReal()) { D.set(i, i, c.real); } } return(D); }
private void initPower(DMatrixRMaj A) { if (A.numRows != A.numCols) { throw new ArgumentException("A must be a square matrix."); } if (seed != null) { q0.set(seed); } else { for (int i = 0; i < A.numRows; i++) { q0.data[i] = 1; } } }
private void createMinor(DMatrix1Row mat) { int w = minWidth - 1; int firstRow = (width - w) * width; for (int i = 0; i < numOpen; i++) { int col = open[i]; int srcIndex = firstRow + col; int dstIndex = i; for (int j = 0; j < w; j++) { tempMat.set(dstIndex, mat.get(srcIndex)); dstIndex += w; srcIndex += width; } } }
/** * Creates aJava.Util.Random symmetric positive definite matrix. * * @param width The width of the square matrix it returns. * @param randJava.Util.Random number generator used to make the matrix. * @return TheJava.Util.Random symmetric positive definite matrix. */ public static DMatrixRMaj symmetricPosDef(int width, Java.Util.Random rand) { // This is not formally proven to work. It just seems to work. DMatrixRMaj a = new DMatrixRMaj(width, 1); DMatrixRMaj b = new DMatrixRMaj(width, width); for (int i = 0; i < width; i++) { a.set(i, 0, rand.NextDouble()); } CommonOps_DDRM.multTransB(a, a, b); for (int i = 0; i < width; i++) { b.add(i, i, 1); } return(b); }
/** * Creates aJava.Util.Random matrix where all elements are zero but diagonal elements. Diagonal elements * randomly drawn from a uniform distribution from min to max, inclusive. * * @param numRows Number of rows in the returned matrix.. * @param numCols Number of columns in the returned matrix. * @param min Minimum value of a diagonal element. * @param max Maximum value of a diagonal element. * @param randJava.Util.Random number generator. * @return AJava.Util.Random diagonal matrix. */ public static DMatrixRMaj diagonal(int numRows, int numCols, double min, double max, Java.Util.Random rand) { if (max < min) { throw new ArgumentException("The max must be >= the min"); } DMatrixRMaj ret = new DMatrixRMaj(numRows, numCols); int N = Math.Min(numRows, numCols); double r = max - min; for (int i = 0; i < N; i++) { ret.set(i, i, rand.NextDouble() * r + min); } return(ret); }
/** * Creates a lower triangular matrix whose values are selected from a uniform distribution. If hessenberg * is greater than zero then a hessenberg matrix of the specified degree is created instead. * * @param dimen Number of rows and columns in the matrix.. * @param hessenberg 0 for triangular matrix and > 0 for hessenberg matrix. * @param min minimum value an element can be. * @param max maximum value an element can be. * @param randJava.Util.Random number generator used. * @return The randomly generated matrix. */ public static DMatrixRMaj triangularLower(int dimen, int hessenberg, double min, double max, Java.Util.Random rand) { if (hessenberg < 0) { throw new SystemException("hessenberg must be more than or equal to 0"); } double range = max - min; DMatrixRMaj A = new DMatrixRMaj(dimen, dimen); for (int i = 0; i < dimen; i++) { int end = Math.Min(dimen, i + hessenberg + 1); for (int j = 0; j < end; j++) { A.set(i, j, rand.NextDouble() * range + min); } } return(A); }
public override /**/ double quality() { return(SpecializedOps_DDRM.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. */ 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; Y.reshape(numRows, 1, false); Z.reshape(numRows, 1, false); // 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++) { Y.data[i] = B.get(i, colB); } // Solve Qa=b // a = Q'b CommonOps_DDRM.multTransA(Q, Y, Z); // solve for Rx = b using the standard upper triangular solver TriangularSolver_DDRM.solveU(R.data, Z.data, numCols); // save the results for (int i = 0; i < numCols; i++) { X.set(i, colB, Z.data[i]); } } }
/** * Creates an upper triangular matrix whose values are selected from a uniform distribution. If hessenberg * is greater than zero then a hessenberg matrix of the specified degree is created instead. * * @param dimen Number of rows and columns in the matrix.. * @param hessenberg 0 for triangular matrix and > 0 for hessenberg matrix. * @param min minimum value an element can be. * @param max maximum value an element can be. * @param randJava.Util.Random number generator used. * @return The randomly generated matrix. */ public static DMatrixRMaj triangularUpper(int dimen, int hessenberg, double min, double max, Java.Util.Random rand) { if (hessenberg < 0) { throw new SystemException("hessenberg must be more than or equal to 0"); } double range = max - min; DMatrixRMaj A = new DMatrixRMaj(dimen, dimen); for (int i = 0; i < dimen; i++) { int start = i <= hessenberg ? 0 : i - hessenberg; for (int j = start; j < dimen; j++) { A.set(i, j, rand.NextDouble() * range + min); } } return(A); }
private List <DMatrixRMaj> createSimulatedMeas(DMatrixRMaj x) { List <DMatrixRMaj> ret = new List <DMatrixRMaj>(); DMatrixRMaj F = createF(T); DMatrixRMaj H = createH(); // UtilEjml.print(F); // UtilEjml.print(H); DMatrixRMaj x_next = new DMatrixRMaj(x); DMatrixRMaj z = new DMatrixRMaj(H.numRows, 1); for (int i = 0; i < MAX_STEPS; i++) { CommonOps_DDRM.mult(F, x, x_next); CommonOps_DDRM.mult(H, x_next, z); ret.Add((DMatrixRMaj)z.copy()); x.set(x_next); } return(ret); }