23 const unsigned CParticleFilterCapable::PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS =
29 void CParticleFilterCapable::performResampling(
31 size_t out_particle_count)
36 const size_t in_particle_count = particlesCount();
40 vector<double> log_ws;
41 log_ws.assign(in_particle_count, .0);
42 for (
size_t i = 0; i < in_particle_count; i++) log_ws[i] = getW(i);
49 performSubstitution(indxs);
52 for (
size_t i = 0; i < out_particle_count; i++)
61 void CParticleFilterCapable::computeResampling(
63 const vector<double>& in_logWeights, vector<size_t>& out_indexes,
64 size_t out_particle_count)
71 size_t i, j, M = in_logWeights.size();
74 if (!out_particle_count) out_particle_count = M;
76 vector<double> linW(M, 0);
83 for (i = 0, inIt = in_logWeights.begin(), outIt = linW.begin(); i < M;
85 linW_SUM += ((*outIt) = exp((*inIt) - max_log_w));
89 linW *= 1.0 / linW_SUM;
93 case CParticleFilter::prMultinomial:
99 mrpt::math::cumsum_tmpl<vector<double>, vector<double>,
double>(
109 sort(T.begin(), T.end());
111 out_indexes.resize(out_particle_count);
114 while (i < out_particle_count)
118 out_indexes[i++] = (
unsigned int)j;
123 if (j >= M) j = M - 1;
129 case CParticleFilter::prResidual:
137 for (i = 0; i < M; i++)
139 N[i] = int(M * linW[i]);
142 size_t N_rnd = out_particle_count >=
R ? (out_particle_count -
R)
148 out_indexes.resize(out_particle_count);
149 for (i = 0, j = 0; i < out_particle_count; i++)
150 for (
size_t k = 0; k < N[i]; k++) out_indexes[j++] = i;
161 vector<double> linW_mod(M);
162 const double M_R_1 = 1.0 / N_rnd;
163 for (i = 0; i < M; i++)
164 linW_mod[i] = M_R_1 * (M * linW[i] - N[i]);
168 mrpt::math::cumsum_tmpl<vector<double>, vector<double>,
double>(
177 sort(T.begin(), T.end());
186 out_indexes[M_fixed + i++] = (
unsigned int)j;
191 if (j >= M) j = M - 1;
197 case CParticleFilter::prStratified:
203 mrpt::math::cumsum_tmpl<vector<double>, vector<double>,
double>(
208 vector<double> T(M + 1);
209 const double _1_M = 1.0 / M;
210 const double _1_M_eps = _1_M - 0.000001;
212 for (i = 0; i < M; i++)
220 out_indexes.resize(out_particle_count);
222 while (i < out_particle_count)
225 out_indexes[i++] = (
unsigned int)j;
229 if (j >= M) j = M - 1;
234 case CParticleFilter::prSystematic:
240 mrpt::math::cumsum_tmpl<vector<double>, vector<double>,
double>(
245 vector<double> T(M + 1);
246 double _1_M = 1.0 / M;
248 for (i = 1; i < M; i++) T[i] = T[i - 1] + _1_M;
251 out_indexes.resize(out_particle_count);
253 while (i < out_particle_count)
256 out_indexes[i++] = (
unsigned int)j;
260 if (j >= M) j = M - 1;
267 "ERROR: Unknown resampling method selected: %i", method));
276 void CParticleFilterCapable::prepareFastDrawSample(
290 "resamplingMethod must be 'prMultinomial' for a dynamic number " 293 size_t i, j = 666666, M = particlesCount();
298 m_fastDrawAuxiliary.CDF.resize(
299 1 + PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS, 0);
300 m_fastDrawAuxiliary.CDF_indexes.resize(
301 PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS, 0);
305 m_fastDrawAuxiliary.PDF.resize(M, 0);
311 for (i = 0; i < M; i++) m_fastDrawAuxiliary.PDF[i] = partEvaluator(i);
313 m_fastDrawAuxiliary.PDF += -
math::maximum(m_fastDrawAuxiliary.PDF);
314 for (i = 0; i < M; i++)
315 SUM += m_fastDrawAuxiliary.PDF[i] = exp(m_fastDrawAuxiliary.PDF[i]);
318 m_fastDrawAuxiliary.PDF *= 1.0 / SUM;
321 for (i = 0; i < PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS; i++)
322 m_fastDrawAuxiliary.CDF[i] =
323 ((
double)i) / ((double)PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS);
324 m_fastDrawAuxiliary.CDF[PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS] = 1.0;
328 for (i = 0, j = 0; i < M && j < PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS;
331 double CDF_next = CDF + m_fastDrawAuxiliary.PDF[i];
332 if (i == (M - 1)) CDF_next = 1.0;
333 if (CDF_next > 1.0) CDF_next = 1.0;
335 while (m_fastDrawAuxiliary.CDF[j] < CDF_next)
336 m_fastDrawAuxiliary.CDF_indexes[j++] = (
unsigned int)i;
341 ASSERT_(j == PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS);
344 #if !defined(_MSC_VER) || (_MSC_VER > 1400) // <=VC2005 doesn't work with this! 347 <<
"\nm_fastDrawAuxiliary.CDF_indexes:" 348 << m_fastDrawAuxiliary.CDF_indexes << endl;
349 cout <<
"m_fastDrawAuxiliary.CDF:" 350 << m_fastDrawAuxiliary.CDF << endl;);
363 size_t i, M = particlesCount();
364 vector<double> PDF(M, 0);
365 for (i = 0; i < M; i++) PDF[i] = partEvaluator(i);
374 m_fastDrawAuxiliary.alreadyDrawnIndexes.resize(idxs.size());
375 for (it = idxs.begin(),
376 it2 = m_fastDrawAuxiliary.alreadyDrawnIndexes.begin();
377 it != idxs.end(); ++it, ++it2)
378 *it2 = (
unsigned int)(*it);
380 m_fastDrawAuxiliary.alreadyDrawnNextOne = 0;
389 size_t CParticleFilterCapable::fastDrawSample(
402 "resamplingMethod must be 'prMultinomial' for a dynamic number " 406 double CDF_next = -1.;
413 size_t j = (size_t)floor(
414 draw * ((
double)PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS - 0.05));
415 CDF = m_fastDrawAuxiliary.CDF[j];
416 size_t i = m_fastDrawAuxiliary.CDF_indexes[j];
419 while (draw > (CDF_next = CDF + m_fastDrawAuxiliary.PDF[i]))
429 "\n[CParticleFilterCapable::fastDrawSample] DEBUG: draw=%f, " 430 "CDF=%f CDF_next=%f\n",
431 draw, CDF, CDF_next););
439 if (m_fastDrawAuxiliary.alreadyDrawnNextOne >=
440 m_fastDrawAuxiliary.alreadyDrawnIndexes.size())
442 "Have you called 'fastDrawSample' more times than the sample " 443 "size? Did you forget calling 'prepareFastCall' before?");
445 return m_fastDrawAuxiliary
446 .alreadyDrawnIndexes[m_fastDrawAuxiliary.alreadyDrawnNextOne++];
455 void CParticleFilterCapable::log2linearWeights(
456 const vector<double>& in_logWeights, vector<double>& out_linWeights)
460 size_t N = in_logWeights.size();
462 out_linWeights.resize(N);
468 for (i = 0; i < N; i++) sumW += out_linWeights[i] = exp(in_logWeights[i]);
472 for (i = 0; i < N; i++) out_linWeights[i] /= sumW;
A namespace of pseudo-random numbers genrators of diferent distributions.
double drawUniform(const double Min, const double Max)
Generate a uniformly distributed pseudo-random number using the MT19937 algorithm, scaled to the selected range.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::vector< uint32_t > vector_uint
#define MRPT_END_WITH_CLEAN_UP(stuff)
#define MRPT_CHECK_NORMAL_NUMBER(val)
The namespace for Bayesian filtering algorithm: different particle filters and Kalman filter algorith...
#define THROW_EXCEPTION(msg)
const Scalar * const_iterator
std::function< double(size_t index)> TParticleProbabilityEvaluator
A callback function type for evaluating the probability of m_particles of being selected, used in "fastDrawSample".
This base provides a set of functions for maths stuff.
TParticleResamplingAlgorithm
Defines the different resampling algorithms.
TParticleResamplingAlgorithm resamplingMethod
The resampling algorithm to use (default=prMultinomial).
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
CONTAINER::Scalar maximum(const CONTAINER &v)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
The configuration of a particle filter.
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
void drawUniformVector(VEC &v, const double unif_min=0, const double unif_max=1)
Fills the given vector with independent, uniformly distributed samples.
bool adaptiveSampleSize
A flag that indicates whether the CParticleFilterCapable object should perform adative sample size (d...