pf.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2017, the mcl_3dl authors
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef MCL_3DL_PF_H
31 #define MCL_3DL_PF_H
32 
33 #include <random>
34 #include <vector>
35 #include <algorithm>
36 #include <functional>
37 #include <cmath>
38 
39 namespace mcl_3dl
40 {
41 namespace pf
42 {
43 template <typename FLT_TYPE = float>
45 {
46 public:
47  virtual FLT_TYPE& operator[](const size_t i) = 0;
48  virtual size_t size() const = 0;
49  virtual void normalize() = 0;
50  template <typename T>
51  T operator+(const T& a)
52  {
53  T in = a;
54  T ret;
55  for (size_t i = 0; i < size(); i++)
56  {
57  ret[i] = (*this)[i] + in[i];
58  }
59  return ret;
60  }
61  template <typename T>
62  FLT_TYPE covElement(
63  const T& e, const size_t& j, const size_t& k)
64  {
65  T exp = e;
66  return ((*this)[k] - exp[k]) * ((*this)[j] - exp[j]);
67  }
68  template <typename T>
69  static T generateNoise(
70  std::default_random_engine& engine_,
71  T mean, T sigma)
72  {
73  T noise;
74  for (size_t i = 0; i < noise.size(); i++)
75  {
76  std::normal_distribution<FLT_TYPE> nd(mean[i], sigma[i]);
77  noise[i] = nd(engine_);
78  }
79  return noise;
80  }
81 
82 protected:
83 };
84 
85 template <typename T, typename FLT_TYPE = float>
86 class Particle
87 {
88 public:
90  {
91  probability_ = 0.0;
92  probability_bias_ = 0.0;
93  }
94  explicit Particle(FLT_TYPE prob)
95  {
96  accum_probability_ = prob;
97  }
98  T state_;
99  FLT_TYPE probability_;
102  bool operator<(const Particle& p2) const
103  {
104  return this->accum_probability_ < p2.accum_probability_;
105  }
106 };
107 
108 template <typename T, typename FLT_TYPE = float>
110 {
111 protected:
112  T e_;
113  FLT_TYPE p_sum_;
114 
115 public:
117  : e_()
118  , p_sum_(0.0)
119  {
120  }
121 
122  void add(const T& s, const FLT_TYPE& prob)
123  {
124  p_sum_ += prob;
125 
126  T e1 = s;
127  for (size_t i = 0; i < e1.size(); i++)
128  {
129  e1[i] = e1[i] * prob;
130  }
131  e_ = e1 + e_;
132  }
133 
135  {
136  assert(p_sum_ > 0.0);
137 
138  T s = e_;
139 
140  for (size_t i = 0; i < s.size(); i++)
141  {
142  s[i] = s[i] / p_sum_;
143  }
144 
145  return s;
146  }
147 
149  {
150  return p_sum_;
151  }
152 };
153 
154 template <typename T, typename FLT_TYPE = float, typename MEAN = ParticleWeightedMean<T, FLT_TYPE>>
156 {
157 public:
158  explicit ParticleFilter(const int num_particles)
159  : engine_(seed_gen_())
160  {
161  particles_.resize(num_particles);
162  }
163  void init(T mean, T sigma)
164  {
165  for (auto& p : particles_)
166  {
167  p.state_ = T::generateNoise(engine_, mean, sigma);
168  p.probability_ = 1.0 / particles_.size();
169  }
170  }
171  void resample(T sigma)
172  {
173  FLT_TYPE accum = 0;
174  for (auto& p : particles_)
175  {
176  accum += p.probability_;
177  p.accum_probability_ = accum;
178  }
179 
180  particles_dup_ = particles_;
181  std::sort(particles_dup_.begin(), particles_dup_.end());
182 
183  const FLT_TYPE pstep = accum / particles_.size();
184  auto it = particles_dup_.begin();
185  auto it_prev = particles_dup_.begin();
186  const FLT_TYPE prob = 1.0 / particles_.size();
187  for (size_t i = 0; i < particles_.size(); ++i)
188  {
189  auto &p = particles_[i];
190  const FLT_TYPE pscan = std::nextafter(pstep * (i + 1), static_cast<FLT_TYPE>(0.0));
191  it = std::lower_bound(it, particles_dup_.end(), Particle<T, FLT_TYPE>(pscan));
192  p.probability_ = prob;
193  if (it == particles_dup_.end())
194  {
195  p.state_ = it_prev->state_;
196  continue;
197  }
198  else if (it == it_prev)
199  {
200  p.state_ = it->state_ + T::generateNoise(engine_, T(), sigma);
201  p.state_.normalize();
202  }
203  else
204  {
205  p.state_ = it->state_;
206  }
207  it_prev = it;
208  }
209  }
210  void noise(T sigma)
211  {
212  for (auto& p : particles_)
213  {
214  p.state_ = p.state_ + T::generateNoise(engine_, T(), sigma);
215  }
216  }
217  void predict(std::function<void(T&)> model)
218  {
219  for (auto& p : particles_)
220  {
221  model(p.state_);
222  }
223  }
224  void bias(std::function<void(const T&, float& p_bias)> prob)
225  {
226  for (auto& p : particles_)
227  {
228  prob(p.state_, p.probability_bias_);
229  }
230  }
231  void measure(std::function<FLT_TYPE(const T&)> likelihood)
232  {
233  auto particles_prev = particles_; // backup old
234  FLT_TYPE sum = 0;
235  for (auto& p : particles_)
236  {
237  p.probability_ *= likelihood(p.state_);
238  sum += p.probability_;
239  }
240  if (sum > 0.0)
241  {
242  for (auto& p : particles_)
243  {
244  p.probability_ /= sum;
245  }
246  }
247  else
248  {
249  particles_ = particles_prev;
250  // std::cerr << "No Particle alive, restoring." << std::endl;
251  }
252  }
253  T expectation(const FLT_TYPE pass_ratio = 1.0)
254  {
255  MEAN mean;
256 
257  if (pass_ratio < 1.0)
258  std::sort(particles_.rbegin(), particles_.rend());
259  for (auto& p : particles_)
260  {
261  mean.add(p.state_, p.probability_);
262  if (mean.getTotalProbability() > pass_ratio)
263  break;
264  }
265  return mean.getMean();
266  }
268  {
269  MEAN mean;
270 
271  for (auto& p : particles_)
272  {
273  mean.add(p.state_, p.probability_ * p.probability_bias_);
274  }
275  return mean.getMean();
276  }
277  std::vector<T> covariance(const FLT_TYPE pass_ratio = 1.0)
278  {
279  T e = expectation(pass_ratio);
280  FLT_TYPE p_sum = 0;
281  size_t p_num = 0;
282  std::vector<T> cov;
283  cov.resize(e.size());
284 
285  for (auto& p : particles_)
286  {
287  p_num++;
288  p_sum += p.probability_;
289  if (p_sum > pass_ratio)
290  break;
291  }
292  p_sum = 0;
293  for (auto& p : particles_)
294  {
295  for (size_t j = 0; j < ie_.size(); j++)
296  {
297  for (size_t k = j; k < ie_.size(); k++)
298  {
299  cov[k][j] = cov[j][k] += p.state_.covElement(e, j, k) * p.probability_;
300  }
301  }
302 
303  p_sum += p.probability_;
304  if (p_sum > pass_ratio)
305  break;
306  }
307  for (size_t j = 0; j < ie_.size(); j++)
308  {
309  for (size_t k = j; k < ie_.size(); k++)
310  {
311  cov[k][j] /= p_sum;
312  cov[j][k] /= p_sum;
313  }
314  }
315 
316  return cov;
317  }
318  T max()
319  {
320  T* m = &particles_[0].state_;
321  FLT_TYPE max_probability = particles_[0].probability_;
322  for (auto& p : particles_)
323  {
324  if (max_probability < p.probability_)
325  {
326  max_probability = p.probability_;
327  m = &p.state_;
328  }
329  }
330  return *m;
331  }
333  {
334  T* m = &particles_[0].state_;
335  FLT_TYPE max_probability =
336  particles_[0].probability_ * particles_[0].probability_bias_;
337  for (auto& p : particles_)
338  {
339  const FLT_TYPE prob = p.probability_ * p.probability_bias_;
340  if (max_probability < prob)
341  {
342  max_probability = prob;
343  m = &p.state_;
344  }
345  }
346  return *m;
347  }
348  T getParticle(const size_t i) const
349  {
350  return particles_[i].state_;
351  }
352  size_t getParticleSize() const
353  {
354  return particles_.size();
355  }
356  void resizeParticle(const size_t num)
357  {
358  FLT_TYPE accum = 0;
359  for (auto& p : particles_)
360  {
361  accum += p.probability_;
362  p.accum_probability_ = accum;
363  }
364 
365  particles_dup_ = particles_;
366  std::sort(particles_dup_.begin(), particles_dup_.end());
367 
368  FLT_TYPE pstep = accum / num;
369  FLT_TYPE pscan = 0;
370  auto it = particles_dup_.begin();
371  auto it_prev = particles_dup_.begin();
372 
373  particles_.resize(num);
374 
375  FLT_TYPE prob = 1.0 / num;
376  for (auto& p : particles_)
377  {
378  pscan += pstep;
379  it = std::lower_bound(it, particles_dup_.end(),
380  Particle<T, FLT_TYPE>(pscan));
381  p.probability_ = prob;
382  if (it == particles_dup_.end())
383  {
384  p.state_ = it_prev->state_;
385  continue;
386  }
387  else
388  {
389  p.state_ = it->state_;
390  }
391  it_prev = it;
392  }
393  }
394  typename std::vector<Particle<T, FLT_TYPE>>::iterator appendParticle(const size_t num)
395  {
396  const size_t size_orig = particles_.size();
397  particles_.resize(size_orig + num);
398  return begin() + size_orig;
399  }
400  typename std::vector<Particle<T, FLT_TYPE>>::iterator begin()
401  {
402  return particles_.begin();
403  }
404  typename std::vector<Particle<T, FLT_TYPE>>::iterator end()
405  {
406  return particles_.end();
407  }
408 
409 protected:
410  std::vector<Particle<T, FLT_TYPE>> particles_;
411  std::vector<Particle<T, FLT_TYPE>> particles_dup_;
412  std::random_device seed_gen_;
413  std::default_random_engine engine_;
414  T ie_;
415 };
416 
417 } // namespace pf
418 } // namespace mcl_3dl
419 
420 #endif // MCL_3DL_PF_H
virtual FLT_TYPE & operator[](const size_t i)=0
T expectation(const FLT_TYPE pass_ratio=1.0)
Definition: pf.h:253
XmlRpcServer s
std::vector< Particle< T, FLT_TYPE > > particles_
Definition: pf.h:410
void measure(std::function< FLT_TYPE(const T &)> likelihood)
Definition: pf.h:231
std::vector< Particle< T, FLT_TYPE > >::iterator appendParticle(const size_t num)
Definition: pf.h:394
FLT_TYPE covElement(const T &e, const size_t &j, const size_t &k)
Definition: pf.h:62
std::vector< T > covariance(const FLT_TYPE pass_ratio=1.0)
Definition: pf.h:277
T operator+(const T &a)
Definition: pf.h:51
void predict(std::function< void(T &)> model)
Definition: pf.h:217
size_t getParticleSize() const
Definition: pf.h:352
FLT_TYPE probability_bias_
Definition: pf.h:100
void init(T mean, T sigma)
Definition: pf.h:163
void add(const T &s, const FLT_TYPE &prob)
Definition: pf.h:122
std::vector< Particle< T, FLT_TYPE > >::iterator end()
Definition: pf.h:404
void noise(T sigma)
Definition: pf.h:210
void resample(T sigma)
Definition: pf.h:171
void bias(std::function< void(const T &, float &p_bias)> prob)
Definition: pf.h:224
T getParticle(const size_t i) const
Definition: pf.h:348
bool operator<(const Particle &p2) const
Definition: pf.h:102
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
void resizeParticle(const size_t num)
Definition: pf.h:356
virtual size_t size() const =0
virtual void normalize()=0
FLT_TYPE getTotalProbability()
Definition: pf.h:148
std::vector< Particle< T, FLT_TYPE > > particles_dup_
Definition: pf.h:411
FLT_TYPE probability_
Definition: pf.h:99
ParticleFilter(const int num_particles)
Definition: pf.h:158
std::vector< Particle< T, FLT_TYPE > >::iterator begin()
Definition: pf.h:400
std::default_random_engine engine_
Definition: pf.h:413
FLT_TYPE accum_probability_
Definition: pf.h:101
Particle(FLT_TYPE prob)
Definition: pf.h:94
std::random_device seed_gen_
Definition: pf.h:412
static T generateNoise(std::default_random_engine &engine_, T mean, T sigma)
Definition: pf.h:69


mcl_3dl
Author(s): Atsushi Watanabe
autogenerated on Mon Jul 8 2019 03:32:36