11 #include <boost/preprocessor/tuple/to_seq.hpp> 12 #include <boost/preprocessor/seq/for_each.hpp> 14 #define ALPS_ACCUMULATOR_VALUE_TYPES_SEQ BOOST_PP_TUPLE_TO_SEQ(ALPS_ACCUMULATOR_VALUE_TYPES_SIZE, (ALPS_ACCUMULATOR_VALUE_TYPES)) 17 namespace accumulators {
24 template<
typename T,
typename B>
27 , m_mn_max_number(128)
28 , m_mn_elements_in_bin(0)
29 , m_mn_elements_in_partial(0)
33 template<
typename T,
typename B>
36 , m_mn_max_number(arg.m_mn_max_number)
37 , m_mn_elements_in_bin(arg.m_mn_elements_in_bin)
38 , m_mn_elements_in_partial(arg.m_mn_elements_in_partial)
39 , m_mn_partial(arg.m_mn_partial)
40 , m_mn_bins(arg.m_mn_bins)
43 template<
typename T,
typename B>
45 using alps::numeric::operator+=;
46 using alps::numeric::operator+;
47 using alps::numeric::operator/;
52 if (!m_mn_elements_in_bin) {
53 m_mn_bins.push_back(val);
54 m_mn_elements_in_bin = 1;
59 ++m_mn_elements_in_partial;
66 if (m_mn_elements_in_partial == m_mn_elements_in_bin && m_mn_bins.size() >= m_mn_max_number) {
67 if (m_mn_max_number % 2 == 1) {
68 m_mn_partial += m_mn_bins[m_mn_max_number - 1];
69 m_mn_elements_in_partial += m_mn_elements_in_bin;
72 m_mn_bins[i] = (m_mn_bins[2 * i] + m_mn_bins[2 * i + 1]) / two;
73 m_mn_bins.erase(m_mn_bins.begin() + m_mn_max_number / 2, m_mn_bins.end());
76 if (m_mn_elements_in_partial == m_mn_elements_in_bin) {
77 m_mn_bins.push_back(m_mn_partial / elements_in_bin);
79 m_mn_elements_in_partial = 0;
83 template<
typename T,
typename B>
87 ar[
"timeseries/partialbin"] = m_mn_partial;
88 ar[
"timeseries/partialbin/@count"] = m_mn_elements_in_partial;
90 ar[
"timeseries/data"] = m_mn_bins;
91 ar[
"timeseries/data/@binningtype"] =
"linear";
92 ar[
"timeseries/data/@minbinsize"] = 0;
93 ar[
"timeseries/data/@binsize"] = m_mn_elements_in_bin;
94 ar[
"timeseries/data/@maxbinnum"] = m_mn_max_number;
97 template<
typename T,
typename B>
100 ar[
"timeseries/data"] >> m_mn_bins;
101 ar[
"timeseries/data/@binsize"] >> m_mn_elements_in_bin;
102 ar[
"timeseries/data/@maxbinnum"] >> m_mn_max_number;
103 if (ar.
is_data(
"timeseries/partialbin")) {
104 ar[
"timeseries/partialbin"] >> m_mn_partial;
105 ar[
"timeseries/partialbin/@count"] >> m_mn_elements_in_partial;
109 template<
typename T,
typename B>
112 const char name[]=
"timeseries/data";
113 const std::size_t ndim=
get_extent(T()).size()+1;
114 return B::can_load(ar) &&
115 detail::archive_trait<T>::can_load(ar, name, ndim) &&
127 template<
typename T,
typename B>
130 m_mn_elements_in_bin =
typename B::count_type();
131 m_mn_elements_in_partial =
typename B::count_type();
133 m_mn_bins = std::vector<typename mean_type<B>::type>();
137 template<
typename T,
typename B>
141 if (comm.
rank() == root) {
142 B::collective_merge(comm, root);
143 if (!m_mn_bins.empty()) {
144 std::vector<typename mean_type<B>::type> local_bins(m_mn_bins), merged_bins;
145 partition_bins(comm, local_bins, merged_bins, root);
156 template<
typename T,
typename B>
160 B::collective_merge(comm, root);
161 if (comm.
rank() == root)
162 throw std::runtime_error(
"A const object cannot be root" +
ALPS_STACKTRACE);
163 else if (!m_mn_bins.empty()) {
164 std::vector<typename mean_type<B>::type> local_bins(m_mn_bins), merged_bins;
165 partition_bins(comm, local_bins, merged_bins, root);
170 template<
typename T,
typename B>
176 using alps::numeric::operator+;
177 using alps::numeric::operator/;
181 typename B::count_type howmany = (elements_in_local_bins - 1) / m_mn_elements_in_bin + 1;
183 typename B::count_type newbins = local_bins.size() / howmany;
185 for (
typename B::count_type i = 0; i < newbins; ++i) {
186 local_bins[i] = local_bins[howmany * i];
187 for (
typename B::count_type j = 1; j < howmany; ++j)
188 local_bins[i] = local_bins[i] + local_bins[howmany * i + j];
189 local_bins[i] = local_bins[i] / howmany_vt;
191 local_bins.resize(newbins);
194 std::vector<std::size_t>
index(comm.
size());
196 std::size_t total_bins = std::accumulate(
index.begin(),
index.end(), 0);
197 std::size_t perbin = total_bins < m_mn_max_number ? 1 : total_bins / m_mn_max_number;
200 merged_bins.resize(perbin == 1 ? total_bins : m_mn_max_number);
201 for (
typename std::vector<
typename mean_type<B>::type>::iterator it = merged_bins.begin(); it != merged_bins.end(); ++it)
204 std::size_t start = std::accumulate(
index.begin(),
index.begin() + comm.
rank(), 0);
205 for (std::size_t i = start / perbin, j = start % perbin, k = 0; i < merged_bins.size() && k < local_bins.size(); ++k) {
206 merged_bins[i] = merged_bins[i] + local_bins[k] / perbin_vt;
213 #define ALPS_ACCUMULATOR_INST_MAX_NUM_BINNING_ACC(r, data, T) \ 214 template class Accumulator<T, max_num_binning_tag, \ 215 Accumulator<T, binning_analysis_tag, \ 216 Accumulator<T, error_tag, \ 217 Accumulator<T, mean_tag, \ 218 Accumulator<T, count_tag, \ 219 AccumulatorBase<T>>>>>>; 227 template<typename T, typename B>
231 , m_mn_elements_in_bin(0)
233 , m_mn_mean(typename
mean_type<B>::type())
235 , m_mn_cannot_rebin(false)
236 , m_mn_jackknife_valid(false)
237 , m_mn_data_is_analyzed(true)
238 , m_mn_jackknife_bins(0)
241 template<
typename T,
typename B>
243 if (!m_mn_data_is_analyzed) {
244 return m_mn_elements_in_bin * m_mn_bins.size();
252 template<
typename T,
typename B>
258 template<
typename T,
typename B>
353 template<
typename T,
typename B>
357 ar[
"count"] = m_mn_count;
358 ar[
"@cannotrebin"] = m_mn_cannot_rebin;
359 ar[
"mean/value"] = m_mn_mean;
360 ar[
"mean/error"] = m_mn_error;
361 ar[
"timeseries/data"] = m_mn_bins;
362 ar[
"timeseries/data/@binsize"] = m_mn_elements_in_bin;
363 ar[
"timeseries/data/@maxbinnum"] = m_mn_max_number;
364 ar[
"timeseries/data/@binningtype"] =
"linear";
365 ar[
"timeseries/data/@jacknife_valid"] = m_mn_jackknife_valid;
366 if (m_mn_jackknife_valid) {
367 ar[
"jacknife/data"] = m_mn_jackknife_bins;
368 ar[
"jacknife/data/@binningtype"] =
"linear";
372 template<
typename T,
typename B>
375 ar[
"timeseries/data"] >> m_mn_bins;
376 ar[
"timeseries/data/@binsize"] >> m_mn_elements_in_bin;
377 ar[
"timeseries/data/@maxbinnum"] >> m_mn_max_number;
378 ar[
"timeseries/data/@jacknife_valid"] >> m_mn_jackknife_valid;
380 ar[
"count"] >> m_mn_count;
381 ar[
"@cannotrebin"] >> m_mn_cannot_rebin;
382 ar[
"mean/value"] >> m_mn_mean;
383 ar[
"mean/error"] >> m_mn_error;
384 if (m_mn_jackknife_valid) {
385 ar[
"jacknife/data"] >> m_mn_jackknife_bins;
389 template<
typename T,
typename B>
392 const char name[]=
"timeseries/data";
393 const std::size_t ndim=
get_extent(T()).size()+1;
395 return B::can_load(ar) &&
396 detail::archive_trait<T>::can_load(ar, name, ndim) &&
401 #define NUMERIC_FUNCTION_IMPLEMENTATION(FUNCTION_NAME) \ 402 template<typename T, typename B> \ 403 void Result<T, max_num_binning_tag, B>:: FUNCTION_NAME () { \ 404 using alps::numeric::sq; \ 405 using alps::numeric::sq; \ 406 using alps::numeric::cbrt; \ 407 using alps::numeric::cbrt; \ 408 using alps::numeric::cb; \ 409 using alps::numeric::cb; \ 411 using alps::numeric::sqrt; \ 413 using alps::numeric::exp; \ 415 using alps::numeric::log; \ 417 using alps::numeric::abs; \ 419 using alps::numeric::pow; \ 421 using alps::numeric::sin; \ 423 using alps::numeric::cos; \ 425 using alps::numeric::tan; \ 427 using alps::numeric::sinh; \ 429 using alps::numeric::cosh; \ 431 using alps::numeric::tanh; \ 433 using alps::numeric::asin; \ 435 using alps::numeric::acos; \ 437 using alps::numeric::atan; \ 438 typedef typename value_type<B>::type (*fptr_type)(typename value_type<B>::type); \ 439 fptr_type fptr=& FUNCTION_NAME; \ 441 B:: FUNCTION_NAME (); \ 461 #undef NUMERIC_FUNCTION_IMPLEMENTATION 463 template<
typename T,
typename B>
473 template<
typename T,
typename B>
483 template<
typename T,
typename B>
485 using alps::numeric::operator-;
486 using alps::numeric::operator+;
487 using alps::numeric::operator*;
488 using alps::numeric::operator/;
491 if (!m_mn_bins.empty() && !m_mn_jackknife_valid) {
492 if (m_mn_cannot_rebin)
493 throw std::runtime_error(
"Cannot build jackknife data structure after nonlinear operations" +
ALPS_STACKTRACE);
494 m_mn_jackknife_bins.clear();
495 m_mn_jackknife_bins.resize(m_mn_bins.size() + 1);
499 scalar_type bin_number = m_mn_bins.size();
500 for(std::size_t j = 0; j < m_mn_bins.size(); ++j)
501 m_mn_jackknife_bins[0] = m_mn_jackknife_bins[0] + m_mn_bins[j];
502 for(std::size_t i = 0; i < m_mn_bins.size(); ++i)
503 m_mn_jackknife_bins[i + 1] = (m_mn_jackknife_bins[0] - m_mn_bins[i]) / (bin_number -
static_cast<scalar_type
>(1));
504 m_mn_jackknife_bins[0] = m_mn_jackknife_bins[0] / bin_number;
506 m_mn_jackknife_valid =
true;
509 template<
typename T,
typename B>
514 using alps::numeric::operator-;
515 using alps::numeric::operator+;
516 using alps::numeric::operator*;
517 using alps::numeric::operator/;
520 if (m_mn_bins.empty())
522 if (!m_mn_data_is_analyzed) {
523 m_mn_count = m_mn_elements_in_bin * m_mn_bins.size();
524 generate_jackknife();
525 if (m_mn_jackknife_bins.size()) {
527 scalar_type bin_number = m_mn_bins.size();
528 for (
typename std::vector<
typename mean_type<B>::type>::const_iterator it = m_mn_jackknife_bins.begin() + 1;
529 it != m_mn_jackknife_bins.end(); ++it)
530 unbiased_mean = unbiased_mean + *it / bin_number;
531 m_mn_mean = m_mn_jackknife_bins[0] - (unbiased_mean - m_mn_jackknife_bins[0]) * (bin_number - static_cast<scalar_type>(1));
533 for (std::size_t i = 0; i < m_mn_bins.size(); ++i)
534 m_mn_error = m_mn_error +
sq(m_mn_jackknife_bins[i + 1] - unbiased_mean);
535 m_mn_error =
sqrt(m_mn_error / bin_number * (bin_number - static_cast<scalar_type>(1)));
538 m_mn_data_is_analyzed =
true;
543 Result<T, binning_analysis_tag,
555 #define ALPS_ACCUMULATOR_INST_MAX_NUM_BINNING_RESULT(r, data, T) \ 556 template class Result<T, max_num_binning_tag, \ 557 Result<T, binning_analysis_tag, \ 558 Result<T, error_tag, \ 559 Result<T, mean_tag, \ 560 Result<T, count_tag, \ 561 ResultBase<T>>>>>>; \ index_mesh::index_type index
result_wrapper cbrt(result_wrapper const &arg)
void check_size(T &, U const &)
#define ALPS_ACCUMULATOR_INST_MAX_NUM_BINNING_ACC(r, data, T)
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)
#define NUMERIC_FUNCTION_IMPLEMENTATION(FUNCTION_NAME)
bool is_attribute(std::string path) const
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].
bool is_data(std::string path) const
result_wrapper sqrt(result_wrapper const &arg)
result_wrapper cb(result_wrapper const &arg)
result_wrapper sq(result_wrapper const &arg)
std::vector< std::size_t > get_extent(T const &value)
mean_result< T > transform(no_prop, const transformer< T > &tf, const InResult &in)
Encapsulation of an MPI communicator and some communicator-related operations.
Metafunction returning "mathematical scalar" type for type T.
void all_gather(const communicator &comm, const T &in_val, std::vector< T > &out_vals)
performs MPI_Allgather() for primitive type T
mean_type< T >::type mean(T const &arg)
result_wrapper log(result_wrapper const &arg)
void reset(accumulator_wrapper &arg)
"Imported" negation functor class (needed to define template specializations in this namespace) ...
boost::array< T, N > exp(boost::array< T, N > arg)
result_wrapper tanh(result_wrapper const &arg)
error_type< T >::type error(T const &arg)
result_wrapper acos(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_VALUE_TYPES_SEQ
Class-holder for reduction operations (and a functor) for type T.
result_wrapper sin(result_wrapper const &arg)
result_wrapper asin(result_wrapper const &arg)
int rank() const
Returns process rank in this communicator.
result_wrapper tan(result_wrapper const &arg)
result_wrapper abs(result_wrapper const &arg)
result_wrapper sinh(result_wrapper const &arg)
boost::array< T, N > sq(boost::array< T, N > arg)
A service functor class for numerical inversion, to be used in transform()
typename covariance_type< Result< T, binning_analysis_tag, Result< T, error_tag, Result< T, mean_tag, Result< T, count_tag, ResultBase< T >>>>>>::type covariance_t
result_wrapper cosh(result_wrapper const &arg)
#define ALPS_ACCUMULATOR_INST_MAX_NUM_BINNING_RESULT(r, data, T)
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 >())