Canoe
Comprehensive Atmosphere N' Ocean Engine
band_decomp.c
Go to the documentation of this file.
1 #include <math.h>
2 #include <stdio.h>
3 
4 /*======================= band_decomp() ======================================*/
5 
6 /*
7  * Decompose a banded matrix.
8  * Adapted from Numerical Recipes in C, 2nd ed., p. 53.
9  * The input matrix must be stored in compact form, as described on p. 52.
10  * Assumes zero-based indexing.
11  */
12 
13 #undef SWAP
14 #define SWAP(a, b) \
15  { \
16  tmp = (a); \
17  (a) = (b); \
18  (b) = tmp; \
19  }
20 #undef TINY
21 #define TINY 1.e-20
22 
23 #undef A
24 #define A(i, j) a[(m1 + m2 + 1) * (i) + (j)]
25 #undef AL
26 #define AL(i, j) al[m1 * (i) + (j)]
27 
28 void band_decomp(int n, int m1, int m2, double *a, double *al, int *index,
29  double *d) {
30  int i, j, k, l, mm;
31  double tmp;
32  static int warned = 0;
33  /*
34  * The following are part of DEBUG_MILESTONE(.) statements:
35  */
36  int idbms = 0;
37  static char dbmsname[] = "band_decomp";
38 
39  mm = m1 + m2 + 1;
40  l = m1;
41  for (i = 0; i < m1; i++) {
42  for (j = m1 - i; j < mm; j++) {
43  A(i, j - l) = A(i, j);
44  }
45  l--;
46  for (j = mm - l - 1; j < mm; j++) {
47  A(i, j) = 0.;
48  }
49  }
50  *d = 1.;
51  l = m1;
52  for (k = 0; k < n; k++) {
53  tmp = A(k, 0);
54  i = k;
55  if (l < n) {
56  l++;
57  }
58  for (j = k + 1; j < l; j++) {
59  if (fabs(A(j, 0)) > fabs(tmp)) {
60  tmp = A(j, 0);
61  i = j;
62  }
63  }
64  index[k] = i;
65  if (tmp == 0.) {
66  /*
67  * Matrix is algorithmically singular.
68  */
69  A(k, 0) = TINY;
70  if (!warned) {
71  fprintf(stderr,
72  "**warning: %s, matrix is algorithmically singular (future "
73  "warnings suppressed)\n",
74  dbmsname);
75  warned = 1;
76  }
77  }
78  if (i != k) {
79  *d = -(*d);
80  for (j = 0; j < mm; j++) {
81  SWAP(A(k, j), A(i, j))
82  }
83  }
84  for (i = k + 1; i < l; i++) {
85  tmp = A(i, 0) / A(k, 0);
86  AL(k, i - k - 1) = tmp;
87  for (j = 1; j < mm; j++) {
88  A(i, j - 1) = A(i, j) - tmp * A(k, j);
89  }
90  A(i, mm - 1) = 0.;
91  }
92  }
93 
94  return;
95 }
96 
97 /*======================= end of band_decomp() ===============================*/
void band_decomp(int n, int m1, int m2, double *a, double *al, int *index, double *d)
Definition: band_decomp.c:28
#define SWAP(a, b)
Definition: band_decomp.c:14
#define TINY
Definition: band_decomp.c:21
#define A(i, j)
Definition: band_decomp.c:24
#define AL(i, j)
Definition: band_decomp.c:26