/* ----------------------- return a permuted tree created -- 96jan04, cca ----------------------- */ Tree * Tree_permute ( Tree *tree, int newToOld[], int oldToNew[] ) { int n, u_old, v_new, v_old, w_old ; Tree *tree2 ; /* --------------- check the input --------------- */ if ( tree == NULL || (n = tree->n) <= 0 || newToOld == NULL || oldToNew == NULL ) { fprintf(stderr, "\n fatal error in Tree_permute(%p,%p,%p)" "\n bad input\n", tree, newToOld, oldToNew) ; spoolesFatal(); } /* ----------------- create a new tree ----------------- */ tree2 = Tree_new() ; Tree_init1(tree2, n) ; /* --------------- fill the fields --------------- */ for ( v_new = 0 ; v_new < n ; v_new++ ) { v_old = newToOld[v_new] ; if ( (w_old = tree->par[v_old]) != -1 ) { tree2->par[v_new] = oldToNew[w_old] ; } if ( (u_old = tree->fch[v_old]) != -1 ) { tree2->fch[v_new] = oldToNew[u_old] ; } if ( (u_old = tree->sib[v_old]) != -1 ) { tree2->sib[v_new] = oldToNew[u_old] ; } } if ( tree->root != -1 ) { tree2->root = oldToNew[tree->root] ; } return(tree2) ; }
/* ----------------------------------------------- initialize the object given the number of nodes created -- 96mar10, cca ----------------------------------------------- */ void DSTree_init1 ( DSTree *dstree, int ndomsep, int nvtx ) { /* --------------- check the input --------------- */ if ( dstree == NULL || ndomsep <= 0 ) { fprintf(stderr, "\n fatal error in DSTree_init1(%p,%d,%d)" "\n bad input\n", dstree, ndomsep, nvtx) ; exit(-1) ; } DSTree_clearData(dstree) ; dstree->tree = Tree_new() ; Tree_init1(dstree->tree, ndomsep) ; dstree->mapIV = IV_new() ; IV_init(dstree->mapIV, nvtx, NULL) ; IV_fill(dstree->mapIV, -1) ; return ; }
/* ----------------------------------------------------------------- compress a tree based on a map from old vertices to new vertices. the restriction on the map is that the set {u | map[u] = U} must be connected for all U. created -- 95nov15, cca modified -- 96jan04, cca bug fixed, N computed incorrectly modified -- 96jun23, cca in calling sequence, int map[] converted to IV *mapIV ----------------------------------------------------------------- */ Tree * Tree_compress ( Tree *tree, IV *mapIV ) { int n, N, u, U, v, V ; int *head, *link, *map ; Tree *tree2 ; /* --------------- check the input --------------- */ if ( tree == NULL || (n = tree->n) <= 0 || mapIV == NULL || n != IV_size(mapIV) || (map = IV_entries(mapIV)) == NULL ) { fprintf(stderr, "\n fatal error in Tree_compress(%p,%p)" "\n bad input\n", tree, mapIV) ; exit(-1) ; } /* ----------------------- initialize the new tree ----------------------- */ N = 1 + IV_max(mapIV) ; tree2 = Tree_new() ; Tree_init1(tree2, N) ; /* ----------------------------------------------------------- get the head/link construct to map old nodes into new nodes ----------------------------------------------------------- */ head = IVinit(N, -1) ; link = IVinit(n, -1) ; for ( v = 0 ; v < n ; v++ ) { if ( (V = map[v]) < 0 || V >= N ) { fprintf(stderr, "\n fatal error in Tree_compress(%p,%p)" "\n map[%d] = %d, N = %d\n", tree, map, v, V, N) ; exit(-1) ; } link[v] = head[V] ; head[V] = v ; } /* --------------------- fill the tree vectors --------------------- */ for ( U = 0 ; U < N ; U++ ) { for ( u = head[U] ; u != -1 ; u = link[u] ) { if ( (v = tree->par[u]) == -1 ) { tree2->par[U] = -1 ; break ; } else if ( (V = map[v]) != U ) { tree2->par[U] = V ; break ; } } } Tree_setFchSibRoot(tree2) ; /* ------------------------ free the working storage ------------------------ */ IVfree(head) ; IVfree(link) ; return(tree2) ; }