5164
|
1 /* ========================================================================== */ |
|
2 /* === UMFPACK_triplet_to_col =============================================== */ |
|
3 /* ========================================================================== */ |
|
4 |
|
5 /* -------------------------------------------------------------------------- */ |
|
6 /* UMFPACK Version 4.4, Copyright (c) 2005 by Timothy A. Davis. CISE Dept, */ |
|
7 /* Univ. of Florida. All Rights Reserved. See ../Doc/License for License. */ |
|
8 /* web: http://www.cise.ufl.edu/research/sparse/umfpack */ |
|
9 /* -------------------------------------------------------------------------- */ |
|
10 |
|
11 /* |
|
12 User callable. Converts triplet input to column-oriented form. Duplicate |
|
13 entries may exist (they are summed in the output). The columns of the |
|
14 column-oriented form are in sorted order. The input is not modified. |
|
15 Returns 1 if OK, 0 if an error occurred. See umfpack_triplet_to_col.h for |
|
16 details. |
|
17 |
|
18 If Map is present (a non-NULL pointer to an Int array of size nz), then on |
|
19 output it holds the position of the triplets in the column-form matrix. |
|
20 That is, suppose p = Map [k], and the k-th triplet is i=Ti[k], j=Tj[k], and |
|
21 aij=Tx[k]. Then i=Ai[p], and aij will have been summed into Ax[p]. Also, |
|
22 Ap[j] <= p < Ap[j+1]. The Map array is not computed if it is (Int *) NULL. |
|
23 |
|
24 Dynamic memory usage: |
|
25 |
|
26 If numerical values are present, then one (two for complex version) |
|
27 workspace of size (nz+1)*sizeof(double) is allocated via UMF_malloc. |
|
28 Next, 4 calls to UMF_malloc are made to obtain workspace of size |
|
29 ((nz+1) + (n_row+1) + n_row + MAX (n_row,n_col)) * sizeof(Int). All of |
|
30 this workspace (4 to 6 objects) are free'd via UMF_free on return. |
|
31 |
|
32 For the complex version, additional space is allocated. |
|
33 |
|
34 An extra array of size nz*sizeof(Int) is allocated if Map is present. |
|
35 */ |
|
36 |
|
37 #include "umf_internal.h" |
|
38 #include "umf_malloc.h" |
|
39 #include "umf_free.h" |
|
40 #include "umf_triplet.h" |
|
41 |
|
42 #ifndef NDEBUG |
|
43 PRIVATE Int init_count ; |
|
44 #endif |
|
45 |
|
46 /* ========================================================================== */ |
|
47 |
|
48 GLOBAL Int UMFPACK_triplet_to_col |
|
49 ( |
|
50 Int n_row, |
|
51 Int n_col, |
|
52 Int nz, |
|
53 const Int Ti [ ], /* size nz */ |
|
54 const Int Tj [ ], /* size nz */ |
|
55 const double Tx [ ], /* size nz */ |
|
56 #ifdef COMPLEX |
|
57 const double Tz [ ], /* size nz */ |
|
58 #endif |
|
59 Int Ap [ ], /* size n_col + 1 */ |
|
60 Int Ai [ ], /* size nz */ |
|
61 double Ax [ ] /* size nz */ |
|
62 #ifdef COMPLEX |
|
63 , double Az [ ] /* size nz */ |
|
64 #endif |
|
65 , Int Map [ ] /* size nz */ |
|
66 ) |
|
67 { |
|
68 |
|
69 /* ---------------------------------------------------------------------- */ |
|
70 /* local variables */ |
|
71 /* ---------------------------------------------------------------------- */ |
|
72 |
|
73 Int *RowCount, *Rp, *Rj, *W, nn, do_values, do_map, *Map2, status ; |
|
74 double *Rx ; |
|
75 #ifdef COMPLEX |
|
76 double *Rz ; |
|
77 Int split ; |
|
78 #endif |
|
79 |
|
80 #ifndef NDEBUG |
|
81 UMF_dump_start ( ) ; |
|
82 init_count = UMF_malloc_count ; |
|
83 #endif |
|
84 |
|
85 /* ---------------------------------------------------------------------- */ |
|
86 /* check inputs */ |
|
87 /* ---------------------------------------------------------------------- */ |
|
88 |
|
89 if (!Ai || !Ap || !Ti || !Tj) |
|
90 { |
|
91 return (UMFPACK_ERROR_argument_missing) ; |
|
92 } |
|
93 |
|
94 if (n_row <= 0 || n_col <= 0) /* must be > 0 */ |
|
95 { |
|
96 return (UMFPACK_ERROR_n_nonpositive) ; |
|
97 } |
|
98 |
|
99 if (nz < 0) /* nz must be >= 0 (singular matrices are OK) */ |
|
100 { |
|
101 return (UMFPACK_ERROR_invalid_matrix) ; |
|
102 } |
|
103 |
|
104 nn = MAX (n_row, n_col) ; |
|
105 |
|
106 /* ---------------------------------------------------------------------- */ |
|
107 /* allocate workspace */ |
|
108 /* ---------------------------------------------------------------------- */ |
|
109 |
|
110 Rx = (double *) NULL ; |
|
111 |
|
112 do_values = Ax && Tx ; |
|
113 |
|
114 if (do_values) |
|
115 { |
|
116 #ifdef COMPLEX |
|
117 Rx = (double *) UMF_malloc (2*nz+2, sizeof (double)) ; |
|
118 split = SPLIT (Tz) && SPLIT (Az) ; |
|
119 if (split) |
|
120 { |
|
121 Rz = Rx + nz ; |
|
122 } |
|
123 else |
|
124 { |
|
125 Rz = (double *) NULL ; |
|
126 } |
|
127 #else |
|
128 Rx = (double *) UMF_malloc (nz+1, sizeof (double)) ; |
|
129 #endif |
|
130 if (!Rx) |
|
131 { |
|
132 DEBUGm4 (("out of memory: triplet work \n")) ; |
|
133 ASSERT (UMF_malloc_count == init_count) ; |
|
134 return (UMFPACK_ERROR_out_of_memory) ; |
|
135 } |
|
136 } |
|
137 |
|
138 do_map = (Map != (Int *) NULL) ; |
|
139 Map2 = (Int *) NULL ; |
|
140 if (do_map) |
|
141 { |
|
142 DEBUG0 (("Do map:\n")) ; |
|
143 Map2 = (Int *) UMF_malloc (nz+1, sizeof (Int)) ; |
|
144 if (!Map2) |
|
145 { |
|
146 DEBUGm4 (("out of memory: triplet map\n")) ; |
|
147 (void) UMF_free ((void *) Rx) ; |
|
148 ASSERT (UMF_malloc_count == init_count) ; |
|
149 return (UMFPACK_ERROR_out_of_memory) ; |
|
150 } |
|
151 } |
|
152 |
|
153 Rj = (Int *) UMF_malloc (nz+1, sizeof (Int)) ; |
|
154 Rp = (Int *) UMF_malloc (n_row+1, sizeof (Int)) ; |
|
155 RowCount = (Int *) UMF_malloc (n_row, sizeof (Int)) ; |
|
156 W = (Int *) UMF_malloc (nn, sizeof (Int)) ; |
|
157 if (!Rj || !Rp || !RowCount || !W) |
|
158 { |
|
159 DEBUGm4 (("out of memory: triplet work (int)\n")) ; |
|
160 (void) UMF_free ((void *) Rx) ; |
|
161 (void) UMF_free ((void *) Map2) ; |
|
162 (void) UMF_free ((void *) Rp) ; |
|
163 (void) UMF_free ((void *) Rj) ; |
|
164 (void) UMF_free ((void *) RowCount) ; |
|
165 (void) UMF_free ((void *) W) ; |
|
166 ASSERT (UMF_malloc_count == init_count) ; |
|
167 return (UMFPACK_ERROR_out_of_memory) ; |
|
168 } |
|
169 |
|
170 ASSERT (UMF_malloc_count == init_count + 4 + |
|
171 (Rx != (double *) NULL) + do_map) ; |
|
172 |
|
173 /* ---------------------------------------------------------------------- */ |
|
174 /* convert from triplet to column form */ |
|
175 /* ---------------------------------------------------------------------- */ |
|
176 |
|
177 if (do_map) |
|
178 { |
|
179 if (do_values) |
|
180 { |
|
181 status = UMF_triplet_map_x (n_row, n_col, nz, Ti, Tj, Ap, Ai, Rp, |
|
182 Rj, W, RowCount, Tx, Ax, Rx |
|
183 #ifdef COMPLEX |
|
184 , Tz, Az, Rz |
|
185 #endif |
|
186 , Map, Map2) ; |
|
187 } |
|
188 else |
|
189 { |
|
190 status = UMF_triplet_map_nox (n_row, n_col, nz, Ti, Tj, Ap, Ai, Rp, |
|
191 Rj, W, RowCount, Map, Map2) ; |
|
192 } |
|
193 } |
|
194 else |
|
195 { |
|
196 if (do_values) |
|
197 { |
|
198 status = UMF_triplet_nomap_x (n_row, n_col, nz, Ti, Tj, Ap, Ai, Rp, |
|
199 Rj, W, RowCount , Tx, Ax, Rx |
|
200 #ifdef COMPLEX |
|
201 , Tz, Az, Rz |
|
202 #endif |
|
203 ) ; |
|
204 } |
|
205 else |
|
206 { |
|
207 status = UMF_triplet_nomap_nox (n_row, n_col, nz, Ti, Tj, Ap, Ai, |
|
208 Rp, Rj, W, RowCount) ; |
|
209 } |
|
210 } |
|
211 |
|
212 /* ---------------------------------------------------------------------- */ |
|
213 /* free the workspace */ |
|
214 /* ---------------------------------------------------------------------- */ |
|
215 |
|
216 (void) UMF_free ((void *) Rx) ; |
|
217 (void) UMF_free ((void *) Map2) ; |
|
218 (void) UMF_free ((void *) Rp) ; |
|
219 (void) UMF_free ((void *) Rj) ; |
|
220 (void) UMF_free ((void *) RowCount) ; |
|
221 (void) UMF_free ((void *) W) ; |
|
222 ASSERT (UMF_malloc_count == init_count) ; |
|
223 |
|
224 return (status) ; |
|
225 } |