MCKL
Monte Carlo Kernel Library
pmcmc.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/algorithm/pmcmc.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_ALGORITHM_PMCMC_HPP
33 #define MCKL_ALGORITHM_PMCMC_HPP
34 
35 #include <mckl/internal/common.hpp>
36 #include <mckl/algorithm/mcmc.hpp>
37 #include <mckl/algorithm/smc.hpp>
39 #include <mckl/random/rng.hpp>
40 
41 MCKL_PUSH_CLANG_WARNING("-Wpadded")
42 
43 namespace mckl {
44 
45 template <typename Param, MatrixLayout Layout, typename T, std::size_t Dim = 0>
46 class PMCMCStateMatrix : public StateMatrix<Layout, T, Dim>
47 {
48  public:
49  using param_type = Param;
50 
52 
53  double log_nc() const { return log_nc_; }
54 
55  void add_log_nc(double nc) { log_nc_ += nc; }
56 
57  const param_type &param() { return param_; }
58 
59  void reset(const param_type &p, double nc = 0)
60  {
61  param_ = p;
62  log_nc_ = nc;
63  }
64 
65  private:
66  param_type param_;
67  double log_nc_;
68 }; // class PMCMCStateMatrix
69 
72 template <typename Param, typename T, typename U = double>
74 {
75  public:
76  using param_type = Param;
77  using state_type = T;
79  using eval_type =
80  std::function<double(typename Particle<T>::rng_type &, param_type &)>;
81  using prior_type = std::function<double(const param_type &)>;
83 
84  template <typename Prior, typename... Args>
85  PMCMCMutation(std::size_t N, std::size_t M, Prior &&prior, Args &&... args)
86  : M_(M), prior_(prior), pf_(N, std::forward<Args>(args)...)
87  {
88  }
89 
90  void reset()
91  {
92  eval_.clear();
93  pf_.reset();
94  }
95 
96  pf_type &pf() { return pf_; }
97 
98  pf_type &pf() const { return pf_; }
99 
101  {
102  PMCMCMutation<Param, T, U> mutation(*this);
103  mutation.pf_.particle().rng_set().reset();
104  mutation.pf_.particle().rng().seed(
105  Seed<typename Particle<T>::rng_type>::instance().get());
106 
107  return mutation;
108  }
109 
110  template <typename Prior>
111  void prior(Prior &&prior)
112  {
113  prior_ = std::forward<Prior>(prior);
114  }
115 
117  template <typename Eval>
118  std::size_t update(Eval &&eval)
119  {
120  eval_.push_back(std::forward<Eval>(eval));
121 
122  return eval_.size() - 1;
123  }
124 
125  std::size_t operator()(std::size_t iter, param_type &param)
126  {
127  if (iter == 0) {
128  pf_.clear();
129  pf_.particle().state().reset(param, 0);
130  pf_.iterate(M_);
131  return 0;
132  }
133 
134  const double lnc = pf_.particle().state().log_nc();
135 
136  double prob = -prior_(param) - lnc;
137  param_type p(param);
138  for (auto &eval : eval_) {
139  prob += eval(pf_.particle().rng(), p);
140  }
141  prob += prior_(p);
142 
143  pf_.clear();
144  pf_.particle().state().reset(p, 0);
145  pf_.iterate(M_);
146  prob += pf_.particle().state().log_nc();
147 
149  double u = std::log(u01(pf_.particle().rng()));
150 
151  if (u < prob) {
152  param = std::move(p);
153  } else {
154  pf_.particle().state().reset(param, lnc);
155  }
156 
157  return u < prob ? 1 : 0;
158  }
159 
160  private:
161  std::size_t M_;
162  prior_type prior_;
163  pf_type pf_;
164  Vector<eval_type> eval_;
165 }; // class PMCMCMutation
166 
167 } // namespace mckl
168 
170 
171 #endif // MCKL_ALGORITHM_PMCMC_HPP
void add_log_nc(double nc)
Definition: pmcmc.hpp:55
PMCMCMutation(std::size_t N, std::size_t M, Prior &&prior, Args &&... args)
Definition: pmcmc.hpp:85
std::function< double(const param_type &)> prior_type
Definition: pmcmc.hpp:81
std::size_t update(Eval &&eval)
Add a new evaluation object for the update step.
Definition: pmcmc.hpp:118
#define MCKL_PUSH_CLANG_WARNING(warning)
Definition: compiler.h:63
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
Definition: memory.hpp:435
STL namespace.
void log(std::size_t n, const float *a, float *y)
Definition: vmf.hpp:226
PMCMCMutation< Param, T, U > clone() const
Definition: pmcmc.hpp:100
pf_type & pf() const
Definition: pmcmc.hpp:98
RealType u01(UIntType u)
Convert uniform unsigned integers to floating points within [0, 1].
Definition: u01.hpp:88
SMCSampler< T, U > pf_type
Definition: pmcmc.hpp:82
typename rng_set_type::rng_type rng_type
Definition: particle.hpp:286
const param_type & param()
Definition: pmcmc.hpp:57
void prior(Prior &&prior)
Definition: pmcmc.hpp:111
void reset(const param_type &p, double nc=0)
Definition: pmcmc.hpp:59
Particle::state_type subtype.
pf_type & pf()
Definition: pmcmc.hpp:96
SizeType< T > size_type
Definition: particle.hpp:282
Definition: mcmc.hpp:40
typename Particle< T >::size_type size_type
Definition: pmcmc.hpp:78
#define MCKL_POP_CLANG_WARNING
Definition: compiler.h:66
Standard uniform distribution on [0, 1)
std::size_t operator()(std::size_t iter, param_type &param)
Definition: pmcmc.hpp:125
SMC sampler.
Definition: smc.hpp:139
double log_nc() const
Definition: pmcmc.hpp:53
Particle Markov chain Monte Carlo mutation.
Definition: pmcmc.hpp:73
RNG default seed generator.
Definition: seed.hpp:339
std::function< double(typename Particle< T >::rng_type &, param_type &)> eval_type
Definition: pmcmc.hpp:80