/*************************************************************************/ /* */ /* Copyright (c) 1994 Stanford University */ /* */ /* All rights reserved. */ /* */ /* Permission is given to use, copy, and modify this software for any */ /* non-commercial purpose as long as this copyright notice is not */ /* removed. All other uses, including redistribution in whole or in */ /* part, are forbidden without prior written permission. */ /* */ /* This software is provided with absolutely no warranty and no */ /* support. */ /* */ /*************************************************************************/ EXTERN_ENV #include #include #include "matrix.h" long *next_in_super, *member_of, *super_parent; long *tree_firstchild, *tree_sibling; long *tree_original_firstchild, *tree_original_sibling; long ops_added; double *crit; extern long *INVP; long OpsFromSuper(long size, long nz) { long ops = 0; ops += size*(size+1)*(2*size+1)/6; ops += size*size*(nz-size); ops += 2*size*(nz-size)*(nz-size+1)/2; return(ops); } long CountSupers(long cols, long *node) { long i, supers; supers = 0; for (i=0; i time_after) { if (allow_critical_to_grow) path_grows = 0; } else path_grows = 0.0; do_merge = (possible && time_before > time_after && path_grows == 0.0); do_merge_simple = (possible && simple_diff < 0); if (do_merge) { JoinTwoSupers2(nz, node, super, parent); ops_added += (ops_after-ops_before); } else break; } i = tree_original_firstchild[super]; while (i != -1) { ConsiderMerge(join, i, M, nz, node, domain, target_size, traversal_order); i = tree_original_sibling[i]; } } void JoinTwoSupers2(long *nz, long *node, long child, long parent) { long i, child_last, member, grandparent; /* record new memberships */ member = parent; while (member != -1) { member_of[member] = child; member = next_in_super[member]; } /* find last member of child */ child_last = child; while (next_in_super[child_last] != -1) child_last = next_in_super[child_last]; /* link in nodes in parent */ next_in_super[child_last] = parent; /* adjust sizes */ nz[child] = nz[parent]+node[child]; node[child] += node[parent]; /* adjust child parent */ super_parent[child] = super_parent[parent]; /* children of 'parent' become children of 'child' */ while (tree_firstchild[parent] != -1) { i = tree_firstchild[parent]; tree_firstchild[parent] = tree_sibling[i]; if (member_of[i] != child) { super_parent[member_of[i]] = child; tree_sibling[i] = tree_firstchild[child]; tree_firstchild[child] = i; } } /* siblings of 'parent' become siblings of 'child' */ grandparent = super_parent[parent]; tree_sibling[child] = tree_sibling[parent]; i = tree_firstchild[grandparent]; if (i == parent) tree_firstchild[grandparent] = child; else { while (tree_sibling[i] != parent) i = tree_sibling[i]; tree_sibling[i] = child; } } void ReorderMatrix(SMatrix M, long super, long *node, long *counter, long *PERM) { long child, member, which_member; if (super != M.n) { super = member_of[super]; member = super; which_member = 0; while (member != -1) { PERM[*counter-node[super]+which_member] = member; member = next_in_super[member]; which_member++; } *counter -= node[super]; } child = tree_firstchild[super]; while (child != -1) { ReorderMatrix(M, child, node, counter, PERM); child = tree_sibling[child]; } } void FixNodeNZAndT(SMatrix M, long *PERM, long *node, long *nz, long *T) { long super, j; long *tmp; tmp = (long *) malloc(M.n*sizeof(long)); for (j=0; j