ALPSCore reference
mean.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #pragma once
8 
9 #include <alps/config.hpp>
10 
15 
16 #include <alps/hdf5/archive.hpp>
17 #include <alps/numeric/inf.hpp>
23 
24 #include <boost/utility.hpp>
25 
26 #include <stdexcept>
27 #include <type_traits>
28 
29 namespace alps {
30  namespace accumulators {
31  // this should be called namespace tag { struct mean; }
32  // but gcc <= 4.4 has lookup error, so name it different
33  struct mean_tag;
34 
35  template<typename T> struct mean_type
36  : public std::conditional<std::is_integral<typename value_type<T>::type>::value, double, typename value_type<T>::type>
37  {};
38 
39  template<typename T> struct has_feature<T, mean_tag> {
40  template<typename R, typename C> static char helper(R(C::*)() const);
41  template<typename C> static char check(std::integral_constant<std::size_t, sizeof(helper(&C::mean))>*);
42  template<typename C> static double check(...);
43  typedef std::integral_constant<bool, sizeof(char) == sizeof(check<T>(0))> type;
44  constexpr static bool value = type::value;
45  };
46 
47  template<typename T> typename mean_type<T>::type mean(T const & arg) {
48  return arg.mean();
49  }
50 
51  namespace detail {
52 
53  template<typename A> typename std::enable_if<
55  , typename mean_type<A>::type
56  >::type mean_impl(A const & acc) {
57  return mean(acc);
58  }
59 
60  template<typename A> typename std::enable_if<
61  !has_feature<A, mean_tag>::value
62  , typename mean_type<A>::type
63  >::type mean_impl(A const & acc) {
64  throw std::runtime_error(std::string(typeid(A).name()) + " has no mean-method" + ALPS_STACKTRACE);
65  return typename mean_type<A>::type();
66  }
67  }
68 
69  namespace impl {
70 
71  template<typename T, typename B> struct Accumulator<T, mean_tag, B> : public B {
72 
73  public:
76 
77  Accumulator(): B(), m_sum(T()) {}
78  Accumulator(Accumulator const & arg): B(arg), m_sum(arg.m_sum) {}
79 
80  template<typename ArgumentPack> Accumulator(ArgumentPack const & args, typename std::enable_if<!is_accumulator<ArgumentPack>::value, int>::type = 0)
81  : B(args), m_sum(T())
82  {}
83 
84  mean_type const mean() const;
85 
86  using B::operator();
87  void operator()(T const & val);
88 
89  template<typename S> void print(S & os, bool terse=false) const {
90  os << alps::short_print(mean());
91  B::print(os, terse);
92  }
93 
94  void save(hdf5::archive & ar) const;
95  void load(hdf5::archive & ar);
96 
97  static std::size_t rank() { return B::rank() + 1; }
98  static bool can_load(hdf5::archive & ar);
99 
100  void reset() {
101  B::reset();
102  m_sum = T();
103  }
104 
106  template <typename A>
107  void merge(const A& rhs)
108  {
109  using alps::numeric::operator+=;
111  B::merge(rhs);
112  check_size(m_sum,rhs.m_sum);
113  m_sum += rhs.m_sum;
114  }
115 
116 #ifdef ALPS_HAVE_MPI
117  void collective_merge(
118  alps::mpi::communicator const & comm
119  , int root
120  );
121  void collective_merge(
122  alps::mpi::communicator const & comm
123  , int root
124  ) const;
125 #endif
126  protected:
127 
128  T const & sum() const;
129 
130  private:
131  T m_sum;
132  };
133 
134  template<typename T, typename B> class Result<T, mean_tag, B> : public B {
135 
136  public:
138  typedef typename detail::make_scalar_result_type<impl::Result,T,mean_tag,B>::type scalar_result_type;
139 
141  : B()
142  , m_mean(mean_type())
143  {}
144 
145  template<typename A> Result(A const & acc)
146  : B(acc)
147  , m_mean(detail::mean_impl(acc))
148  {}
149 
150  mean_type const mean() const {
151  return m_mean;
152  }
153 
154  template<typename S> void print(S & os, bool terse=false) const {
155  os << alps::short_print(mean());
156  B::print(os, terse);
157  }
158 
159  void save(hdf5::archive & ar) const;
160  void load(hdf5::archive & ar);
161 
162  static std::size_t rank() { return B::rank() + 1; }
163  static bool can_load(hdf5::archive & ar);
164 
165  template<typename U> void operator+=(U const & arg) { augadd(arg); }
166  template<typename U> void operator-=(U const & arg) { augsub(arg); }
167  template<typename U> void operator*=(U const & arg) { augmul(arg); }
168  template<typename U> void operator/=(U const & arg) { augdiv(arg); }
169  void negate();
170  void inverse();
171 
172  #define NUMERIC_FUNCTION_DECLARATION(FUNCTION_NAME) \
173  void FUNCTION_NAME ();
174 
190 
191  #undef NUMERIC_FUNCTION_DECLARATION
192 
193  private:
194 
195  mean_type m_mean;
196 
197  #define NUMERIC_FUNCTION_OPERATOR(OP_NAME, OPEQ_NAME, OP, OP_TOKEN) \
198  template<typename U> void aug ## OP_TOKEN (U const & arg, typename std::enable_if<!std::is_scalar<U>::value, int>::type = 0) { \
199  using alps::numeric:: OP_NAME ; \
200  m_mean = m_mean OP arg.mean(); \
201  B:: OPEQ_NAME (arg); \
202  } \
203  template<typename U> void aug ## OP_TOKEN (U const & arg, \
204  typename std::enable_if<std::is_scalar<U>::value, int>::type = 0) { \
205  using alps::numeric:: OP_NAME ; \
206  m_mean = m_mean OP static_cast<typename alps::numeric::scalar<mean_type>::type>(arg); \
207  B:: OPEQ_NAME (arg); \
208  }
209 
210  NUMERIC_FUNCTION_OPERATOR(operator+, operator+=, +, add)
211  NUMERIC_FUNCTION_OPERATOR(operator-, operator-=, -, sub)
212  NUMERIC_FUNCTION_OPERATOR(operator*, operator*=, *, mul)
213  NUMERIC_FUNCTION_OPERATOR(operator/, operator/=, /, div)
214 
215  #undef NUMERIC_FUNCTION_OPERATOR
216  };
217 
218  template<typename T, typename B> class BaseWrapper<T, mean_tag, B> : public B {
219  public:
220  virtual bool has_mean() const = 0;
221  virtual typename mean_type<B>::type mean() const = 0;
222  };
223 
224  template<typename T, typename B> class DerivedWrapper<T, mean_tag, B> : public B {
225  public:
226  DerivedWrapper(): B() {}
227  DerivedWrapper(T const & arg): B(arg) {}
228 
230 
231  typename mean_type<B>::type mean() const { return detail::mean_impl(this->m_data); }
232  };
233 
234  }
235  }
236 }
void merge(const A &rhs)
Merge the sum (mean) of given accumulator of type A into this sum (mean)
Definition: mean.hpp:107
alps::accumulators::mean_type< B >::type mean_type
Definition: mean.hpp:137
result_wrapper cbrt(result_wrapper const &arg)
void check_size(T &, U const &)
Definition: check_size.hpp:40
#define NUMERIC_FUNCTION_OPERATOR(OP_NAME, OPEQ_NAME, OP, OP_TOKEN)
Definition: mean.hpp:197
void load(archive &ar, std::string const &path, T &value, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:309
result_wrapper cos(result_wrapper const &arg)
result_wrapper sqrt(result_wrapper const &arg)
Accumulator(ArgumentPack const &args, typename std::enable_if<!is_accumulator< ArgumentPack >::value, int >::type=0)
Definition: mean.hpp:80
result_wrapper cb(result_wrapper const &arg)
result_wrapper sq(result_wrapper const &arg)
std::integral_constant< bool, sizeof(char)==sizeof(check< T >0))> type
Definition: mean.hpp:43
detail::short_print_proxy< T const > short_print(T const &v, std::size_t p=6)
Definition: short_print.hpp:29
Encapsulation of an MPI communicator and some communicator-related operations.
Definition: mpi.hpp:111
mean_type< T >::type mean(T const &arg)
Definition: mean.hpp:47
result_wrapper log(result_wrapper const &arg)
void reset(accumulator_wrapper &arg)
void print(S &os, bool terse=false) const
Definition: mean.hpp:154
result_wrapper tanh(result_wrapper const &arg)
result_wrapper acos(result_wrapper const &arg)
alps::accumulators::mean_type< B >::type mean_type
Definition: mean.hpp:74
std::ostream & print(std::ostream &s, const dict_value &dv, bool terse)
Definition: dict_value.cpp:186
void print(S &os, bool terse=false) const
Definition: mean.hpp:89
detail::make_scalar_result_type< impl::Result, T, mean_tag, B >::type scalar_result_type
Definition: mean.hpp:138
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
result_wrapper sin(result_wrapper const &arg)
result_wrapper asin(result_wrapper const &arg)
result_wrapper tan(result_wrapper const &arg)
result_wrapper abs(result_wrapper const &arg)
result_wrapper sinh(result_wrapper const &arg)
#define NUMERIC_FUNCTION_DECLARATION(FUNCTION_NAME)
Definition: mean.hpp:172
Result< T, mean_tag, typename B::result_type > result_type
Definition: mean.hpp:75
std::vector< T > & merge(std::vector< T > &left, const std::vector< T > &right)
Vector merge.
result_wrapper cosh(result_wrapper const &arg)
result_wrapper atan(result_wrapper const &arg)
void save(archive &ar, std::string const &path, T const &value, std::vector< std::size_t >=std::vector< std::size_t >(), std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
Definition: archive.hpp:292