/// <summary> /// Symbolic ordering and analysis for QR /// </summary> static SymbolicFactorization SymbolicAnalysis(int order, SparseMatrix A) { // ori: cs_sqr int n = A.n, k; bool ok = true; int[] post; SymbolicFactorization S = new SymbolicFactorization(); // allocate result S S.q = Ordering.AMD(order, A); // fill-reducing ordering if (order != 0 && S.q == null) { return(null); } SparseMatrix C = order > 0 ? (SparseMatrix)A.Permute(null, S.q, false) : A; S.parent = Common.EliminationTree(C, true); // etree of C'*C, where C=A(:,q) post = Common.TreePostorder(S.parent, n); S.cp = Common.ColumnCounts(C, S.parent, post, true); // col counts chol(C'*C) ok = C != null && S.parent != null && S.cp != null && CountV(C, S); if (ok) { for (S.unz = 0, k = 0; k < n; k++) { S.unz += S.cp[k]; } } ok = ok && S.lnz >= 0 && S.unz >= 0; // int overflow guard return(ok ? S : null); // return result S }