Blender V2.61 - r43446
|
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