32 #ifndef VSMC_CORE_WEIGHT_SET_HPP
33 #define VSMC_CORE_WEIGHT_SET_HPP
50 size_(N), ess_(static_cast<double>(N)), weight_(N), log_weight_(N) {}
52 #if VSMC_HAS_CXX11_DEFAULTED_FUNCTIONS
55 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
59 #else // VSMC_HAS_CXX11_DEFAULTED_FUNCTIONS
61 size_(other.size_), ess_(other.ess_),
62 weight_(other.weight_), log_weight_(other.log_weight_) {}
68 weight_ = other.weight_;
69 log_weight_ = other.log_weight_;
75 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
77 size_(other.size_), ess_(other.ess_),
78 weight_(cxx11::
move(other.weight_)),
79 log_weight_(cxx11::
move(other.log_weight_)) {}
92 #endif // VSMC_HAS_CXX11_DEFAULTED_FUNCTIONS
96 size_type
size ()
const {
return size_;}
99 double ess ()
const {
return ess_;}
102 template <
typename InputIter>
103 double ess (InputIter first,
bool use_log)
const
105 std::vector<double, AlignedAllocator<double> > buffer(size_);
106 double *
const bptr = &buffer[0];
107 #if VSMC_HAS_CXX11LIB_ALGORITHM
108 std::copy_n(first, size_, bptr);
110 for (size_type i = 0; i != size_; ++i, ++first)
118 template <
typename RandomIter>
119 double ess (RandomIter first,
int stride,
bool use_log)
const
121 std::vector<double, AlignedAllocator<double> > buffer(size_);
122 double *
const bptr = &buffer[0];
123 for (size_type i = 0; i != size_; ++i, first += stride)
130 template <
typename InputIter>
131 double cess (InputIter first,
bool use_log)
const
133 std::vector<double, AlignedAllocator<double> > buffer(size_);
134 double *
const bptr = &buffer[0];
135 #if VSMC_HAS_CXX11LIB_ALGORITHM
136 std::copy_n(first, size_, bptr);
138 for (size_type i = 0; i != size_; ++i, ++first)
146 template <
typename RandomIter>
147 double cess (RandomIter first,
int stride,
bool use_log)
const
149 std::vector<double, AlignedAllocator<double> > buffer(size_);
150 double *
const bptr = &buffer[0];
151 for (size_type i = 0; i != size_; ++i, first += stride)
166 template <
typename OutputIter>
168 {std::copy(weight_.begin(), weight_.end(), first);}
172 template <
typename RandomIter>
175 const double *
const wptr = &weight_[0];
176 for (size_type i = 0; i != size_; ++i, first += stride)
181 template <
typename OutputIter>
183 {std::copy(log_weight_.begin(), log_weight_.end(), first);}
187 template <
typename RandomIter>
190 const double *
const lwptr = &log_weight_[0];
191 for (size_type i = 0; i != size_; ++i, first += stride)
196 double weight (size_type
id)
const {
return weight_[id];}
199 double log_weight (size_type
id)
const {
return log_weight_[id];}
206 std::fill_n(&weight_[0], size_, 1 / ess_);
207 std::memset(&log_weight_[0], 0,
sizeof(
double) * size_);
213 template <
typename InputIter>
216 double *
const wptr = &weight_[0];
217 #if VSMC_HAS_CXX11LIB_ALGORITHM
218 std::copy_n(first, size_, wptr);
220 for (size_type i = 0; i != size_; ++i, ++first)
229 template <
typename RandomIter>
232 double *
const wptr = &weight_[0];
233 for (size_type i = 0; i != size_; ++i, first += stride)
241 template <
typename InputIter>
244 double *
const wptr = &weight_[0];
245 for (size_type i = 0; i != size_; ++i, ++first)
254 template <
typename RandomIter>
257 double *
const wptr = &weight_[0];
258 for (size_type i = 0; i != size_; ++i, first += stride)
266 template <
typename InputIter>
269 double *
const lwptr = &log_weight_[0];
270 #if VSMC_HAS_CXX11LIB_ALGORITHM
271 std::copy_n(first, size_, lwptr);
273 for (size_type i = 0; i != size_; ++i, ++first)
276 post_set_log_weight();
282 template <
typename RandomIter>
285 double *
const lwptr = &log_weight_[0];
286 for (size_type i = 0; i != size_; ++i, first += stride)
288 post_set_log_weight();
294 template <
typename InputIter>
297 double *
const lwptr = &log_weight_[0];
298 for (size_type i = 0; i != size_; ++i, ++first)
300 post_set_log_weight();
307 template <
typename RandomIter>
310 double *
const lwptr = &log_weight_[0];
311 for (size_type i = 0; i != size_; ++i, first += stride)
313 post_set_log_weight();
317 template <
typename URNG>
318 size_type
draw (URNG &eng)
const
319 {
return draw_(eng, weight_.begin(), weight_.end(),
true);}
340 {
math::vExp(size_, &log_weight_[0], &weight_[0]);}
344 {
math::vLn(size_, &weight_[0], &log_weight_[0]);}
349 double *
const lwptr = &log_weight_[0];
350 double dmax = lwptr[0];
351 for (size_type i = 0; i != size_; ++i)
355 for (size_type i = 0; i != size_; ++i)
362 double *
const wptr = &weight_[0];
369 virtual double compute_ess (
const double *first,
bool use_log)
const
371 std::vector<double, AlignedAllocator<double> > buffer(size_);
372 double *
const bptr = &buffer[0];
375 math::vAdd(size_, &log_weight_[0], first, bptr);
376 double dmax = bptr[0];
377 for (size_type i = 0; i != size_; ++i)
381 for (size_type i = 0; i != size_; ++i)
397 const double *bptr = first;
398 const double *
const wptr = &weight_[0];
399 std::vector<double, AlignedAllocator<double> > buffer;
401 buffer.resize(size_);
408 for (size_type i = 0; i != size_; ++i) {
409 double wb = wptr[i] * bptr[i];
411 below += wb * bptr[i];
414 return above * above / below;
421 std::vector<double, AlignedAllocator<double> > weight_;
422 std::vector<double, AlignedAllocator<double> > log_weight_;
425 void post_set_log_weight ()
432 void post_set_weight ()
457 size_type
size ()
const {
return 0;}
459 double ess ()
const {
return max_ess();}
461 template <
typename InputIter>
462 double ess (InputIter,
bool)
const {
return max_ess();}
464 template <
typename RandomIter>
465 double ess (RandomIter,
int,
bool)
const {
return max_ess();}
467 template <
typename InputIter>
468 double cess (InputIter,
bool)
const {
return max_ess();}
470 template <
typename RandomIter>
471 double cess (RandomIter,
int,
bool)
const {
return max_ess();}
477 template <
typename OutputIter>
480 template <
typename RandomIter>
483 template <
typename OutputIter>
486 template <
typename RandomIter>
489 double weight (size_type)
const {
return 1;}
495 template <
typename InputIter>
498 template <
typename RandomIter>
501 template <
typename InputIter>
504 template <
typename RandomIter>
507 template <
typename InputIter>
510 template <
typename RandomIter>
513 template <
typename InputIter>
516 template <
typename RandomIter>
519 template <
typename URNG>
520 size_type
draw (URNG &)
const {
return 0;}
524 static double max_ess ()
525 {
return std::numeric_limits<double>::max
VSMC_MNE ();}
530 #endif // VSMC_CORE_WEIGHT_SET_HPP
virtual void log_weight2weight()
Compute unormalized logarithm weights from normalized weights.
void set_weight(RandomIter, int)
void vAdd(std::size_t n, const T *a, const T *b, T *y)
For , compute .
double ess() const
ESS of the particle collection based on the current weights.
void set_log_weight(InputIter)
double log_weight(size_type id) const
Get the unnormalized logarithm weight of the id'th particle.
virtual void normalize_weight()
Normalize weights such that the summation is one.
void read_weight(OutputIter first) const
Read normalized weights through an output iterator.
void read_log_weight(RandomIter first, int stride) const
Read unnormalized logarithm weights through a random access iterator with (possible non-uniform strid...
void set_weight(InputIter first)
Set normalized weight, unnormalized logarithm weight and ESS by changing the (possible unnormalized) ...
void read_log_weight(OutputIter) const
virtual size_type resample_size() const
Size of the weight set for the purpose of resampling.
void set_weight(RandomIter first, int stride)
Set normalized weight, unnormalized logarithm weight and ESS by changing the (possible unnormalized) ...
void read_log_weight(OutputIter first) const
Read unnormalized logarithm weights through an output iterator.
double cess(RandomIter first, int stride, bool use_log) const
Compute CESS given (log) incremental weights.
void add_log_weight(RandomIter first, int stride)
Set normalized weight, unnormalized logarithm weight and ESS by adding to the unnormalized logarithm ...
void mul_weight(RandomIter first, int stride)
Set normalized weight, unnormalized logarithm weight and ESS by multiply the normalized weight with (...
double log_weight(size_type) const
size_type resample_size() const
void read_weight(RandomIter, int) const
void vMul(std::size_t n, const T *a, const T *b, T *y)
For , compute .
void mul_weight(InputIter)
void add_log_weight(InputIter)
void * memset(void *dst, int ch, std::size_t n)
SIMD optimized memset with non-temporal store for large buffers.
virtual void normalize_log_weight()
Normalize logarithm weights such that the maximum is zero.
void add_log_weight(InputIter first)
Set normalized weight, unnormalized logarithm weight and ESS by adding to the unnormalized logarithm ...
double * mutable_weight_data()
double ess(InputIter first, bool use_log) const
Compute ESS given (log) incremental weights.
size_type draw(URNG &) const
void add_log_weight(RandomIter, int)
#define VSMC_MNE
Avoid MSVC stupid behavior: MNE = Macro No Expansion.
double * mutable_log_weight_data()
void set_log_weight(RandomIter first, int stride)
Set normalized weight, unnormalized logarithm weight and ESS by changing the (possible unnormalized) ...
T dot(std::size_t n, const T *x, const T *y)
The dot product.
double weight(size_type id) const
Get the normalized weight of the id'th particle.
void scal(std::size_t n, T a, T *x)
Scale a vector.
void vLn(std::size_t n, const T *a, T *y)
For , compute .
remove_reference< T >::type && move(T &&t) noexcept
void read_resample_weight(double *) const
An empty weight set class.
void mul_weight(RandomIter, int)
double cess(InputIter, bool) const
virtual void weight2log_weight()
Compute unormalized weights from normalized logarithm weights.
double weight(size_type) const
T asum(std::size_t n, const T *x)
Sum of vector magnitudes.
double cess(InputIter first, bool use_log) const
Compute CESS given (log) incremental weights.
double cess(RandomIter, int, bool) const
const double * weight_data() const
Read only access to the raw data of weight.
void set_weight(InputIter)
virtual double compute_cess(const double *first, bool use_log) const
Compute CESS given (logarithm) unormalized incremental weights.
void set_equal_weight()
Set normalized weight, unnormalized logarithm weight and ESS such that each particle has a equal weig...
virtual double compute_ess(const double *first, bool use_log) const
Compute ESS given (logarithm) unormalzied incremental weights.
double ess(RandomIter first, int stride, bool use_log) const
Compute ESS given (log) incremental weights.
void read_log_weight(RandomIter, int) const
void read_weight(RandomIter first, int stride) const
Read normalized weights through a random access iterator with (possible non-uniform stride) ...
double ess(RandomIter, int, bool) const
virtual void read_resample_weight(double *first) const
Read normalized weights through an output iterator for the purpose of resampling. ...
size_type draw(URNG &eng) const
Draw a sample according to the weights.
void vExp(std::size_t n, const T *a, T *y)
For , compute .
void mul_weight(InputIter first)
Set normalized weight, unnormalized logarithm weight and ESS by multiply the normalized weight with (...
WeightSet & operator=(const WeightSet &)=default
virtual const double * resample_weight_data() const
Read only access to the resampling weights.
void set_log_weight(InputIter first)
Set normalized weight, unnormalized logarithm weight and ESS by changing the (possible unnormalized) ...
void set_log_weight(RandomIter, int)
double ess(InputIter, bool) const
void read_weight(OutputIter) const
const double * log_weight_data() const
Read only access to the raw data of logarithm weight.