particlefilter.h
Go to the documentation of this file.
1 #ifndef PARTICLEFILTER_H
2 #define PARTICLEFILTER_H
3 #include <stdlib.h>
4 #include <float.h>
5 #include <sys/types.h>
6 #include<vector>
7 #include<utility>
8 #include<cmath>
10 
11 
22 typedef std::pair<uint,uint> UIntPair;
23 
24 template <class OutputIterator, class Iterator>
25 double toNormalForm(OutputIterator& out, const Iterator & begin, const Iterator & end){
26  //determine the maximum
27  //double lmax=-MAXDOUBLE;
28  double lmax=-DBL_MAX;
29  for (Iterator it=begin; it!=end; it++){
30  lmax=lmax>((double)(*it))? lmax: (double)(*it);
31  }
32  //convert to raw form
33  for (Iterator it=begin; it!=end; it++){
34  *out=exp((double)(*it)-lmax);
35  out++;
36  }
37  return lmax;
38 }
39 
40 template <class OutputIterator, class Iterator, class Numeric>
41 void toLogForm(OutputIterator& out, const Iterator & begin, const Iterator & end, Numeric lmax){
42  //determine the maximum
43  for (Iterator it=begin; it!=end; it++){
44  *out=log((Numeric)(*it))-lmax;
45  out++;
46  }
47  return lmax;
48 }
49 
50 template <class WeightVector>
51 void resample(std::vector<int>& indexes, const WeightVector& weights, unsigned int nparticles=0){
52  double cweight=0;
53 
54  //compute the cumulative weights
55  unsigned int n=0;
56  for (typename WeightVector::const_iterator it=weights.begin(); it!=weights.end(); ++it){
57  cweight+=(double)*it;
58  n++;
59  }
60 
61  if (nparticles>0)
62  n=nparticles;
63 
64  //compute the interval
65  double interval=cweight/n;
66 
67  //compute the initial target weight
68  double target=interval*::drand48();
69  //compute the resampled indexes
70 
71  cweight=0;
72  indexes.resize(n);
73 
74  n=0;
75  unsigned int i=0;
76  for (typename WeightVector::const_iterator it=weights.begin(); it!=weights.end(); ++it, ++i){
77  cweight+=(double)* it;
78  while(cweight>target){
79  indexes[n++]=i;
80  target+=interval;
81  }
82  }
83 }
84 
85 template <typename Vector>
86 void repeatIndexes(Vector& dest, const std::vector<int>& indexes, const Vector& particles){
87  assert(indexes.size()==particles.size());
88  dest.resize(particles.size());
89  unsigned int i=0;
90  for (std::vector<int>::const_iterator it=indexes.begin(); it!=indexes.end(); ++it){
91  dest[i]=particles[*it];
92  i++;
93  }
94 }
95 
96 
97 template <class Iterator>
98 double neff(const Iterator& begin, const Iterator& end){
99  double sum=0;
100  for (Iterator it=begin; it!=end; ++it){
101  sum+=*it;
102  }
103  double cum=0;
104  for (Iterator it=begin; it!=end; ++it){
105  double w=*it/sum;
106  cum+=w*w;
107  }
108  return 1./cum;
109 }
110 
111 template <class Iterator>
112 void normalize(const Iterator& begin, const Iterator& end){
113  double sum=0;
114  for (Iterator it=begin; it!=end; ++it){
115  sum+=*it;
116  }
117  for (Iterator it=begin; it!=end; ++it){
118  *it=*it/sum;
119  }
120 }
121 
122 template <class OutputIterator, class Iterator>
123 void rle(OutputIterator& out, const Iterator & begin, const Iterator & end){
124  unsigned int current=0;
125  unsigned int count=0;
126  for (Iterator it=begin; it!=end; it++){
127  if (it==begin){
128  current=*it;
129  count=1;
130  continue;
131  }
132  if (((uint)*it) ==current)
133  count++;
134  if (((uint)*it)!=current){
135  *out=std::make_pair(current,count);
136  out++;
137  current=*it;
138  count=1;
139  }
140  }
141  if (count>0)
142  *out=std::make_pair(current,count);
143  out++;
144 }
145 
146 //BEGIN legacy
147 template <class Particle, class Numeric>
149  std::vector<unsigned int> resampleIndexes(const std::vector<Particle> & particles, int nparticles=0) const;
150  std::vector<Particle> resample(const std::vector<Particle> & particles, int nparticles=0) const;
151  Numeric neff(const std::vector<Particle> & particles) const;
152 };
153 
154 /*Implementation of the above stuff*/
155 template <class Particle, class Numeric>
156 std::vector<unsigned int> uniform_resampler<Particle, Numeric>:: resampleIndexes(const std::vector<Particle>& particles, int nparticles) const{
157  Numeric cweight=0;
158 
159  //compute the cumulative weights
160  unsigned int n=0;
161  for (typename std::vector<Particle>::const_iterator it=particles.begin(); it!=particles.end(); ++it){
162  cweight+=(Numeric)*it;
163  n++;
164  }
165 
166  if (nparticles>0)
167  n=nparticles;
168 
169  //compute the interval
170  Numeric interval=cweight/n;
171 
172  //compute the initial target weight
173  Numeric target=interval*::drand48();
174  //compute the resampled indexes
175 
176  cweight=0;
177  std::vector<unsigned int> indexes(n);
178  n=0;
179  unsigned int i=0;
180  for (typename std::vector<Particle>::const_iterator it=particles.begin(); it!=particles.end(); ++it, ++i){
181  cweight+=(Numeric)* it;
182  while(cweight>target){
183  indexes[n++]=i;
184  target+=interval;
185  }
186  }
187  return indexes;
188 }
189 
190 template <class Particle, class Numeric>
192  (const typename std::vector<Particle>& particles, int nparticles) const{
193  Numeric cweight=0;
194 
195  //compute the cumulative weights
196  unsigned int n=0;
197  for (typename std::vector<Particle>::const_iterator it=particles.begin(); it!=particles.end(); ++it){
198  cweight+=(Numeric)*it;
199  n++;
200  }
201 
202  if (nparticles>0)
203  n=nparticles;
204 
205  //weight of the particles after resampling
206  double uw=1./n;
207 
208  //compute the interval
209  Numeric interval=cweight/n;
210 
211  //compute the initial target weight
212  Numeric target=interval*::drand48();
213  //compute the resampled indexes
214 
215  cweight=0;
216  std::vector<Particle> resampled;
217  n=0;
218  unsigned int i=0;
219  for (typename std::vector<Particle>::const_iterator it=particles.begin(); it!=particles.end(); ++it, ++i){
220  cweight+=(Numeric)*it;
221  while(cweight>target){
222  resampled.push_back(*it);
223  resampled.back().setWeight(uw);
224  target+=interval;
225  }
226  }
227  return resampled;
228 }
229 
230 template <class Particle, class Numeric>
231 Numeric uniform_resampler<Particle,Numeric>::neff(const std::vector<Particle> & particles) const{
232  double cum=0;
233  double sum=0;
234  for (typename std::vector<Particle>::const_iterator it=particles.begin(); it!=particles.end(); ++it){
235  Numeric w=(Numeric)*it;
236  cum+=w*w;
237  sum+=w;
238  }
239  return sum*sum/cum;
240 }
241 
242 
243 /*
244 
245 The following are patterns for the evolution and the observation classes
246 The user should implement classes having the specified meaning
247 
248 template <class State, class Numeric, class Observation>
249 struct observer{
250  Observation& observation
251  Numeric observe(const class State&) const;
252 };
253 
254 template <class State, class Numeric, class Input>
255 struct evolver{
256  Input& input;
257  State& evolve(const State& s);
258 };
259 */
260 
261 
262 template <class Particle, class EvolutionModel>
263 struct evolver{
265  void evolve(std::vector<Particle>& particles);
266  void evolve(std::vector<Particle>& dest, const std::vector<Particle>& src);
267 };
268 
269 template <class Particle, class EvolutionModel>
270 void evolver<Particle, EvolutionModel>::evolve(std::vector<Particle>& particles){
271  for (typename std::vector<Particle>::iterator it=particles.begin(); it!=particles.end(); ++it){
272  *it=evolutionModel.evolve(*it);
273  }
274 }
275 
276 template <class Particle, class EvolutionModel>
277 void evolver<Particle, EvolutionModel>::evolve(std::vector<Particle>& dest, const std::vector<Particle>& src){
278  dest.clear();
279  for (typename std::vector<Particle>::const_iterator it=src.begin(); it!=src.end(); ++it)
280  dest.push_back(evolutionModel.evolve(*it));
281 }
282 
283 
284 template <class Particle, class Numeric, class QualificationModel, class EvolutionModel, class LikelyhoodModel>
289  void evolve(std::vector<Particle>& particles);
290  void evolve(std::vector<Particle>& dest, const std::vector<Particle>& src);
291 };
292 
293 template <class Particle, class Numeric, class QualificationModel, class EvolutionModel, class LikelyhoodModel>
295  (std::vector<Particle>&particles){
296  std::vector<Numeric> observationWeights(particles.size());
297  unsigned int i=0;
298  for (typename std::vector<Particle>::const_iterator it=particles.begin(); it!=particles.end(); ++it, i++){
299  observationWeights[i]=likelyhoodModel.likelyhood(qualificationModel.evolve(*it));
300  }
302  std::vector<unsigned int> indexes(resampler.resampleIndexes(observationWeights));
303  for (typename std::vector<unsigned int>::const_iterator it=indexes.begin(); it!=indexes.end(); it++){
304  Particle & particle=particles[*it];
305  particle=evolutionModel.evolve(particle);
306  particle.setWeight(likelyhoodModel.likelyhood(particle)/observationWeights[*it]);
307  }
308 }
309 
310 template <class Particle, class Numeric, class QualificationModel, class EvolutionModel, class LikelyhoodModel>
312  (std::vector<Particle>& dest, const std::vector<Particle>& src){
313  dest.clear();
314  std::vector<Numeric> observationWeights(src.size());
315  unsigned int i=0;
316  for (typename std::vector<Particle>::const_iterator it=src.begin(); it!=src.end(); ++it, i++){
317  observationWeights[i]=likelyhoodModel.likelyhood(qualificationModel.evolve(*it));
318  }
320  std::vector<unsigned int> indexes(resampler.resampleIndexes(observationWeights));
321  for (typename std::vector<unsigned int>::const_iterator it=indexes.begin(); it!=indexes.end(); it++){
322  Particle & particle=src[*it];
323  dest.push_back(evolutionModel.evolve(particle));
324  dest.back().weight*=likelyhoodModel.likelyhood(particle)/observationWeights[*it];
325  }
326 }
327 //END legacy
328 
329 #endif
toNormalForm
double toNormalForm(OutputIterator &out, const Iterator &begin, const Iterator &end)
Definition: particlefilter.h:25
auxiliary_evolver::evolutionModel
EvolutionModel evolutionModel
Definition: particlefilter.h:286
normalize
void normalize(const Iterator &begin, const Iterator &end)
Definition: particlefilter.h:112
uniform_resampler
Definition: particlefilter.h:148
UIntPair
std::pair< uint, uint > UIntPair
Definition: particlefilter.h:22
uniform_resampler::resampleIndexes
std::vector< unsigned int > resampleIndexes(const std::vector< Particle > &particles, int nparticles=0) const
Definition: particlefilter.h:156
n
#define n
Definition: eig3.cpp:11
Particle::setWeight
void setWeight(double _w)
Definition: particlefilter_test.cpp:15
EvolutionModel
Definition: particlefilter_test.cpp:26
Particle
Definition: particlefilter_test.cpp:11
evolver
Definition: particlefilter.h:263
rle
void rle(OutputIterator &out, const Iterator &begin, const Iterator &end)
Definition: particlefilter.h:123
LikelyhoodModel
Definition: particlefilter_test.cpp:40
evolver::evolve
void evolve(std::vector< Particle > &particles)
Definition: particlefilter.h:270
auxiliary_evolver::qualificationModel
QualificationModel qualificationModel
Definition: particlefilter.h:287
toLogForm
void toLogForm(OutputIterator &out, const Iterator &begin, const Iterator &end, Numeric lmax)
Definition: particlefilter.h:41
gvalues.h
uniform_resampler::resample
std::vector< Particle > resample(const std::vector< Particle > &particles, int nparticles=0) const
Definition: particlefilter.h:192
evolver::evolutionModel
EvolutionModel evolutionModel
Definition: particlefilter.h:264
neff
double neff(const Iterator &begin, const Iterator &end)
Definition: particlefilter.h:98
uniform_resampler::neff
Numeric neff(const std::vector< Particle > &particles) const
Definition: particlefilter.h:231
auxiliary_evolver
Definition: particlefilter.h:285
auxiliary_evolver::evolve
void evolve(std::vector< Particle > &particles)
Definition: particlefilter.h:295
resample
void resample(std::vector< int > &indexes, const WeightVector &weights, unsigned int nparticles=0)
Definition: particlefilter.h:51
auxiliary_evolver::likelyhoodModel
LikelyhoodModel likelyhoodModel
Definition: particlefilter.h:288
QualificationModel
Definition: particlefilter_test.cpp:34
repeatIndexes
void repeatIndexes(Vector &dest, const std::vector< int > &indexes, const Vector &particles)
Definition: particlefilter.h:86


openslam_gmapping
Author(s): Cyrill Stachniss, Udo Frese, Giorgio Grisetti, Wolfram Burgard
autogenerated on Thu Oct 19 2023 02:25:51