Blender V2.61 - r43446

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