~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to intern/opennl/superlu/sp_coletree.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*  Elimination tree computation and layout routines */
 
3
 
 
4
#include <stdio.h>
 
5
#include <stdlib.h>
 
6
#include "ssp_defs.h"
 
7
 
 
8
/* 
 
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.
 
12
 *  
 
13
 *  Calls are:
 
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.
 
19
 *
 
20
 *  This implementation uses path compression but not weighted union.
 
21
 *  See Tarjan's book for details.
 
22
 *  John Gilbert, CMI, 1987.
 
23
 *
 
24
 *  Implemented path-halving by XSL 07/05/95.
 
25
 */
 
26
 
 
27
static int      *pp;            /* parent array for sets */
 
28
 
 
29
static 
 
30
int *mxCallocInt(int n)
 
31
{
 
32
    register int i;
 
33
    int *buf;
 
34
 
 
35
    buf = (int *) SUPERLU_MALLOC( n * sizeof(int) );
 
36
    if ( !buf ) {
 
37
         ABORT("SUPERLU_MALLOC fails for buf in mxCallocInt()");
 
38
       }
 
39
    for (i = 0; i < n; i++) buf[i] = 0;
 
40
    return (buf);
 
41
}
 
42
      
 
43
static
 
44
void initialize_disjoint_sets (
 
45
        int n
 
46
        )
 
47
{
 
48
        pp = mxCallocInt(n);
 
49
}
 
50
 
 
51
 
 
52
static
 
53
int make_set (
 
54
        int i
 
55
        )
 
56
{
 
57
        pp[i] = i;
 
58
        return i;
 
59
}
 
60
 
 
61
 
 
62
static
 
63
int link (
 
64
        int s,
 
65
        int t
 
66
        )
 
67
{
 
68
        pp[s] = t;
 
69
        return t;
 
70
}
 
71
 
 
72
 
 
73
/* PATH HALVING */
 
74
static
 
75
int find (int i)
 
76
{
 
77
    register int p, gp;
 
78
    
 
79
    p = pp[i];
 
80
    gp = pp[p];
 
81
    while (gp != p) {
 
82
        pp[i] = gp;
 
83
        i = gp;
 
84
        p = pp[i];
 
85
        gp = pp[p];
 
86
    }
 
87
    return (p);
 
88
}
 
89
 
 
90
#if 0
 
91
/* PATH COMPRESSION */
 
92
static
 
93
int find (
 
94
        int i
 
95
        )
 
96
{
 
97
        if (pp[i] != i) 
 
98
                pp[i] = find (pp[i]);
 
99
        return pp[i];
 
100
}
 
101
#endif
 
102
 
 
103
static
 
104
void finalize_disjoint_sets (
 
105
        void
 
106
        )
 
107
{
 
108
        SUPERLU_FREE(pp);
 
109
}
 
110
 
 
111
 
 
112
/*
 
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.
 
116
 *
 
117
 *      Input:
 
118
 *        Sparse matrix A.  Numeric values are ignored, so any
 
119
 *        explicit zeros are treated as nonzero.
 
120
 *      Output:
 
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.
 
124
 *
 
125
 *      John R. Gilbert, Xerox, 10 Dec 1990
 
126
 *      Based on code by JRG dated 1987, 1988, and 1990.
 
127
 */
 
128
 
 
129
/*
 
130
 * Nonsymmetric elimination tree
 
131
 */
 
132
int
 
133
sp_coletree(
 
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 */
 
138
            )
 
139
{
 
140
        int     *root;                  /* root of subtee of etree      */
 
141
        int     *firstcol;              /* first nonzero col in each row*/
 
142
        int     rset, cset;             
 
143
        int     row, col;
 
144
        int     rroot;
 
145
        int     p;
 
146
 
 
147
        root = mxCallocInt (nc);
 
148
        initialize_disjoint_sets (nc);
 
149
 
 
150
        /* Compute firstcol[row] = first nonzero column in row */
 
151
 
 
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++) {
 
156
                        row = arow[p];
 
157
                        firstcol[row] = SUPERLU_MIN(firstcol[row], col);
 
158
                }
 
159
 
 
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. */
 
164
 
 
165
        for (col = 0; col < nc; col++) {
 
166
                cset = make_set (col);
 
167
                root[cset] = 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;
 
172
                        rset = find (row);
 
173
                        rroot = root[rset];
 
174
                        if (rroot != col) {
 
175
                                parent[rroot] = col;
 
176
                                cset = link (cset, rset);
 
177
                                root[cset] = col;
 
178
                        }
 
179
                }
 
180
        }
 
181
 
 
182
        SUPERLU_FREE (root);
 
183
        SUPERLU_FREE (firstcol);
 
184
        finalize_disjoint_sets ();
 
185
        return 0;
 
186
}
 
