ALPSCore reference
error.cpp
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 #include <boost/preprocessor/tuple/to_seq.hpp>
8 #include <boost/preprocessor/seq/for_each.hpp>
9 
10 #include <alps/config.hpp>
11 
13 #include <alps/hdf5/vector.hpp>
14 
15 #define ALPS_ACCUMULATOR_VALUE_TYPES_SEQ BOOST_PP_TUPLE_TO_SEQ(ALPS_ACCUMULATOR_VALUE_TYPES_SIZE, (ALPS_ACCUMULATOR_VALUE_TYPES))
16 
17 namespace alps {
18  namespace accumulators {
19  namespace impl {
20 
21  //
22  // Accumulator<T, error_tag, B>
23  //
24 
25  template<typename T, typename B>
27  using std::sqrt;
28  using alps::numeric::sqrt;
29  using alps::numeric::operator/;
30  using alps::numeric::operator-;
31  using alps::numeric::operator*;
32 
33  // TODO: make library for scalar type
35  const error_scalar_type one=1;
36  if (cnt<=one) return alps::numeric::inf<error_type>(m_sum2);
37  return sqrt((m_sum2 / cnt - B::mean() * B::mean()) / (cnt - one));
38  }
39 
40  template<typename T, typename B>
42  using alps::numeric::operator*;
43  using alps::numeric::operator+=;
45 
46  B::operator()(val);
47  check_size(m_sum2, val);
48  m_sum2 += val * val;
49  }
50 
51  template<typename T, typename B>
53  B::save(ar);
54  ar["mean/error"] = error();
55  }
56 
57  template<typename T, typename B>
58  void Accumulator<T, error_tag, B>::load(hdf5::archive & ar) { // TODO: make archive const
59  using alps::numeric::operator*;
60  using alps::numeric::operator+;
61 
62  B::load(ar);
64  ar["mean/error"] >> error;
65  // TODO: make library for scalar type
67  m_sum2 = (error * error * (cnt - static_cast<error_scalar_type>(1)) + B::mean() * B::mean()) * cnt;
68  }
69 
70  template<typename T, typename B>
71  bool Accumulator<T, error_tag, B>::can_load(hdf5::archive & ar) { // TODO: make archive const
73  const char name[]="mean/error";
74  const std::size_t ndim=std::is_scalar<T>::value? 0 : get_extent(T()).size();
75  return B::can_load(ar) &&
76  detail::archive_trait<error_type>::can_load(ar, name, ndim);
77  }
78 
79 #ifdef ALPS_HAVE_MPI
80  template<typename T, typename B>
82  alps::mpi::communicator const & comm
83  , int root
84  ) {
85  if (comm.rank() == root) {
86  B::collective_merge(comm, root);
87  B::reduce_if(comm, T(m_sum2), m_sum2, std::plus<typename alps::hdf5::scalar_type<T>::type>(), root);
88  } else
89  const_cast<Accumulator<T, error_tag, B> const *>(this)->collective_merge(comm, root);
90  }
91 
92  template<typename T, typename B>
94  alps::mpi::communicator const & comm
95  , int root
96  ) const {
97  B::collective_merge(comm, root);
98  if (comm.rank() == root)
99  throw std::runtime_error("A const object cannot be root" + ALPS_STACKTRACE);
100  else
101  B::reduce_if(comm, m_sum2, std::plus<typename alps::hdf5::scalar_type<T>::type>(), root);
102  }
103 #endif
104 
105  #define ALPS_ACCUMULATOR_INST_ERROR_ACC(r, data, T) \
106  template class Accumulator<T, error_tag, \
107  Accumulator<T, mean_tag, \
108  Accumulator<T, count_tag, \
109  AccumulatorBase<T>>>>;
111 
112  //
113  // Result<T, error_tag, B>
114  //
115 
116  template<typename T, typename B>
117  void Result<T, error_tag, B>::save(hdf5::archive & ar) const {
118  B::save(ar);
119  ar["mean/error"] = error();
120  }
121 
122  template<typename T, typename B>
124  B::load(ar);
125  ar["mean/error"] >> m_error;
126  }
127 
128  template<typename T, typename B>
129  bool Result<T, error_tag, B>::can_load(hdf5::archive & ar) { // TODO: make archive const
131  const char name[]="mean/error";
132  const std::size_t ndim=std::is_scalar<T>::value? 0 : get_extent(T()).size();
133  return B::can_load(ar) &&
134  detail::archive_trait<error_type>::can_load(ar, name, ndim);
135  }
136 
137  template<typename T, typename B>
139  B::negate();
140  }
141 
142  template<typename T, typename B>
144  using alps::numeric::operator*;
145  using alps::numeric::operator/;
146  m_error = this->error() / (this->mean() * this->mean());
147  B::inverse();
148  }
149 
150  #define NUMERIC_FUNCTION_USING \
151  using alps::numeric::sq; \
152  using alps::numeric::cbrt; \
153  using alps::numeric::cb; \
154  using std::sqrt; \
155  using alps::numeric::sqrt; \
156  using std::exp; \
157  using alps::numeric::exp; \
158  using std::log; \
159  using alps::numeric::log; \
160  using std::abs; \
161  using alps::numeric::abs; \
162  using std::pow; \
163  using alps::numeric::pow; \
164  using std::sin; \
165  using alps::numeric::sin; \
166  using std::cos; \
167  using alps::numeric::cos; \
168  using std::tan; \
169  using alps::numeric::tan; \
170  using std::sinh; \
171  using alps::numeric::sinh; \
172  using std::cosh; \
173  using alps::numeric::cosh; \
174  using std::tanh; \
175  using alps::numeric::tanh; \
176  using std::asin; \
177  using alps::numeric::asin; \
178  using std::acos; \
179  using alps::numeric::acos; \
180  using std::atan; \
181  using alps::numeric::atan; \
182  using alps::numeric::operator+; \
183  using alps::numeric::operator-; \
184  using alps::numeric::operator*; \
185  using alps::numeric::operator/;
186 
187  #define NUMERIC_FUNCTION_IMPLEMENTATION(FUNCTION_NAME, ERROR) \
188  template<typename T, typename B> \
189  void Result<T, error_tag, B>:: FUNCTION_NAME () { \
190  B:: FUNCTION_NAME (); \
191  NUMERIC_FUNCTION_USING \
192  m_error = ERROR ; \
193  }
194 
197  NUMERIC_FUNCTION_IMPLEMENTATION(tan, abs(error_scalar_type(1) / (cos(this->mean()) * cos(this->mean())) * m_error))
199  NUMERIC_FUNCTION_IMPLEMENTATION(cosh, abs(sinh(this->mean()) * m_error))
200  NUMERIC_FUNCTION_IMPLEMENTATION(tanh, abs(error_scalar_type(1) / (cosh(this->mean()) * cosh(this->mean())) * m_error))
204  // abs does not change the error, so nothing has to be done ...
206  NUMERIC_FUNCTION_IMPLEMENTATION(sqrt, abs(m_error / (sqrt(this->mean()) * error_scalar_type(2) )))
208  NUMERIC_FUNCTION_IMPLEMENTATION(cbrt, abs(m_error / ( sq( cbrt(this->mean()) )*error_scalar_type(3) )))
209  NUMERIC_FUNCTION_IMPLEMENTATION(exp, exp(this->mean()) * m_error)
211 
212  #undef NUMERIC_FUNCTION_IMPLEMENTATION
213 
214  #define ALPS_ACCUMULATOR_INST_ERROR_RESULT(r, data, T) \
215  template class Result<T, error_tag, \
216  Result<T, mean_tag, \
217  Result<T, count_tag, \
218  ResultBase<T>>>>;
220  }
221  }
222 }
#define NUMERIC_FUNCTION_IMPLEMENTATION(FUNCTION_NAME, ERROR)
Definition: error.cpp:187
result_wrapper cbrt(result_wrapper const &arg)
void check_size(T &, U const &)
Definition: check_size.hpp:40
alps::numeric::scalar< error_type >::type error_scalar_type
Definition: error.hpp:75
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
boost::array< T, N > sqrt(boost::array< T, N > arg)
result_wrapper cos(result_wrapper const &arg)
result_wrapper sqrt(result_wrapper const &arg)
result_wrapper cb(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_VALUE_TYPES_SEQ
Definition: error.cpp:15
result_wrapper sq(result_wrapper const &arg)
std::vector< std::size_t > get_extent(T const &value)
Definition: archive.hpp:280
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)
boost::array< T, N > exp(boost::array< T, N > arg)
alps::numeric::scalar< error_type >::type error_scalar_type
Definition: error.hpp:137
result_wrapper tanh(result_wrapper const &arg)
error_type< T >::type error(T const &arg)
Definition: error.hpp:47
result_wrapper acos(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_INST_ERROR_ACC(r, data, T)
Definition: error.cpp:105
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
result_wrapper sin(result_wrapper const &arg)
result_wrapper asin(result_wrapper const &arg)
int rank() const
Returns process rank in this communicator.
Definition: mpi.hpp:156
result_wrapper tan(result_wrapper const &arg)
result_wrapper abs(result_wrapper const &arg)
alps::accumulators::error_type< B >::type error_type
Definition: error.hpp:74
result_wrapper sinh(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_INST_ERROR_RESULT(r, data, T)
Definition: error.cpp:214
result_wrapper cosh(result_wrapper const &arg)
count_type< T >::type count(T const &arg)
Definition: count.hpp:39
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