NEURON
bdfactor.c
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 
4 /**************************************************************************
5 **
6 ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
7 **
8 ** Meschach Library
9 **
10 ** This Meschach Library is provided "as is" without any express
11 ** or implied warranty of any kind with respect to this software.
12 ** In particular the authors shall not be liable for any direct,
13 ** indirect, special, incidental or consequential damages arising
14 ** in any way from use of the software.
15 **
16 ** Everyone is granted permission to copy, modify and redistribute this
17 ** Meschach Library, provided:
18 ** 1. All copies contain this copyright notice.
19 ** 2. All modified copies shall carry a notice stating who
20 ** made the last modification and the date of such modification.
21 ** 3. No charge is made for this software or works derived from it.
22 ** This clause shall not be construed as constraining other software
23 ** distributed on the same medium as this software, nor is a
24 ** distribution fee considered a charge.
25 **
26 ***************************************************************************/
27 
28 
29 /*
30  Band matrix factorisation routines
31  */
32 
33 /* bdfactor.c 18/11/93 */
34 static char rcsid[] = "$Id: ";
35 
36 #include <stdio.h>
37 #include "matrix2.h"
38 #include <math.h>
39 
40 
41 /* generate band matrix
42  for a matrix with n columns,
43  lb subdiagonals and ub superdiagonals;
44 
45  Way of saving a band of a matrix:
46  first we save subdiagonals (from 0 to lb-1);
47  then main diagonal (in the lb row)
48  and then superdiagonals (from lb+1 to lb+ub)
49  in such a way that the elements which were previously
50  in one column are now also in one column
51 */
52 
53 BAND *bd_get(lb,ub,n)
54 int lb, ub, n;
55 {
56  BAND *A;
57 
58  if (lb < 0 || ub < 0 || n <= 0)
59  error(E_NEG,"bd_get");
60 
61  if ((A = NEW(BAND)) == (BAND *)NULL)
62  error(E_MEM,"bd_get");
63  else if (mem_info_is_on()) {
64  mem_bytes(TYPE_BAND,0,sizeof(BAND));
66  }
67 
68  lb = A->lb = min(n-1,lb);
69  ub = A->ub = min(n-1,ub);
70  A->mat = m_get(lb+ub+1,n);
71  return A;
72 }
73 
74 int bd_free(A)
75 BAND *A;
76 {
77  if ( A == (BAND *)NULL || A->lb < 0 || A->ub < 0 )
78  /* don't trust it */
79  return (-1);
80 
81  if (A->mat) m_free(A->mat);
82 
83  if (mem_info_is_on()) {
84  mem_bytes(TYPE_BAND,sizeof(BAND),0);
86  }
87 
88  free((char *)A);
89  return 0;
90 }
91 
92 
93 /* resize band matrix */
94 
95 BAND *bd_resize(A,new_lb,new_ub,new_n)
96 BAND *A;
97 int new_lb,new_ub,new_n;
98 {
99  int lb,ub,i,j,l,shift,umin;
100  Real **Av;
101 
102  if (new_lb < 0 || new_ub < 0 || new_n <= 0)
103  error(E_NEG,"bd_resize");
104  if ( ! A )
105  return bd_get(new_lb,new_ub,new_n);
106  if ( A->lb+A->ub+1 > A->mat->m )
107  error(E_INTERN,"bd_resize");
108 
109  if ( A->lb == new_lb && A->ub == new_ub && A->mat->n == new_n )
110  return A;
111 
112  lb = A->lb;
113  ub = A->ub;
114  Av = A->mat->me;
115  umin = min(ub,new_ub);
116 
117  /* ensure that unused triangles at edges are zero'd */
118 
119  for ( i = 0; i < lb; i++ )
120  for ( j = A->mat->n - lb + i; j < A->mat->n; j++ )
121  Av[i][j] = 0.0;
122  for ( i = lb+1,l=1; l <= umin; i++,l++ )
123  for ( j = 0; j < l; j++ )
124  Av[i][j] = 0.0;
125 
126  new_lb = A->lb = min(new_lb,new_n-1);
127  new_ub = A->ub = min(new_ub,new_n-1);
128  A->mat = m_resize(A->mat,new_lb+new_ub+1,new_n);
129  Av = A->mat->me;
130 
131  /* if new_lb != lb then move the rows to get the main diag
132  in the new_lb row */
133 
134  if (new_lb > lb) {
135  shift = new_lb-lb;
136 
137  for (i=lb+umin, l=i+shift; i >= 0; i--,l--)
138  MEM_COPY(Av[i],Av[l],new_n*sizeof(Real));
139  for (l=shift-1; l >= 0; l--)
140  __zero__(Av[l],new_n);
141  }
142  else if (new_lb < lb) {
143  shift = lb - new_lb;
144 
145  for (i=shift, l=0; i <= lb+umin; i++,l++)
146  MEM_COPY(Av[i],Av[l],new_n*sizeof(Real));
147  for (i=lb+umin+1; i <= new_lb+new_ub; i++)
148  __zero__(Av[i],new_n);
149  }
150 
151  return A;
152 }
153 
154 
155 
157 BAND *A,*B;
158 {
159  int lb,ub,i,j,n;
160 
161  if ( !A )
162  error(E_NULL,"bd_copy");
163 
164  if (A == B) return B;
165 
166  n = A->mat->n;
167  if ( !B )
168  B = bd_get(A->lb,A->ub,n);
169  else if (B->lb != A->lb || B->ub != A->ub || B->mat->n != n )
170  B = bd_resize(B,A->lb,A->ub,n);
171 
172  if (A->mat == B->mat) return B;
173  ub = B->ub = A->ub;
174  lb = B->lb = A->lb;
175 
176  for ( i=0, j=n-lb; i <= lb; i++, j++ )
177  MEM_COPY(A->mat->me[i],B->mat->me[i],j*sizeof(Real));
178 
179  for ( i=lb+1, j=1; i <= lb+ub; i++, j++ )
180  MEM_COPY(A->mat->me[i]+j,B->mat->me[i]+j,(n - j)*sizeof(Real));
181 
182  return B;
183 }
184 
185 
186 /* copy band matrix to a square matrix */
188 BAND *bA;
189 MAT *A;
190 {
191  int i,j,l,n,n1;
192  int lb, ub;
193  Real **bmat;
194 
195  if ( !bA || !A)
196  error(E_NULL,"band2mat");
197  if ( bA->mat == A )
198  error(E_INSITU,"band2mat");
199 
200  ub = bA->ub;
201  lb = bA->lb;
202  n = bA->mat->n;
203  n1 = n-1;
204  bmat = bA->mat->me;
205 
206  A = m_resize(A,n,n);
207  m_zero(A);
208 
209  for (j=0; j < n; j++)
210  for (i=min(n1,j+lb),l=lb+j-i; i >= max(0,j-ub); i--,l++)
211  A->me[i][j] = bmat[l][j];
212 
213  return A;
214 }
215 
216 /* copy a square matrix to a band matrix with
217  lb subdiagonals and ub superdiagonals */
218 BAND *mat2band(A,lb,ub,bA)
219 BAND *bA;
220 MAT *A;
221 int lb, ub;
222 {
223  int i, j, l, n1;
224  Real **bmat;
225 
226  if (! A || ! bA)
227  error(E_NULL,"mat2band");
228  if (ub < 0 || lb < 0)
229  error(E_SIZES,"mat2band");
230  if (bA->mat == A)
231  error(E_INSITU,"mat2band");
232 
233  n1 = A->n-1;
234  lb = min(n1,lb);
235  ub = min(n1,ub);
236  bA = bd_resize(bA,lb,ub,n1+1);
237  bmat = bA->mat->me;
238 
239  for (j=0; j <= n1; j++)
240  for (i=min(n1,j+lb),l=lb+j-i; i >= max(0,j-ub); i--,l++)
241  bmat[l][j] = A->me[i][j];
242 
243  return bA;
244 }
245 
246 
247 
248 /* transposition of matrix in;
249  out - matrix after transposition;
250  can be done in situ
251 */
252 
253 BAND *bd_transp(in,out)
254 BAND *in, *out;
255 {
256  int i, j, jj, l, k, lb, ub, lub, n, n1;
257  int in_situ;
258  Real **in_v, **out_v;
259 
260  if ( in == (BAND *)NULL || in->mat == (MAT *)NULL )
261  error(E_NULL,"bd_transp");
262 
263  lb = in->lb;
264  ub = in->ub;
265  lub = lb+ub;
266  n = in->mat->n;
267  n1 = n-1;
268 
269  in_situ = ( in == out );
270  if ( ! in_situ )
271  out = bd_resize(out,ub,lb,n);
272  else
273  { /* only need to swap lb and ub fields */
274  out->lb = ub;
275  out->ub = lb;
276  }
277 
278  in_v = in->mat->me;
279 
280  if (! in_situ) {
281  int sh_in,sh_out;
282 
283  out_v = out->mat->me;
284  for (i=0, l=lub, k=lb-i; i <= lub; i++,l--,k--) {
285  sh_in = max(-k,0);
286  sh_out = max(k,0);
287  MEM_COPY(&(in_v[i][sh_in]),&(out_v[l][sh_out]),
288  (n-sh_in-sh_out)*sizeof(Real));
289  /**********************************
290  for (j=n1-sh_out, jj=n1-sh_in; j >= sh_in; j--,jj--) {
291  out_v[l][jj] = in_v[i][j];
292  }
293  **********************************/
294  }
295  }
296  else if (ub == lb) {
297  Real tmp;
298 
299  for (i=0, l=lub, k=lb-i; i < lb; i++,l--,k--) {
300  for (j=n1-k, jj=n1; j >= 0; j--,jj--) {
301  tmp = in_v[l][jj];
302  in_v[l][jj] = in_v[i][j];
303  in_v[i][j] = tmp;
304  }
305  }
306  }
307  else if (ub > lb) { /* hence i-ub <= 0 & l-lb >= 0 */
308  int p,pp,lbi;
309 
310  for (i=0, l=lub; i < (lub+1)/2; i++,l--) {
311  lbi = lb-i;
312  for (j=l-lb, jj=0, p=max(-lbi,0), pp = max(l-ub,0); j <= n1;
313  j++,jj++,p++,pp++) {
314  in_v[l][pp] = in_v[i][p];
315  in_v[i][jj] = in_v[l][j];
316  }
317  for ( ; p <= n1-max(lbi,0); p++,pp++)
318  in_v[l][pp] = in_v[i][p];
319  }
320 
321  if (lub%2 == 0) { /* shift only */
322  i = lub/2;
323  for (j=max(i-lb,0), jj=0; jj <= n1-ub+i; j++,jj++)
324  in_v[i][jj] = in_v[i][j];
325  }
326  }
327  else { /* ub < lb, hence ub-l <= 0 & lb-i >= 0 */
328  int p,pp,ubi;
329 
330  for (i=0, l=lub; i < (lub+1)/2; i++,l--) {
331  ubi = i-ub;
332  for (j=n1-max(lb-l,0), jj=n1-max(-ubi,0), p=n1-lb+i, pp=n1;
333  p >= 0; j--, jj--, pp--, p--) {
334  in_v[i][jj] = in_v[l][j];
335  in_v[l][pp] = in_v[i][p];
336  }
337  for ( ; jj >= max(ubi,0); j--, jj--)
338  in_v[i][jj] = in_v[l][j];
339  }
340 
341  if (lub%2 == 0) { /* shift only */
342  i = lub/2;
343  for (j=n1-lb+i, jj=n1-max(ub-i,0); j >= 0; j--, jj--)
344  in_v[i][jj] = in_v[i][j];
345  }
346  }
347 
348  return out;
349 }
350 
351 
352 
353 /* bdLUfactor -- gaussian elimination with partial pivoting
354  -- on entry, the matrix A in band storage with elements
355  in rows 0 to lb+ub;
356  The jth column of A is stored in the jth column of
357  band A (bA) as follows:
358  bA->mat->me[lb+j-i][j] = A->me[i][j] for
359  max(0,j-lb) <= i <= min(A->n-1,j+ub);
360  -- on exit: U is stored as an upper triangular matrix
361  with lb+ub superdiagonals in rows lb to 2*lb+ub,
362  and the matrix L is stored in rows 0 to lb-1.
363  Matrix U is permuted, whereas L is not permuted !!!
364  Therefore we save some memory.
365  */
366 BAND *bdLUfactor(bA,pivot)
367 BAND *bA;
368 PERM *pivot;
369 {
370  int i, j, k, l, n, n1, lb, ub, lub, k_end, k_lub;
371  int i_max, shift;
372  Real **bA_v;
373  Real max1, temp;
374 
375  if ( bA==(BAND *)NULL || pivot==(PERM *)NULL )
376  error(E_NULL,"bdLUfactor");
377 
378  lb = bA->lb;
379  ub = bA->ub;
380  lub = lb+ub;
381  n = bA->mat->n;
382  n1 = n-1;
383  lub = lb+ub;
384 
385  if ( pivot->size != n )
386  error(E_SIZES,"bdLUfactor");
387 
388 
389  /* initialise pivot with identity permutation */
390  for ( i=0; i < n; i++ )
391  pivot->pe[i] = i;
392 
393  /* extend band matrix */
394  /* extended part is filled with zeros */
395  bA = bd_resize(bA,lb,min(n1,lub),n);
396  bA_v = bA->mat->me;
397 
398 
399  /* main loop */
400 
401  for ( k=0; k < n1; k++ )
402  {
403  k_end = max(0,lb+k-n1);
404  k_lub = min(k+lub,n1);
405 
406  /* find the best pivot row */
407 
408  max1 = 0.0;
409  i_max = -1;
410  for ( i=lb; i >= k_end; i-- ) {
411  temp = fabs(bA_v[i][k]);
412  if ( temp > max1 )
413  { max1 = temp; i_max = i; }
414  }
415 
416  /* if no pivot then ignore column k... */
417  if ( i_max == -1 )
418  continue;
419 
420  /* do we pivot ? */
421  if ( i_max != lb ) /* yes we do... */
422  {
423  /* save transposition using non-shifted indices */
424  shift = lb-i_max;
425  px_transp(pivot,k+shift,k);
426  for ( i=lb, j=k; j <= k_lub; i++,j++ )
427  {
428  temp = bA_v[i][j];
429  bA_v[i][j] = bA_v[i-shift][j];
430  bA_v[i-shift][j] = temp;
431  }
432  }
433 
434  /* row operations */
435  for ( i=lb-1; i >= k_end; i-- ) {
436  temp = bA_v[i][k] /= bA_v[lb][k];
437  shift = lb-i;
438  for ( j=k+1,l=i+1; j <= k_lub; l++,j++ )
439  bA_v[l][j] -= temp*bA_v[l+shift][j];
440  }
441  }
442 
443  return bA;
444 }
445 
446 
447 /* bdLUsolve -- given an LU factorisation in bA, solve bA*x=b */
448 /* pivot is changed upon return */
449 VEC *bdLUsolve(bA,pivot,b,x)
450 BAND *bA;
451 PERM *pivot;
452 VEC *b,*x;
453 {
454  int i,j,l,n,n1,pi,lb,ub,jmin, maxj;
455  Real c;
456  Real **bA_v;
457 
458  if ( bA==(BAND *)NULL || b==(VEC *)NULL || pivot==(PERM *)NULL )
459  error(E_NULL,"bdLUsolve");
460  if ( bA->mat->n != b->dim || bA->mat->n != pivot->size)
461  error(E_SIZES,"bdLUsolve");
462 
463  lb = bA->lb;
464  ub = bA->ub;
465  n = b->dim;
466  n1 = n-1;
467  bA_v = bA->mat->me;
468 
469  x = v_resize(x,b->dim);
470  px_vec(pivot,b,x);
471 
472  /* solve Lx = b; implicit diagonal = 1
473  L is not permuted, therefore it must be permuted now
474  */
475 
476  px_inv(pivot,pivot);
477  for (j=0; j < n; j++) {
478  jmin = j+1;
479  c = x->ve[j];
480  maxj = max(0,j+lb-n1);
481  for (i=jmin,l=lb-1; l >= maxj; i++,l--) {
482  if ( (pi = pivot->pe[i]) < jmin)
483  pi = pivot->pe[i] = pivot->pe[pi];
484  x->ve[pi] -= bA_v[l][j]*c;
485  }
486  }
487 
488  /* solve Ux = b; explicit diagonal */
489 
490  x->ve[n1] /= bA_v[lb][n1];
491  for (i=n-2; i >= 0; i--) {
492  c = x->ve[i];
493  for (j=min(n1,i+ub), l=lb+j-i; j > i; j--,l--)
494  c -= bA_v[l][j]*x->ve[j];
495  x->ve[i] = c/bA_v[lb][i];
496  }
497 
498  return (x);
499 }
500 
501 /* LDLfactor -- L.D.L' factorisation of A in-situ;
502  A is a band matrix
503  it works using only lower bandwidth & main diagonal
504  so it is possible to set A->ub = 0
505  */
506 
508 BAND *A;
509 {
510  int i,j,k,n,n1,lb,ki,jk,ji,lbkm,lbkp;
511  Real **Av;
512  Real c, cc;
513 
514  if ( ! A )
515  error(E_NULL,"bdLDLfactor");
516 
517  if (A->lb == 0) return A;
518 
519  lb = A->lb;
520  n = A->mat->n;
521  n1 = n-1;
522  Av = A->mat->me;
523 
524  for (k=0; k < n; k++) {
525  lbkm = lb-k;
526  lbkp = lb+k;
527 
528  /* matrix D */
529  c = Av[lb][k];
530  for (j=max(0,-lbkm), jk=lbkm+j; j < k; j++, jk++) {
531  cc = Av[jk][j];
532  c -= Av[lb][j]*cc*cc;
533  }
534  if (c == 0.0)
535  error(E_SING,"bdLDLfactor");
536  Av[lb][k] = c;
537 
538  /* matrix L */
539 
540  for (i=min(n1,lbkp), ki=lbkp-i; i > k; i--,ki++) {
541  c = Av[ki][k];
542  for (j=max(0,i-lb), ji=lb+j-i, jk=lbkm+j; j < k;
543  j++, ji++, jk++)
544  c -= Av[lb][j]*Av[ji][j]*Av[jk][j];
545  Av[ki][k] = c/Av[lb][k];
546  }
547  }
548 
549  return A;
550 }
551 
552 /* solve A*x = b, where A is factorized by
553  Choleski LDL^T factorization */
555 BAND *A;
556 VEC *b, *x;
557 {
558  int i,j,l,n,n1,lb,ilb;
559  Real **Av, *Avlb;
560  Real c;
561 
562  if ( ! A || ! b )
563  error(E_NULL,"bdLDLsolve");
564  if ( A->mat->n != b->dim )
565  error(E_SIZES,"bdLDLsolve");
566 
567  n = A->mat->n;
568  n1 = n-1;
569  x = v_resize(x,n);
570  lb = A->lb;
571  Av = A->mat->me;
572  Avlb = Av[lb];
573 
574  /* solve L*y = b */
575  x->ve[0] = b->ve[0];
576  for (i=1; i < n; i++) {
577  ilb = i-lb;
578  c = b->ve[i];
579  for (j=max(0,ilb), l=j-ilb; j < i; j++,l++)
580  c -= Av[l][j]*x->ve[j];
581  x->ve[i] = c;
582  }
583 
584  /* solve D*z = y */
585  for (i=0; i < n; i++)
586  x->ve[i] /= Avlb[i];
587 
588  /* solve L^T*x = z */
589  for (i=n-2; i >= 0; i--) {
590  ilb = i+lb;
591  c = x->ve[i];
592  for (j=min(n1,ilb), l=ilb-j; j > i; j--,l++)
593  c -= Av[l][i]*x->ve[j];
594  x->ve[i] = c;
595  }
596 
597  return x;
598 }
599 
600 
601 /* ******************************************************
602  This function is a contribution from Ruediger Franke.
603  His e-mail addres is: Ruediger.Franke@rz.tu-ilmenau.de
604 
605  ******************************************************
606 */
607 
608 /* bd_mv_mlt --
609  * computes out = A * x
610  * may not work in situ (x != out)
611  */
612 
613 VEC *bd_mv_mlt(A, x, out)
614 BAND *A;
615 VEC *x, *out;
616 {
617  int i, j, j_end, k;
618  int start_idx, end_idx;
619  int n, m, lb, ub;
620  Real **A_me;
621  Real *x_ve;
622  Real sum;
623 
624  if (!A || !x)
625  error(E_NULL,"bd_mv_mlt");
626  if (x->dim != A->mat->n)
627  error(E_SIZES,"bd_mv_mlt");
628  if (!out || out->dim != A->mat->n)
629  out = v_resize(out, A->mat->n);
630  if (out == x)
631  error(E_INSITU,"bd_mv_mlt");
632 
633  n = A->mat->n;
634  m = A->mat->m;
635  lb = A->lb;
636  ub = A->ub;
637  A_me = A->mat->me;
638  start_idx = lb;
639  end_idx = m + n-1 - ub;
640  for (i=0; i<n; i++, start_idx--, end_idx--) {
641  j = max(0, start_idx);
642  k = max(0, -start_idx);
643  j_end = min(m, end_idx);
644  x_ve = x->ve + k;
645  sum = 0.0;
646  for (; j < j_end; j++, k++)
647  sum += A_me[j][k] * *x_ve++;
648  out->ve[i] = sum;
649  }
650 
651  return out;
652 }
653 
654 
655 
MAT * m_get(int, int)
Definition: memory.c:36
VEC * bd_mv_mlt(BAND *A, VEC *x, VEC *out)
Definition: bdfactor.c:613
double max(double a, double b)
Definition: geometry3d.cpp:22
#define B(i)
Definition: multisplit.cpp:62
PERM * px_inv(PERM *px, PERM *out)
int bd_free(BAND *A)
Definition: bdfactor.c:74
#define E_SING
Definition: err.h:98
#define E_NEG
Definition: err.h:114
#define min(a, b)
Definition: matrix.h:157
BAND * bdLUfactor(BAND *bA, PERM *pivot)
Definition: bdfactor.c:366
#define Real
Definition: machine.h:189
static Object ** v_resize(void *v)
Definition: ivocvect.cpp:1297
size_t p
BAND * mat2band(MAT *A, int lb, int ub, BAND *bA)
Definition: bdfactor.c:218
static philox4x32_key_t k
Definition: nrnran123.cpp:11
VEC * bdLDLsolve(BAND *A, VEC *b, VEC *x)
Definition: bdfactor.c:554
u_int n
Definition: matrix.h:74
BAND * bd_get(int lb, int ub, int n)
Definition: bdfactor.c:53
BAND * bd_resize(BAND *A, int new_lb, int new_ub, int new_n)
Definition: bdfactor.c:95
VEC * px_vec(PERM *, VEC *, VEC *)
PERM * px_transp(PERM *px, u_int i, u_int j)
Definition: pxop.c:208
Real * ve
Definition: matrix.h:69
int mem_info_is_on(void)
Definition: meminfo.c:221
Definition: matrix.h:67
VEC * bdLUsolve(BAND *bA, PERM *pivot, VEC *b, VEC *x)
Definition: bdfactor.c:449
u_int size
Definition: matrix.h:88
#define E_SIZES
Definition: err.h:95
int const size_t const size_t n
Definition: nrngsl.h:12
int lb
Definition: matrix.h:82
MAT * mat
Definition: matrix.h:81
u_int dim
Definition: matrix.h:68
#define mem_bytes(type, old_size, new_size)
Definition: meminfo.h:136
int m_free(MAT *)
void MEM_COPY(char *from, char *to, int len)
Definition: extras.c:37
#define E_NULL
Definition: err.h:102
size_t j
static char rcsid[]
Definition: bdfactor.c:34
BAND * bdLDLfactor(BAND *A)
Definition: bdfactor.c:507
void __zero__(Real *dp, int len)
Definition: machine.c:133
Definition: matrix.h:80
MAT * band2mat(BAND *bA, MAT *A)
Definition: bdfactor.c:187
static Object ** m_resize(void *v)
Definition: matrix.cpp:190
#define i
Definition: md1redef.h:12
#define A(i)
Definition: multisplit.cpp:61
#define c
static Object ** m_zero(void *v)
Definition: matrix.cpp:511
#define error(err_num, fn_name)
Definition: err.h:73
fabs
Definition: extdef.h:3
u_int m
Definition: matrix.h:74
#define mem_numvar(type, num)
Definition: meminfo.h:139
#define TYPE_BAND
Definition: meminfo.h:50
BAND * bd_transp(BAND *in, BAND *out)
Definition: bdfactor.c:253
BAND * bd_copy(BAND *A, BAND *B)
Definition: bdfactor.c:156
for(i=0;i< n;i++)
Definition: matrix.h:87
return NULL
Definition: cabcode.cpp:461
Real ** me
Definition: matrix.h:76
#define E_INTERN
Definition: err.h:111
#define NEW(type)
Definition: matrix.h:136
Definition: matrix.h:73
u_int * pe
Definition: matrix.h:88
int ub
Definition: matrix.h:82
#define E_MEM
Definition: err.h:97
#define E_INSITU
Definition: err.h:106