Main MRPT website > C++ reference for MRPT 1.9.9
CParticleFilterData.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef CParticleFilterData_H
10 #define CParticleFilterData_H
11 
12 #include <mrpt/utils/core_defs.h>
15 
16 
17 #include <deque>
18 #include <algorithm>
19 
20 namespace mrpt
21 {
22 namespace bayes
23 {
24 /** A curiously recurring template pattern (CRTP) approach to providing the
25  * basic functionality of any CParticleFilterData<> class.
26  * Users should inherit from CParticleFilterData<>, which in turn will
27  * automatically inhirit from this base class.
28  * \sa CParticleFilter, CParticleFilterCapable, CParticleFilterData
29  * \ingroup mrpt_base_grp
30  */
31 template <class Derived, class particle_list_t>
33 {
34  /// CRTP helper method
35  inline const Derived& derived() const
36  {
37  return *dynamic_cast<const Derived*>(this);
38  }
39  /// CRTP helper method
40  inline Derived& derived() { return *dynamic_cast<Derived*>(this); }
41  double getW(size_t i) const override
42  {
43  if (i >= derived().m_particles.size())
44  THROW_EXCEPTION_FMT("Index %i is out of range!", (int)i);
45  return derived().m_particles[i].log_w;
46  }
47 
48  void setW(size_t i, double w) override
49  {
50  if (i >= derived().m_particles.size())
51  THROW_EXCEPTION_FMT("Index %i is out of range!", (int)i);
52  derived().m_particles[i].log_w = w;
53  }
54 
55  size_t particlesCount() const override
56  {
57  return derived().m_particles.size();
58  }
59 
60  double normalizeWeights(double* out_max_log_w = nullptr) override
61  {
63  if (derived().m_particles.empty()) return 0;
64  double minW = derived().m_particles[0].log_w;
65  double maxW = minW;
66 
67  /* Compute the max/min of weights: */
68  for (typename particle_list_t::iterator it =
69  derived().m_particles.begin();
70  it != derived().m_particles.end(); ++it)
71  {
72  maxW = std::max<double>(maxW, it->log_w);
73  minW = std::min<double>(minW, it->log_w);
74  }
75  /* Normalize: */
76  for (typename particle_list_t::iterator it =
77  derived().m_particles.begin();
78  it != derived().m_particles.end(); ++it)
79  it->log_w -= maxW;
80  if (out_max_log_w) *out_max_log_w = maxW;
81 
82  /* Return the max/min ratio: */
83  return exp(maxW - minW);
84  MRPT_END
85  }
86 
87  double ESS() const override
88  {
90  double cum = 0;
91 
92  /* Sum of weights: */
93  double sumLinearWeights = 0;
94  for (typename particle_list_t::const_iterator it =
95  derived().m_particles.begin();
96  it != derived().m_particles.end(); ++it)
97  sumLinearWeights += exp(it->log_w);
98  /* Compute ESS: */
99  for (typename particle_list_t::const_iterator it =
100  derived().m_particles.begin();
101  it != derived().m_particles.end(); ++it)
102  cum += utils::square(exp(it->log_w) / sumLinearWeights);
103 
104  if (cum == 0)
105  return 0;
106  else
107  return 1.0 / (derived().m_particles.size() * cum);
108  MRPT_END
109  }
110 
111  /** Replaces the old particles by copies determined by the indexes in
112  * "indx", performing an efficient copy of the necesary particles only and
113  * allowing the number of particles to change.*/
114  void performSubstitution(const std::vector<size_t>& indx) override
115  {
116  MRPT_START
117  particle_list_t parts;
118  typename particle_list_t::iterator itDest, itSrc;
119  const size_t M_old = derived().m_particles.size();
120  size_t i, j, lastIndxOld = 0;
121  std::vector<bool> oldParticlesReused(M_old, false);
123  std::vector<size_t> sorted_indx(indx);
124 
125  /* Assure the input index is sorted: */
126  std::sort(sorted_indx.begin(), sorted_indx.end());
127  /* Set the new size: */
128  parts.resize(sorted_indx.size());
129  for (i = 0, itDest = parts.begin(); itDest != parts.end();
130  i++, itDest++)
131  {
132  const size_t sorted_idx = sorted_indx[i];
133  itDest->log_w = derived().m_particles[sorted_idx].log_w;
134  /* We can safely delete old m_particles from [lastIndxOld,indx[i]-1]
135  * (inclusive): */
136  for (j = lastIndxOld; j < sorted_idx; j++)
137  {
138  if (!oldParticlesReused
139  [j]) /* If reused we can not delete that memory! */
140  derived().m_particles[j].d.reset();
141  }
142 
143  /* For the next iteration:*/
144  lastIndxOld = sorted_idx;
145 
146  /* If this is the first time that the old particle "indx[i]"
147  * appears, */
148  /* we can reuse the old "data" instead of creating a new copy: */
149  if (!oldParticlesReused[sorted_idx])
150  {
151  /* Reuse the data from the particle: */
152  parts[i].d.reset(derived().m_particles[sorted_idx].d.get());
153  oldParticlesReused[sorted_idx] = true;
154  }
155  else
156  {
157  /* Make a copy of the particle's data: */
158  ASSERT_(derived().m_particles[sorted_idx].d);
159  parts[i].d.reset(new typename Derived::CParticleDataContent(
160  *derived().m_particles[sorted_idx].d));
161  }
162  }
163  /* Free memory of unused particles */
164  for (itSrc = derived().m_particles.begin(),
165  oldPartIt = oldParticlesReused.begin();
166  itSrc != derived().m_particles.end(); itSrc++, oldPartIt++)
167  if (!*oldPartIt) itSrc->d.reset();
168  /* Copy the pointers only to the final destination */
169  derived().m_particles.resize(parts.size());
170  for (itSrc = parts.begin(), itDest = derived().m_particles.begin();
171  itSrc != parts.end(); itSrc++, itDest++)
172  {
173  itDest->log_w = itSrc->log_w;
174  itDest->d.move_from(itSrc->d);
175  }
176  parts.clear();
177  MRPT_END
178  }
179 
180 }; // end CParticleFilterDataImpl<>
181 
182 /** This template class declares the array of particles and its internal data,
183  * managing some memory-related issues and providing an easy implementation of
184  * virtual methods required for implementing a CParticleFilterCapable.
185  * See also the methods in the base class CParticleFilterDataImpl<>.
186  *
187  * Since CProbabilityParticle implements all the required operators, the
188  * member "m_particles" can be safely copied with "=" or copy constructor
189  * operators
190  * and new objects will be created internally instead of copying the internal
191  * pointers, which would lead to memory corruption.
192  *
193  * \sa CParticleFilter, CParticleFilterCapable, CParticleFilterDataImpl
194  * \ingroup mrpt_base_grp
195  */
196 template <class T>
198 {
199  public:
200  /** This is the type inside the corresponding CParticleData class */
202  /** Use this to refer to each element in the m_particles array. */
204  /** Use this type to refer to the list of particles m_particles. */
205  typedef std::deque<CParticleData> CParticleList;
206 
207  /** The array of particles */
209 
210  /** Default constructor */
212  /** Free the memory of all the particles and reset the array "m_particles"
213  * to length zero */
214  void clearParticles() { m_particles.clear(); }
215  /** Dumps the sequence of particles and their weights to a stream (requires
216  * T implementing CSerializable).
217  * \sa readParticlesFromStream
218  */
219  template <class STREAM>
220  void writeParticlesToStream(STREAM& out) const
221  {
222  MRPT_START
223  uint32_t n = static_cast<uint32_t>(m_particles.size());
224  out << n;
225  typename CParticleList::const_iterator it;
226  for (it = m_particles.begin(); it != m_particles.end(); ++it)
227  out << it->log_w << (*it->d);
228  MRPT_END
229  }
230 
231  /** Reads the sequence of particles and their weights from a stream
232  * (requires T implementing CSerializable).
233  * \sa writeParticlesToStream
234  */
235  template <class STREAM>
237  {
238  MRPT_START
239  clearParticles(); // Erase previous content:
240  uint32_t n;
241  in >> n;
242  m_particles.resize(n);
243  typename CParticleList::iterator it;
244  for (it = m_particles.begin(); it != m_particles.end(); ++it)
245  {
246  in >> it->log_w;
247  it->d.reset(new T());
248  in >> *it->d;
249  }
250  MRPT_END
251  }
252 
253  /** Returns a vector with the sequence of the logaritmic weights of all the
254  * samples.
255  */
256  void getWeights(std::vector<double>& out_logWeights) const
257  {
258  MRPT_START
259  out_logWeights.resize(m_particles.size());
261  typename CParticleList::const_iterator it2;
262  for (it = out_logWeights.begin(), it2 = m_particles.begin();
263  it2 != m_particles.end(); ++it, ++it2)
264  *it = it2->log_w;
265  MRPT_END
266  }
267 
268  /** Returns the particle with the highest weight.
269  */
271  {
272  MRPT_START
273  const CParticleData* ret = nullptr;
274  ASSERT_(m_particles.size() > 0)
275 
276  typename CParticleList::const_iterator it;
277  for (it = m_particles.begin(); it != m_particles.end(); ++it)
278  {
279  if (ret == nullptr || it->log_w > ret->log_w) ret = &(*it);
280  }
281  return ret;
282  MRPT_END
283  }
284 
285 }; // End of class def.
286 
287 } // namespace bayes
288 } // namespace mrpt
289 #endif
Derived & derived()
CRTP helper method.
double normalizeWeights(double *out_max_log_w=nullptr) override
Normalize the (logarithmic) weights, such as the maximum weight is zero.
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
GLenum GLsizei n
Definition: glext.h:5074
Scalar * iterator
Definition: eigen_plugins.h:26
double ESS() const override
Returns the normalized ESS (Estimated Sample Size), in the range [0,1].
const CParticleData * getMostLikelyParticle() const
Returns the particle with the highest weight.
const Scalar * const_iterator
Definition: eigen_plugins.h:27
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
size_t particlesCount() const override
Get the m_particles count.
void getWeights(std::vector< double > &out_logWeights) const
Returns a vector with the sequence of the logaritmic weights of all the samples.
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:55
T CParticleDataContent
This is the type inside the corresponding CParticleData class.
CParticleList m_particles
The array of particles.
#define MRPT_END
CProbabilityParticle< T > CParticleData
Use this to refer to each element in the m_particles array.
This virtual class defines the interface that any particles based PDF class must implement in order t...
This template class declares the array of particles and its internal data, managing some memory-relat...
void performSubstitution(const std::vector< size_t > &indx) override
Replaces the old particles by copies determined by the indexes in "indx", performing an efficient cop...
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double getW(size_t i) const override
Access to i&#39;th particle (logarithm) weight, where first one is index 0.
std::deque< CParticleData > CParticleList
Use this type to refer to the list of particles m_particles.
A template class for holding a the data and the weight of a particle.
void readParticlesFromStream(STREAM &in)
Reads the sequence of particles and their weights from a stream (requires T implementing CSerializabl...
const Derived & derived() const
CRTP helper method.
GLuint in
Definition: glext.h:7274
#define ASSERT_(f)
void clearParticles()
Free the memory of all the particles and reset the array "m_particles" to length zero.
CParticleFilterData()
Default constructor.
unsigned __int32 uint32_t
Definition: rptypes.h:47
A curiously recurring template pattern (CRTP) approach to providing the basic functionality of any CP...
void setW(size_t i, double w) override
Modifies i&#39;th particle (logarithm) weight, where first one is index 0.
void writeParticlesToStream(STREAM &out) const
Dumps the sequence of particles and their weights to a stream (requires T implementing CSerializable)...



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019