SMPelement * SMPfindElt(SMPmatrix *eMatrix, int Row, int Col, int CreateIfMissing) { MatrixPtr Matrix = (MatrixPtr)eMatrix; ElementPtr Element; /* Begin `SMPfindElt'. */ assert( IS_SPARSE( Matrix ) ); Row = Matrix->ExtToIntRowMap[Row]; Col = Matrix->ExtToIntColMap[Col]; Element = Matrix->FirstInCol[Col]; Element = spcFindElementInCol(Matrix, &Element, Row, Col, CreateIfMissing); return (SMPelement *)Element; }
static void LoadGmin(SMPmatrix *eMatrix, double Gmin) { MatrixPtr Matrix = (MatrixPtr)eMatrix; int I; ArrayOfElementPtrs Diag; ElementPtr diag; /* Begin `LoadGmin'. */ assert( IS_SPARSE( Matrix ) ); if (Gmin != 0.0) { Diag = Matrix->Diag; for (I = Matrix->Size; I > 0; I--) { if ((diag = Diag[I])) diag->Real += Gmin; } } return; }
node_idx Forest::InternalRestrict(level k, node_idx p, node_idx q) { //Easy Terminal Cases if (p == 0 || p == q) return q; if (q == 0) return p; if (k == 0) return q; //Check for an entry in the Cache. node_idx result; result = RestrictCache[k]->hit(p, q); if (result >= 0) { if (!(FDDL_NODE(k, result).flags & FLAG_DELETED)) return result; if (garbage_alg != O_STRICT) return CheckIn(k, result); } result = NewNode(k); //result initially has size 0. Node *nodeP = &FDDL_NODE(k, p); Node *nodeQ = &FDDL_NODE(k, q); int psize = nodeP->size; int qsize = nodeQ->size; //If neither node is sparse, do things the easy way. if (!IS_SPARSE(nodeP) && !IS_SPARSE(nodeQ)) { for (arc_idx i = 0; i < (psize > qsize ? psize : qsize); i++) { node_idx u = InternalRestrict(k - 1, i < psize ? FULL_ARC(k, nodeP, i) : 0, i < qsize ? FULL_ARC(k, nodeQ, i) : 0); SetArc(k, result, i, u); } } else if (IS_SPARSE(nodeP) && IS_SPARSE(nodeQ)) { //If both nodes are sparse, do things the fast way! //Scan from left to right. If i is the smaller value, put it in the //node. If j is the smaller value, put it in the node. If i==j, put //the union of i and j in the node. for (arc_idx i = 0, j = 0; i < psize || j < qsize;) { arc_idx pdx = SPARSE_INDEX(k, nodeP, i); node_idx pval = SPARSE_ARC(k, nodeP, i); arc_idx qdx = SPARSE_INDEX(k, nodeQ, j); node_idx qval = SPARSE_ARC(k, nodeQ, j); if (i >= psize) { SetArc(k, result, qdx, qval); j++; } else if (j >= qsize) { SetArc(k, result, pdx, pval); i++; } else if (pdx < qdx) { SetArc(k, result, pdx, pval); i++; } else if (qdx < pdx) { SetArc(k, result, qdx, qval); j++; } else { SetArc(k, result, pdx, InternalRestrict(k - 1, pval, qval)); i++; j++; } } } else { if (IS_SPARSE(nodeP) && !IS_SPARSE(nodeQ)) { int j = 0; for (int i = 0; i < nodeP->size || j < nodeQ->size;) { int idx = SPARSE_INDEX(k, nodeP, i); int ival = SPARSE_ARC(k, nodeP, i); int jval = FULL_ARC(k, nodeQ, j); if (i >= nodeP->size) { SetArc(k, result, j, jval); j++; } else if (j >= nodeQ->size) { SetArc(k, result, idx, ival); i++; } else if (j < idx) { SetArc(k, result, j, jval); j++; } else if (idx < j) { SetArc(k, result, idx, ival); i++; } else { SetArc(k, result, j, InternalRestrict(k - 1, ival, jval)); i++; j++; } } } else if (IS_SPARSE(nodeQ) && !IS_SPARSE(nodeP)) { int j = 0; for (int i = 0; i < nodeP->size || j < nodeQ->size;) { int jdx = SPARSE_INDEX(k, nodeQ, j); int jval = SPARSE_ARC(k, nodeQ, j); int ival = FULL_ARC(k, nodeP, i); if (i >= nodeP->size) { SetArc(k, result, jdx, jval); j++; } else if (j >= nodeQ->size) { SetArc(k, result, i, ival); i++; } else if (i < jdx) { SetArc(k, result, i, ival); i++; } else if (jdx < i) { SetArc(k, result, jdx, jval); j++; } else { SetArc(k, result, i, InternalRestrict(k - 1, ival, jval)); i++; j++; } } } } node_idx newresult = CheckIn(k, result); // if (k > 0 && newresult) // FDDL_NODE (k, newresult).flags |= FLAG_CHECKED_IN; RestrictCache[k]->add(newresult, p, q); return newresult; }