1
/* ========================================================================== */
2
/* === UMF_triplet ========================================================== */
3
/* ========================================================================== */
5
/* -------------------------------------------------------------------------- */
6
/* UMFPACK Version 4.1 (Apr. 30, 2003), Copyright (c) 2003 by Timothy A. */
7
/* Davis. All Rights Reserved. See ../README for License. */
8
/* email: davis@cise.ufl.edu CISE Department, Univ. of Florida. */
9
/* web: http://www.cise.ufl.edu/research/sparse/umfpack */
10
/* -------------------------------------------------------------------------- */
13
Not user callable. Converts triplet input to column-oriented form.
14
Duplicate entries may exist (they are summed in the output). The columns
15
of the column-oriented form are in sorted order. The input is not modified.
16
Returns 1 if OK, 0 if an error occured.
18
Compiled into four different routines for each version (di, dl, zi, zl),
19
for a total of 16 different routines.
22
#include "umf_internal.h"
23
#include "umf_malloc.h"
28
GLOBAL Int UMF_triplet_map_x
30
GLOBAL Int UMF_triplet_map_nox
34
GLOBAL Int UMF_triplet_nomap_x
36
GLOBAL Int UMF_triplet_nomap_nox
43
const Int Ti [ ], /* size nz */
44
const Int Tj [ ], /* size nz */
45
Int Ap [ ], /* size n_col + 1 */
46
Int Ai [ ], /* size nz */
47
Int Rp [ ], /* size n_row + 1 */
48
Int Rj [ ], /* size nz */
49
Int W [ ], /* size max (n_row, n_col) */
50
Int RowCount [ ] /* size n_row */
52
, const double Tx [ ] /* size nz */
53
, double Ax [ ] /* size nz */
54
, double Rx [ ] /* size nz */
56
, const double Tz [ ] /* size nz */
57
, double Az [ ] /* size nz */
58
, double Rz [ ] /* size nz */
62
, Int Map [ ] /* size nz */
63
, Int Map2 [ ] /* size nz */
68
/* ---------------------------------------------------------------------- */
70
/* ---------------------------------------------------------------------- */
72
Int i, j, k, p, cp, p1, p2, pdest, pj ;
77
/* ---------------------------------------------------------------------- */
78
/* count the entries in each row (also counting duplicates) */
79
/* ---------------------------------------------------------------------- */
81
/* use W as workspace for row counts (including duplicates) */
82
for (i = 0 ; i < n_row ; i++)
87
for (k = 0 ; k < nz ; k++)
91
if (i < 0 || i >= n_row || j < 0 || j >= n_col)
93
return (UMFPACK_ERROR_invalid_matrix) ;
97
DEBUG1 ((ID " triplet: "ID" "ID" ", k, i, j)) ;
101
ASSIGN (tt, Tx [k], Tz [k]) ;
109
/* ---------------------------------------------------------------------- */
110
/* compute the row pointers */
111
/* ---------------------------------------------------------------------- */
114
for (i = 0 ; i < n_row ; i++)
116
Rp [i+1] = Rp [i] + W [i] ;
120
/* W is now equal to the row pointers */
122
/* ---------------------------------------------------------------------- */
123
/* construct the row form */
124
/* ---------------------------------------------------------------------- */
126
for (k = 0 ; k < nz ; k++)
141
/* Rp stays the same, but W [i] is advanced to the start of row i+1 */
144
for (i = 0 ; i < n_row ; i++)
146
ASSERT (W [i] == Rp [i+1]) ;
149
for (k = 0 ; k < nz ; k++)
151
/* make sure that kth triplet is mapped correctly */
153
DEBUG1 (("First row map: Map ["ID"] = "ID"\n", k, p)) ;
156
ASSERT (j == Rj [p]) ;
157
ASSERT (Rp [i] <= p && p < Rp [i+1]) ;
162
/* ---------------------------------------------------------------------- */
163
/* sum up duplicates */
164
/* ---------------------------------------------------------------------- */
166
/* use W [j] to hold position in Ri/Rx/Rz of a_ij, for row i [ */
168
for (j = 0 ; j < n_col ; j++)
177
for (i = 0 ; i < n_row ; i++)
182
/* At this point, W [j] < p1 holds true for all columns j, */
183
/* because Ri/Rx/Rz is stored in row oriented order. */
187
for (j = 0 ; j < n_col ; j++)
189
ASSERT (W [j] < p1) ;
193
for (p = p1 ; p < p2 ; p++)
196
ASSERT (j >= 0 && j < n_col) ;
200
/* this column index, j, is already in row i, at position pj */
202
ASSERT (Rj [pj] == j) ;
218
/* also keep track in W[j] of position of a_ij for case above */
223
/* no need to move the entry if pdest is equal to p */
228
Rx [pdest] = Rx [p] ;
230
Rz [pdest] = Rz [p] ;
237
RowCount [i] = pdest - p1 ;
240
/* done using W for position of a_ij ] */
242
/* ---------------------------------------------------------------------- */
243
/* merge Map and Map2 into a single Map */
244
/* ---------------------------------------------------------------------- */
249
for (k = 0 ; k < nz ; k++)
251
Map [k] = Map2 [Map [k]] ;
257
/* no duplicates, so no need to recompute Map */
258
for (k = 0 ; k < nz ; k++)
260
ASSERT (Map2 [k] == k) ;
263
for (k = 0 ; k < nz ; k++)
265
/* make sure that kth triplet is mapped correctly */
267
DEBUG1 (("Second row map: Map ["ID"] = "ID"\n", k, p)) ;
270
ASSERT (j == Rj [p]) ;
271
ASSERT (Rp [i] <= p && p < Rp [i+1]) ;
276
/* now the kth triplet maps to p = Map [k], and thus to Rj/Rx [p] */
278
/* ---------------------------------------------------------------------- */
279
/* count the entries in each column */
280
/* ---------------------------------------------------------------------- */
282
/* [ use W as work space for column counts of A */
283
for (j = 0 ; j < n_col ; j++)
288
for (i = 0 ; i < n_row ; i++)
290
for (p = Rp [i] ; p < Rp [i] + RowCount [i] ; p++)
293
ASSERT (j >= 0 && j < n_col) ;
298
/* ---------------------------------------------------------------------- */
299
/* create the column pointers */
300
/* ---------------------------------------------------------------------- */
303
for (j = 0 ; j < n_col ; j++)
305
Ap [j+1] = Ap [j] + W [j] ;
307
/* done using W as workspace for column counts of A ] */
309
for (j = 0 ; j < n_col ; j++)
314
/* ---------------------------------------------------------------------- */
315
/* construct the column form */
316
/* ---------------------------------------------------------------------- */
318
for (i = 0 ; i < n_row ; i++)
320
for (p = Rp [i] ; p < Rp [i] + RowCount [i] ; p++)
336
/* ---------------------------------------------------------------------- */
337
/* merge Map and Map2 into a single Map */
338
/* ---------------------------------------------------------------------- */
341
for (k = 0 ; k < nz ; k++)
343
Map [k] = Map2 [Map [k]] ;
347
/* now the kth triplet maps to p = Map [k], and thus to Ai/Ax [p] */
350
for (j = 0 ; j < n_col ; j++)
352
ASSERT (W [j] == Ap [j+1]) ;
355
UMF_dump_col_matrix (
367
Ai, Ap, n_row, n_col, nz) ;
370
for (k = 0 ; k < nz ; k++)
372
/* make sure that kth triplet is mapped correctly */
374
DEBUG1 (("Col map: Map ["ID"] = "ID"\t", k, p)) ;
377
ASSERT (i == Ai [p]) ;
378
DEBUG1 ((" i "ID" j "ID" Ap[j] "ID" p "ID" Ap[j+1] "ID"\n",
379
i, j, Ap [j], p, Ap [j+1])) ;
380
ASSERT (Ap [j] <= p && p < Ap [j+1]) ;
385
return (UMFPACK_OK) ;