Blender  V2.59
heap_relax_snode.c
Go to the documentation of this file.
00001 
00004 /*
00005  * -- SuperLU routine (version 3.0) --
00006  * Univ. of California Berkeley, Xerox Palo Alto Research Center,
00007  * and Lawrence Berkeley National Lab.
00008  * October 15, 2003
00009  *
00010  */
00011 /*
00012   Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
00013  
00014   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
00015   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00016  
00017   Permission is hereby granted to use or copy this program for any
00018   purpose, provided the above notices are retained on all copies.
00019   Permission to modify the code and to distribute modified code is
00020   granted, provided the above notices are retained, and a notice that
00021   the code was modified is included with the above copyright notice.
00022 */
00023 
00024 #include "ssp_defs.h"
00025 
00026 void
00027 heap_relax_snode (
00028              const     int n,
00029              int       *et,           /* column elimination tree */
00030              const int relax_columns, /* max no of columns allowed in a
00031                                          relaxed snode */
00032              int       *descendants,  /* no of descendants of each node
00033                                          in the etree */
00034              int       *relax_end     /* last column in a supernode */
00035              )
00036 {
00037 /*
00038  * Purpose
00039  * =======
00040  *    relax_snode() - Identify the initial relaxed supernodes, assuming that 
00041  *    the matrix has been reordered according to the postorder of the etree.
00042  *
00043  */ 
00044     register int i, j, k, l, parent;
00045     register int snode_start;   /* beginning of a snode */
00046     int *et_save, *post, *inv_post, *iwork;
00047     int nsuper_et = 0, nsuper_et_post = 0;
00048 
00049     /* The etree may not be postordered, but is heap ordered. */
00050 
00051     iwork = (int*) intMalloc(3*n+2); 
00052     if ( !iwork ) ABORT("SUPERLU_MALLOC fails for iwork[]");
00053     inv_post = iwork + n+1;
00054     et_save = inv_post + n+1;
00055 
00056     /* Post order etree */
00057     post = (int *) TreePostorder(n, et);
00058     for (i = 0; i < n+1; ++i) inv_post[post[i]] = i;
00059 
00060     /* Renumber etree in postorder */
00061     for (i = 0; i < n; ++i) {
00062         iwork[post[i]] = post[et[i]];
00063         et_save[i] = et[i]; /* Save the original etree */
00064     }
00065     for (i = 0; i < n; ++i) et[i] = iwork[i];
00066 
00067     /* Compute the number of descendants of each node in the etree */
00068     ifill (relax_end, n, EMPTY);
00069     for (j = 0; j < n; j++) descendants[j] = 0;
00070     for (j = 0; j < n; j++) {
00071         parent = et[j];
00072         if ( parent != n )  /* not the dummy root */
00073             descendants[parent] += descendants[j] + 1;
00074     }
00075 
00076     /* Identify the relaxed supernodes by postorder traversal of the etree. */
00077     for (j = 0; j < n; ) { 
00078         parent = et[j];
00079         snode_start = j;
00080         while ( parent != n && descendants[parent] < relax_columns ) {
00081             j = parent;
00082             parent = et[j];
00083         }
00084         /* Found a supernode in postordered etree; j is the last column. */
00085         ++nsuper_et_post;
00086         k = n;
00087         for (i = snode_start; i <= j; ++i)
00088             k = SUPERLU_MIN(k, inv_post[i]);
00089         l = inv_post[j];
00090         if ( (l - k) == (j - snode_start) ) {
00091             /* It's also a supernode in the original etree */
00092             relax_end[k] = l;           /* Last column is recorded */
00093             ++nsuper_et;
00094         } else {
00095             for (i = snode_start; i <= j; ++i) {
00096                 l = inv_post[i];
00097                 if ( descendants[i] == 0 ) relax_end[l] = l;
00098             }
00099         }
00100         j++;
00101         /* Search for a new leaf */
00102         while ( descendants[j] != 0 && j < n ) j++;
00103     }
00104 
00105 #if ( PRNTlevel>=1 )
00106     printf(".. heap_snode_relax:\n"
00107            "\tNo of relaxed snodes in postordered etree:\t%d\n"
00108            "\tNo of relaxed snodes in original etree:\t%d\n",
00109            nsuper_et_post, nsuper_et);
00110 #endif
00111 
00112     /* Recover the original etree */
00113     for (i = 0; i < n; ++i) et[i] = et_save[i];
00114 
00115     SUPERLU_FREE(post);
00116     SUPERLU_FREE(iwork);
00117 }
00118 
00119