A Survey of Gaussian Convolution Algorithms
filter_util.c
Go to the documentation of this file.
1 
20 #include "filter_util.h"
21 #include <assert.h>
22 #include <math.h>
23 #include <string.h>
24 
26 #define MAX_Q 7
27 
47 void recursive_filter_impulse(num *h, long N,
48  const num *b, int p, const num *a, int q)
49 {
50  long m, n;
51 
52  assert(h && N > 0 && b && p >= 0 && a && q > 0);
53 
54  for (n = 0; n < N; ++n)
55  {
56  h[n] = (n <= p) ? b[n] : 0;
57 
58  for (m = 1; m <= q && m <= n; ++m)
59  h[n] -= a[m] * h[n - m];
60  }
61 
62  return;
63 }
64 
86 void init_recursive_filter(num *dest, const num *src, long N, long stride,
87  const num *b, int p, const num *a, int q,
88  num sum, num tol, long max_iter)
89 {
90  num h[MAX_Q + 1];
91  long n;
92  int m;
93 
94  assert(dest && src && N > 0 && stride != 0
95  && b && p >= 0 && a && 0 < q && q <= MAX_Q
96  && tol > 0 && max_iter > 0);
97 
98  /* Compute the first q taps of the impulse response, h_0, ..., h_{q-1} */
99  recursive_filter_impulse(h, q, b, p, a, q);
100 
101  /* Compute dest_m = sum_{n=1}^m h_{m-n} src_n, m = 0, ..., q-1 */
102  for (m = 0; m < q; ++m)
103  for (dest[m] = 0, n = 1; n <= m; ++n)
104  dest[m] += h[m - n] * src[stride * extension(N, n)];
105 
106  for (n = 0; n < max_iter; ++n)
107  {
108  num cur = src[stride * extension(N, -n)];
109 
110  /* dest_m = dest_m + h_{n+m} src_{-n} */
111  for (m = 0; m < q; ++m)
112  dest[m] += h[m] * cur;
113 
114  sum -= fabs(h[0]);
115 
116  if (sum <= tol)
117  break;
118 
119  /* Compute the next impulse response tap, h_{n+q} */
120  h[q] = (n + q <= p) ? b[n + q] : 0;
121 
122  for (m = 1; m <= q; ++m)
123  h[q] -= a[m] * h[q - m];
124 
125  /* Shift the h array for the next iteration */
126  for (m = 0; m < q; ++m)
127  h[m] = h[m + 1];
128  }
129 
130  return;
131 }