Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}