187
 
 
188
/*
 
189
 *  q = TreePostorder (n, p);
 
190
 *
 
191
 *      Postorder a tree.
 
192
 *      Input:
 
193
 *        p is a vector of parent pointers for a forest whose
 
194
 *        vertices are the integers 0 to n-1; p[root]==n.
 
195
 *      Output:
 
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.
 
198
 *
 
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. )
 
203
 *
 
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.
 
207
 *    
 
208
 *  Written by John Gilbert, Xerox, 10 Dec 1990.
 
209
 *  Based on code written by John Gilbert at CMI in 1987.
 
210
 */
 
211
 
 
212
static int      *first_kid, *next_kid;  /* Linked list of children.     */
 
213
static int      *post, postnum;
 
214
 
 
215
static
 
216
/*
 
217
 * Depth-first search from vertex v.
 
218
 */
 
219
void etdfs (
 
220
        int     v
 
221
        )
 
222
{
 
223
        int     w;
 
224
 
 
225
        for (w = first_kid[v]; w != -1; w = next_kid[w]) {
 
226
                etdfs (w);
 
227
        }
 
228
        /* post[postnum++] = v; in Matlab */
 
229
        post[v] = postnum++;    /* Modified by X.Li on 2/14/95 */
 
230
}
 
231
 
 
232
 
 
233
/*
 
234
 * Post order a tree
 
235
 */
 
236
int *TreePostorder(
 
237
        int n,
 
238
        int *parent
 
239
)
 
240
{
 
241
        int     v, dad;
 
242
 
 
243
        /* Allocate storage for working arrays and results      */
 
244
        first_kid =     mxCallocInt (n+1);
 
245
        next_kid  =     mxCallocInt (n+1);
 
246
        post      =     mxCallocInt (n+1);
 
247
 
 
248
        /* Set up structure describing children */
 
249
        for (v = 0; v <= n; first_kid[v++] = -1);
 
250
        for (v = n-1; v >= 0; v--) {
 
251
                dad = parent[v];
 
252
                next_kid[v] = first_kid[dad];
 
253
                first_kid[dad] = v;
 
254
        }
 
255
 
 
256
        /* Depth-first search from dummy root vertex #n */
 
257
        postnum = 0;
 
258
        etdfs (n);
 
259
 
 
260
        SUPERLU_FREE (first_kid);
 
261
        SUPERLU_FREE (next_kid);
 
262
        return post;
 
263
}
 
264
 
 
265
 
 
266
/*
 
267
 *      p = spsymetree (A);
 
268
 *
 
269
 *      Find the elimination tree for symmetric matrix A.
 
270
 *      This uses Liu's algorithm, and runs in time O(nz*log n).
 
271
 *
 
272
 *      Input:
 
273
 *        Square sparse matrix A.  No check is made for symmetry;
 
274
 *        elements below and on the diagonal are ignored.
 
275
 *        Numeric values are ignored, so any explicit zeros are 
 
276
 *        treated as nonzero.
 
277
 *      Output:
 
278
 *        Integer array of parents representing the etree, with n
 
279
 *        meaning a root of the elimination forest.
 
280
 *      Note:  
 
281
 *        This routine uses only the upper triangle, while sparse
 
282
 *        Cholesky (as in spchol.c) uses only the lower.  Matlab's
 
283
 *        dense Cholesky uses only the upper.  This routine could
 
284
 *        be modified to use the lower triangle either by transposing
 
285
 *        the matrix or by traversing it by rows with auxiliary
 
286
 *        pointer and link arrays.
 
287
 *
 
288
 *      John R. Gilbert, Xerox, 10 Dec 1990
 
289
 *      Based on code by JRG dated 1987, 1988, and 1990.
 
290
 *      Modified by X.S. Li, November 1999.
 
291
 */
 
292
 
 
293
/*
 
294
 * Symmetric elimination tree
 
295
 */
 
296
int
 
297
sp_symetree(
 
298
            int *acolst, int *acolend, /* column starts and ends past 1 */
 
299
            int *arow,            /* row indices of A */
 
300
            int n,                /* dimension of A */
 
301
            int *parent     /* parent in elim tree */
 
302
            )
 
303
{
 
304
        int     *root;              /* root of subtree of etree         */
 
305
        int     rset, cset;             
 
306
        int     row, col;
 
307
        int     rroot;
 
308
        int     p;
 
309
 
 
310
        root = mxCallocInt (n);
 
311
        initialize_disjoint_sets (n);
 
312
 
 
313
        for (col = 0; col < n; col++) {
 
314
                cset = make_set (col);
 
315
                root[cset] = col;
 
316
                parent[col] = n; /* Matlab */
 
317
                for (p = acolst[col]; p < acolend[col]; p++) {
 
318
                        row = arow[p];
 
319
                        if (row >= col) continue;
 
320
                        rset = find (row);
 
321
                        rroot = root[rset];
 
322
                        if (rroot != col) {
 
323
                                parent[rroot] = col;
 
324
                                cset = link (cset, rset);
 
325
                                root[cset] = col;
 
326
                        }
 
327
                }
 
328
        }
 
329
        SUPERLU_FREE (root);
 
330
        finalize_disjoint_sets ();
 
331
        return 0;
 
332
} /* SP_SYMETREE */