/** * 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); }
public virtual DMatrixRMaj getU(DMatrixRMaj U, bool transpose, bool compact) { U = BidiagonalDecompositionRow_DDRM.handleU(U, false, compact, m, n, min); if (compact) { // U = Q*U1 DMatrixRMaj Q1 = decompQRP.getQ(null, true); DMatrixRMaj U1 = decompBi.getU(null, false, true); CommonOps_DDRM.mult(Q1, U1, U); } else { // U = [Q1*U1 Q2] DMatrixRMaj Q = decompQRP.getQ(U, false); DMatrixRMaj U1 = decompBi.getU(null, false, true); DMatrixRMaj Q1 = CommonOps_DDRM.extract(Q, 0, Q.numRows, 0, min); DMatrixRMaj tmp = new DMatrixRMaj(Q1.numRows, U1.numCols); CommonOps_DDRM.mult(Q1, U1, tmp); CommonOps_DDRM.insert(tmp, Q, 0, 0); } if (transpose) { CommonOps_DDRM.transpose(U); } return(U); }
/** * <p> * Returns the null-space from the singular value decomposition. The null space is a set of non-zero vectors that * when multiplied by the original matrix return zero. * </p> * * <p> * The null space is found by extracting the columns in V that are associated singular values less than * or equal to the threshold. In some situations a non-compact SVD is required. * </p> * * @param svd A precomputed decomposition. Not modified. * @param nullSpace Storage for null space. Will be reshaped as needed. Modified. * @param tol Threshold for selecting singular values. Try UtilEjml.EPS. * @return The null space. */ public static DMatrixRMaj nullSpace(SingularValueDecomposition_F64 <DMatrixRMaj> svd, DMatrixRMaj nullSpace, double tol) { int N = svd.numberOfSingularValues(); double[] s = svd.getSingularValues(); DMatrixRMaj V = svd.getV(null, true); if (V.numRows != svd.numCols()) { throw new ArgumentException( "Can't compute the null space using a compact SVD for a matrix of this size."); } // first determine the size of the null space int numVectors = svd.numCols() - N; for (int i = 0; i < N; i++) { if (s[i] <= tol) { numVectors++; } } // declare output data if (nullSpace == null) { nullSpace = new DMatrixRMaj(numVectors, svd.numCols()); } else { nullSpace.reshape(numVectors, svd.numCols()); } // now extract the vectors int count = 0; for (int i = 0; i < N; i++) { if (s[i] <= tol) { CommonOps_DDRM.extract(V, i, i + 1, 0, V.numCols, nullSpace, count++, 0); } } for (int i = N; i < svd.numCols(); i++) { CommonOps_DDRM.extract(V, i, i + 1, 0, V.numCols, nullSpace, count++, 0); } CommonOps_DDRM.transpose(nullSpace); return(nullSpace); }
/** * Returns a vector from the PCA's basis. * * @param which Which component's vector is to be returned. * @return Vector from the PCA basis. */ public double[] getBasisVector(int which) { if (which < 0 || which >= numComponents) { throw new ArgumentException("Invalid component"); } DMatrixRMaj v = new DMatrixRMaj(1, A.numCols); CommonOps_DDRM.extract(V_t, which, which + 1, 0, A.numCols, v, 0, 0); return(v.data); }
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); }
public bool process(DMatrixRMaj A, int numSingularValues, DMatrixRMaj nullspace) { decomposition.decompose(A); if (A.numRows > A.numCols) { Q.reshape(A.numCols, Math.Min(A.numRows, A.numCols)); decomposition.getQ(Q, true); } else { Q.reshape(A.numCols, A.numCols); decomposition.getQ(Q, false); } nullspace.reshape(Q.numRows, numSingularValues); CommonOps_DDRM.extract(Q, 0, Q.numRows, Q.numCols - numSingularValues, Q.numCols, nullspace, 0, 0); return(true); }
private void solveWithLU(double real, int index, DMatrixRMaj r) { DMatrixRMaj A = new DMatrixRMaj(index, index); CommonOps_DDRM.extract(_implicit.A, 0, index, 0, index, A, 0, 0); for (int i = 0; i < index; i++) { A.add(i, i, -real); } r.reshape(index, 1, false); SpecializedOps_DDRM.subvector(_implicit.A, 0, index, index, false, 0, r); CommonOps_DDRM.changeSign(r); // TODO this must be very inefficient if (!solver.setA(A)) { throw new InvalidOperationException("Solve failed"); } solver.solve(r, r); }
public void extract(Matrix src, int srcY0, int srcY1, int srcX0, int srcX1, Matrix dst, int dstY0, int dstX0) { CommonOps_DDRM.extract((DMatrixRMaj)src, srcY0, srcY1, srcX0, srcX1, (DMatrixRMaj)dst, dstY0, dstX0); }
/** * Computes the QR decomposition of the provided matrix. * * @param A Matrix which is to be decomposed. Not modified. */ public void decompose(DMatrixRMaj A) { this.QR = (DMatrixRMaj)A.copy(); int N = Math.Min(A.numCols, A.numRows); gammas = new double[A.numCols]; DMatrixRMaj A_small = new DMatrixRMaj(A.numRows, A.numCols); DMatrixRMaj A_mod = new DMatrixRMaj(A.numRows, A.numCols); DMatrixRMaj v = new DMatrixRMaj(A.numRows, 1); DMatrixRMaj Q_k = new DMatrixRMaj(A.numRows, A.numRows); for (int i = 0; i < N; i++) { // reshape temporary variables A_small.reshape(QR.numRows - i, QR.numCols - i, false); A_mod.reshape(A_small.numRows, A_small.numCols, false); v.reshape(A_small.numRows, 1, false); Q_k.reshape(v.getNumElements(), v.getNumElements(), false); // use extract matrix to get the column that is to be zeroed CommonOps_DDRM.extract(QR, i, QR.numRows, i, i + 1, v, 0, 0); double max = CommonOps_DDRM.elementMaxAbs(v); if (max > 0 && v.getNumElements() > 1) { // normalize to reduce overflow issues CommonOps_DDRM.divide(v, max); // compute the magnitude of the vector double tau = NormOps_DDRM.normF(v); if (v.get(0) < 0) { tau *= -1.0; } double u_0 = v.get(0) + tau; double gamma = u_0 / tau; CommonOps_DDRM.divide(v, u_0); v.set(0, 1.0); // extract the submatrix of A which is being operated on CommonOps_DDRM.extract(QR, i, QR.numRows, i, QR.numCols, A_small, 0, 0); // A = (I - γ*u*u<sup>T</sup>)A CommonOps_DDRM.setIdentity(Q_k); CommonOps_DDRM.multAddTransB(-gamma, v, v, Q_k); CommonOps_DDRM.mult(Q_k, A_small, A_mod); // save the results CommonOps_DDRM.insert(A_mod, QR, i, i); CommonOps_DDRM.insert(v, QR, i, i); QR.unsafe_set(i, i, -tau * max); // save gamma for recomputing Q later on gammas[i] = gamma; } } }