vSMC
vSMC: Scalable Monte Carlo
nintegrate_base.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/integrate/nintegrate_base.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, 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 VSMC_INTEGRATE_NINTEGRATE_BASE_HPP
33 #define VSMC_INTEGRATE_NINTEGRATE_BASE_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 #ifdef VSMC_MSVC
38 #define VSMC_STATIC_ASSERT_INTEGRATE_NINTEGRATE_BASE_DERIVED
39 #else // VSMC_MSVC
40 #define VSMC_STATIC_ASSERT_INTEGRATE_NINTEGRATE_BASE_DERIVED \
41  VSMC_STATIC_ASSERT( \
42  (cxx11::is_base_of<NIntegrateBase<Derived>, Derived>::value), \
43  USE_CRTP_NIntegrateBase_WITH_A_CLASS_NOT_DERIVED_FROM_THE_BASE)
44 #endif // VSMC_MSVC
45 
46 #define VSMC_STATIC_ASSERT_INTEGRATE_NINTEGRATE_BASE_NO_IMPL(member) \
47  VSMC_STATIC_ASSERT((cxx11::is_same<Derived, NullType>::value), \
48  DERIVED_FROM_NIntegrateBase_WITHOUT_IMPLEMENTATION_OF_##member##_IN_THE_Derived_TEMPLATE_PARAMETER)
49 
50 #define VSMC_RUNTIME_ASSERT_INTEGRATE_NINTEGRATE_BASE_DERIVED \
51  VSMC_RUNTIME_ASSERT((dynamic_cast<Derived *>(this)), \
52  ("DERIVED FROM NIntegrateBase " \
53  "WITH INCORRECT **Derived** TEMPLATE PARAMTER"));
54 
55 namespace vsmc {
56 
59 template <typename Derived>
61 {
62  protected :
63 
64  typedef std::size_t size_type;
65  typedef cxx11::function<double (double)> eval_type;
66 
70  {return *this;}
72 
78  double integrate_segment (double a, double b, const eval_type &eval)
79  {
80  return integrate_segment_dispatch(a, b, eval,
81  &Derived::integrate_segment);
82  }
83 
84  double operator() (size_type N, const double *grid, const eval_type &eval)
85  {
86  if (N < 2)
87  return 0;
88 
89  double integral = 0;
90  for (size_type i = 1; i != N; ++i)
91  integral += this->integrate_segment(grid[i - 1], grid[i], eval);
92 
93  return integral;
94  }
95 
96  private :
97 
98  template <typename D>
99  double integrate_segment_dispatch (double a, double b,
100  const eval_type &eval,
101  double (D::*) (double, double, const eval_type &))
102  {
105  return static_cast<Derived *>(this)->integrate_segment(a, b, eval);
106  }
107 
108  template <typename D>
109  double integrate_segment_dispatch (double a, double b,
110  const eval_type &eval,
111  double (D::*) (double, double, const eval_type &) const)
112  {
115  return static_cast<Derived *>(this)->integrate_segment(a, b, eval);
116  }
117 
118  double integrate_segment_dispatch (double a, double b,
119  const eval_type &eval,
120  double (*) (double, double, const eval_type &))
121  {return Derived::integrate_segment(a, b, eval);}
122 
123  double integrate_segment_dispatch (double, double, const eval_type &,
124  double (NIntegrateBase::*) (double, double, const eval_type &))
125  {
128  return 0;
129  }
130 }; // class NIntegrateBase
131 
134 template <>
135 class NIntegrateBase<Virtual>
136 {
137  public :
138 
139  typedef std::size_t size_type;
140  typedef cxx11::function<double (double)> eval_type;
141 
142  protected :
143 
147  {return *this;}
148  virtual ~NIntegrateBase () {}
149 
150  virtual double integrate_segment (double, double, const eval_type &) = 0;
151 }; // class NIntegrateBase<Virtual>
152 
153 } // namespace vsmc
154 
155 #endif // VSMC_INTEGRATE_NINTEGRATE_BASE_HPP
Definition: adapter.hpp:37
Numerical integration base dispatch class.
NIntegrateBase(const NIntegrateBase< Derived > &)
#define VSMC_STATIC_ASSERT_INTEGRATE_NINTEGRATE_BASE_DERIVED
NIntegrateBase(const NIntegrateBase< Virtual > &)
cxx11::function< double(double)> eval_type
double operator()(size_type N, const double *grid, const eval_type &eval)
#define VSMC_STATIC_ASSERT_INTEGRATE_NINTEGRATE_BASE_NO_IMPL(member)
double integrate_segment(double a, double b, const eval_type &eval)
Integrate a segment on the grid.
cxx11::function< double(double)> eval_type
NIntegrateBase< Derived > & operator=(const NIntegrateBase< Derived > &)
#define VSMC_RUNTIME_ASSERT_INTEGRATE_NINTEGRATE_BASE_DERIVED
#define VSMC_CRTP_DESTRUCTOR_PREFIX
CRTP style base classes (virtual) destructor.
Definition: defines.hpp:49
Numerical integration base dispatch class.