//@Override public DMatrixSparseCSC getQ(DMatrixSparseCSC Q, bool compact) { if (Q == null) { Q = new DMatrixSparseCSC(1, 1, 0); } if (compact) { Q.reshape(V.numRows, n, 0); } else { Q.reshape(V.numRows, m, 0); } DMatrixSparseCSC I = CommonOps_DSCC.identity(V.numRows, Q.numCols); for (int i = V.numCols - 1; i >= 0; i--) { QrHelperFunctions_DSCC.rank1UpdateMultR(V, i, beta[i], I, Q, gwork, gx); I.set(Q); } // Apply P transpose to Q CommonOps_DSCC.permutationInverse(structure.pinv, structureP, V.numRows); CommonOps_DSCC.permuteRowInv(structureP, Q, I); // Remove fictitious rows if (V.numRows > m) { CommonOps_DSCC.extractRows(I, 0, m, Q); } else { Q.set(I); } return(Q); }
private void performDecomposition(DMatrixSparseCSC A) { int[] w = gwork.data; int[] permCol = applyReduce.getArrayQ(); int[] parent = structure.getParent(); int[] leftmost = structure.getLeftMost(); // permutation that was done to ensure all rows have non-zero elements int[] pinv_structure = structure.getPinv(); int s = m2; // clear mark nodes. See addRowsInAInToC //Arrays.fill(w, 0, m2, -1); for (var i = 0; i < m2; i++) { w[i] = -1; } //Arrays.fill(x, 0, m2, 0); Array.Clear(x, 0, m2); // the counts from structure are actually an upper limit. the actual counts can be lower R.nz_length = 0; V.nz_length = 0; // compute V and R for (int k = 0; k < n; k++) { R.col_idx[k] = R.nz_length; int p1 = V.col_idx[k] = V.nz_length; w[k] = k; V.nz_rows[V.nz_length++] = k; // Add V(k,k) to V's pattern int top = n; int col = permCol != null ? permCol[k] : k; int idx0 = A.col_idx[col]; int idx1 = A.col_idx[col + 1]; for (int p = idx0; p < idx1; p++) { int i = leftmost[A.nz_rows[p]]; int len; for (len = 0; w[i] != k; i = parent[i]) { w[s + len++] = i; w[i] = k; } while (len > 0) { w[s + --top] = w[s + --len]; } i = pinv_structure[A.nz_rows[p]]; x[i] = A.nz_values[p]; if (i > k && w[i] < k) { V.nz_rows[V.nz_length++] = i; w[i] = k; } } // apply previously computed Householder vectors to the current columns for (int p = top; p < n; p++) { int i = w[s + p]; QrHelperFunctions_DSCC.applyHouseholder(V, i, beta[i], x); R.nz_rows[R.nz_length] = i; R.nz_values[R.nz_length++] = x[i]; x[i] = 0; if (parent[i] == k) { ImplSparseSparseMult_DSCC.addRowsInAInToC(V, i, V, k, w); } } for (int p = p1; p < V.nz_length; p++) { V.nz_values[p] = x[V.nz_rows[p]]; x[V.nz_rows[p]] = 0; } R.nz_rows[R.nz_length] = k; double max = QrHelperFunctions_DDRM.findMax(V.nz_values, p1, V.nz_length - p1); if (max == 0.0) { singular = true; R.nz_values[R.nz_length] = 0; beta[k] = 0; } else { R.nz_values[R.nz_length] = QrHelperFunctions_DSCC.computeHouseholder(V.nz_values, p1, V.nz_length, max, Beta); beta[k] = Beta.value; } R.nz_length++; } R.col_idx[n] = R.nz_length; V.col_idx[n] = V.nz_length; }