A Survey of Gaussian Convolution Algorithms
gaussian_short_conv.c
Go to the documentation of this file.
1 
20 #include "gaussian_short_conv.h"
21 #include <assert.h>
22 #include <math.h>
23 
24 #ifndef M_PI_4
25 
26 #define M_PI_4 0.78539816339744830961566084581987572
27 #endif
28 
29 /* Define coefficients for computing short DCTs */
30 #ifndef M_1_SQRT2
31 
32 #define M_1_SQRT2 0.70710678118654752440084436210484904
33 #endif
34 #ifndef M_SQRT3
35 
36 #define M_SQRT3 1.73205080756887729352744634150587237
37 #endif
38 #ifndef M_COSPI_8
39 
40 #define M_COSPI_8 0.92387953251128675612818318939678829
41 #endif
42 #ifndef M_COSPI3_8
43 
44 #define M_COSPI3_8 0.38268343236508977172845998403039887
45 #endif
46 
47 
63 void gaussian_short_conv(num *dest, const num *src,
64  long N, long stride, num sigma)
65 {
66  double alpha = (2.0 * M_PI_4 * M_PI_4) * (sigma * sigma);
67 
68  assert(dest && src && 0 < N && N <= 4 && stride != 0 && sigma > 0);
69 
70  switch (N)
71  {
72  case 1:
73  dest[0] = src[0];
74  break;
75  case 2:
76  {
77  double F0 = 0.5 * (src[0] + src[stride]);
78  double F1 = 0.5 * (src[0] - src[stride]);
79  F1 *= exp(-alpha);
80  dest[0] = (num)(F0 + F1);
81  dest[stride] = (num)(F0 - F1);
82  }
83  break;
84  case 3:
85  {
86  double F0 = (src[0] + src[stride] + src[stride * 2]) / 3.0;
87  double F1 = ((0.5*M_SQRT3) * (src[0] - src[stride * 2])) / 3.0;
88  double F2 = (0.5*(src[0] + src[stride * 2]) - src[stride]) / 3.0;
89  F1 *= exp(-alpha);
90  F2 *= exp(-4.0 * alpha);
91  dest[0] = (num)(F0 + M_SQRT3 * F1 + F2);
92  dest[stride] = (num)(F0 - 2.0 * F2);
93  dest[stride * 2] = (num)(F0 - M_SQRT3 * F1 + F2);
94  }
95  break;
96  case 4:
97  {
98  double F0 = (src[0] + src[stride]
99  + src[stride * 2] + src[stride * 3]) / 4.0;
100  double F1 = (M_COSPI_8 * (src[0] - src[stride * 3])
101  + M_COSPI3_8 * (src[stride] - src[stride * 2])) / 4.0;
102  double F2 = (M_1_SQRT2 * (src[0] - src[stride]
103  + src[stride * 2] - src[stride * 3])) / 4.0;
104  double F3 = (M_COSPI3_8 * (src[0] - src[stride * 3])
105  - M_COSPI_8 * (src[stride] - src[stride * 2])) / 4.0;
106  F1 *= exp(-alpha);
107  F2 *= exp(-4.0 * alpha);
108  F3 *= exp(-9.0 * alpha);
109  dest[0] = (num)(F0 + 2.0 *
110  (M_COSPI_8 * F1 + M_1_SQRT2 * F2 + M_COSPI3_8 * F3));
111  dest[stride] = (num)(F0 + 2.0 *
112  (M_COSPI3_8 * F1 - M_1_SQRT2 * F2 - M_COSPI_8 * F3));
113  dest[stride * 2] = (num)(F0 + 2.0 *
114  (-M_COSPI3_8 * F1 - M_1_SQRT2 * F2 + M_COSPI_8 * F3));
115  dest[stride * 3] = (num)(F0 + 2.0 *
116  (-M_COSPI_8 * F1 + M_1_SQRT2 * F2 - M_COSPI3_8 * F3));
117  }
118  break;
119  }
120 
121  return;
122 }