NEURON
iter0.c
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 /**************************************************************************
4 **
5 ** Copyright (C) 1993 David E. Stewart & 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 /* iter0.c 14/09/93 */
29 
30 /* ITERATIVE METHODS - service functions */
31 
32 /* functions for creating and releasing ITER structures;
33  for memory information;
34  for getting some values from an ITER variable;
35  for changing values in an ITER variable;
36  see also iter.c
37 */
38 
39 #include <stdio.h>
40 #include "iter.h"
41 #include <math.h>
42 
43 
44 static char rcsid[] = "iter0.c,v 1.1 1997/12/04 17:55:26 hines Exp";
45 
46 
47 /* standard functions */
48 
49 /* standard information */
50 void iter_std_info(ip,nres,res,Bres)
51 ITER *ip;
52 double nres;
53 VEC *res, *Bres;
54 {
55  if (nres >= 0.0)
56  printf(" %d. residual = %g\n",ip->steps,nres);
57  else
58  printf(" %d. residual = %g (WARNING !!! should be >= 0) \n",
59  ip->steps,nres);
60 }
61 
62 /* standard stopping criterion */
63 int iter_std_stop_crit(ip, nres, res, Bres)
64 ITER *ip;
65 double nres;
66 VEC *res, *Bres;
67 {
68  /* standard stopping criterium */
69  if (nres <= ip->init_res*ip->eps) return TRUE;
70  return FALSE;
71 }
72 
73 
74 /* iter_get - create a new structure pointing to ITER */
75 
76 ITER *iter_get(lenb, lenx)
77 int lenb, lenx;
78 {
79  ITER *ip;
80 
81  if ((ip = NEW(ITER)) == (ITER *) NULL)
82  error(E_MEM,"iter_get");
83  else if (mem_info_is_on()) {
84  mem_bytes(TYPE_ITER,0,sizeof(ITER));
85  mem_numvar(TYPE_ITER,1);
86  }
87 
88  /* default values */
89 
90  ip->shared_x = FALSE;
91  ip->shared_b = FALSE;
92  ip->k = 0;
93  ip->limit = ITER_LIMIT_DEF;
94  ip->eps = ITER_EPS_DEF;
95  ip->steps = 0;
96 
97  if (lenb > 0) ip->b = v_get(lenb);
98  else ip->b = (VEC *)NULL;
99 
100  if (lenx > 0) ip->x = v_get(lenx);
101  else ip->x = (VEC *)NULL;
102 
103  ip->Ax = (Fun_Ax) NULL;
104  ip->A_par = NULL;
105  ip->ATx = (Fun_Ax) NULL;
106  ip->AT_par = NULL;
107  ip->Bx = (Fun_Ax) NULL;
108  ip->B_par = NULL;
109  ip->info = iter_std_info;
111  ip->init_res = 0.0;
112 
113  return ip;
114 }
115 
116 
117 /* iter_free - release memory */
118 int iter_free(ip)
119 ITER *ip;
120 {
121  if (ip == (ITER *)NULL) return -1;
122 
123  if (mem_info_is_on()) {
124  mem_bytes(TYPE_ITER,sizeof(ITER),0);
125  mem_numvar(TYPE_ITER,-1);
126  }
127 
128  if ( !ip->shared_x && ip->x != NULL ) v_free(ip->x);
129  if ( !ip->shared_b && ip->b != NULL ) v_free(ip->b);
130 
131  free((char *)ip);
132 
133  return 0;
134 }
135 
136 ITER *iter_resize(ip,new_lenb,new_lenx)
137 ITER *ip;
138 int new_lenb, new_lenx;
139 {
140  VEC *old;
141 
142  if ( ip == (ITER *) NULL)
143  error(E_NULL,"iter_resize");
144 
145  old = ip->x;
146  ip->x = v_resize(ip->x,new_lenx);
147  if ( ip->shared_x && old != ip->x )
148  warning(WARN_SHARED_VEC,"iter_resize");
149  old = ip->b;
150  ip->b = v_resize(ip->b,new_lenb);
151  if ( ip->shared_b && old != ip->b )
152  warning(WARN_SHARED_VEC,"iter_resize");
153 
154  return ip;
155 }
156 
157 
158 /* print out ip structure - for diagnostic purposes mainly */
159 void iter_dump(fp,ip)
160 ITER *ip;
161 FILE *fp;
162 {
163  if (ip == NULL) {
164  fprintf(fp," ITER structure: NULL\n");
165  return;
166  }
167 
168  fprintf(fp,"\n ITER structure:\n");
169  fprintf(fp," ip->shared_x = %s, ip->shared_b = %s\n",
170  (ip->shared_x ? "TRUE" : "FALSE"),
171  (ip->shared_b ? "TRUE" : "FALSE") );
172  fprintf(fp," ip->k = %d, ip->limit = %d, ip->steps = %d, ip->eps = %g\n",
173  ip->k,ip->limit,ip->steps,ip->eps);
174  fprintf(fp," ip->x = 0x%p, ip->b = 0x%p\n",ip->x,ip->b);
175  fprintf(fp," ip->Ax = 0x%p, ip->A_par = 0x%p\n",ip->Ax,ip->A_par);
176  fprintf(fp," ip->ATx = 0x%p, ip->AT_par = 0x%p\n",ip->ATx,ip->AT_par);
177  fprintf(fp," ip->Bx = 0x%p, ip->B_par = 0x%p\n",ip->Bx,ip->B_par);
178  fprintf(fp," ip->info = 0x%p, ip->stop_crit = 0x%p, ip->init_res = %g\n",
179  ip->info,ip->stop_crit,ip->init_res);
180  fprintf(fp,"\n");
181 
182 }
183 
184 
185 /* copy the structure ip1 to ip2 preserving vectors x and b of ip2
186  (vectors x and b in ip2 are the same before and after iter_copy2)
187  if ip2 == NULL then a new structure is created with x and b being NULL
188  and other members are taken from ip1
189 */
190 ITER *iter_copy2(ip1,ip2)
191 ITER *ip1, *ip2;
192 {
193  VEC *x, *b;
194  int shx, shb;
195 
196  if (ip1 == (ITER *)NULL)
197  error(E_NULL,"iter_copy2");
198 
199  if (ip2 == (ITER *)NULL) {
200  if ((ip2 = NEW(ITER)) == (ITER *) NULL)
201  error(E_MEM,"iter_copy2");
202  else if (mem_info_is_on()) {
203  mem_bytes(TYPE_ITER,0,sizeof(ITER));
204  mem_numvar(TYPE_ITER,1);
205  }
206  ip2->x = ip2->b = NULL;
207  ip2->shared_x = ip2->shared_x = FALSE;
208  }
209 
210  x = ip2->x;
211  b = ip2->b;
212  shb = ip2->shared_b;
213  shx = ip2->shared_x;
214  MEM_COPY(ip1,ip2,sizeof(ITER));
215  ip2->x = x;
216  ip2->b = b;
217  ip2->shared_x = shx;
218  ip2->shared_b = shb;
219 
220  return ip2;
221 }
222 
223 
224 /* copy the structure ip1 to ip2 copying also the vectors x and b */
225 ITER *iter_copy(ip1,ip2)
226 ITER *ip1, *ip2;
227 {
228  VEC *x, *b;
229 
230  if (ip1 == (ITER *)NULL)
231  error(E_NULL,"iter_copy");
232 
233  if (ip2 == (ITER *)NULL) {
234  if ((ip2 = NEW(ITER)) == (ITER *) NULL)
235  error(E_MEM,"iter_copy2");
236  else if (mem_info_is_on()) {
237  mem_bytes(TYPE_ITER,0,sizeof(ITER));
238  mem_numvar(TYPE_ITER,1);
239  }
240  }
241 
242  x = ip2->x;
243  b = ip2->b;
244 
245  MEM_COPY(ip1,ip2,sizeof(ITER));
246  if (ip1->x)
247  ip2->x = v_copy(ip1->x,x);
248  if (ip1->b)
249  ip2->b = v_copy(ip1->b,b);
250 
251  ip2->shared_x = ip2->shared_b = FALSE;
252 
253  return ip2;
254 }
255 
256 
257 /*** functions to generate sparse matrices with random entries ***/
258 
259 
260 /* iter_gen_sym -- generate symmetric positive definite
261  n x n matrix,
262  nrow - number of nonzero entries in a row
263  */
265 int n, nrow;
266 {
267  SPMAT *A;
268  VEC *u;
269  Real s1;
270  int i, j, k, k_max;
271 
272  if (nrow <= 1) nrow = 2;
273  /* nrow should be even */
274  if ((nrow & 1)) nrow -= 1;
275  A = sp_get(n,n,nrow);
276  u = v_get(A->m);
277  v_zero(u);
278  for ( i = 0; i < A->m; i++ )
279  {
280  k_max = ((rand() >> 8) % (nrow/2));
281  for ( k = 0; k <= k_max; k++ )
282  {
283  j = (rand() >> 8) % A->n;
284  s1 = mrand();
285  sp_set_val(A,i,j,s1);
286  sp_set_val(A,j,i,s1);
287  u->ve[i] += fabs(s1);
288  u->ve[j] += fabs(s1);
289  }
290  }
291  /* ensure that A is positive definite */
292  for ( i = 0; i < A->m; i++ )
293  sp_set_val(A,i,i,u->ve[i] + 1.0);
294 
295  V_FREE(u);
296  return A;
297 }
298 
299 
300 /* iter_gen_nonsym -- generate non-symmetric m x n sparse matrix, m >= n
301  nrow - number of entries in a row;
302  diag - number which is put in diagonal entries and then permuted
303  (if diag is zero then 1.0 is there)
304 */
306 int m, n, nrow;
307 double diag;
308 {
309  SPMAT *A;
310  PERM *px;
311  int i, j, k, k_max;
312  Real s1;
313 
314  if (nrow <= 1) nrow = 2;
315  if (diag == 0.0) diag = 1.0;
316  A = sp_get(m,n,nrow);
317  px = px_get(n);
318  for ( i = 0; i < A->m; i++ )
319  {
320  k_max = (rand() >> 8) % (nrow-1);
321  for ( k = 0; k <= k_max; k++ )
322  {
323  j = (rand() >> 8) % A->n;
324  s1 = mrand();
325  sp_set_val(A,i,j,-s1);
326  }
327  }
328  /* to make it likely that A is nonsingular, use pivot... */
329  for ( i = 0; i < 2*A->n; i++ )
330  {
331  j = (rand() >> 8) % A->n;
332  k = (rand() >> 8) % A->n;
333  px_transp(px,j,k);
334  }
335  for ( i = 0; i < A->n; i++ )
336  sp_set_val(A,i,px->pe[i],diag);
337 
338  PX_FREE(px);
339  return A;
340 }
341 
342 
343 /* iter_gen_nonsym -- generate non-symmetric positive definite
344  n x n sparse matrix;
345  nrow - number of entries in a row
346 */
348 int n, nrow;
349 {
350  SPMAT *A;
351  PERM *px;
352  VEC *u;
353  int i, j, k, k_max;
354  Real s1;
355 
356  if (nrow <= 1) nrow = 2;
357  A = sp_get(n,n,nrow);
358  px = px_get(n);
359  u = v_get(A->m);
360  v_zero(u);
361  for ( i = 0; i < A->m; i++ )
362  {
363  k_max = (rand() >> 8) % (nrow-1);
364  for ( k = 0; k <= k_max; k++ )
365  {
366  j = (rand() >> 8) % A->n;
367  s1 = mrand();
368  sp_set_val(A,i,j,-s1);
369  u->ve[i] += fabs(s1);
370  }
371  }
372  /* ensure that A is positive definite */
373  for ( i = 0; i < A->m; i++ )
374  sp_set_val(A,i,i,u->ve[i] + 1.0);
375 
376  PX_FREE(px);
377  V_FREE(u);
378  return A;
379 }
380 
381 
382 
static Frame * fp
Definition: code.cpp:161
#define TRUE
Definition: err.c:57
#define FALSE
Definition: err.c:56
#define error(err_num, fn_name)
Definition: err.h:73
#define WARN_SHARED_VEC
Definition: err.h:123
#define E_MEM
Definition: err.h:97
#define E_NULL
Definition: err.h:102
void MEM_COPY(char *from, char *to, int len)
Definition: extras.c:37
#define diag(s)
Definition: fmenu.cpp:192
void warning(const char *s, const char *t)
Definition: hoc.cpp:1522
double mrand(void)
Definition: init.c:148
VEC * v_zero(VEC *x)
Definition: init.c:40
int iter_free(ITER *ip)
Definition: iter0.c:118
ITER * iter_copy2(ITER *ip1, ITER *ip2)
Definition: iter0.c:190
ITER * iter_copy(ITER *ip1, ITER *ip2)
Definition: iter0.c:225
SPMAT * iter_gen_nonsym(int m, int n, int nrow, double diag)
Definition: iter0.c:305
ITER * iter_resize(ITER *ip, int new_lenb, int new_lenx)
Definition: iter0.c:136
void iter_std_info(ITER *ip, double nres, VEC *res, VEC *Bres)
Definition: iter0.c:50
int iter_std_stop_crit(ITER *ip, double nres, VEC *res, VEC *Bres)
Definition: iter0.c:63
ITER * iter_get(int lenb, int lenx)
Definition: iter0.c:76
void iter_dump(FILE *fp, ITER *ip)
Definition: iter0.c:159
SPMAT * iter_gen_sym(int n, int nrow)
Definition: iter0.c:264
SPMAT * iter_gen_nonsym_posdef(int n, int nrow)
Definition: iter0.c:347
static char rcsid[]
Definition: iter0.c:44
#define ITER_LIMIT_DEF
Definition: iter.h:134
VEC *(* Fun_Ax)(void *, VEC *, VEC *)
Definition: iter.h:49
#define ITER_EPS_DEF
Definition: iter.h:135
static double v_get(void *v)
Definition: ivocvect.cpp:1395
static Object ** v_resize(void *v)
Definition: ivocvect.cpp:1383
#define Real
Definition: machine.h:189
PERM * px_transp(PERM *px, u_int i, u_int j)
Definition: pxop.c:208
#define v_copy(in, out)
Definition: matrix.h:404
PERM * px_get(int)
int v_free(VEC *)
#define PX_FREE(px)
Definition: matrix.h:215
#define NEW(type)
Definition: matrix.h:136
#define V_FREE(vec)
Definition: matrix.h:214
#define i
Definition: md1redef.h:12
int mem_info_is_on(void)
Definition: meminfo.c:221
#define mem_numvar(type, num)
Definition: meminfo.h:139
#define mem_bytes(type, old_size, new_size)
Definition: meminfo.h:136
fabs
Definition: extdef.h:3
#define A(i)
Definition: multisplit.cpp:63
#define printf
Definition: mwprefix.h:26
#define fprintf
Definition: mwprefix.h:30
int const size_t const size_t n
Definition: nrngsl.h:11
size_t j
static philox4x32_key_t k
Definition: nrnran123.cpp:11
double sp_set_val(SPMAT *A, int i, int j, double val)
Definition: sparse.c:66
SPMAT * sp_get(int m, int n, int maxlen)
Definition: sparse.c:198
#define NULL
Definition: sptree.h:16
Definition: iter.h:56
int shared_b
Definition: iter.h:58
unsigned k
Definition: iter.h:59
int limit
Definition: iter.h:60
int(* stop_crit)()
Definition: iter.h:93
Fun_Ax ATx
Definition: iter.h:71
Fun_Ax Bx
Definition: iter.h:75
Real eps
Definition: iter.h:62
int steps
Definition: iter.h:61
int shared_x
Definition: iter.h:57
Fun_Ax Ax
Definition: iter.h:68
void * A_par
Definition: iter.h:69
VEC * x
Definition: iter.h:64
void * AT_par
Definition: iter.h:73
void(* info)()
Definition: iter.h:92
VEC * b
Definition: iter.h:66
Real init_res
Definition: iter.h:108
void * B_par
Definition: iter.h:76
Definition: matrix.h:87
u_int * pe
Definition: matrix.h:88
Definition: sparse.h:54
Definition: matrix.h:67
Real * ve
Definition: matrix.h:69