1 /* support.c */
2
3 #include "../../InpMtx.h"
4
5 /*--------------------------------------------------------------------*/
6 /*
7 --------------------------------------------------------------------
8 purpose --
9 this method is used to determine the support of this matrix
10 for a matrix-vector multiply y[] = A * x[] when A is a
11 nonsymmetric matrix.
12
13 rowsupIV -- filled with row indices of y[] which will be updated.
14 colsupIV -- filled with row indices of x[] which will be used.
15
16 created -- 98aug01, cca
17 --------------------------------------------------------------------
18 */
19 void
InpMtx_supportNonsym(InpMtx * A,IV * rowsupIV,IV * colsupIV)20 InpMtx_supportNonsym (
21 InpMtx *A,
22 IV *rowsupIV,
23 IV *colsupIV
24 ) {
25 char *colmark, *rowmark ;
26 int chev, col, colcount, ii, loc, maxcol, maxrow, nent, off, row,
27 rowcount ;
28 int *colsup, *ivec1, *ivec2, *rowsup ;
29 /*
30 ---------------
31 check the input
32 ---------------
33 */
34 if ( A == NULL || rowsupIV == NULL || colsupIV == NULL ) {
35 fprintf(stderr, "\n fatal error in InpMtx_supportNonsym(%p,%p,%p)"
36 "\n bad input\n", A, rowsupIV, colsupIV) ;
37 exit(-1) ;
38 }
39 if ( !INPMTX_IS_BY_ROWS(A)
40 && !INPMTX_IS_BY_COLUMNS(A)
41 && !INPMTX_IS_BY_CHEVRONS(A) ) {
42 fprintf(stderr, "\n fatal error in InpMtx_supportNonsym(%p,%p,%p)"
43 "\n coordinate type\n", A, rowsupIV, colsupIV) ;
44 exit(-1) ;
45 }
46 ivec1 = InpMtx_ivec1(A) ;
47 ivec2 = InpMtx_ivec2(A) ;
48 nent = A->nent ;
49 /*
50 -----------------------------------------------------------------
51 (1) determine the maximum row and column numbers in these entries
52 (2) allocate marking vectors for rows and columns
53 (3) fill marking vectors for rows and columns
54 (4) fill support vectors
55 -----------------------------------------------------------------
56 */
57 if ( INPMTX_IS_BY_ROWS(A) ) {
58 maxrow = IVmax(nent, ivec1, &loc) ;
59 maxcol = IVmax(nent, ivec2, &loc) ;
60 rowmark = CVinit(1+maxrow, 'O') ;
61 colmark = CVinit(1+maxcol, 'O') ;
62 rowcount = colcount = 0 ;
63 for ( ii = 0 ; ii < nent ; ii++ ) {
64 row = ivec1[ii] ; col = ivec2[ii] ;
65 if ( rowmark[row] == 'O' ) {
66 rowcount++ ;
67 }
68 rowmark[row] = 'X' ;
69 if ( colmark[col] == 'O' ) {
70 colcount++ ;
71 }
72 colmark[col] = 'X' ;
73 }
74 } else if ( INPMTX_IS_BY_COLUMNS(A) ) {
75 maxrow = IVmax(nent, ivec2, &loc) ;
76 maxcol = IVmax(nent, ivec1, &loc) ;
77 rowmark = CVinit(1+maxrow, 'O') ;
78 colmark = CVinit(1+maxcol, 'O') ;
79 rowcount = colcount = 0 ;
80 for ( ii = 0 ; ii < nent ; ii++ ) {
81 row = ivec2[ii] ; col = ivec1[ii] ;
82 if ( rowmark[row] == 'O' ) {
83 rowcount++ ;
84 }
85 rowmark[row] = 'X' ;
86 if ( colmark[col] == 'O' ) {
87 colcount++ ;
88 }
89 colmark[col] = 'X' ;
90 }
91 } else if ( INPMTX_IS_BY_CHEVRONS(A) ) {
92 maxrow = maxcol = -1 ;
93 for ( ii = 0 ; ii < nent ; ii++ ) {
94 chev = ivec1[ii] ; off = ivec2[ii] ;
95 if ( off >= 0 ) {
96 row = chev ; col = chev + off ;
97 } else {
98 col = chev ; row = chev - off ;
99 }
100 if ( maxrow < row ) {
101 maxrow = row ;
102 }
103 if ( maxcol < col ) {
104 maxcol = col ;
105 }
106 }
107 rowmark = CVinit(1+maxrow, 'O') ;
108 colmark = CVinit(1+maxcol, 'O') ;
109 rowcount = colcount = 0 ;
110 for ( ii = 0 ; ii < nent ; ii++ ) {
111 chev = ivec1[ii] ; off = ivec2[ii] ;
112 if ( off >= 0 ) {
113 row = chev ; col = chev + off ;
114 } else {
115 col = chev ; row = chev - off ;
116 }
117 if ( rowmark[row] == 'O' ) {
118 rowcount++ ;
119 }
120 rowmark[row] = 'X' ;
121 if ( colmark[col] == 'O' ) {
122 colcount++ ;
123 }
124 colmark[col] = 'X' ;
125 }
126 }
127 IV_setSize(rowsupIV, rowcount) ;
128 rowsup = IV_entries(rowsupIV) ;
129 for ( row = rowcount = 0 ; row <= maxrow ; row++ ) {
130 if ( rowmark[row] == 'X' ) {
131 rowsup[rowcount++] = row ;
132 }
133 }
134 IV_setSize(colsupIV, colcount) ;
135 colsup = IV_entries(colsupIV) ;
136 for ( col = colcount = 0 ; col <= maxcol ; col++ ) {
137 if ( colmark[col] == 'X' ) {
138 colsup[colcount++] = col ;
139 }
140 }
141 CVfree(colmark) ;
142 CVfree(rowmark) ;
143
144 return ; }
145
146 /*--------------------------------------------------------------------*/
147 /*
148 --------------------------------------------------------------------
149 purpose --
150 this method is used to determine the support of this matrix
151 for a matrix-vector multiply y[] = A * x[] when A is a
152 nonsymmetric matrix.
153
154 rowsupIV -- filled with row indices of y[] which will be updated.
155 colsupIV -- filled with row indices of x[] which will be used.
156
157 created -- 98aug01, cca
158 --------------------------------------------------------------------
159 */
160 void
InpMtx_supportNonsymT(InpMtx * A,IV * rowsupIV,IV * colsupIV)161 InpMtx_supportNonsymT (
162 InpMtx *A,
163 IV *rowsupIV,
164 IV *colsupIV
165 ) {
166 char *colmark, *rowmark ;
167 int chev, col, colcount, ii, loc, maxcol, maxrow, nent, off, row,
168 rowcount ;
169 int *colsup, *ivec1, *ivec2, *rowsup ;
170 /*
171 ---------------
172 check the input
173 ---------------
174 */
175 if ( A == NULL || rowsupIV == NULL || colsupIV == NULL ) {
176 fprintf(stderr, "\n fatal error in InpMtx_supportNonsymT(%p,%p,%p)"
177 "\n bad input\n", A, rowsupIV, colsupIV) ;
178 exit(-1) ;
179 }
180 if ( !INPMTX_IS_BY_ROWS(A)
181 && !INPMTX_IS_BY_COLUMNS(A)
182 && !INPMTX_IS_BY_CHEVRONS(A) ) {
183 fprintf(stderr, "\n fatal error in InpMtx_supportNonsymT(%p,%p,%p)"
184 "\n coordinate type\n", A, rowsupIV, colsupIV) ;
185 exit(-1) ;
186 }
187 ivec1 = InpMtx_ivec1(A) ;
188 ivec2 = InpMtx_ivec2(A) ;
189 nent = A->nent ;
190 /*
191 -----------------------------------------------------------------
192 (1) determine the maximum row and column numbers in these entries
193 (2) allocate marking vectors for rows and columns
194 (3) fill marking vectors for rows and columns
195 (4) fill support vectors
196 -----------------------------------------------------------------
197 */
198 if ( INPMTX_IS_BY_ROWS(A) ) {
199 maxrow = IVmax(nent, ivec1, &loc) ;
200 maxcol = IVmax(nent, ivec2, &loc) ;
201 rowmark = CVinit(1+maxcol, 'O') ;
202 colmark = CVinit(1+maxrow, 'O') ;
203 rowcount = colcount = 0 ;
204 for ( ii = 0 ; ii < nent ; ii++ ) {
205 row = ivec1[ii] ; col = ivec2[ii] ;
206 if ( colmark[row] == 'O' ) {
207 colcount++ ;
208 }
209 colmark[row] = 'X' ;
210 if ( rowmark[col] == 'O' ) {
211 rowcount++ ;
212 }
213 rowmark[col] = 'X' ;
214 }
215 } else if ( INPMTX_IS_BY_COLUMNS(A) ) {
216 maxrow = IVmax(nent, ivec2, &loc) ;
217 maxcol = IVmax(nent, ivec1, &loc) ;
218 rowmark = CVinit(1+maxcol, 'O') ;
219 colmark = CVinit(1+maxrow, 'O') ;
220 rowcount = colcount = 0 ;
221 for ( ii = 0 ; ii < nent ; ii++ ) {
222 row = ivec2[ii] ; col = ivec1[ii] ;
223 if ( colmark[row] == 'O' ) {
224 colcount++ ;
225 }
226 colmark[row] = 'X' ;
227 if ( rowmark[col] == 'O' ) {
228 rowcount++ ;
229 }
230 rowmark[col] = 'X' ;
231 }
232 } else if ( INPMTX_IS_BY_CHEVRONS(A) ) {
233 maxrow = maxcol = -1 ;
234 for ( ii = 0 ; ii < nent ; ii++ ) {
235 chev = ivec1[ii] ; off = ivec2[ii] ;
236 if ( off >= 0 ) {
237 row = chev ; col = chev + off ;
238 } else {
239 col = chev ; row = chev - off ;
240 }
241 if ( maxrow < row ) {
242 maxrow = row ;
243 }
244 if ( maxcol < col ) {
245 maxcol = col ;
246 }
247 }
248 rowmark = CVinit(1+maxcol, 'O') ;
249 colmark = CVinit(1+maxrow, 'O') ;
250 rowcount = colcount = 0 ;
251 for ( ii = 0 ; ii < nent ; ii++ ) {
252 chev = ivec1[ii] ; off = ivec2[ii] ;
253 if ( off >= 0 ) {
254 row = chev ; col = chev + off ;
255 } else {
256 col = chev ; row = chev - off ;
257 }
258 if ( colmark[row] == 'O' ) {
259 colcount++ ;
260 }
261 colmark[row] = 'X' ;
262 if ( rowmark[col] == 'O' ) {
263 rowcount++ ;
264 }
265 rowmark[col] = 'X' ;
266 }
267 }
268 IV_setSize(rowsupIV, rowcount) ;
269 rowsup = IV_entries(rowsupIV) ;
270 for ( col = rowcount = 0 ; col <= maxcol ; col++ ) {
271 if ( rowmark[col] == 'X' ) {
272 rowsup[rowcount++] = col ;
273 }
274 }
275 IV_setSize(colsupIV, colcount) ;
276 colsup = IV_entries(colsupIV) ;
277 for ( row = colcount = 0 ; row <= maxrow ; row++ ) {
278 if ( colmark[row] == 'X' ) {
279 colsup[colcount++] = row ;
280 }
281 }
282 CVfree(colmark) ;
283 CVfree(rowmark) ;
284
285 return ; }
286
287 /*--------------------------------------------------------------------*/
288 /*
289 --------------------------------------------------------------------
290 purpose --
291 this method is used to determine the support of this matrix
292 for a matrix-vector multiply y[] = A * x[] when A is a
293 nonsymmetric matrix.
294
295 rowsupIV -- filled with row indices of y[] which will be updated.
296 colsupIV -- filled with row indices of x[] which will be used.
297
298 created -- 98aug01, cca
299 --------------------------------------------------------------------
300 */
301 void
InpMtx_supportNonsymH(InpMtx * A,IV * rowsupIV,IV * colsupIV)302 InpMtx_supportNonsymH (
303 InpMtx *A,
304 IV *rowsupIV,
305 IV *colsupIV
306 ) {
307 /*
308 ---------------
309 check the input
310 ---------------
311 */
312 if ( A == NULL || rowsupIV == NULL || colsupIV == NULL ) {
313 fprintf(stderr, "\n fatal error in InpMtx_supportNonsymH(%p,%p,%p)"
314 "\n bad input\n", A, rowsupIV, colsupIV) ;
315 exit(-1) ;
316 }
317 if ( !INPMTX_IS_BY_ROWS(A)
318 && !INPMTX_IS_BY_COLUMNS(A)
319 && !INPMTX_IS_BY_CHEVRONS(A) ) {
320 fprintf(stderr, "\n fatal error in InpMtx_supportNonsymH(%p,%p,%p)"
321 "\n coordinate type\n", A, rowsupIV, colsupIV) ;
322 exit(-1) ;
323 }
324 InpMtx_supportNonsymT(A, rowsupIV, colsupIV) ;
325
326 return ; }
327
328 /*--------------------------------------------------------------------*/
329 /*
330 --------------------------------------------------------------------
331 purpose --
332 this method is used to determine the support of this matrix
333 for a matrix-vector multiply y[] = A * x[] when A is a
334 symmetric matrix.
335
336 supIV -- filled with row indices of y[] which will be updated
337 and row indices of x[] which will be used.
338
339 created -- 98aug01, cca
340 --------------------------------------------------------------------
341 */
342 void
InpMtx_supportSym(InpMtx * A,IV * supIV)343 InpMtx_supportSym (
344 InpMtx *A,
345 IV *supIV
346 ) {
347 char *mark ;
348 int chev, col, count, ii, loc, maxcol, maxrow, maxv, nent, off, row ;
349 int *ivec1, *ivec2, *sup ;
350 /*
351 ---------------
352 check the input
353 ---------------
354 */
355 if ( A == NULL || supIV == NULL ) {
356 fprintf(stderr, "\n fatal error in InpMtx_supportSym(%p,%p)"
357 "\n bad input\n", A, supIV) ;
358 exit(-1) ;
359 }
360 if ( !INPMTX_IS_BY_ROWS(A)
361 && !INPMTX_IS_BY_COLUMNS(A)
362 && !INPMTX_IS_BY_CHEVRONS(A) ) {
363 fprintf(stderr, "\n fatal error in InpMtx_supportSym(%p,%p)"
364 "\n coordinate type\n", A, supIV) ;
365 exit(-1) ;
366 }
367 ivec1 = InpMtx_ivec1(A) ;
368 ivec2 = InpMtx_ivec2(A) ;
369 nent = A->nent ;
370 /*
371 -----------------------------------------------------------------
372 (1) determine the maximum row and column numbers in these entries
373 (2) allocate marking vectors for rows and columns
374 (3) fill marking vectors for rows and columns
375 (4) fill support vectors
376 -----------------------------------------------------------------
377 */
378 if ( INPMTX_IS_BY_ROWS(A) ) {
379 maxrow = IVmax(nent, ivec1, &loc) ;
380 maxcol = IVmax(nent, ivec2, &loc) ;
381 maxv = (maxrow >= maxcol) ? maxrow : maxcol ;
382 mark = CVinit(1+maxv, 'O') ;
383 count = 0 ;
384 for ( ii = 0 ; ii < nent ; ii++ ) {
385 row = ivec1[ii] ; col = ivec2[ii] ;
386 if ( mark[row] == 'O' ) {
387 count++ ;
388 }
389 mark[row] = 'X' ;
390 if ( mark[col] == 'O' ) {
391 count++ ;
392 }
393 mark[col] = 'X' ;
394 }
395 } else if ( INPMTX_IS_BY_COLUMNS(A) ) {
396 maxrow = IVmax(nent, ivec2, &loc) ;
397 maxcol = IVmax(nent, ivec1, &loc) ;
398 maxv = (maxrow >= maxcol) ? maxrow : maxcol ;
399 mark = CVinit(1+maxv, 'O') ;
400 count = 0 ;
401 for ( ii = 0 ; ii < nent ; ii++ ) {
402 row = ivec2[ii] ; col = ivec1[ii] ;
403 if ( mark[row] == 'O' ) {
404 count++ ;
405 }
406 mark[row] = 'X' ;
407 if ( mark[col] == 'O' ) {
408 count++ ;
409 }
410 mark[col] = 'X' ;
411 }
412 } else if ( INPMTX_IS_BY_CHEVRONS(A) ) {
413 maxv = -1 ;
414 for ( ii = 0 ; ii < nent ; ii++ ) {
415 chev = ivec1[ii] ; off = ivec2[ii] ;
416 if ( off >= 0 ) {
417 row = chev ; col = chev + off ;
418 if ( maxv < col ) {
419 maxv = col ;
420 }
421 } else {
422 col = chev ; row = chev - off ;
423 if ( maxv < row ) {
424 maxv = row ;
425 }
426 }
427 }
428 mark = CVinit(1+maxv, 'O') ;
429 count = 0 ;
430 for ( ii = 0 ; ii < nent ; ii++ ) {
431 chev = ivec1[ii] ; off = ivec2[ii] ;
432 if ( off >= 0 ) {
433 row = chev ; col = chev + off ;
434 } else {
435 col = chev ; row = chev - off ;
436 }
437 if ( mark[row] == 'O' ) {
438 count++ ;
439 }
440 mark[row] = 'X' ;
441 if ( mark[col] == 'O' ) {
442 count++ ;
443 }
444 mark[col] = 'X' ;
445 }
446 }
447 IV_setSize(supIV, count) ;
448 sup = IV_entries(supIV) ;
449 for ( row = count = 0 ; row <= maxv ; row++ ) {
450 if ( mark[row] == 'X' ) {
451 sup[count++] = row ;
452 }
453 }
454 CVfree(mark) ;
455
456 return ; }
457
458 /*--------------------------------------------------------------------*/
459 /*
460 --------------------------------------------------------------------
461 purpose --
462 this method is used to determine the support of this matrix
463 for a matrix-vector multiply y[] = A * x[] when A is a
464 Hermitian matrix.
465
466 supIV -- filled with row indices of y[] which will be updated
467 and row indices of x[] which will be used.
468
469 created -- 98aug01, cca
470 --------------------------------------------------------------------
471 */
472 void
InpMtx_supportHerm(InpMtx * A,IV * supIV)473 InpMtx_supportHerm (
474 InpMtx *A,
475 IV *supIV
476 ) {
477 /*
478 ---------------
479 check the input
480 ---------------
481 */
482 if ( A == NULL || supIV == NULL ) {
483 fprintf(stderr, "\n fatal error in InpMtx_supportHerm(%p,%p)"
484 "\n bad input\n", A, supIV) ;
485 exit(-1) ;
486 }
487 if ( !INPMTX_IS_BY_ROWS(A)
488 && !INPMTX_IS_BY_COLUMNS(A)
489 && !INPMTX_IS_BY_CHEVRONS(A) ) {
490 fprintf(stderr, "\n fatal error in InpMtx_supportHerm(%p,%p)"
491 "\n coordinate type\n", A, supIV) ;
492 exit(-1) ;
493 }
494 InpMtx_supportSym(A, supIV) ;
495
496 return ; }
497
498 /*--------------------------------------------------------------------*/
499