9 #include <alps/config.hpp> 30 #include <boost/utility.hpp> 35 #include <type_traits> 38 namespace accumulators {
41 struct binning_analysis_tag;
44 :
public std::conditional<std::is_integral<typename value_type<T>::type>::value, double, typename value_type<T>::type>
51 template<
typename T>
struct has_feature<T, binning_analysis_tag> {
52 template<
typename R,
typename C>
static char helper(R(C::*)()
const);
53 template<
typename C>
static char check(std::integral_constant<std::size_t,
sizeof(helper(&
C::autocorrelation))>*);
54 template<
typename C>
static double check(...);
55 typedef std::integral_constant<bool, sizeof(char) == sizeof(check<T>(0))>
type;
56 constexpr
static bool value = type::value;
60 return arg.autocorrelation();
65 template<
typename A>
typename std::enable_if<
68 >::type autocorrelation_impl(A
const & acc) {
72 template<
typename A>
typename std::enable_if<
73 !has_feature<A, binning_analysis_tag>::value
75 >::type autocorrelation_impl(A
const & ) {
76 throw std::runtime_error(std::string(
typeid(A).name()) +
" has no autocorrelation-method" +
ALPS_STACKTRACE);
83 template<
typename T,
typename B>
struct Accumulator<T, binning_analysis_tag, B> :
public B {
105 return m_ac_sum2.size() < 8 ? 1 : m_ac_sum2.size() - 7;
111 void operator()(T
const & val);
113 template<
typename S>
void print(S & os,
bool terse=
false)
const {
116 <<
" #" << this->
count()
119 <<
" (warning: print result rather than accumulator)";
121 os <<
"DEBUG PRINTING of the accumulator object state (use mean(), error() and autocorrelation() methods instead)\n" 122 <<
"No-binning parent accumulator state:\n";
124 os <<
"\nLog-binning accumulator state:\n" 127 if (m_ac_sum2.size() > 0) {
128 for (std::size_t i = 0; i < binning_depth(); ++i)
130 <<
" bin #" << std::setw(3) << i + 1
131 <<
" : " << std::setw(8) << m_ac_count[i]
135 os <<
"No measurements" << std::endl;
142 static std::size_t
rank() {
return B::rank() + 1; }
148 template <
typename A>
154 merge(m_ac_count,rhs.m_ac_count);
155 merge(m_ac_sum,rhs.m_ac_sum);
156 merge(m_ac_sum2,rhs.m_ac_sum2);
160 void collective_merge(
164 void collective_merge(
172 std::vector<T> m_ac_sum;
173 std::vector<T> m_ac_sum2;
174 std::vector<T> m_ac_partial;
175 std::vector<typename count_type<B>::type> m_ac_count;
179 template<
typename T,
typename B>
class Result<T, binning_analysis_tag, B> :
public B {
184 typedef typename std::vector<error_type>::iterator error_iterator;
187 typedef typename detail::make_scalar_result_type<impl::Result,T,binning_analysis_tag,B>::type
scalar_result_type;
192 template<
typename A>
Result(A
const & acc)
194 , m_ac_autocorrelation(detail::autocorrelation_impl(acc))
195 , m_ac_errors(acc.binning_depth())
197 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
198 *it = acc.error(it - m_ac_errors.begin());
201 error_type
const error(std::size_t bin_level = std::numeric_limits<std::size_t>::max())
const;
204 return m_ac_autocorrelation;
207 template<
typename S>
void print(S & os,
bool terse=
false)
const {
210 <<
" #" << this->
count()
216 if (m_ac_errors.size() > 0) {
217 for (std::size_t i = 0; i < m_ac_errors.size(); ++i)
219 <<
" bin #" << std::setw(3) << i + 1
231 static std::size_t
rank() {
return B::rank() + 1; }
236 template<
typename U>
void operator*=(U
const & arg) { augmul(arg); }
237 template<
typename U>
void operator/=(U
const & arg) { augdiv(arg); }
262 std::vector<typename alps::accumulators::error_type<B>::type> m_ac_errors;
265 template <
typename U>
struct is_rel_type
266 :
public std::integral_constant<bool, std::is_same<U,self_type>::value ||
267 std::is_base_of<U,self_type>::value ||
268 std::is_base_of<self_type,U>::value > {};
271 template <
typename U>
struct is_rel_or_scalar_type
272 :
public std::integral_constant<bool, std::is_scalar<U>::value || is_rel_type<U>::value> {};
275 template<
typename U>
void augaddsub (U
const & arg,
typename std::enable_if<is_rel_type<U>::value,
int>::type = 0) {
276 using alps::numeric::operator+;
277 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
278 *it = *it + dynamic_cast<self_type const &>(arg).error(it - m_ac_errors.begin());
280 template<
typename U>
void augaddsub (U
const & arg,
typename std::enable_if<!is_rel_or_scalar_type<U>::value,
int>::type = 0) {
281 using alps::numeric::operator+;
282 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
283 *it = *it + dynamic_cast<scalar_result_type const &>(arg).error(it - m_ac_errors.begin());
285 template<
typename U>
void augaddsub (U
const & ,
typename std::enable_if<std::is_scalar<U>::value,
int>::type = 0) {}
287 template<
typename U>
void augmul (U
const & arg,
typename std::enable_if<is_rel_type<U>::value,
int>::type = 0) {
288 using alps::numeric::operator*;
289 using alps::numeric::operator+;
290 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
291 *it = arg.mean() * *it + this->
mean() *
dynamic_cast<self_type
const &
>(arg).
error(it - m_ac_errors.begin());
294 template<
typename U>
void augmul (U
const & arg,
typename std::enable_if<!is_rel_or_scalar_type<U>::value,
int>::type = 0) {
295 using alps::numeric::operator*;
296 using alps::numeric::operator+;
297 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
298 *it = (*it)*arg.mean() + this->
mean() *
dynamic_cast<scalar_result_type
const &
>(arg).
error(it - m_ac_errors.begin());
301 template<
typename U>
void augmul (U
const & arg,
typename std::enable_if<std::is_scalar<U>::value,
int>::type = 0) {
302 using alps::numeric::operator*;
303 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
304 *it = *it * static_cast<error_scalar_type>(arg);
308 template<
typename U>
void augdiv (U
const & arg,
typename std::enable_if<is_rel_type<U>::value,
int>::type = 0) {
309 using alps::numeric::operator*;
310 using alps::numeric::operator/;
311 using alps::numeric::operator+;
312 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
313 *it = *it / arg.mean() + this->
mean() *
dynamic_cast<self_type
const &
>(arg).
error(it - m_ac_errors.begin()) / (arg.mean() * arg.mean());
316 template<
typename U>
void augdiv (U
const & arg,
typename std::enable_if<!is_rel_or_scalar_type<U>::value,
int>::type = 0) {
317 using alps::numeric::operator*;
318 using alps::numeric::operator/;
319 using alps::numeric::operator+;
320 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
321 *it = *it / arg.mean() + this->
mean() *
dynamic_cast<scalar_result_type
const &
>(arg).
error(it - m_ac_errors.begin()) / (arg.mean() * arg.mean());
324 template<
typename U>
void augdiv (U
const & arg,
typename std::enable_if<std::is_scalar<U>::value,
int>::type = 0) {
325 using alps::numeric::operator/;
326 for (error_iterator it = m_ac_errors.begin(); it != m_ac_errors.end(); ++it)
327 *it = *it / static_cast<error_scalar_type>(arg);
332 template<
typename T,
typename B>
class BaseWrapper<T, binning_analysis_tag, B> :
public B {
334 virtual bool has_autocorrelation()
const = 0;
338 template<
typename T,
typename B>
class DerivedWrapper<T, binning_analysis_tag, B> :
public B {
detail::make_scalar_result_type< impl::Result, T, binning_analysis_tag, B >::type scalar_result_type
result_wrapper cbrt(result_wrapper const &arg)
static std::size_t rank()
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 >())
autocorrelation_type const autocorrelation() const
void operator+=(U const &arg)
result_wrapper cos(result_wrapper const &arg)
void operator*=(U const &arg)
result_wrapper sqrt(result_wrapper const &arg)
result_wrapper cb(result_wrapper const &arg)
result_wrapper sq(result_wrapper const &arg)
void operator/=(U const &arg)
static std::size_t rank()
detail::short_print_proxy< T const > short_print(T const &v, std::size_t p=6)
alps::accumulators::autocorrelation_type< B >::type autocorrelation_type
Encapsulation of an MPI communicator and some communicator-related operations.
uint32_t binning_depth() const
Metafunction returning "mathematical scalar" type for type T.
boost::array< T, N > & operator+=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
mean_type< T >::type mean(T const &arg)
void merge(const A &rhs)
Merge the bins of the given accumulator of type A into this accumulator.
void print(S &os, bool terse=false) const
result_wrapper log(result_wrapper const &arg)
void reset(accumulator_wrapper &arg)
boost::array< T, N > & operator/=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
boost::array< T, N > exp(boost::array< T, N > arg)
result_wrapper tanh(result_wrapper const &arg)
DerivedWrapper(T const &arg)
error_type< T >::type error(T const &arg)
boost::array< T, N > & operator*=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
result_wrapper acos(result_wrapper const &arg)
Result< T, binning_analysis_tag, typename B::result_type > result_type
std::ostream & print(std::ostream &s, const dict_value &dv, bool terse)
autocorrelation_type< T >::type autocorrelation(T const &arg)
result_wrapper sin(result_wrapper const &arg)
result_wrapper asin(result_wrapper const &arg)
result_wrapper tan(result_wrapper const &arg)
Accumulator(ArgumentPack const &args, typename std::enable_if<!is_accumulator< ArgumentPack >::value, int >::type=0)
result_wrapper sinh(result_wrapper const &arg)
void print(S &os, bool terse=false) const
bool has_autocorrelation() const
change_value_type< typename value_type< T >::type, int >::type type
autocorrelation_type< B >::type autocorrelation() const
std::integral_constant< bool, sizeof(char)==sizeof(check< T >0))> type
std::vector< T > & merge(std::vector< T > &left, const std::vector< T > &right)
Vector merge.
result_wrapper cosh(result_wrapper const &arg)
count_type< T >::type count(T const &arg)
boost::array< T, N > & operator-=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
result_wrapper atan(result_wrapper const &arg)
Defines a function to rectangularize a vector-of-vectors.
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 >())
void operator-=(U const &arg)