00001 #ifndef Impala_Core_Array_MakeGaussian1d_h
00002 #define Impala_Core_Array_MakeGaussian1d_h
00003
00004
00005 #include "Core/Array/Arrays.h"
00006
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Array
00012 {
00013
00014
00015
00016
00017
00018
00019 static inline double
00020 Gauss(const double x, const double sigma)
00021 {
00022
00023 return exp(-0.5 * x * x / (sigma*sigma));
00024 }
00025
00026 static inline double
00027 Hermite(const double x, const double H0, const double sigma, const int order)
00028 {
00029 if (!order)
00030 return H0;
00031
00032 double a = 1./(sigma*sigma);
00033 double ax = a*x;
00034 double Hnmin1 = H0;
00035 double Hn = -ax*H0;
00036
00037 int n;
00038 for( n = 2; n <= order; n++ ) {
00039 double Hnmin2 = Hnmin1;
00040 Hnmin1 = Hn;
00041 Hn = a*(1-n)*Hnmin2 - ax*Hnmin1;
00042 }
00043
00044 return (order%2) ? -Hn : Hn;
00045 }
00046
00047 static inline int
00048 filterWidth(double sigma, int deri, double acc, int maxlen)
00049 {
00050 double acc2;
00051 int fsize;
00052
00053 acc2 = 1.0 - (1.0 - acc)/2.0;
00054
00055 fsize = 2*int(acc*sigma+0.5)+1;
00056
00057
00058
00059
00060 if ( !(maxlen%2) )
00061 maxlen--;
00062 if (fsize > maxlen)
00063 fsize = maxlen;
00064
00065 return fsize;
00066 }
00067
00068 static inline double*
00069 makeFilter(double sigma, int deri, double acc, int fsize, int maxfsize)
00070 {
00071 double* filter = new double[fsize];
00072
00073 fsize = fsize/2;
00074 double* center = filter + fsize;
00075
00076
00077 int i;
00078 double sum = Gauss(0.0, sigma);
00079 center[0] = sum;
00080
00081 for (i=1; i<=fsize; i++) {
00082 double val = Gauss(i, sigma);
00083 sum += val+val;
00084 center[i] = val;
00085 center[-i] = val;
00086 }
00087
00088
00089 for (i=-fsize; i<=fsize; i++)
00090 center[i] /= sum;
00091
00092
00093 if (deri > 0)
00094 for (i=-fsize; i<=fsize; i++)
00095 center[i] = Hermite(i, center[i], sigma, deri);
00096
00097 fsize = fsize * 2 + 1;
00098 return filter;
00099 }
00100
00103 inline Array2dScalarReal64*
00104 MakeGaussian1d(double sigma, int deri, double acc, int maxfsize, int fsize = 0)
00105 {
00106 if (fsize < 1) {
00107 fsize = filterWidth(sigma, deri, acc, maxfsize);
00108 }
00109
00110 double* fData = makeFilter(sigma, deri, acc, fsize, maxfsize);
00111 return ArrayCreate<Array2dScalarReal64>(fsize, 1, 0, 0, fData);
00112 }
00113
00114 }
00115 }
00116 }
00117
00118 #endif