12 #include <boost/preprocessor/tuple/to_seq.hpp> 13 #include <boost/preprocessor/seq/for_each.hpp> 15 #define ALPS_ACCUMULATOR_VALUE_TYPES_SEQ BOOST_PP_TUPLE_TO_SEQ(ALPS_ACCUMULATOR_VALUE_TYPES_SIZE, (ALPS_ACCUMULATOR_VALUE_TYPES)) 18 #define BOOST_ENABLE_ASSERT_HANDLER 19 #include "boost/assert.hpp" 22 inline void assertion_failed_msg(
char const * expr,
char const * msg,
char const *
function,
char const * file,
long line)
24 std::ostringstream errmsg;
25 errmsg <<
"Boost assertion " << expr <<
" failed in " 27 << file <<
"(" << line <<
"): " 29 throw std::logic_error(errmsg.str());
32 inline void assertion_failed(
char const * expr,
char const *
function,
char const * file,
long line)
34 std::ostringstream errmsg;
35 errmsg <<
"Boost assertion " << expr <<
" failed in " 37 << file <<
"(" << line <<
")";
38 throw std::logic_error(errmsg.str());
43 namespace accumulators {
50 template<
typename T,
typename B>
59 template<
typename T,
typename B>
62 , m_ac_sum(arg.m_ac_sum)
63 , m_ac_sum2(arg.m_ac_sum2)
64 , m_ac_partial(arg.m_ac_partial)
65 , m_ac_count(arg.m_ac_count)
100 template<
typename T,
typename B>
103 using alps::numeric::operator*;
104 using alps::numeric::operator-;
105 using alps::numeric::operator/;
125 if (m_ac_sum2.size()<8) {
127 }
else if (bin_level > m_ac_sum2.size() - 8) {
128 bin_level = m_ac_sum2.size() - 8;
135 if (m_ac_sum2.size() < 2)
139 error_scalar_type one = 1;
141 error_scalar_type binlen = 1ll << bin_level;
142 BOOST_ASSERT_MSG(bin_level<m_ac_count.size(),
"bin_level within the range of m_ac_count");
143 error_scalar_type N_i = m_ac_count[bin_level];
144 BOOST_ASSERT_MSG(bin_level<m_ac_sum.size(),
"bin_level within the range of m_ac_sum");
145 error_type sum_i = m_ac_sum[bin_level];
146 BOOST_ASSERT_MSG(bin_level<m_ac_sum2.size(),
"bin_level within the range of m_ac_sum2");
147 error_type sum2_i = m_ac_sum2[bin_level];
148 error_type var_i = (sum2_i / binlen - sum_i * sum_i / (N_i * binlen)) / (N_i * binlen);
149 return sqrt(var_i / (N_i - one));
152 template<
typename T,
typename B>
154 using alps::numeric::operator*;
155 using alps::numeric::operator-;
156 using alps::numeric::operator/;
163 mean_type err =
error();
166 if (m_ac_sum2.size() < 2)
169 mean_scalar_type one = 1;
170 mean_scalar_type two = 2;
172 mean_scalar_type N_0 = m_ac_count[0];
173 mean_type sum_0 = m_ac_sum[0];
174 mean_type sum2_0 = m_ac_sum2[0];
175 mean_type var_0 = (sum2_0 - sum_0 * sum_0 / N_0) / N_0;
177 mean_scalar_type fac =
B::count() - 1;
178 return (err * err * fac / var_0 - one) / two;
181 template<
typename T,
typename B>
183 using alps::numeric::operator+=;
184 using alps::numeric::operator*;
188 if(
B::count() == (1UL << m_ac_sum2.size())) {
189 m_ac_sum2.push_back(T());
191 m_ac_sum.push_back(T());
193 m_ac_partial.push_back(m_ac_sum[0]);
197 BOOST_ASSERT_MSG(m_ac_partial.size() >= m_ac_sum2.size(),
"m_ac_partial is as large as m_ac_sum2");
198 BOOST_ASSERT_MSG(m_ac_count.size() >= m_ac_sum2.size(),
"m_ac_count is as large as m_ac_sum2");
199 BOOST_ASSERT_MSG(m_ac_sum.size() >= m_ac_sum2.size(),
"m_ac_sum is as large as m_ac_sum2");
200 for (
unsigned i = 0; i < m_ac_sum2.size(); ++i) {
201 m_ac_partial[i] += val;
204 if (!(
B::count() & ((1ll << i) - 1))) {
205 m_ac_sum2[i] += m_ac_partial[i] * m_ac_partial[i];
206 m_ac_sum[i] += m_ac_partial[i];
208 m_ac_partial[i] = T();
214 template<
typename T,
typename B>
218 ar[
"tau/partialbin"] = m_ac_sum;
219 ar[
"tau/data"] = m_ac_sum2;
220 ar[
"tau/ac_count"] = m_ac_count;
221 ar[
"tau/ac_partial"] = m_ac_partial;
224 template<
typename T,
typename B>
227 if (ar.
is_data(
"tau/partialbin"))
228 ar[
"tau/partialbin"] >> m_ac_sum;
229 ar[
"tau/data"] >> m_ac_sum2;
230 if (ar.
is_data(
"tau/ac_count"))
231 ar[
"tau/ac_count"] >> m_ac_count;
232 if (ar.
is_data(
"tau/ac_partial"))
233 ar[
"tau/ac_partial"] >> m_ac_partial;
236 template<
typename T,
typename B>
239 const char name[]=
"tau/data";
240 const std::size_t ndim=
get_extent(T()).size()+1;
241 return B::can_load(ar) &&
242 detail::archive_trait<T>::can_load(ar, name, ndim);
245 template<
typename T,
typename B>
248 m_ac_sum = std::vector<T>();
249 m_ac_sum2 = std::vector<T>();
250 m_ac_partial = std::vector<T>();
251 m_ac_count = std::vector<typename count_type<B>::type>();
255 template<
typename T,
typename B>
261 if (comm.
rank() == root) {
262 B::collective_merge(comm, root);
266 m_ac_count.resize(size);
269 m_ac_sum.resize(size);
271 B::reduce_if(comm, std::vector<T>(m_ac_sum), m_ac_sum, std::plus<mean_scalar_type>(), root);
273 m_ac_sum2.resize(size);
275 B::reduce_if(comm, std::vector<T>(m_ac_sum2), m_ac_sum2, std::plus<mean_scalar_type>(), root);
281 template<
typename T,
typename B>
286 B::collective_merge(comm, root);
287 if (comm.
rank() == root)
288 throw std::runtime_error(
"A const object cannot be root" +
ALPS_STACKTRACE);
294 std::vector<typename count_type<B>::type>
count(m_ac_count);
299 std::vector<T> sum(m_ac_sum);
302 B::reduce_if(comm, sum, std::plus<mean_scalar_type>(), root);
305 std::vector<T> sum2(m_ac_sum2);
308 B::reduce_if(comm, sum2, std::plus<mean_scalar_type>(), root);
314 #define ALPS_ACCUMULATOR_INST_BINNING_ANALYSIS_ACC(r, data, T) \ 315 template class Accumulator<T, binning_analysis_tag, \ 316 Accumulator<T, error_tag, \ 317 Accumulator<T, mean_tag, \ 318 Accumulator<T, count_tag, \ 319 AccumulatorBase<T>>>>>; 327 template<typename T, typename B>
330 , m_ac_autocorrelation()
334 template<
typename T,
typename B>
336 if (m_ac_errors.size() < 2)
340 return m_ac_errors[std::min(m_ac_errors.size()-1, bin_level)];
343 template<
typename T,
typename B>
346 ar[
"error_bins"]=m_ac_errors;
347 ar[
"tau"] = m_ac_autocorrelation;
350 template<
typename T,
typename B>
353 ar[
"error_bins"] >> m_ac_errors;
354 ar[
"tau"] >> m_ac_autocorrelation;
357 template<
typename T,
typename B>
360 const char name[]=
"tau";
361 const std::size_t ndim=
get_extent(T()).size();
362 return B::can_load(ar) &&
363 detail::archive_trait<T>::can_load(ar, name, ndim);
366 template<
typename T,
typename B>
374 template<
typename T,
typename B>
376 using alps::numeric::operator*;
377 using alps::numeric::operator/;
378 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
379 *it = dynamic_cast<self_type &>(*this).error(it - m_ac_errors.begin()) / (this->
mean() * this->
mean());
383 #define NUMERIC_FUNCTION_USING \ 384 using alps::numeric::sq; \ 385 using alps::numeric::cbrt; \ 386 using alps::numeric::cb; \ 388 using alps::numeric::sqrt; \ 390 using alps::numeric::exp; \ 392 using alps::numeric::log; \ 394 using alps::numeric::abs; \ 396 using alps::numeric::pow; \ 398 using alps::numeric::sin; \ 400 using alps::numeric::cos; \ 402 using alps::numeric::tan; \ 404 using alps::numeric::sinh; \ 406 using alps::numeric::cosh; \ 408 using alps::numeric::tanh; \ 410 using alps::numeric::asin; \ 412 using alps::numeric::acos; \ 414 using alps::numeric::atan; \ 415 using alps::numeric::operator+; \ 416 using alps::numeric::operator-; \ 417 using alps::numeric::operator*; \ 418 using alps::numeric::operator/; 420 #define NUMERIC_FUNCTION_DECL(FUNCTION_NAME) \ 421 template<typename T, typename B> \ 422 void Result<T, binning_analysis_tag, B>:: FUNCTION_NAME() 427 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
434 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
441 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
448 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
455 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
462 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
469 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
470 *it =
abs(error_scalar_type(1) /
sqrt( -this->
mean() * this->
mean() + error_scalar_type(1) ) * *it);
476 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
477 *it =
abs(error_scalar_type(-1) /
sqrt( -this->
mean() * this->
mean() + error_scalar_type(1) ) * *it);
483 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
484 *it =
abs(error_scalar_type(1) / (this->
mean() * this->
mean() + error_scalar_type(1)) * *it);
492 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
493 *it =
abs( this->
mean() * (*it) * error_scalar_type(2) );
499 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
500 *it =
abs(*it / (
sqrt(this->
mean()) * error_scalar_type(2) ));
506 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
507 *it =
abs(
sq(this->
mean()) * (*it) * error_scalar_type(3) );
513 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
514 *it =
abs(*it / (
sq(
cbrt(this->
mean())) * error_scalar_type(3) ));
520 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
527 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
531 #define ALPS_ACCUMULATOR_INST_BINNING_ANALYSIS_RESULT(r, data, T) \ 532 template class Result<T, binning_analysis_tag, \ 533 Result<T, error_tag, \ 534 Result<T, mean_tag, \ 535 Result<T, count_tag, \ boost::array< T, N > sinh(boost::array< T, N > arg)
result_wrapper cbrt(result_wrapper const &arg)
void check_size(T &, U const &)
boost::array< T, N > tanh(boost::array< T, N > arg)
boost::array< T, N > cbrt(boost::array< T, N > arg)
boost::array< T, N > atan(boost::array< T, N > arg)
boost::array< T, N > log(boost::array< T, N > arg)
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 >())
int size() const
Returns the number of processes in this communicator.
boost::array< T, N > sqrt(boost::array< T, N > arg)
result_wrapper cos(result_wrapper const &arg)
void all_reduce(const alps::mpi::communicator &comm, const T *val, int n, T *out_val, const OP &)
Performs MPI_Allreduce for array of a primitive type, T[n].
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
boost::array< T, N > cos(boost::array< T, N > arg)
bool is_data(std::string path) const
result_wrapper sqrt(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_INST_BINNING_ANALYSIS_RESULT(r, data, T)
result_wrapper cb(result_wrapper const &arg)
result_wrapper sq(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_VALUE_TYPES_SEQ
std::vector< std::size_t > get_extent(T const &value)
#define NUMERIC_FUNCTION_USING
Encapsulation of an MPI communicator and some communicator-related operations.
std::enable_if<!is_sequence< T >::value, void >::type set_negative_0(T &x)
Metafunction returning "mathematical scalar" type for type T.
mean_type< T >::type mean(T const &arg)
boost::array< T, N > cosh(boost::array< T, N > arg)
result_wrapper log(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_INST_BINNING_ANALYSIS_ACC(r, data, T)
void assertion_failed_msg(char const *expr, char const *msg, char const *function, char const *file, long line)
void reset(accumulator_wrapper &arg)
boost::array< T, N > exp(boost::array< T, N > arg)
void rectangularize(const T &)
Make sure that vector-of-vectors is a rectangular matrix (generic dummy template) ...
result_wrapper tanh(result_wrapper const &arg)
error_type< T >::type error(T const &arg)
#define NUMERIC_FUNCTION_DECL(FUNCTION_NAME)
result_wrapper acos(result_wrapper const &arg)
boost::array< T, N > asin(boost::array< T, N > arg)
boost::array< T, N > sin(boost::array< T, N > arg)
Class-holder for reduction operations (and a functor) for type T.
autocorrelation_type< T >::type autocorrelation(T const &arg)
result_wrapper sin(result_wrapper const &arg)
result_wrapper asin(result_wrapper const &arg)
int rank() const
Returns process rank in this communicator.
boost::array< T, N > acos(boost::array< T, N > arg)
result_wrapper tan(result_wrapper const &arg)
result_wrapper abs(result_wrapper const &arg)
void assertion_failed(char const *expr, char const *function, char const *file, long line)
boost::array< T, N > cb(boost::array< T, N > arg)
boost::array< T, N > tan(boost::array< T, N > arg)
result_wrapper sinh(result_wrapper const &arg)
boost::array< T, N > sq(boost::array< T, N > arg)
result_wrapper cosh(result_wrapper const &arg)
count_type< T >::type count(T 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 >())