#ifndef _FILTER_H #define _FILTER_H #include #include template class Filter { public: void updateSamples(); void samples( std::vector& data ); // replicate one sample n times, for initialization void nsamples( S& data, int n ); protected: std::vector cur,next; std::vector cdf,weight; void predict(); void makeCdf(); virtual double fixWeight(int i) { return 1.0; } virtual S moveSample( S& sample ) { return sample; } }; /* * Nonsense due to linking problems with templated classes */ using namespace std; template void Filter::nsamples( S& data, int n ) { next.resize(n); weight.resize(next.size()); cdf.resize(next.size()); for (int i = 0; i < next.size(); ++i) { next[i] = data; weight[i] = 1; cdf[i] = i+1; //cdf[n] holds the value of sum[-infty,n] weight } } template void Filter::samples( vector& data ) { if (&next != &data) next = data; weight.resize(next.size()); cdf.resize(next.size()); for (int i = 0; i < next.size(); ++i) { weight[i] = 1; cdf[i] = i+1; //cdf[n] holds the value of sum[-infty,n] weight } } template void Filter::predict() { next.resize(cur.size()); for (int i=0; i=) in the cdf // TODO check that this works with the cdf double choice = (cdf[cdf.size()-1]*rand()/(RAND_MAX+1.0) ); int low, middle, high; low = 0; high = cdf.size(); while (high>(low+1)) { middle = (high+low)/2; if (choice < cdf[middle]) high = middle; else low = middle; } #ifdef DEBUG cout << "Sample advances: " << cur[high] << endl; #endif next[i] = moveSample(cur[high]); } } template void Filter::makeCdf() { if (cdf.size() < 1) return; for (int i=0; i void Filter::updateSamples() { cur = next; /* * pick some of the old samples and map them to new samples using a model * picking is weighted */ predict(); /* * determine the importance of each new sample based on data from observations * recreate the cumulative distribution */ makeCdf(); } #endif