100
smc/sampling/CumulativeSampler.h
Normal file
100
smc/sampling/CumulativeSampler.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef CUMULATIVESAMPLER_H
|
||||
#define CUMULATIVESAMPLER_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include "../Particle.h"
|
||||
#include "ParticleTrajectorieSampler.h"
|
||||
|
||||
namespace SMC {
|
||||
|
||||
/**
|
||||
* drawing trajectories using a cumulative drawer
|
||||
*/
|
||||
template <typename State>
|
||||
class CumulativeSampler : public ParticleTrajectorieSampler<State> {
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
CumulativeSampler(){
|
||||
|
||||
}
|
||||
|
||||
/** draw a single particle */
|
||||
Particle<State> drawSingleParticle(std::vector<Particle<State>> const& particles){
|
||||
|
||||
// ensure the copy vector has the same size as the real particle vector
|
||||
std::vector<Particle<State>> particlesCopy;
|
||||
particlesCopy.resize(particles.size());
|
||||
|
||||
// swap both vectors
|
||||
particlesCopy = particles;
|
||||
|
||||
// calculate cumulative weight
|
||||
double cumWeight = 0;
|
||||
for (uint32_t i = 0; i < particles.size(); ++i) {
|
||||
cumWeight += particlesCopy[i].weight;
|
||||
particlesCopy[i].weight = cumWeight;
|
||||
}
|
||||
|
||||
return draw(cumWeight, particlesCopy, particles);
|
||||
|
||||
}
|
||||
|
||||
/** draw a trajectorie of n particles */
|
||||
std::vector<Particle<State>> drawTrajectorie(std::vector<Particle<State>> const& particles, const int numRealizations){
|
||||
|
||||
// ensure the copy vector has the same size as the real particle vector
|
||||
std::vector<Particle<State>> particlesCopy;
|
||||
particlesCopy.reserve(particles.size());
|
||||
particlesCopy = particles;
|
||||
|
||||
// calculate cumulative weight
|
||||
double cumWeight = 0;
|
||||
for (uint32_t i = 0; i < particles.size(); ++i) {
|
||||
cumWeight += particlesCopy[i].weight;
|
||||
particlesCopy[i].weight = cumWeight;
|
||||
}
|
||||
|
||||
// now draw the initial weights and therefore the corresponding particles
|
||||
std::vector<Particle<State>> trajectorie;
|
||||
trajectorie.reserve(numRealizations);
|
||||
for (uint32_t i = 0; i < numRealizations; ++i) {
|
||||
trajectorie.push_back(draw(cumWeight, particlesCopy, particles));
|
||||
}
|
||||
|
||||
return trajectorie;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** function for drawing particles */
|
||||
Particle<State> draw(const double cumWeight, std::vector<Particle<State>> const& cumParticles, std::vector<Particle<State>> const& origParticles){
|
||||
|
||||
// random value between [0;1]
|
||||
const double rand01 = double(rand()) / double(RAND_MAX);
|
||||
|
||||
// random value between [0; cumulativeWeight]
|
||||
const double rand = rand01 * cumWeight;
|
||||
|
||||
// search comparator
|
||||
auto comp = [] (const Particle<State>& s, const double d) {return s.weight < d;};
|
||||
auto it = std::lower_bound(cumParticles.begin(), cumParticles.end(), rand, comp);
|
||||
|
||||
//get the idx for the iterator it. this is the same as std::distance(..,..)
|
||||
int idx = it - cumParticles.begin();
|
||||
|
||||
//get the original weight instead of the cumulative weight
|
||||
Particle<State> drawnParticle = *it;
|
||||
drawnParticle.weight = origParticles[idx].weight;
|
||||
|
||||
return drawnParticle;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ARTIFICIALDISTRIBUTION_H
|
||||
31
smc/sampling/ParticleTrajectorieSampler.h
Normal file
31
smc/sampling/ParticleTrajectorieSampler.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef PARTICLETRAJECTORIESAMPLER_H
|
||||
#define PARTICLETRAJECTORIESAMPLER_H
|
||||
|
||||
#include <vector>
|
||||
#include "..//Particle.h"
|
||||
|
||||
namespace SMC {
|
||||
|
||||
/**
|
||||
* interface for Sampling Trajectories of Particles
|
||||
*/
|
||||
template <typename State>
|
||||
class ParticleTrajectorieSampler {
|
||||
|
||||
public:
|
||||
|
||||
/** draw a single particle */
|
||||
virtual Particle<State> drawSingleParticle(std::vector<Particle<State>> const& particles) = 0;
|
||||
|
||||
/** draw a trajectorie of all incoming particles / like resampling*/
|
||||
virtual std::vector<Particle<State>> drawTrajectorie(std::vector<Particle<State>>const& particles, const int num) = 0;
|
||||
|
||||
private:
|
||||
|
||||
/** function for drawing particles */
|
||||
virtual Particle<State> draw(const double cumWeight, std::vector<Particle<State>> const& cumParticles, std::vector<Particle<State>> const& origParticles) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ARTIFICIALDISTRIBUTION_H
|
||||
Reference in New Issue
Block a user