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


openslam_gmapping
Author(s): Giorgio Grisetti, Cyrill Stachniss, Wolfram Burgard
autogenerated on Mon Jun 10 2019 14:04:22