Go to the documentation of this file.00001 #ifndef DATASMOOTHER_H
00002 #define DATASMOOTHER_H
00003
00004 #include <list>
00005 #include <stdio.h>
00006 #include <math.h>
00007 #include <values.h>
00008 #include "stat.h"
00009 #include <assert.h>
00010
00011 namespace GMapping {
00012
00013 class DataSmoother {
00014 public:
00015 struct DataPoint {
00016 DataPoint(double _x=0.0, double _y=0.0) { x=_x;y=_y;}
00017 double x;
00018 double y;
00019 };
00020
00021 typedef std::vector<DataPoint> Data;
00022
00023 DataSmoother(double parzenWindow) {
00024 init(parzenWindow);
00025 };
00026
00027 virtual ~DataSmoother() {
00028 m_data.clear();
00029 m_cummulated.clear();
00030 };
00031
00032 void init(double parzenWindow) {
00033 m_data.clear();
00034 m_cummulated.clear();
00035 m_int=-1;
00036 m_parzenWindow = parzenWindow;
00037 m_from = MAXDOUBLE;
00038 m_to = -MAXDOUBLE;
00039 m_lastStep = 0.001;
00040 };
00041
00042
00043 double sqr(double x) {
00044 return x*x;
00045 }
00046
00047
00048 void setMinToZero() {
00049 double minval=MAXDOUBLE;
00050
00051 for (Data::const_iterator it = m_data.begin(); it != m_data.end(); it++) {
00052 const DataPoint& d = *it;
00053 if (minval > d.y)
00054 minval = d.y;
00055 }
00056
00057 for (Data::iterator it = m_data.begin(); it != m_data.end(); it++) {
00058 DataPoint& d = *it;
00059 d.y = d.y - minval;
00060 }
00061
00062 m_cummulated.clear();
00063 }
00064
00065 void add(double x, double p) {
00066 m_data.push_back(DataPoint(x,p));
00067 m_int=-1;
00068
00069 if (x-3.0*m_parzenWindow < m_from)
00070 m_from = x - 3.0*m_parzenWindow;
00071
00072 if (x+3.0*m_parzenWindow > m_to)
00073 m_to = x + 3.0*m_parzenWindow;
00074
00075 m_cummulated.clear();
00076 }
00077
00078 void integrate(double step) {
00079 m_lastStep = step;
00080 double sum=0;
00081 for (double x=m_from; x<=m_to; x+=step)
00082 sum += smoothedData(x)*step;
00083 m_int = sum;
00084 }
00085
00086 double integral(double step, double xTo) {
00087 double sum=0;
00088 for (double x=m_from; x<=xTo; x+=step)
00089 sum += smoothedData(x)*step;
00090 return sum;
00091 }
00092
00093
00094 double smoothedData(double x) {
00095 assert( m_data.size() > 0 );
00096
00097 double p=0;
00098 double sum_y=0;
00099 for (Data::const_iterator it = m_data.begin(); it != m_data.end(); it++) {
00100 const DataPoint& d = *it;
00101 double dist = fabs(x - d.x);
00102 p += d.y * exp( -0.5 * sqr ( dist/m_parzenWindow ) );
00103 sum_y += d.y;
00104 }
00105 double denom = sqrt(2.0 * M_PI) * (sum_y) * m_parzenWindow;
00106 p *= 1./denom;
00107
00108 return p;
00109 }
00110
00111 double sampleNumeric(double step) {
00112
00113 assert( m_data.size() > 0 );
00114
00115 if (m_int <0 || step != m_lastStep)
00116 integrate(step);
00117
00118 double r = sampleUniformDouble(0.0, m_int);
00119 double sum2=0;
00120 for (double x=m_from; x<=m_to; x+=step) {
00121 sum2 += smoothedData(x)*step;
00122 if (sum2 > r)
00123 return x-0.5*step;
00124 }
00125 return m_to;
00126 }
00127
00128 void computeCummuated() {
00129 assert( m_data.size() > 0 );
00130 m_cummulated.resize(m_data.size());
00131 std::vector<double>::iterator cit = m_cummulated.begin();
00132 double sum=0;
00133 for (Data::const_iterator it = m_data.begin(); it != m_data.end(); ++it) {
00134 sum += it->y;
00135 (*cit) = sum;
00136 ++cit;
00137 }
00138 }
00139
00140 double sample() {
00141
00142 assert( m_data.size() > 0 );
00143
00144 if (m_cummulated.size() == 0) {
00145 computeCummuated();
00146 }
00147 double maxval = m_cummulated.back();
00148
00149 double random = sampleUniformDouble(0.0, maxval);
00150 int nCum = (int) m_cummulated.size();
00151 double sum=0;
00152 int i=0;
00153 while (i<nCum) {
00154 sum += m_cummulated[i];
00155
00156 if (sum >= random) {
00157 return m_data[i].x + sampleGaussian(m_parzenWindow);
00158 }
00159 i++;
00160 }
00161 assert(0);
00162 }
00163
00164
00165 void sampleMultiple(std::vector<double>& samples, int num) {
00166
00167 assert( m_data.size() > 0 );
00168 samples.clear();
00169
00170 if (m_cummulated.size() == 0) {
00171 computeCummuated();
00172 }
00173 double maxval = m_cummulated.back();
00174
00175 std::vector<double> randoms(num);
00176 for (int i=0; i<num; i++)
00177 randoms[i] = sampleUniformDouble(0.0, maxval);
00178
00179 std::sort(randoms.begin(), randoms.end());
00180
00181 int nCum = (int) m_cummulated.size();
00182
00183 double sum=0;
00184 int i=0;
00185 int j=0;
00186 while (i<nCum && j < num) {
00187 sum += m_cummulated[i];
00188
00189 while (sum >= randoms[j] && j < num) {
00190 samples.push_back( m_data[i].x + sampleGaussian(m_parzenWindow) );
00191 j++;
00192 }
00193 i++;
00194 }
00195 }
00196
00197
00198
00199 void approxGauss(double step, double* mean, double* sigma) {
00200
00201 assert( m_data.size() > 0 );
00202
00203 double sum=0;
00204 double d=0;
00205
00206 *mean=0;
00207 for (double x=m_from; x<=m_to; x+=step) {
00208 d = smoothedData(x);
00209 sum += d;
00210 *mean += x*d;
00211 }
00212 *mean /= sum;
00213
00214 double var=0;
00215 for (double x=m_from; x<=m_to; x+=step) {
00216 d = smoothedData(x);
00217 var += sqr(x-*mean) * d;
00218 }
00219 var /= sum;
00220
00221 *sigma = sqrt(var);
00222 }
00223
00224 double gauss(double x, double mean, double sigma) {
00225 return 1.0/(sqrt(2.0*M_PI)*sigma) * exp(-0.5 * sqr( (x-mean)/sigma));
00226 }
00227
00228 double cramerVonMisesToGauss(double step, double mean, double sigma) {
00229
00230 double p=0;
00231 double s=0;
00232 double g=0;
00233 double sint=0;
00234 double gint=0;
00235
00236 for (double x=m_from; x<=m_to; x+=step) {
00237 s = smoothedData(x);
00238 sint += s * step;
00239
00240 g = gauss(x, mean, sigma);
00241 gint += g * step;
00242
00243 p += sqr( (sint - gint) );
00244 }
00245
00246 return p;
00247 }
00248
00249 double kldToGauss(double step, double mean, double sigma) {
00250
00251 double p=0;
00252 double d=0;
00253 double g=0;
00254
00255 double sd=0;
00256 double sg=0;
00257
00258 for (double x=m_from; x<=m_to; x+=step) {
00259
00260 d = 1e-10 + smoothedData(x);
00261 g = 1e-10 + gauss(x, mean, sigma);
00262
00263 sd += d;
00264 sg += g;
00265
00266 p += d * log(d/g);
00267 }
00268
00269 sd *= step;
00270 sg *= step;
00271
00272 if (fabs(sd-sg) > 0.1)
00273 assert(0);
00274
00275 p *= step;
00276 return p;
00277 }
00278
00279
00280 void gnuplotDumpData(FILE* fp) {
00281 for (Data::const_iterator it = m_data.begin(); it != m_data.end(); it++) {
00282 const DataPoint& d = *it;
00283 fprintf(fp, "%f %f\n", d.x, d.y);
00284 }
00285 }
00286
00287 void gnuplotDumpSmoothedData(FILE* fp, double step) {
00288 for (double x=m_from; x<=m_to; x+=step)
00289 fprintf(fp, "%f %f\n", x, smoothedData(x));
00290 }
00291
00292 protected:
00293 Data m_data;
00294 std::vector<double> m_cummulated;
00295 double m_int;
00296 double m_lastStep;
00297
00298 double m_parzenWindow;
00299 double m_from;
00300 double m_to;
00301
00302 };
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 }
00450
00451 #endif