2
/* Elimination tree computation and layout routines */
9
* Implementation of disjoint set union routines.
10
* Elements are integers in 0..n-1, and the
11
* names of the sets themselves are of type int.
14
* initialize_disjoint_sets (n) initial call.
15
* s = make_set (i) returns a set containing only i.
16
* s = link (t, u) returns s = t union u, destroying t and u.
17
* s = find (i) return name of set containing i.
18
* finalize_disjoint_sets final call.
20
* This implementation uses path compression but not weighted union.
21
* See Tarjan's book for details.
22
* John Gilbert, CMI, 1987.
24
* Implemented path-halving by XL 7/5/95.
27
static int *pp; /* parent array for sets */
30
int *mxCallocInt(int n)
35
buf = (int *) SUPERLU_MALLOC( n * sizeof(int) );
37
ABORT("SUPERLU_MALLOC fails for buf in mxCallocInt()");
39
for (i = 0; i < n; i++) buf[i] = 0;
44
void initialize_disjoint_sets (
91
/* PATH COMPRESSION */
104
void finalize_disjoint_sets (
113
* Find the elimination tree for A'*A.
114
* This uses something similar to Liu's algorithm.
115
* It runs in time O(nz(A)*log n) and does not form A'*A.
118
* Sparse matrix A. Numeric values are ignored, so any
119
* explicit zeros are treated as nonzero.
121
* Integer array of parents representing the elimination
122
* tree of the symbolic product A'*A. Each vertex is a
123
* column of A, and nc means a root of the elimination forest.
125
* John R. Gilbert, Xerox, 10 Dec 1990
126
* Based on code by JRG dated 1987, 1988, and 1990.
130
* Nonsymmetric elimination tree
134
int *acolst, int *acolend, /* column start and end past 1 */
135
int *arow, /* row indices of A */
136
int nr, int nc, /* dimension of A */
137
int *parent /* parent in elim tree */
140
int *root; /* root of subtee of etree */
141
int *firstcol; /* first nonzero col in each row*/
147
root = mxCallocInt (nc);
148
initialize_disjoint_sets (nc);
150
/* Compute firstcol[row] = first nonzero column in row */
152
firstcol = mxCallocInt (nr);
153
for (row = 0; row < nr; firstcol[row++] = nc);
154
for (col = 0; col < nc; col++)
155
for (p = acolst[col]; p < acolend[col]; p++) {
157
firstcol[row] = SUPERLU_MIN(firstcol[row], col);
160
/* Compute etree by Liu's algorithm for symmetric matrices,
161
except use (firstcol[r],c) in place of an edge (r,c) of A.
162
Thus each row clique in A'*A is replaced by a star
163
centered at its first vertex, which has the same fill. */
165
for (col = 0; col < nc; col++) {
166
cset = make_set (col);
168
parent[col] = nc; /* Matlab */
169
for (p = acolst[col]; p < acolend[col]; p++) {
170
row = firstcol[arow[p]];
171
if (row >= col) continue;
176
cset = link (cset, rset);
183
SUPERLU_FREE (firstcol);
184
finalize_disjoint_sets ();
189
* q = TreePostorder (n, p);
193
* p is a vector of parent pointers for a forest whose
194
* vertices are the integers 0 to n-1; p[root]==n.
196
* q is a vector indexed by 0..n-1 such that q[i] is the
197
* i-th vertex in a postorder numbering of the tree.
199
* ( 2/7/95 modified by X.Li:
200
* q is a vector indexed by 0:n-1 such that vertex i is the
201
* q[i]-th vertex in a postorder numbering of the tree.
202
* That is, this is the inverse of the previous q. )
204
* In the child structure, lower-numbered children are represented
205
* first, so that a tree which is already numbered in postorder
206
* will not have its order changed.
208
* Written by John Gilbert, Xerox, 10 Dec 1990.
209
* Based on code written by John Gilbert at CMI in 1987.
212
static int *first_kid, *next_kid; /* Linked list of children. */
213
static int *post, postnum;
217
static int *parent_s;
221
* Depth-first search from vertex v.
230
/* traverse non-branching portion of the tree */
231
while (c = first_kid[w], c != -1 && next_kid[c] == -1) {
234
/* call all branches */
235
for (; c != -1; c = next_kid[c]) {
238
/* output non-branching portion in reverse order */
252
for (w = first_kid[v]; w != -1; w = next_kid[w]) {
255
/* post[postnum++] = v; in Matlab */
256
post[v] = postnum++; /* Modified by X.Li on 2/14/95 */
270
/* Allocate storage for working arrays and results */
271
first_kid = mxCallocInt (n+1);
272
next_kid = mxCallocInt (n+1);
273
post = mxCallocInt (n+1);
275
/* Set up structure describing children */
276
for (v = 0; v <= n; first_kid[v++] = -1);
277
for (v = n-1; v >= 0; v--) {
279
next_kid[v] = first_kid[dad];
283
/* Depth-first search from dummy root vertex #n */
292
SUPERLU_FREE (first_kid);
293
SUPERLU_FREE (next_kid);