Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/umfpack/src/amd/amd_preprocess.c
3203 views
1
/* ========================================================================= */
2
/* === AMD_preprocess ====================================================== */
3
/* ========================================================================= */
4
5
/* ------------------------------------------------------------------------- */
6
/* AMD Version 1.1 (Jan. 21, 2004), Copyright (c) 2004 by Timothy A. Davis, */
7
/* Patrick R. Amestoy, and Iain S. Duff. See ../README for License. */
8
/* email: [email protected] CISE Department, Univ. of Florida. */
9
/* web: http://www.cise.ufl.edu/research/sparse/amd */
10
/* ------------------------------------------------------------------------- */
11
12
/* Sorts, removes duplicate entries, and transposes from the nonzero pattern of
13
* a column-form matrix A, to obtain the matrix R.
14
* See amd.h for a complete description of AMD_preprocess
15
*/
16
17
#include "amd_internal.h"
18
19
GLOBAL Int AMD_preprocess /* returns AMD_OK if input is OK, AMD_INVALID
20
* if the matrix is invalid, or AMD_OUT_OF_MEMORY
21
* if out of memory for the 2n workspace. */
22
(
23
Int n, /* input matrix: A is n-by-n */
24
const Int Ap [ ], /* size n+1 */
25
const Int Ai [ ], /* size nz = Ap [n] */
26
27
/* output matrix R: */
28
Int Rp [ ], /* size n+1 */
29
Int Ri [ ] /* size nz (or less, if duplicates present) */
30
)
31
{
32
/* --------------------------------------------------------------------- */
33
/* local variables */
34
/* --------------------------------------------------------------------- */
35
36
Int *Flag, *W ;
37
38
/* --------------------------------------------------------------------- */
39
/* check inputs (note: fewer restrictions than AMD_order) */
40
/* --------------------------------------------------------------------- */
41
42
if (!AMD_preprocess_valid (n, Ap, Ai) || !Ri || !Rp)
43
{
44
return (AMD_INVALID) ;
45
}
46
47
/* --------------------------------------------------------------------- */
48
/* allocate workspace */
49
/* --------------------------------------------------------------------- */
50
51
W = (Int *) ALLOCATE (MAX (n,1) * sizeof (Int)) ;
52
if (!W)
53
{
54
return (AMD_OUT_OF_MEMORY) ;
55
}
56
Flag = (Int *) ALLOCATE (MAX (n,1) * sizeof (Int)) ;
57
if (!Flag)
58
{
59
FREE (W) ;
60
return (AMD_OUT_OF_MEMORY) ;
61
}
62
63
/* --------------------------------------------------------------------- */
64
/* preprocess the matrix: sort, remove duplicates, and transpose */
65
/* --------------------------------------------------------------------- */
66
67
AMD_wpreprocess (n, Ap, Ai, Rp, Ri, W, Flag) ;
68
69
/* --------------------------------------------------------------------- */
70
/* free the workspace */
71
/* --------------------------------------------------------------------- */
72
73
FREE (W) ;
74
FREE (Flag) ;
75
return (AMD_OK) ;
76
}
77
78
79
/* ========================================================================= */
80
/* === AMD_wpreprocess ===================================================== */
81
/* ========================================================================= */
82
83
/* The AMD_wpreprocess routine is not user-callable. It does not check its
84
* input for errors or allocate workspace (that is done by the user-callable
85
* AMD_preprocess routine). It does handle the n=0 case. */
86
87
GLOBAL void AMD_wpreprocess
88
(
89
Int n, /* input matrix: A is n-by-n */
90
const Int Ap [ ], /* size n+1 */
91
const Int Ai [ ], /* size nz = Ap [n] */
92
93
/* output matrix R: */
94
Int Rp [ ], /* size n+1 */
95
Int Ri [ ], /* size nz (or less, if duplicates present) */
96
97
Int W [ ], /* workspace of size n */
98
Int Flag [ ] /* workspace of size n */
99
)
100
{
101
102
/* --------------------------------------------------------------------- */
103
/* local variables */
104
/* --------------------------------------------------------------------- */
105
106
Int i, j, p, p2 ;
107
108
/* --------------------------------------------------------------------- */
109
/* count the entries in each row of A (excluding duplicates) */
110
/* --------------------------------------------------------------------- */
111
112
for (i = 0 ; i < n ; i++)
113
{
114
W [i] = 0 ; /* # of nonzeros in row i (excl duplicates) */
115
Flag [i] = EMPTY ; /* Flag [i] = j if i appears in column j */
116
}
117
for (j = 0 ; j < n ; j++)
118
{
119
p2 = Ap [j+1] ;
120
for (p = Ap [j] ; p < p2 ; p++)
121
{
122
i = Ai [p] ;
123
if (Flag [i] != j)
124
{
125
/* row index i has not yet appeared in column j */
126
W [i]++ ; /* one more entry in row i */
127
Flag [i] = j ; /* flag row index i as appearing in col j*/
128
}
129
}
130
}
131
132
/* --------------------------------------------------------------------- */
133
/* compute the row pointers for R */
134
/* --------------------------------------------------------------------- */
135
136
Rp [0] = 0 ;
137
for (i = 0 ; i < n ; i++)
138
{
139
Rp [i+1] = Rp [i] + W [i] ;
140
}
141
for (i = 0 ; i < n ; i++)
142
{
143
W [i] = Rp [i] ;
144
Flag [i] = EMPTY ;
145
}
146
147
/* --------------------------------------------------------------------- */
148
/* construct the row form matrix R */
149
/* --------------------------------------------------------------------- */
150
151
/* R = row form of pattern of A */
152
for (j = 0 ; j < n ; j++)
153
{
154
p2 = Ap [j+1] ;
155
for (p = Ap [j] ; p < p2 ; p++)
156
{
157
i = Ai [p] ;
158
if (Flag [i] != j)
159
{
160
/* row index i has not yet appeared in column j */
161
Ri [W [i]++] = j ; /* put col j in row i */
162
Flag [i] = j ; /* flag row index i as appearing in col j*/
163
}
164
}
165
}
166
167
#ifndef NDEBUG
168
for (j = 0 ; j < n ; j++)
169
{
170
ASSERT (W [j] == Rp [j+1]) ;
171
}
172
ASSERT (AMD_valid (n, n, Rp, Ri)) ;
173
#endif
174
}
175
176
177
/* ========================================================================= */
178
/* === AMD_preprocess_valid ================================================ */
179
/* ========================================================================= */
180
181
/* Not user-callable. Checks a matrix and returns TRUE if it is valid as input
182
* to AMD_wpreprocess, FALSE otherwise. */
183
184
GLOBAL Int AMD_preprocess_valid
185
(
186
Int n,
187
const Int Ap [ ],
188
const Int Ai [ ]
189
)
190
{
191
Int i, j, p, nz ;
192
193
if (n < 0 || !Ai || !Ap)
194
{
195
return (FALSE) ;
196
}
197
nz = Ap [n] ;
198
if (Ap [0] != 0 || nz < 0)
199
{
200
/* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */
201
AMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ;
202
return (FALSE) ;
203
}
204
for (j = 0 ; j < n ; j++)
205
{
206
if (Ap [j] > Ap [j+1])
207
{
208
/* column pointers must be ascending */
209
AMD_DEBUG0 (("column "ID" pointer bad\n", j)) ;
210
return (FALSE) ;
211
}
212
}
213
for (p = 0 ; p < nz ; p++)
214
{
215
i = Ai [p] ;
216
AMD_DEBUG3 (("row: "ID"\n", i)) ;
217
if (i < 0 || i >= n)
218
{
219
/* row index out of range */
220
AMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i)) ;
221
return (FALSE) ;
222
}
223
}
224
return (TRUE) ;
225
}
226
227