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