Bayes Filters Library
ResamplingWithPrior.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-2019 Istituto Italiano di Tecnologia (IIT)
3  *
4  * This software may be modified and distributed under the terms of the
5  * BSD 3-Clause license. See the accompanying LICENSE file for details.
6  */
7 
9 #include <BayesFilters/utils.h>
10 
11 #include <algorithm>
12 #include <numeric>
13 #include <vector>
14 
15 using namespace bfl;
16 using namespace Eigen;
17 
18 
19 ResamplingWithPrior::ResamplingWithPrior(std::unique_ptr<bfl::ParticleSetInitialization> init_model, const double prior_ratio, const unsigned int seed) noexcept :
20  Resampling(seed),
21  init_model_(std::move(init_model)),
22  prior_ratio_(prior_ratio)
23 { }
24 
25 
26 ResamplingWithPrior::ResamplingWithPrior(std::unique_ptr<ParticleSetInitialization> init_model, const double prior_ratio) noexcept :
27  Resampling(1),
28  init_model_(std::move(init_model)),
29  prior_ratio_(prior_ratio)
30 { }
31 
32 
33 ResamplingWithPrior::ResamplingWithPrior(std::unique_ptr<ParticleSetInitialization> init_model) noexcept :
34  Resampling(1),
35  init_model_(std::move(init_model))
36 { }
37 
38 
40  Resampling(std::move(resampling)),
41  init_model_(std::move(resampling.init_model_))
42 {
43  prior_ratio_ = resampling.prior_ratio_;
44  resampling.prior_ratio_ = 0.5;
45 }
46 
47 
49 {
50  if (this == &resampling)
51  return *this;
52 
53  Resampling::operator=(std::move(resampling));
54 
55  init_model_ = std::move(resampling.init_model_);
56 
57  return *this;
58 }
59 
60 
61 void ResamplingWithPrior::resample(const ParticleSet& cor_particles, ParticleSet& res_particles, Ref<VectorXi> res_parents)
62 {
63  int num_prior_particles = static_cast<int>(std::floor(cor_particles.state().cols() * prior_ratio_));
64  int num_resample_particles = cor_particles.state().cols() - num_prior_particles;
65 
66  /* Consider two subsets of particles. */
67  ParticleSet res_particles_left(num_prior_particles, cor_particles.dim_linear, cor_particles.dim_circular);
68  ParticleSet res_particles_right(num_resample_particles, cor_particles.dim_linear, cor_particles.dim_circular);
69  Ref<VectorXi> res_parents_right(res_parents.tail(num_resample_particles));
70 
71  /* Copy particles to be resampled in a temporary. */
72  ParticleSet tmp_particles(num_resample_particles, cor_particles.dim_linear, cor_particles.dim_circular);
73  int j = 0;
74  for (std::size_t i : sort_indices(cor_particles.weight().array().exp()))
75  {
76  if (j >= num_prior_particles)
77  {
78  tmp_particles.state(j - num_prior_particles) = cor_particles.state(i);
79  tmp_particles.mean(j - num_prior_particles) = cor_particles.mean(i);
80  tmp_particles.covariance(j - num_prior_particles) = cor_particles.covariance(i);
81  tmp_particles.weight(j - num_prior_particles) = cor_particles.weight(i);
82  }
83  j++;
84  }
85 
86  /* Normalize weights using LogSumExp. */
87  tmp_particles.weight().array() -= utils::log_sum_exp(tmp_particles.weight());
88 
89  /* Resample from tmp_particles. */
90  Resampling::resample(tmp_particles, res_particles_right, res_parents_right);
91  res_parents_right.array() += num_prior_particles;
92 
93  /* Initialize from scratch num_prior_particles particles. */
94  init_model_->initialize(res_particles_left);
95 
96  /* Merge the two subset together. */
97  res_particles = std::move(res_particles_left + res_particles_right);
98 
99  /* Reset weights.*/
100  res_particles.weight().setConstant(-std::log(cor_particles.state().cols()));
101 
102  /* Since num_prior_particles were created from scratch,
103  they do not have a parent. */
104  res_parents.head(num_prior_particles).array() = -1;
105 }
106 
107 
108 std::vector<unsigned int> ResamplingWithPrior::sort_indices(const Ref<const VectorXd>& vector)
109 {
110  std::vector<unsigned int> idx(vector.size());
111  std::iota(idx.begin(), idx.end(), 0);
112 
113  std::sort(idx.begin(), idx.end(),
114  [&vector](size_t idx1, size_t idx2) { return vector[idx1] < vector[idx2]; });
115 
116  return idx;
117 }
bfl::ResamplingWithPrior::ResamplingWithPrior
ResamplingWithPrior(std::unique_ptr< bfl::ParticleSetInitialization > init_model, const double prior_ratio, const unsigned int seed) noexcept
Definition: ResamplingWithPrior.cpp:19
bfl::GaussianMixture::dim_circular
std::size_t dim_circular
Definition: GaussianMixture.h:77
bfl::utils::log_sum_exp
double log_sum_exp(const Eigen::MatrixBase< Derived > &data)
Return the element-wise logarithm of the sum of exponentials of the input data.
Definition: utils.h:72
bfl::ResamplingWithPrior::operator=
ResamplingWithPrior & operator=(ResamplingWithPrior &&resampling) noexcept
Definition: ResamplingWithPrior.cpp:48
bfl::Resampling::resample
virtual void resample(const bfl::ParticleSet &cor_particles, bfl::ParticleSet &res_particles, Eigen::Ref< Eigen::VectorXi > res_parents)
Definition: Resampling.cpp:67
bfl
Port of boost::any for C++11 compilers.
Definition: AdditiveMeasurementModel.h:13
bfl::GaussianMixture::dim_linear
std::size_t dim_linear
Definition: GaussianMixture.h:75
bfl::GaussianMixture::mean
Eigen::Ref< Eigen::MatrixXd > mean()
Definition: GaussianMixture.cpp:94
bfl::ResamplingWithPrior
Definition: ResamplingWithPrior.h:25
bfl::ResamplingWithPrior::resample
void resample(const ParticleSet &cor_particles, ParticleSet &res_particles, Eigen::Ref< Eigen::VectorXi > res_parents) override
Definition: ResamplingWithPrior.cpp:61
utils.h
ResamplingWithPrior.h
bfl::GaussianMixture::covariance
Eigen::Ref< Eigen::MatrixXd > covariance()
Definition: GaussianMixture.cpp:130
bfl::ResamplingWithPrior::sort_indices
std::vector< unsigned int > sort_indices(const Eigen::Ref< const Eigen::VectorXd > &vector)
Definition: ResamplingWithPrior.cpp:108
bfl::Resampling
Definition: Resampling.h:22
bfl::ParticleSet::state
Eigen::Ref< Eigen::MatrixXd > state()
Definition: ParticleSet.cpp:84
bfl::ParticleSet
Definition: ParticleSet.h:20
bfl::GaussianMixture::weight
Eigen::Ref< Eigen::VectorXd > weight()
Definition: GaussianMixture.cpp:166
bfl::Resampling::operator=
Resampling & operator=(const Resampling &resampling)
Definition: Resampling.cpp:36