NEURON
spswap.c
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 /**************************************************************************
4 **
5 ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
6 **
7 ** Meschach Library
8 **
9 ** This Meschach Library is provided "as is" without any express
10 ** or implied warranty of any kind with respect to this software.
11 ** In particular the authors shall not be liable for any direct,
12 ** indirect, special, incidental or consequential damages arising
13 ** in any way from use of the software.
14 **
15 ** Everyone is granted permission to copy, modify and redistribute this
16 ** Meschach Library, provided:
17 ** 1. All copies contain this copyright notice.
18 ** 2. All modified copies shall carry a notice stating who
19 ** made the last modification and the date of such modification.
20 ** 3. No charge is made for this software or works derived from it.
21 ** This clause shall not be construed as constraining other software
22 ** distributed on the same medium as this software, nor is a
23 ** distribution fee considered a charge.
24 **
25 ***************************************************************************/
26 
27 
28 /*
29  Sparse matrix swap and permutation routines
30  Modified Mon 09th Nov 1992, 08:50:54 PM
31  to use Karen George's suggestion to use unordered rows
32 */
33 
34 static char rcsid[] = "spswap.c,v 1.1 1997/12/04 17:55:54 hines Exp";
35 
36 #include <stdio.h>
37 #include "sparse2.h"
38 #include <math.h>
39 
40 
41 #define btos(x) ((x) ? "TRUE" : "FALSE")
42 
43 /* scan_to -- updates scan (int) vectors to point to the last row in each
44  column with row # <= max_row, if any */
45 void scan_to(A, scan_row, scan_idx, col_list, max_row)
46 SPMAT *A;
48 int max_row;
49 {
50  int col, idx, j_idx, row_num;
51  SPROW *r;
52  row_elt *e;
53 
54  if ( ! A || ! scan_row || ! scan_idx || ! col_list )
55  error(E_NULL,"scan_to");
56  if ( scan_row->dim != scan_idx->dim || scan_idx->dim != col_list->dim )
57  error(E_SIZES,"scan_to");
58 
59  if ( max_row < 0 )
60  return;
61 
62  if ( ! A->flag_col )
64 
65  for ( j_idx = 0; j_idx < scan_row->dim; j_idx++ )
66  {
67  row_num = scan_row->ive[j_idx];
68  idx = scan_idx->ive[j_idx];
69  col = col_list->ive[j_idx];
70 
71  if ( col < 0 || col >= A->n )
72  error(E_BOUNDS,"scan_to");
73  if ( row_num < 0 )
74  {
75  idx = col;
76  continue;
77  }
78  r = &(A->row[row_num]);
79  if ( idx < 0 )
80  error(E_INTERN,"scan_to");
81  e = &(r->elt[idx]);
82  if ( e->col != col )
83  error(E_INTERN,"scan_to");
84  if ( idx < 0 )
85  {
86  printf("scan_to: row_num = %d, idx = %d, col = %d\n",
87  row_num, idx, col);
88  error(E_INTERN,"scan_to");
89  }
90  /* if ( e->nxt_row <= max_row )
91  chase_col(A, col, &row_num, &idx, max_row); */
92  while ( e->nxt_row >= 0 && e->nxt_row <= max_row )
93  {
94  row_num = e->nxt_row;
95  idx = e->nxt_idx;
96  e = &(A->row[row_num].elt[idx]);
97  }
98 
99  /* printf("scan_to: computed j_idx = %d, row_num = %d, idx = %d\n",
100  j_idx, row_num, idx); */
101  scan_row->ive[j_idx] = row_num;
102  scan_idx->ive[j_idx] = idx;
103  }
104 }
105 
106 /* patch_col -- patches column access paths for fill-in */
107 void patch_col(A, col, old_row, old_idx, row_num, idx)
108 SPMAT *A;
109 int col, old_row, old_idx, row_num, idx;
110 {
111  SPROW *r;
112  row_elt *e;
113 
114  if ( old_row >= 0 )
115  {
116  r = &(A->row[old_row]);
117  old_idx = sprow_idx2(r,col,old_idx);
118  e = &(r->elt[old_idx]);
119  e->nxt_row = row_num;
120  e->nxt_idx = idx;
121  }
122  else
123  {
124  A->start_row[col] = row_num;
125  A->start_idx[col] = idx;
126  }
127 }
128 
129 /* chase_col -- chases column access path in column col, starting with
130  row_num and idx, to find last row # in this column <= max_row
131  -- row_num is returned; idx is also set by this routine
132  -- assumes that the column access paths (possibly without the
133  nxt_idx fields) are set up */
134 row_elt *chase_col(A, col, row_num, idx, max_row)
135 SPMAT *A;
136 int col, *row_num, *idx, max_row;
137 {
138  int old_idx, old_row, tmp_idx, tmp_row;
139  SPROW *r;
140  row_elt *e=0;
141 
142  if ( col < 0 || col >= A->n )
143  error(E_BOUNDS,"chase_col");
144  tmp_row = *row_num;
145  if ( tmp_row < 0 )
146  {
147  if ( A->start_row[col] > max_row )
148  {
149  tmp_row = -1;
150  tmp_idx = col;
151  return (row_elt *)NULL;
152  }
153  else
154  {
155  tmp_row = A->start_row[col];
156  tmp_idx = A->start_idx[col];
157  }
158  }
159  else
160  tmp_idx = *idx;
161 
162  old_row = tmp_row;
163  old_idx = tmp_idx;
164  while ( tmp_row >= 0 && tmp_row < max_row )
165  {
166  r = &(A->row[tmp_row]);
167  /* tmp_idx = sprow_idx2(r,col,tmp_idx); */
168  if ( tmp_idx < 0 || tmp_idx >= r->len ||
169  r->elt[tmp_idx].col != col )
170  {
171 #ifdef DEBUG
172  printf("chase_col:error: col = %d, row # = %d, idx = %d\n",
173  col, tmp_row, tmp_idx);
174  printf("chase_col:error: old_row = %d, old_idx = %d\n",
175  old_row, old_idx);
176  printf("chase_col:error: A =\n");
177  sp_dump(stdout,A);
178 #endif
179  error(E_INTERN,"chase_col");
180  }
181  e = &(r->elt[tmp_idx]);
182  old_row = tmp_row;
183  old_idx = tmp_idx;
184  tmp_row = e->nxt_row;
185  tmp_idx = e->nxt_idx;
186  }
187  if ( old_row > max_row )
188  {
189  old_row = -1;
190  old_idx = col;
191  e = (row_elt *)NULL;
192  }
193  else if ( tmp_row <= max_row && tmp_row >= 0 )
194  {
195  old_row = tmp_row;
196  old_idx = tmp_idx;
197  }
198 
199  *row_num = old_row;
200  if ( old_row >= 0 )
201  *idx = old_idx;
202  else
203  *idx = col;
204 
205  return e;
206 }
207 
208 /* chase_past -- as for chase_col except that we want the first
209  row whose row # >= min_row; -1 indicates no such row */
210 row_elt *chase_past(A, col, row_num, idx, min_row)
211 SPMAT *A;
212 int col, *row_num, *idx, min_row;
213 {
214  SPROW *r;
215  row_elt *e;
216  int tmp_idx, tmp_row;
217 
218  tmp_row = *row_num;
219  tmp_idx = *idx;
220  chase_col(A,col,&tmp_row,&tmp_idx,min_row);
221  if ( tmp_row < 0 ) /* use A->start_row[..] etc. */
222  {
223  if ( A->start_row[col] < 0 )
224  tmp_row = -1;
225  else
226  {
227  tmp_row = A->start_row[col];
228  tmp_idx = A->start_idx[col];
229  }
230  }
231  else if ( tmp_row < min_row )
232  {
233  r = &(A->row[tmp_row]);
234  if ( tmp_idx < 0 || tmp_idx >= r->len ||
235  r->elt[tmp_idx].col != col )
236  error(E_INTERN,"chase_past");
237  tmp_row = r->elt[tmp_idx].nxt_row;
238  tmp_idx = r->elt[tmp_idx].nxt_idx;
239  }
240 
241  *row_num = tmp_row;
242  *idx = tmp_idx;
243  if ( tmp_row < 0 )
244  e = (row_elt *)NULL;
245  else
246  {
247  if ( tmp_idx < 0 || tmp_idx >= A->row[tmp_row].len ||
248  A->row[tmp_row].elt[tmp_idx].col != col )
249  error(E_INTERN,"bump_col");
250  e = &(A->row[tmp_row].elt[tmp_idx]);
251  }
252 
253  return e;
254 }
255 
256 /* bump_col -- move along to next nonzero entry in column col after row_num
257  -- update row_num and idx */
258 row_elt *bump_col(A, col, row_num, idx)
259 SPMAT *A;
260 int col, *row_num, *idx;
261 {
262  SPROW *r;
263  row_elt *e;
264  int tmp_row, tmp_idx;
265 
266  tmp_row = *row_num;
267  tmp_idx = *idx;
268  /* printf("bump_col: col = %d, row# = %d, idx = %d\n",
269  col, *row_num, *idx); */
270  if ( tmp_row < 0 )
271  {
272  tmp_row = A->start_row[col];
273  tmp_idx = A->start_idx[col];
274  }
275  else
276  {
277  r = &(A->row[tmp_row]);
278  if ( tmp_idx < 0 || tmp_idx >= r->len ||
279  r->elt[tmp_idx].col != col )
280  error(E_INTERN,"bump_col");
281  e = &(r->elt[tmp_idx]);
282  tmp_row = e->nxt_row;
283  tmp_idx = e->nxt_idx;
284  }
285  if ( tmp_row < 0 )
286  {
287  e = (row_elt *)NULL;
288  tmp_idx = col;
289  }
290  else
291  {
292  if ( tmp_idx < 0 || tmp_idx >= A->row[tmp_row].len ||
293  A->row[tmp_row].elt[tmp_idx].col != col )
294  error(E_INTERN,"bump_col");
295  e = &(A->row[tmp_row].elt[tmp_idx]);
296  }
297  *row_num = tmp_row;
298  *idx = tmp_idx;
299 
300  return e;
301 }
302 
303 
#define error(err_num, fn_name)
Definition: err.h:73
#define E_NULL
Definition: err.h:102
#define E_INTERN
Definition: err.h:111
#define E_BOUNDS
Definition: err.h:96
#define E_SIZES
Definition: err.h:95
#define A(i)
Definition: multisplit.cpp:63
#define printf
Definition: mwprefix.h:26
#define e
Definition: passive0.cpp:22
SPMAT * sp_col_access(SPMAT *A)
Definition: sparse.c:376
void sp_dump(FILE *fp, SPMAT *A)
Definition: sparseio.c:127
#define sprow_idx2(r, c, hint)
Definition: sparse.h:78
static int * col_list
Definition: spchfctr.c:147
static int * scan_row
Definition: spchfctr.c:146
static int * scan_idx
Definition: spchfctr.c:146
row_elt * chase_col(SPMAT *A, int col, int *row_num, int *idx, int max_row)
Definition: spswap.c:134
row_elt * bump_col(SPMAT *A, int col, int *row_num, int *idx)
Definition: spswap.c:258
row_elt * chase_past(SPMAT *A, int col, int *row_num, int *idx, int min_row)
Definition: spswap.c:210
void scan_to(SPMAT *A, IVEC *scan_row, IVEC *scan_idx, IVEC *col_list, int max_row)
Definition: spswap.c:45
static char rcsid[]
Definition: spswap.c:34
void patch_col(SPMAT *A, int col, int old_row, int old_idx, int row_num, int idx)
Definition: spswap.c:107
#define NULL
Definition: sptree.h:16
Definition: matrix.h:92
Definition: sparse.h:54
Definition: sparse.h:49
int len
Definition: sparse.h:50
row_elt * elt
Definition: sparse.h:51
Definition: sparse.h:44
int nxt_row
Definition: sparse.h:45
int nxt_idx
Definition: sparse.h:45
int col
Definition: sparse.h:45