MCKL
Monte Carlo Kernel Library
weight.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/core/weight.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_CORE_WEIGHT_HPP
33 #define MCKL_CORE_WEIGHT_HPP
34 
35 #include <mckl/internal/common.hpp>
36 #include <mckl/internal/cblas.hpp>
37 #include <mckl/core/is_equal.hpp>
39 
40 namespace mckl {
41 
44 class Weight
45 {
46  public:
47  using size_type = std::size_t;
48 
49  explicit Weight(size_type N = 0) : ess_(0), data_(N) { set_equal(); }
50 
52  size_type size() const { return data_.size(); }
53 
55  void resize(size_type N) { data_.resize(N); }
56 
58  void reserve(size_type N) { data_.reserve(N); }
59 
61  void shrink_to_fit() { data_.shrink_to_fit(); }
62 
64  double ess() const { return ess_; }
65 
67  const double *data() const { return data_.data(); }
68 
70  template <typename OutputIter>
71  OutputIter read(OutputIter first) const
72  {
73  return std::copy(data_.begin(), data_.end(), first);
74  }
75 
77  void set_equal()
78  {
79  std::fill(data_.begin(), data_.end(), 1.0 / size());
80  ess_ = static_cast<double>(size());
81  }
82 
84  template <typename InputIter>
85  void set(InputIter first)
86  {
87  std::copy_n(first, size(), data_.begin());
88  normalize(false);
89  }
90 
96  template <typename InputIter>
97  void set_exact(double ess, InputIter first)
98  {
99  ess_ = ess;
100  std::copy_n(first, size(), data_.begin());
101  }
102 
104  template <typename InputIter>
105  void mul(InputIter first)
106  {
107  for (size_type i = 0; i != size(); ++i, ++first) {
108  data_[i] *= *first;
109  }
110  normalize(false);
111  }
112 
114  void mul(const double *first)
115  {
116  ::mckl::mul(size(), first, data_.data(), data_.data());
117  normalize(false);
118  }
119 
121  void mul(double *first) { mul(const_cast<const double *>(first)); }
122 
124  template <typename InputIter>
125  void set_log(InputIter first)
126  {
127  std::copy_n(first, size(), data_.begin());
128  normalize(true);
129  }
130 
132  template <typename InputIter>
133  void add_log(InputIter first)
134  {
135  log(size(), data_.data(), data_.data());
136  for (size_type i = 0; i != size(); ++i) {
137  data_[i] += *first;
138  }
139  normalize(true);
140  }
141 
143  void add_log(const double *first)
144  {
145  log(size(), data_.data(), data_.data());
146  add(size(), first, data_.data(), data_.data());
147  normalize(true);
148  }
149 
151  void add_log(double *first) { add_log(const_cast<const double *>(first)); }
152 
155  template <typename RNGType>
156  size_type draw(RNGType &rng) const
157  {
159 
160  return dist(rng, data_.begin(), data_.end(), true);
161  }
162 
163  friend bool operator==(const Weight &w1, const Weight &w2)
164  {
165  return w1.ess_ == w2.ess_ && w1.data_ == w2.data_;
166  }
167 
168  friend bool operator!=(const Weight &w1, const Weight &w2)
169  {
170  return !(w1 == w2);
171  }
172 
173  friend bool is_equal(const Weight &w1, const Weight &w2)
174  {
175  return is_equal(w1.ess_, w2.ess_) && is_equal(w1.data_, w2.data_);
176  }
177 
178  private:
179  double ess_;
180  Vector<double> data_;
181 
182  template <typename InputIter>
183  double max_element(size_type n, InputIter first)
184  {
185  using value_type =
186  typename std::iterator_traits<InputIter>::value_type;
187 
188  value_type v = -const_inf<value_type>();
189  for (size_type i = 0; i != n; ++i, ++first) {
190  if (v < *first) {
191  v = *first;
192  }
193  }
194 
195  return static_cast<double>(v);
196  }
197 
198  void normalize(bool use_log)
199  {
200  double *w = data_.data();
201  double accw = 0;
202  double essw = 0;
203  const double lmax = use_log ? max_element(size(), w) : 0;
205  const size_type m = size() / k;
206  const size_type l = size() % k;
207  for (size_type i = 0; i != m; ++i, w += k) {
208  normalize(k, w, accw, essw, use_log, lmax);
209  }
210  normalize(l, w, accw, essw, use_log, lmax);
211  ::mckl::mul(size(), 1 / accw, data_.data(), data_.data());
212  ess_ = accw * accw / essw;
213  }
214 
215  void normalize(size_type n, double *w, double &accw, double &essw,
216  bool use_log, double lmax)
217  {
218  internal::size_check<MCKL_BLAS_INT>(n, "Weight::normalize");
219 
220  if (use_log) {
221  sub(n, w, lmax, w);
222  exp(n, w, w);
223  }
224  accw = std::accumulate(w, w + n, accw);
225  essw +=
226  internal::cblas_ddot(static_cast<MCKL_BLAS_INT>(n), w, 1, w, 1);
227  }
228 }; // class Weight
229 
233 
234 } // namespace mckl
235 
236 #endif // MCKL_CORE_WEIGHT_HPP
const double * data() const
Pointer to data of the normalized weight.
Definition: weight.hpp:67
void set_log(InputIter first)
Set .
Definition: weight.hpp:125
friend bool operator!=(const Weight &w1, const Weight &w2)
Definition: weight.hpp:168
void mul(std::size_t n, const float *a, const float *b, float *y)
Definition: vmf.hpp:124
typename WeightTypeTrait< T >::type WeightType
Definition: weight.hpp:232
double ess() const
Return the ESS of the particle system.
Definition: weight.hpp:64
void mul(InputIter first)
Set .
Definition: weight.hpp:105
void set_exact(double ess, InputIter first)
Set exact values of ESS and normalized weights.
Definition: weight.hpp:97
void shrink_to_fit()
Shrink to fit.
Definition: weight.hpp:61
Weights of samples.
Definition: weight.hpp:44
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
Definition: memory.hpp:435
#define MCKL_DEFINE_TYPE_DISPATCH_TRAIT(Outer, Inner, Default)
Definition: traits.hpp:39
void log(std::size_t n, const float *a, float *y)
Definition: vmf.hpp:226
size_type size() const
Size of this Weight object.
Definition: weight.hpp:52
void mul(const double *first)
Set .
Definition: weight.hpp:114
void sub(std::size_t n, const float *a, const float *b, float *y)
Definition: vmf.hpp:121
size_type draw(RNGType &rng) const
Draw integer index in the range according to the weights.
Definition: weight.hpp:156
friend bool operator==(const Weight &w1, const Weight &w2)
Definition: weight.hpp:163
void set_equal()
Set .
Definition: weight.hpp:77
OutputIter read(OutputIter first) const
Read all normalized weights to an output iterator.
Definition: weight.hpp:71
void add_log(InputIter first)
Set .
Definition: weight.hpp:133
void mul(double *first)
Set .
Definition: weight.hpp:121
void resize(size_type N)
Resize the Weight object.
Definition: weight.hpp:55
void reserve(size_type N)
Reserve space.
Definition: weight.hpp:58
Definition: mcmc.hpp:40
void exp(std::size_t n, const float *a, float *y)
Definition: vmf.hpp:221
std::size_t size_type
Definition: weight.hpp:47
Draw a single sample given weights.
Weight(size_type N=0)
Definition: weight.hpp:49
friend bool is_equal(const Weight &w1, const Weight &w2)
Definition: weight.hpp:173
void add_log(double *first)
Set .
Definition: weight.hpp:151
void add_log(const double *first)
Set .
Definition: weight.hpp:143
void add(std::size_t n, const float *a, const float *b, float *y)
Definition: vmf.hpp:119