Canoe
Comprehensive Atmosphere N' Ocean Engine
band_improve.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 
3 #include "linalg.h"
4 
5 #undef IMIN
6 #define IMIN(i, j) \
7  ({ \
8  const int _i = (int)(i); \
9  const int _j = (int)(j); \
10  _i < _j ? _i : _j; \
11  })
12 
13 #undef IMAX
14 #define IMAX(i, j) \
15  ({ \
16  const int _i = (int)(i); \
17  const int _j = (int)(j); \
18  _i > _j ? _i : _j; \
19  })
20 
21 /*======================= band_improve() =====================================*/
22 /*
23  * Based on Numerical Recipes in C, Secion 2.5, Iterative Improvement of
24  * a Solution to Linear Equations.
25  * This is for the band-diagnonal matrix case, and is analogous to lu_improve().
26  * AORIG is the original matrix in compact form, whereas A and AL are the
27  * matrices returned from band_decomp().
28  * NOTE: The functionality of band_multiply() is echoed here because of the
29  * requirement of double precision.
30  * Assumes zero-based indexing.
31  */
32 
33 #undef AORIG
34 #define AORIG(i, j) aorig[(m1 + m2 + 1) * (i) + (j)]
35 
36 void band_improve(int n, int m1, int m2, double *aorig, double *a, double *al,
37  int *index, double *b, double *x) {
38  int k, j, i, tmploop;
39  static int n_max = 0;
40  double *r;
41  double sdp; /* NOTE: sdp must be double precision. */
42  /*
43  * The following are part of DEBUG_MILESTONE(.) statements:
44  */
45  int idbms = 0;
46  static char dbmsname[] = "band_improve";
47 
48  /*
49  * Allocate memory.
50  */
51  if (n_max == 0) {
52  n_max = n;
53  r = (double *)malloc(n_max * sizeof(double));
54  } else if (n > n_max) {
55  free(r);
56  n_max = n;
57  r = (double *)malloc(n_max * sizeof(double));
58  }
59 
60  /*
61  * The band-diagonal indexing is as in band_multiply().
62  */
63  for (i = 0; i < n; i++) {
64  k = i - m1;
65  tmploop = IMIN(m1 + m2 + 1, n - k);
66  sdp = -b[i];
67  for (j = IMAX(0, -k); j < tmploop; j++) {
68  sdp += AORIG(i, j) * x[j + k];
69  }
70  r[i] = sdp;
71  }
72 
73  band_back_sub(n, m1, m2, a, al, index, r);
74 
75  for (i = 0; i < n; i++) {
76  x[i] -= r[i];
77  }
78 
79  free(r);
80 
81  return;
82 }
83 
84 /*======================= end of band_improve() ==============================*/
void band_back_sub(int n, int m1, int m2, double *a, double *al, int *index, double *b)
Definition: band_back_sub.c:22
void band_improve(int n, int m1, int m2, double *aorig, double *a, double *al, int *index, double *b, double *x)
Definition: band_improve.c:36
#define IMIN(i, j)
Definition: band_improve.c:6
#define IMAX(i, j)
Definition: band_improve.c:14
#define AORIG(i, j)
Definition: band_improve.c:34