OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
tree.c
Go to the documentation of this file.
1/*****************************************************************************
2/
3/ SPACE SPArse Cholesky Elimination) Library: tree.c
4/
5/ author J"urgen Schulze, University of Paderborn
6/ created 09/15/99
7/
8/ This file contains functions dealing with elimination/front tree object
9/
10******************************************************************************
11
12Data type: struct elimtree
13 int nvtx; number of vertices in the tree
14 int nfronts; number of fronts in the tree
15 int root; root of the tree
16 int *ncolfactor; number of factor columns in front
17 int *ncolupdate; number of update columns for front
18 int *parent; parent in front tree
19 int *firstchild; first child in front tree
20 int *silbings; silbings in front tree
21 int *vtx2front; maps vertices to fronts
22Comments:
23 o Structure used to hold the elimination/front tree; the tree is used to
24 guide the symbolical and numerical factorization; a "node" in the tree
25 can be a single vertex (in the context of an elimination tree) or a group
26 of vertices (as for a front tree)
27 o NOTE: Also the ordering can be expressed in terms of front trees; the
28 permutation vector perm is then obtained by a post order traversal
29 of the tree (see method permFromElimTree below)
30Methods in lib/tree.c:
31- T = newElimTree(int nvtx, int nfronts);
32 o Initial: root = -1
33- void freeElimTree(elimtree_t *T);
34- void printElimTree(elimtree_t *T);
35- int firstPostorder(elimtree_t *T);
36 o returns the first front in a post order traversal of T
37- int firstPostorder2(elimtree_t *T, int root);
38 o returns the first front in a post order traversal of T[root]
39- int nextPostorder(elimtree_t *T, int J);
40 o returns the front that follows J in a post order traversal of T
41- int firstPreorder(elimtree_t *T);
42 o returns the first front in a pre order traversal of T
43- int nextPreorder(elimtree_t *T, int J);
44 o returns the front that follows J in a pre order traversal of T
45- T = setupElimTree(graph_t *G, int *perm, int *invp);
46 o constructs an elimination tree for G with permutation vectors perm,
47 invp; a union-find algorithm is used to set up the parent vector of T;
48 T->root and vectors T->firstchild, T->silbings are initialized by
49 calling initFchSilbRoot; vector T->ncolupdate is filled by calling
50 function setupCSSFromGraph (see below)
51- void initFchSilbRoot(elimtree_t *T);
52 o uses vector T->parent to initialize T->firstchild, T->silbings, T->root
53- void permFromElimTree(elimtree_t *T, int *perm);
54 o fills vectors perm, invp according to a post order traversal of T
55- T2 = expandElimTree(elimtree_t *T, int *vtxmap, int nvtxorg)
56 o creates and returns an elimtree object for the uncompressed graph;
57 the map from original vertices to compressed vertices is found in vector
58 vtxmap; the number of original vertices (i.e. the length of vector
59 vtxmap) is nvtxorg
60 o NOTE: the function only expands vector T->vtx2front and sets
61 T2->nvtx to nvtxorg; all other vectors are copied from T to T2, i.e.
62 the number of fronts and the tree structure are the same in T and T2
63- PTP = permuteElimTree(elimtree_t *T, int *perm);
64 o in T: vtx2front[u] points to front containing vertex u
65 in PTP: vtx2front[k] points to front containing column k = perm[u]
66 o NOTE: the function only permutes vector T->vtx2front; all other vectors
67 are copied from T to PTP, i.e. the number of fronts and the tree
68 structure are the same in T and PTP
69- T2 = fundamentalFronts(elimtree_t *T);
70 o compresses chains of fronts to a single front; once a map from original
71 fronts to compressed fronts is known, the compressed elimtree object T2
72 can be created by calling compressElimTree (see below)
73- T2 = mergeFronts(elimtree_t *T, int maxzeros);
74 o merges small subtrees together in one front; it returns an elimtree
75 object T2 where a front has either been merged with none or all of its
76 children; the maximal number of zero entries that is allowed to be
77 introduced when merging the fronts together is given by maxzeros
78- T2 = compressElimTree(elimtree_t *T, int *frontmap, int cnfronts);
79 o creates a new front tree using frontmap; vector frontmap maps the
80 original fronts of T to a smaller set of fronts; cnfronts is number of
81 new fronts (i.e. the maximal entry in frontmap)
82- int justifyFronts(elimtree_t *T);
83 o orders the children of a front so that the working storage in the
84 multifrontal algorithm is minimized; the function returns the amount
85 of extra working storage for the justified tree
86- int nWorkspace(elimtree_t *T);
87 o returns the size of the working storage in the multifrontal algorithm
88 (measured in terms of FLOATS, for BYTES multiply with sizeof(FLOAT))
89- int nFactorIndices(elimtree_t *T);
90 o returns the number of indices taken by the factor matrix represented by T
91- int nFactorEntries(elimtree_t *T);
92 o returns the number of entries taken by the factor matrix represented by T
93- FLOAT nFactorOps(elimtree_t *T);
94 o returns the number of operations required to compute the factor matrix
95 represented by T
96- void subtreeFactorOps(elimtree *T, FLOAT *ops)
97 o returns in ops[K] the number of operations required to factor the fronts
98 in tree T(K) (this includes front K)
99- FLOAT nTriangularOps(elimtree_t *T);
100 o returns the number of operations required to solve the triangular systems
101
102******************************************************************************/
103
104#include <space.h>
105
106
107/*****************************************************************************
108******************************************************************************/
111{ elimtree_t *T;
112
113 mymalloc(T, 1, elimtree_t);
114 mymalloc(T->ncolfactor, nfronts, PORD_INT);
115 mymalloc(T->ncolupdate, nfronts, PORD_INT);
116 mymalloc(T->parent, nfronts, PORD_INT);
117 mymalloc(T->firstchild, nfronts, PORD_INT);
118 mymalloc(T->silbings, nfronts, PORD_INT);
119 mymalloc(T->vtx2front, nvtx, PORD_INT);
120
121 T->nvtx = nvtx;
122 T->nfronts = nfronts;
123 T->root = -1;
124
125 return(T);
126}
127
128
129/*****************************************************************************
130******************************************************************************/
131void
133{
134 free(T->ncolfactor);
135 free(T->ncolupdate);
136 free(T->parent);
137 free(T->firstchild);
138 free(T->silbings);
139 free(T->vtx2front);
140 free(T);
141}
142
143
144/*****************************************************************************
145******************************************************************************/
146void
148{ PORD_INT *ncolfactor, *ncolupdate, *parent, *firstchild, *silbings, *vtx2front;
149 PORD_INT *first, *link, nvtx, nfronts, root, J, K, u, count, child;
150
151 nvtx = T->nvtx;
152 nfronts = T->nfronts;
153 root = T->root;
154 ncolfactor = T->ncolfactor;
155 ncolupdate = T->ncolupdate;
156 parent = T->parent;
157 firstchild = T->firstchild;
158 silbings = T->silbings;
159 vtx2front = T->vtx2front;
160
161 printf("#fronts %d, root %d\n", nfronts, root);
162
163 /* -----------------------------------------------------------
164 store the vertices/columns of a front in a bucket structure
165 ----------------------------------------------------------- */
166 mymalloc(first, nfronts, PORD_INT);
167 mymalloc(link, nvtx, PORD_INT);
168
169 for (J = 0; J < nfronts; J++)
170 first[J] = -1;
171 for (u = nvtx-1; u >= 0; u--)
172 { J = vtx2front[u];
173 link[u] = first[J];
174 first[J] = u;
175 }
176
177 /* -----------------------------------------------------------
178 print fronts according to a postorder traversal of the tree
179 ----------------------------------------------------------- */
180 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
181 { printf("--- front %d, ncolfactor %d, ncolupdate %d, parent %d\n",
182 K, ncolfactor[K], ncolupdate[K], parent[K]);
183 count = 0;
184 printf("children:\n");
185 for (child = firstchild[K]; child != -1; child = silbings[child])
186 { printf("%5d", child);
187 if ((++count % 16) == 0)
188 printf("\n");
189 }
190 if ((count % 16) != 0)
191 printf("\n");
192 count = 0;
193 printf("vertices mapped to front:\n");
194 for (u = first[K]; u != -1; u = link[u])
195 { printf("%5d", u);
196 if ((++count % 16) == 0)
197 printf("\n");
198 }
199 if ((count % 16) != 0)
200 printf("\n");
201 }
202
203 /* ----------------------
204 free memory and return
205 ---------------------- */
206 free(first); free(link);
207}
208
209
210/*****************************************************************************
211******************************************************************************/
214{ PORD_INT *firstchild, J;
215
216 firstchild = T->firstchild;
217
218 if ((J = T->root) != -1)
219 while (firstchild[J] != -1)
220 J = firstchild[J];
221 return(J);
222}
223
224
225/*****************************************************************************
226******************************************************************************/
229{ PORD_INT *firstchild, J;
230
231 firstchild = T->firstchild;
232
233 if ((J = root) != -1)
234 while (firstchild[J] != -1)
235 J = firstchild[J];
236 return(J);
237}
238
239
240/*****************************************************************************
241******************************************************************************/
244{ PORD_INT *parent, *firstchild, *silbings;
245
246 parent = T->parent;
247 firstchild = T->firstchild;
248 silbings = T->silbings;
249
250 if (silbings[J] != -1)
251 { J = silbings[J];
252 while (firstchild[J] != -1)
253 J = firstchild[J];
254 }
255 else J = parent[J];
256 return(J);
257}
258
259
260/*****************************************************************************
261******************************************************************************/
264{
265 return(T->root);
266}
267
268
269/*****************************************************************************
270******************************************************************************/
273{ PORD_INT *parent, *firstchild, *silbings;
274
275 parent = T->parent;
276 firstchild = T->firstchild;
277 silbings = T->silbings;
278
279 if (firstchild[J] != -1)
280 J = firstchild[J];
281 else
282 { while ((silbings[J] == -1) && (parent[J] != -1))
283 J = parent[J];
284 J = silbings[J];
285 }
286 return(J);
287}
288
289
290/*****************************************************************************
291******************************************************************************/
294{ elimtree_t *T;
295 css_t *css;
296 PORD_INT *xadj, *adjncy, *vwght, *ncolfactor, *ncolupdate, *parent;
297 PORD_INT *vtx2front, *realroot, *uf_father, *uf_size;
298 PORD_INT *xnzl, *nzlsub, *xnzlsub;
299 PORD_INT nvtx, front, front2, froot, f, r, u, v, i, istart, istop;
300 PORD_INT prevlen, len, h, hsub;
301
302 nvtx = G->nvtx;
303 xadj = G->xadj;
304 adjncy = G->adjncy;
305 vwght = G->vwght;
306
307 /* --------------------------
308 set up the working storage
309 -------------------------- */
310 mymalloc(realroot, nvtx, PORD_INT);
311 mymalloc(uf_father, nvtx, PORD_INT);
312 mymalloc(uf_size, nvtx, PORD_INT);
313
314 /* ------------------------------------------------
315 allocate storage for the elimination tree object
316 ------------------------------------------------ */
317 T = newElimTree(nvtx, nvtx);
318 ncolfactor = T->ncolfactor;
319 ncolupdate = T->ncolupdate;
320 parent = T->parent;
321 vtx2front = T->vtx2front;
322
323 /* -----------------------------
324 set up the parent vector of T
325 ----------------------------- */
326 for (front = 0; front < nvtx; front++)
327 { parent[front] = -1;
328 u = invp[front]; /* only vertex u belongs to this front */
329 uf_father[front] = front; /* front forms a set in union-find structure */
330 uf_size[front] = 1; /* the set consists of a single front */
331 realroot[front] = front;
332 froot = front;
333
334 /* run through the adjacency list of u */
335 istart = xadj[u];
336 istop = xadj[u+1];
337 for (i = istart; i < istop; i++)
338 { v = adjncy[i];
339 front2 = perm[v];
340 if (front2 < front)
341 { r = front2;
342
343 while (uf_father[r] != r) /* find root of front2 in union-find */
344 r = uf_father[r];
345 while (front2 != r) /* path compression */
346 { f = front2;
347 front2 = uf_father[front2];
348 uf_father[f] = r;
349 }
350
351 f = realroot[r]; /* merge union-find sets */
352 if ((parent[f] == -1) && (f != front))
353 { parent[f] = front;
354 if (uf_size[froot] < uf_size[r])
355 { uf_father[froot] = r;
356 uf_size[r] += uf_size[froot];
357 froot = r;
358 }
359 else
360 { uf_father[r] = froot;
361 uf_size[froot] += uf_size[r];
362 }
363 realroot[froot] = front;
364 }
365 }
366 }
367 }
368
369 /* ---------------------------------------------
370 set the vectors T->firstchild and T->silbings
371 --------------------------------------------- */
373
374 /* ----------------------------------------------------------
375 set the vectors T->vtx2front, T->ncolfactor, T->ncolupdate
376 ---------------------------------------------------------- */
377 css = setupCSSFromGraph(G, perm, invp);
378 xnzl = css->xnzl;
379 nzlsub = css->nzlsub;
380 xnzlsub = css->xnzlsub;
381
382 prevlen = 0;
383 for (front = 0; front < nvtx; front++)
384 { u = invp[front];
385 ncolfactor[front] = vwght[u];
386 ncolupdate[front] = 0;
387 vtx2front[u] = front;
388 len = xnzl[front+1] - xnzl[front];
389 if (prevlen - 1 == len)
390 ncolupdate[front] = ncolupdate[front-1] - vwght[u];
391 else
392 { h = xnzlsub[front] + 1;
393 for (i = 1; i < len; i++)
394 { hsub = nzlsub[h++];
395 v = invp[hsub];
396 ncolupdate[front] += vwght[v];
397 }
398 }
399 prevlen = len;
400 }
401
402 /* ----------------------
403 free memory and return
404 ---------------------- */
405 free(css);
406 free(realroot); free(uf_father); free(uf_size);
407 return(T);
408}
409
410
411/*****************************************************************************
412******************************************************************************/
413void
415{ PORD_INT *parent, *firstchild, *silbings, nfronts, J, pJ;
416
417 nfronts = T->nfronts;
418 parent = T->parent;
419 firstchild = T->firstchild;
420 silbings = T->silbings;
421
422 for (J = 0; J < nfronts; J++)
423 silbings[J] = firstchild[J] = -1;
424
425 for (J = nfronts-1; J >= 0; J--)
426 if ((pJ = parent[J]) != -1)
427 { silbings[J] = firstchild[pJ];
428 firstchild[pJ] = J;
429 }
430 else
431 { silbings[J] = T->root;
432 T->root = J;
433 }
434}
435
436
437/*****************************************************************************
438******************************************************************************/
439void
441{ PORD_INT *vtx2front, *first, *link;
442 PORD_INT nvtx, nfronts, K, u, count;
443
444 nvtx = T->nvtx;
445 nfronts = T->nfronts;
446 vtx2front = T->vtx2front;
447
448 /* -----------------------------------------------------------
449 store the vertices/columns of a front in a bucket structure
450 ----------------------------------------------------------- */
451 mymalloc(first, nfronts, PORD_INT);
452 mymalloc(link, nvtx, PORD_INT);
453
454 for (K = 0; K < nfronts; K++)
455 first[K] = -1;
456 for (u = nvtx-1; u >= 0; u--)
457 { K = vtx2front[u];
458 link[u] = first[K];
459 first[K] = u;
460 }
461
462 /* -----------------------------------------------------
463 postorder traversal of the elimination tree to obtain
464 the permutation vectors perm, invp
465 ----------------------------------------------------- */
466 count = 0;
467 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
468 for (u = first[K]; u != -1; u = link[u])
469 { perm[u] = count;
470 count++;
471 }
472
473 /* ----------------------
474 free memory and return
475 ---------------------- */
476 free(first); free(link);
477}
478
479
480/*****************************************************************************
481******************************************************************************/
484{ elimtree_t *PTP;
485 PORD_INT nvtx, nfronts, J, u;
486
487 nvtx = T->nvtx;
488 nfronts = T->nfronts;
489
490 /* --------------------------------------------------------------
491 allocate space for the new elimtree object and copy front data
492 the permuted tree has the same number of fronts/tree structure
493 -------------------------------------------------------------- */
494 PTP = newElimTree(nvtx, nfronts);
495 PTP->root = T->root;
496 for (J = 0; J < nfronts; J++)
497 { PTP->ncolfactor[J] = T->ncolfactor[J];
498 PTP->ncolupdate[J] = T->ncolupdate[J];
499 PTP->parent[J] = T->parent[J];
500 PTP->firstchild[J] = T->firstchild[J];
501 PTP->silbings[J] = T->silbings[J];
502 }
503
504 /* ---------------------------------------------------------------------
505 set up the new vtx2front vector; the trees only differ in this vector
506 --------------------------------------------------------------------- */
507 for (u = 0; u < nvtx; u++)
508 PTP->vtx2front[perm[u]] = T->vtx2front[u];
509
510 return(PTP);
511}
512
513
514/*****************************************************************************
515******************************************************************************/
518{ elimtree_t *T2;
519 PORD_INT *vtx2front, *vtx2front2;
520 PORD_INT nfronts, J, u;
521
522 nfronts = T->nfronts;
523
524 /* --------------------------------------------------------------
525 allocate space for the new elimtree object and copy front data
526 the expanded tree has the same number of fronts/tree structure
527 -------------------------------------------------------------- */
528 T2 = newElimTree(nvtxorg, nfronts);
529 T2->root = T->root;
530 for (J = 0; J < nfronts; J++)
531 { T2->ncolfactor[J] = T->ncolfactor[J];
532 T2->ncolupdate[J] = T->ncolupdate[J];
533 T2->parent[J] = T->parent[J];
534 T2->firstchild[J] = T->firstchild[J];
535 T2->silbings[J] = T->silbings[J];
536 }
537
538 /* ---------------------------------------------------------------------
539 set up the new vtx2front vector; the trees only differ in this vector
540 --------------------------------------------------------------------- */
541 vtx2front = T->vtx2front;
542 vtx2front2 = T2->vtx2front;
543 for (u = 0; u < nvtxorg; u++)
544 vtx2front2[u] = vtx2front[vtxmap[u]];
545
546 return(T2);
547}
548
549
550/*****************************************************************************
551******************************************************************************/
554{ elimtree_t *T2;
555 PORD_INT *ncolfactor, *ncolupdate, *parent, *firstchild, *silbings;
556 PORD_INT *frontmap, nfronts, cnfronts, J, child;
557
558 nfronts = T->nfronts;
559 ncolfactor = T->ncolfactor;
560 ncolupdate = T->ncolupdate;
561 parent = T->parent;
562 firstchild = T->firstchild;
563 silbings = T->silbings;
564
565 /* -------------------------
566 set up the working arrays
567 ------------------------- */
568 mymalloc(frontmap, nfronts, PORD_INT);
569
570 /* -----------------------------
571 search the fundamental fronts
572 ----------------------------- */
573 cnfronts = 0;
574 J = T->root;
575 while (J != -1)
576 { while (firstchild[J] != -1)
577 J = firstchild[J];
578 frontmap[J] = cnfronts++;
579 while ((silbings[J] == -1) && (parent[J] != -1))
580 { J = parent[J];
581 child = firstchild[J];
582 if ((silbings[child] != -1)
583 || (ncolupdate[child] != ncolfactor[J] + ncolupdate[J]))
584 frontmap[J] = cnfronts++;
585 else
586 frontmap[J] = frontmap[child];
587 }
588 J = silbings[J];
589 }
590
591 /* ------------------------------
592 construct new elimination tree
593 ------------------------------ */
594 T2 = compressElimTree(T, frontmap, cnfronts);
595
596 /* ----------------------
597 free memory and return
598 ---------------------- */
599 free(frontmap);
600 return(T2);
601}
602
603
604/*****************************************************************************
605******************************************************************************/
608{ elimtree_t *T2;
609 PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings;
610 PORD_INT *frontmap, *newncolfactor, *nzeros, *rep;
611 PORD_INT nfronts, cnfronts, K, ncolfrontK, J, Jall, cost;
612
613 nfronts = T->nfronts;
614 ncolfactor = T->ncolfactor;
615 ncolupdate = T->ncolupdate;
616 firstchild = T->firstchild;
617 silbings = T->silbings;
618
619 /* -------------------------
620 set up the working arrays
621 ------------------------- */
622 mymalloc(frontmap, nfronts, PORD_INT);
623 mymalloc(newncolfactor, nfronts, PORD_INT);
624 mymalloc(nzeros, nfronts, PORD_INT);
625 mymalloc(rep, nfronts, PORD_INT);
626 for (K = 0; K < nfronts; K++)
627 { newncolfactor[K] = ncolfactor[K];
628 nzeros[K] = 0;
629 rep[K] = K;
630 }
631
632 /* -----------------------------------------------------
633 perform a postorder traversal of the elimination tree
634 ----------------------------------------------------- */
635 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
636 if (firstchild[K] != -1)
637 { ncolfrontK = newncolfactor[K] + ncolupdate[K];
638 Jall = 0;
639 cost = 0;
640 for (J = firstchild[K]; J != -1; J = silbings[J])
641 { Jall += newncolfactor[J];
642 cost -= newncolfactor[J] * newncolfactor[J];
643 cost += 2*newncolfactor[J] * (ncolfrontK - ncolupdate[J]);
644 cost += 2*nzeros[J];
645 }
646 cost += Jall * Jall;
647 cost = cost / 2;
648 if (cost < maxzeros)
649 { for (J = firstchild[K]; J != -1; J = silbings[J])
650 { rep[J] = K;
651 newncolfactor[K] += newncolfactor[J];
652 }
653 nzeros[K] = cost;
654 }
655 }
656
657 /* ----------------------------------
658 construct frontmap from vector rep
659 ---------------------------------- */
660 cnfronts = 0;
661 for (K = 0; K < nfronts; K++)
662 if (rep[K] == K)
663 frontmap[K] = cnfronts++;
664 else
665 { for (J = K; rep[J] != J; J = rep[J]);
666 rep[K] = J;
667 }
668 for (K = 0; K < nfronts; K++)
669 if ((J = rep[K]) != K)
670 frontmap[K] = frontmap[J];
671
672 /* ------------------------------
673 construct new elimination tree
674 ------------------------------ */
675 T2 = compressElimTree(T, frontmap, cnfronts);
676
677 /* ----------------------
678 free memory and return
679 ---------------------- */
680 free(frontmap); free(newncolfactor);
681 free(nzeros); free(rep);
682 return(T2);
683}
684
685
686/*****************************************************************************
687******************************************************************************/
690{ elimtree_t *T2;
691 PORD_INT *ncolfactor, *ncolupdate, *parent, *vtx2front;
692 PORD_INT nvtx, nfronts, u, K, pK, newfront, pnewfront;
693
694 nvtx = T->nvtx;
695 nfronts = T->nfronts;
696 ncolfactor = T->ncolfactor;
697 ncolupdate = T->ncolupdate;
698 parent = T->parent;
699 vtx2front = T->vtx2front;
700
701 /* --------------------------------------------
702 allocate memory for the new elimtree T2
703 and init. ncolfactor, ncolupdate, and parent
704 -------------------------------------------- */
705 T2 = newElimTree(nvtx, cnfronts);
706 for (K = 0; K < cnfronts; K++)
707 { T2->ncolfactor[K] = T2->ncolupdate[K] = 0;
708 T2->parent[K] = -1;
709 }
710
711 /* --------------------------------------------------------------
712 set the new vectors T2->ncolfactor, T2->ncolupdate, T2->parent
713 -------------------------------------------------------------- */
714 for (K = 0; K < nfronts; K++)
715 { newfront = frontmap[K];
716 T2->ncolfactor[newfront] += ncolfactor[K];
717 if (((pK = parent[K]) != -1)
718 && ((pnewfront = frontmap[pK]) != newfront))
719 { T2->parent[newfront] = pnewfront;
720 T2->ncolupdate[newfront] = ncolupdate[K];
721 }
722 }
723
724 /* ---------------------------------------------------
725 set the new vectors T2->firstchild and T2->silbings
726 --------------------------------------------------- */
727 initFchSilbRoot(T2);
728
729 /* ------------------------------------
730 set the the new vector T2->vtx2front
731 ------------------------------------ */
732 for (u = 0; u < nvtx; u++)
733 T2->vtx2front[u] = frontmap[vtx2front[u]];
734 return(T2);
735}
736
737
738/*****************************************************************************
739******************************************************************************/
742{ PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings, *minWspace, *list;
743 PORD_INT nfronts, K, ncolfrontK, frontsizeK, wspace, child, nxtchild;
744 PORD_INT count, m, s, i;
745
746 nfronts = T->nfronts;
747 ncolfactor = T->ncolfactor;
748 ncolupdate = T->ncolupdate;
749 firstchild = T->firstchild;
750 silbings = T->silbings;
751
752 /* -------------------------
753 set up the working arrays
754 ------------------------- */
755 mymalloc(minWspace, nfronts, PORD_INT);
756 mymalloc(list, nfronts, PORD_INT);
757
758 /* ---------------------------------------------------------
759 postorder traversal of the elimination tree to obtain the
760 optimal justification of the children of each front
761 ---------------------------------------------------------- */
762 wspace = 0;
763 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
764 { ncolfrontK = ncolfactor[K] + ncolupdate[K];
765 frontsizeK = (ncolfrontK * (ncolfrontK + 1)) >> 1;
766
767 if ((child = firstchild[K]) == -1)
768 minWspace[K] = frontsizeK;
769 else
770 { count = 0;
771
772 /* sort children according to their minWspace value */
773 while (child != -1)
774 { list[count++] = child;
775 child = silbings[child];
776 }
777 insertUpIntsWithStaticIntKeys(count, list, minWspace);
778 firstchild[K] = -1;
779 for (i = 0; i < count; i++)
780 { child = list[i];
781 silbings[child] = firstchild[K];
782 firstchild[K] = child;
783 }
784
785 /* compute minWspace[K] */
786 child = firstchild[K];
787 nxtchild = silbings[child];
788 m = s = minWspace[child];
789 while (nxtchild != -1)
790 { s = s - minWspace[child]
791 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
792 + minWspace[nxtchild];
793 m = max(m, s);
794 child = nxtchild;
795 nxtchild = silbings[nxtchild];
796 }
797 s = s - minWspace[child]
798 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
799 + frontsizeK;
800 minWspace[K] = max(m, s);
801 }
802
803 wspace = max(wspace, minWspace[K]);
804 }
805
806 /* ----------------------
807 free memory and return
808 ---------------------- */
809 free(minWspace); free(list);
810 return(wspace);
811}
812
813
814/*****************************************************************************
815******************************************************************************/
818{ PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings, *minWspace;
819 PORD_INT nfronts, K, ncolfrontK, frontsizeK, wspace, child, nxtchild, m, s;
820
821 nfronts = T->nfronts;
822 ncolfactor = T->ncolfactor;
823 ncolupdate = T->ncolupdate;
824 firstchild = T->firstchild;
825 silbings = T->silbings;
826
827 /* -------------------------
828 set up the working arrays
829 ------------------------- */
830 mymalloc(minWspace, nfronts, PORD_INT);
831
832 /* -------------------------------------------
833 postorder traversal of the elimination tree
834 ------------------------------------------- */
835 wspace = 0;
836 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
837 { ncolfrontK = ncolfactor[K] + ncolupdate[K];
838 frontsizeK = (ncolfrontK * (ncolfrontK + 1)) >> 1;
839
840 if ((child = firstchild[K]) == -1)
841 minWspace[K] = frontsizeK;
842 else
843 { child = firstchild[K];
844 nxtchild = silbings[child];
845 m = s = minWspace[child];
846 while (nxtchild != -1)
847 { s = s - minWspace[child]
848 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
849 + minWspace[nxtchild];
850 m = max(m, s);
851 child = nxtchild;
852 nxtchild = silbings[nxtchild];
853 }
854 s = s - minWspace[child]
855 + ((ncolupdate[child] * (ncolupdate[child] + 1)) >> 1)
856 + frontsizeK;
857 minWspace[K] = max(m, s);
858 }
859
860 wspace = max(wspace, minWspace[K]);
861 }
862
863 /* ----------------------
864 free memory and return
865 ---------------------- */
866 free(minWspace);
867 return(wspace);
868}
869
870
871/*****************************************************************************
872******************************************************************************/
875{ PORD_INT *ncolfactor, *ncolupdate;
876 PORD_INT nfronts, ind, K;
877
878 nfronts = T->nfronts;
879 ncolfactor = T->ncolfactor;
880 ncolupdate = T->ncolupdate;
881
882 ind = 0;
883 for (K = 0; K < nfronts; K++)
884 ind += (ncolfactor[K] + ncolupdate[K]);
885 return(ind);
886}
887
888
889/*****************************************************************************
890******************************************************************************/
893{ PORD_INT *ncolfactor, *ncolupdate;
894 PORD_INT ent, tri, rec, K;
895
896 ncolfactor = T->ncolfactor;
897 ncolupdate = T->ncolupdate;
898
899 ent = 0;
900 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
901 { tri = ncolfactor[K];
902 rec = ncolupdate[K];
903 ent += (tri * (tri+1)) / 2;
904 ent += (tri * rec);
905 }
906 return(ent);
907}
908
909
910/*****************************************************************************
911******************************************************************************/
912FLOAT
914{ PORD_INT *ncolfactor, *ncolupdate;
915 FLOAT ops, tri, rec;
916 PORD_INT K;
917
918 ncolfactor = T->ncolfactor;
919 ncolupdate = T->ncolupdate;
920
921 ops = 0.0;
922 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
923 { tri = ncolfactor[K];
924 rec = ncolupdate[K];
925 ops += (tri*tri*tri) / 3.0 + (tri*tri) / 2.0 - (5*tri) / 6.0;
926 ops += (tri*tri*rec) + (rec*(rec+1)*tri);
927 }
928 return(ops);
929}
930
931
932/*****************************************************************************
933******************************************************************************/
934void
936{ PORD_INT *ncolfactor, *ncolupdate;
937 FLOAT tri, rec;
938 PORD_INT J, K;
939
940 ncolfactor = T->ncolfactor;
941 ncolupdate = T->ncolupdate;
942
943 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
944 { tri = ncolfactor[K];
945 rec = ncolupdate[K];
946 ops[K] = (tri*tri*tri) / 3.0 + (tri*tri) / 2.0 - (5*tri) / 6.0;
947 ops[K] += (tri*tri*rec) + (rec*(rec+1)*tri);
948 for (J = T->firstchild[K]; J != -1; J = T->silbings[J])
949 ops[K] += ops[J];
950 }
951}
952
953
954/*****************************************************************************
955******************************************************************************/
956FLOAT
958{ PORD_INT *ncolfactor, *ncolupdate;
959 FLOAT ops, tri, rec;
960 PORD_INT K;
961
962 ncolfactor = T->ncolfactor;
963 ncolupdate = T->ncolupdate;
964
965 ops = 0.0;
966 for (K = firstPostorder(T); K != -1; K = nextPostorder(T, K))
967 { tri = ncolfactor[K];
968 rec = ncolupdate[K];
969 ops += (tri*tri) + 2.0*tri*rec; /* forward ops */
970 ops += (tri*tri) + 2.0*tri*rec; /* backward ops */
971 }
972 return(ops);
973}
974
#define mymalloc(ptr, nr, type)
Definition macros.h:23
#define max(a, b)
Definition macros.h:21
css_t * setupCSSFromGraph(graph_t *, PORD_INT *, PORD_INT *)
Definition symbfac.c:90
void insertUpIntsWithStaticIntKeys(PORD_INT, PORD_INT *, PORD_INT *)
Definition sort.c:39
char root[ROOTLEN]
Definition rad2rad_c.c:124
PORD_INT * xnzlsub
Definition types.h:210
PORD_INT * nzlsub
Definition types.h:209
PORD_INT * xnzl
Definition types.h:208
PORD_INT nfronts
Definition types.h:152
PORD_INT * silbings
Definition types.h:158
PORD_INT * parent
Definition types.h:156
PORD_INT * firstchild
Definition types.h:157
PORD_INT * ncolfactor
Definition types.h:154
PORD_INT root
Definition types.h:153
PORD_INT nvtx
Definition types.h:151
PORD_INT * vtx2front
Definition types.h:159
PORD_INT * ncolupdate
Definition types.h:155
PORD_INT * xadj
Definition types.h:35
PORD_INT nvtx
Definition types.h:31
PORD_INT * vwght
Definition types.h:37
PORD_INT * adjncy
Definition types.h:36
PORD_INT firstPostorder2(elimtree_t *T, PORD_INT root)
Definition tree.c:228
void printElimTree(elimtree_t *T)
Definition tree.c:147
elimtree_t * setupElimTree(graph_t *G, PORD_INT *perm, PORD_INT *invp)
Definition tree.c:293
elimtree_t * fundamentalFronts(elimtree_t *T)
Definition tree.c:553
PORD_INT justifyFronts(elimtree_t *T)
Definition tree.c:741
elimtree_t * mergeFronts(elimtree_t *T, PORD_INT maxzeros)
Definition tree.c:607
void subtreeFactorOps(elimtree_t *T, FLOAT *ops)
Definition tree.c:935
PORD_INT nFactorIndices(elimtree_t *T)
Definition tree.c:874
elimtree_t * expandElimTree(elimtree_t *T, PORD_INT *vtxmap, PORD_INT nvtxorg)
Definition tree.c:517
void permFromElimTree(elimtree_t *T, PORD_INT *perm)
Definition tree.c:440
elimtree_t * newElimTree(PORD_INT nvtx, PORD_INT nfronts)
Definition tree.c:110
FLOAT nFactorOps(elimtree_t *T)
Definition tree.c:913
PORD_INT firstPostorder(elimtree_t *T)
Definition tree.c:213
FLOAT nTriangularOps(elimtree_t *T)
Definition tree.c:957
elimtree_t * compressElimTree(elimtree_t *T, PORD_INT *frontmap, PORD_INT cnfronts)
Definition tree.c:689
PORD_INT nWorkspace(elimtree_t *T)
Definition tree.c:817
void freeElimTree(elimtree_t *T)
Definition tree.c:132
void initFchSilbRoot(elimtree_t *T)
Definition tree.c:414
elimtree_t * permuteElimTree(elimtree_t *T, PORD_INT *perm)
Definition tree.c:483
PORD_INT nFactorEntries(elimtree_t *T)
Definition tree.c:892
PORD_INT firstPreorder(elimtree_t *T)
Definition tree.c:263
PORD_INT nextPostorder(elimtree_t *T, PORD_INT J)
Definition tree.c:243
PORD_INT nextPreorder(elimtree_t *T, PORD_INT J)
Definition tree.c:272
double FLOAT
Definition types.h:23
#define PORD_INT
Definition types.h:20
struct _css css_t
struct _graph graph_t
struct _elimtree elimtree_t