9 #include <alps/config.hpp> 28 #include <boost/utility.hpp> 29 #include <boost/function.hpp> 32 #include <type_traits> 35 namespace accumulators {
38 struct max_num_binning_tag;
41 template<
typename C,
typename M>
class max_num_binning_proxy {
42 typedef typename std::size_t size_type;
45 max_num_binning_proxy(std::vector<M>
const & bins, C
const & num_elements, size_type
const & max_number)
46 : m_max_number(max_number)
47 , m_num_elements(num_elements)
51 std::vector<M>
const & bins()
const {
55 C num_elements()
const {
56 return m_num_elements;
59 size_type max_number()
const {
63 std::ostream&
print(std::ostream& os,
bool terse)
const 73 os << m_num_elements <<
" elements per bin, bins are:\n";
74 for (
size_t i=0; i<m_bins.size(); ++i) {
82 size_type m_max_number;
84 std::vector<M>
const & m_bins;
87 template<
typename C,
typename M>
inline std::ostream & operator<<(std::ostream & os, max_num_binning_proxy<C, M>
const & arg) {
88 return arg.print(os,
true);
96 template<
typename T>
struct has_feature<T, max_num_binning_tag> {
97 template<
typename R,
typename C>
static char helper(R(C::*)()
const);
98 template<
typename C>
static char check(std::integral_constant<std::size_t,
sizeof(helper(&
C::max_num_binning))>*);
99 template<
typename C>
static double check(...);
100 typedef std::integral_constant<bool, sizeof(char) == sizeof(check<T>(0))>
type;
101 constexpr
static bool value = type::value;
105 return arg.max_num_binning();
114 template<
typename A>
typename std::enable_if<
117 >
::type max_num_binning_impl(A
const & acc) {
120 template<
typename A>
typename std::enable_if<
121 !has_feature<A, max_num_binning_tag>::value
123 >
::type max_num_binning_impl(A
const & ) {
124 throw std::runtime_error(std::string(
typeid(A).name()) +
" has no max_num_binning-method" +
ALPS_STACKTRACE);
128 template<
typename A,
typename OP>
void transform_impl(
131 ,
typename std::enable_if<has_feature<A, max_num_binning_tag>::value,
int>::
type = 0
135 template<
typename A,
typename OP>
void transform_impl(
138 ,
typename std::enable_if<!has_feature<A, max_num_binning_tag>::value,
int>::
type = 0
140 throw std::runtime_error(std::string(
typeid(A).name()) +
" has no transform-method" +
ALPS_STACKTRACE);
146 template<
typename T,
typename B>
struct Accumulator<T, max_num_binning_tag, B> :
public B {
157 , m_mn_max_number(args[max_bin_number | 128])
158 , m_mn_elements_in_bin(0)
159 , m_mn_elements_in_partial(0)
164 return max_num_binning_type(m_mn_bins, m_mn_elements_in_bin, m_mn_max_number);
168 throw std::runtime_error(
"Transform can only be applied to a result" +
ALPS_STACKTRACE);
171 template <
typename U,
typename OP>
void transform(U
const &, OP) {
172 throw std::runtime_error(
"Transform can only be applied to a result" +
ALPS_STACKTRACE);
176 void operator()(T
const & val);
178 template<
typename S>
void print(S & os,
bool terse=
false)
const {
181 <<
" #" << this->
count()
186 os <<
"Full-binning accumulator state:\n" 187 <<
"Mean +/-error (tau): " 199 static std::size_t
rank() {
return B::rank() + 1; }
207 template <
typename A>
210 throw std::logic_error(
"Merging of FullBinningAccumulators is not yet implemented.\n" 211 "Please contact ALPSCore developers and provide the code\n" 212 "where you are using the merge() method.");
233 std::size_t m_mn_max_number;
234 typename B::count_type m_mn_elements_in_bin, m_mn_elements_in_partial;
236 std::vector<typename mean_type<B>::type> m_mn_bins;
241 template<
typename T,
typename B>
class Result<T, max_num_binning_tag, B> :
public B {
245 typedef typename detail::make_scalar_result_type<impl::Result,T,max_num_binning_tag,B>::type
scalar_result_type;
250 template<
typename A>
Result(A
const & acc,
typename std::enable_if<std::is_base_of<
ResultBase<T>, A>::value,
int>::type = 0)
252 , m_mn_max_number(acc.m_mn_max_number)
253 , m_mn_elements_in_bin(acc.m_mn_elements_in_bin)
254 , m_mn_bins(acc.m_mn_bins)
255 , m_mn_count(acc.
count())
256 , m_mn_mean(acc.
mean())
257 , m_mn_error(acc.
error())
258 , m_mn_cannot_rebin(acc.m_mn_cannot_rebin)
259 , m_mn_jackknife_valid(acc.m_mn_jackknife_valid)
260 , m_mn_data_is_analyzed(acc.m_mn_data_is_analyzed)
261 , m_mn_jackknife_bins(acc.m_mn_jackknife_bins)
264 template<
typename A>
Result(A
const & acc,
typename std::enable_if<!std::is_base_of<
ResultBase<T>, A>::value,
int>::type = 0)
266 , m_mn_max_number(detail::max_num_binning_impl(acc).max_number())
267 , m_mn_elements_in_bin(detail::max_num_binning_impl(acc).num_elements())
268 , m_mn_bins(detail::max_num_binning_impl(acc).bins())
269 , m_mn_count(acc.
count())
270 , m_mn_mean(acc.
mean())
271 , m_mn_error(acc.
error())
272 , m_mn_cannot_rebin(false)
273 , m_mn_jackknife_valid(false)
274 , m_mn_data_is_analyzed(true)
275 , m_mn_jackknife_bins(0)
278 typename B::count_type
count()
const;
283 return max_num_binning_type(m_mn_bins, m_mn_elements_in_bin, m_mn_max_number);
303 template<
typename S>
void print(S & os,
bool terse=
false)
const {
305 os <<
"Mean +/-error (tau): " 317 static std::size_t
rank() {
return B::rank() + 1; }
321 template<
typename U>
void operator+=(U
const & arg) { augadd(arg); }
322 template<
typename U>
void operator-=(U
const & arg) { augsub(arg); }
323 template<
typename U>
void operator*=(U
const & arg) { augmul(arg); }
324 template<
typename U>
void operator/=(U
const & arg) { augdiv(arg); }
327 generate_jackknife();
328 m_mn_data_is_analyzed =
false;
329 m_mn_cannot_rebin =
true;
330 typename std::vector<typename mean_type<B>::type>::iterator it;
331 for (it = m_mn_bins.begin(); it != m_mn_bins.end(); ++it)
333 for (it = m_mn_jackknife_bins.begin(); it != m_mn_jackknife_bins.end(); ++it)
338 template <
typename OP,
typename U>
void transform(OP op, U
const & arg) {
339 generate_jackknife();
340 arg.generate_jackknife();
341 if (arg.get_jackknife_bins().size() != m_mn_jackknife_bins.size())
342 throw std::runtime_error(
"Unable to transform: unequal number of bins" +
ALPS_STACKTRACE);
343 m_mn_data_is_analyzed =
false;
344 m_mn_cannot_rebin =
true;
345 typename std::vector<typename mean_type<B>::type>::iterator it;
346 typename std::vector<typename mean_type<U>::type>::const_iterator jt;
347 for (it = m_mn_bins.begin(), jt = arg.get_bins().begin(); it != m_mn_bins.end(); ++it, ++jt)
349 for (it = m_mn_jackknife_bins.begin(), jt = arg.get_jackknife_bins().begin(); it != m_mn_jackknife_bins.end(); ++it, ++jt)
377 std::size_t m_mn_max_number;
378 typename B::count_type m_mn_elements_in_bin;
379 std::vector<typename mean_type<B>::type> m_mn_bins;
380 mutable typename B::count_type m_mn_count;
383 mutable bool m_mn_cannot_rebin;
384 mutable bool m_mn_jackknife_valid;
385 mutable bool m_mn_data_is_analyzed;
386 mutable std::vector<typename mean_type<B>::type> m_mn_jackknife_bins;
389 const std::vector<typename mean_type<B>::type>&
get_bins()
const {
393 return m_mn_jackknife_bins;
395 void generate_jackknife()
const;
398 void analyze()
const;
400 #define NUMERIC_FUNCTION_OPERATOR(OP_NAME, OPEQ_NAME, OP, OP_TOKEN, OP_STD) \ 401 template<typename U> void aug ## OP_TOKEN (U const & arg, typename std::enable_if<!std::is_scalar<U>::value, int>::type = 0) { \ 402 typedef typename value_type<B>::type self_value_type; \ 403 typedef typename value_type<U>::type arg_value_type; \ 404 transform(boost::function<self_value_type(self_value_type, arg_value_type)>( OP_STD <self_value_type, arg_value_type, self_value_type>()), arg); \ 405 B:: OPEQ_NAME (arg); \ 407 template<typename U> void aug ## OP_TOKEN (U const & arg, typename std::enable_if<std::is_scalar<U>::value, int>::type = 0) { \ 408 using alps::numeric:: OP_NAME ; \ 409 typedef typename mean_type<B>::type mean_type; \ 410 generate_jackknife(); \ 411 m_mn_data_is_analyzed = false; \ 412 m_mn_cannot_rebin = true; \ 413 typename std::vector<mean_type>::iterator it; \ 414 for (it = m_mn_bins.begin(); it != m_mn_bins.end(); ++it) \ 415 *it = *it OP static_cast<typename alps::numeric::scalar<mean_type>::type>(arg); \ 416 for (it = m_mn_jackknife_bins.begin(); it != m_mn_jackknife_bins.end(); ++it) \ 417 *it = *it OP static_cast<typename alps::numeric::scalar<mean_type>::type>(arg); \ 419 B:: OPEQ_NAME (arg); \ 427 #undef NUMERIC_FUNCTION_OPERATOR 430 template<
typename T,
typename B>
class BaseWrapper<T, max_num_binning_tag, B> :
public B {
432 virtual bool has_max_num_binning()
const = 0;
437 template<
typename T,
typename B>
class DerivedWrapper<T, max_num_binning_tag, B> :
public B {
result_wrapper cbrt(result_wrapper const &arg)
detail::max_num_binning_proxy< typename count_type< T >::type, typename mean_type< T >::type > type
DerivedWrapper(T const &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 >())
Accumulator(ArgumentPack const &args, typename std::enable_if<!is_accumulator< ArgumentPack >::value, int >::type=0)
result_wrapper cos(result_wrapper const &arg)
result_wrapper sqrt(result_wrapper const &arg)
result_wrapper cb(result_wrapper const &arg)
std::integral_constant< bool, sizeof(char)==sizeof(check< T >0))> type
max_num_binning_type const max_num_binning() const
result_wrapper sq(result_wrapper const &arg)
void operator*=(U const &arg)
max_num_binning_type const max_num_binning() const
void operator+=(U const &arg)
mean_result< T > transform(no_prop, const transformer< T > &tf, const InResult &in)
detail::short_print_proxy< T const > short_print(T const &v, std::size_t p=6)
static std::size_t rank()
Encapsulation of an MPI communicator and some communicator-related operations.
void print(S &os, bool terse=false) const
alps::accumulators::max_num_binning_type< B >::type max_num_binning_type
void print(S &os, bool terse=false) const
mean_type< T >::type mean(T const &arg)
const std::vector< typename mean_type< B >::type > & get_jackknife_bins() const
result_wrapper log(result_wrapper const &arg)
void transform(U const &, OP)
max_num_binning_type< T >::type max_num_binning(T const &arg)
void reset(accumulator_wrapper &arg)
boost::array< T, N > exp(boost::array< T, N > arg)
alps::accumulators::max_num_binning_type< B >::type max_num_binning_type
result_wrapper tanh(result_wrapper const &arg)
error_type< T >::type error(T const &arg)
std::conditional< is_sequence< value_type< T >::type >::value, detail::matrix_covariance_type< typename average_type< typename element_type< value_type< T >::type >::type >::type >, typename average_type< value_type< T >::type >::type >::type type
result_wrapper acos(result_wrapper const &arg)
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)
max_num_binning_type< B >::type max_num_binning() const
result_wrapper tan(result_wrapper const &arg)
void transform(boost::function< typename value_type< B >::type(typename value_type< B >::type)> op)
result_wrapper abs(result_wrapper const &arg)
void transform(OP op, U const &arg)
result_wrapper sinh(result_wrapper const &arg)
void merge(const A &rhs)
Merge the bins of the given accumulator of type A into this accumulator.
#define NUMERIC_FUNCTION_OPERATOR(OP_NAME, OPEQ_NAME, OP, OP_TOKEN, OP_STD)
static std::size_t rank()
bool has_max_num_binning() const
std::vector< T > & merge(std::vector< T > &left, const std::vector< T > &right)
Vector merge.
detail::make_scalar_result_type< impl::Result, T, max_num_binning_tag, B >::type scalar_result_type
void operator-=(U const &arg)
Result(A const &acc, typename std::enable_if<!std::is_base_of< ResultBase< T >, A >::value, int >::type=0)
result_wrapper cosh(result_wrapper const &arg)
Result(A const &acc, typename std::enable_if< std::is_base_of< ResultBase< T >, A >::value, int >::type=0)
Result< T, max_num_binning_tag, typename B::result_type > result_type
count_type< T >::type count(T const &arg)
void operator/=(U const &arg)
result_wrapper atan(result_wrapper const &arg)
bool has_transform() const
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 >())
const std::vector< typename mean_type< B >::type > & get_bins() const