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 /** @file mean_err_count.cpp
8     Test basic accumulator statistics.
9 */
10 
11 #include <boost/foreach.hpp>
12 #include <boost/math/special_functions/fpclassify.hpp> /* for portable isinf() */
13 
14 #include "alps/accumulators.hpp"
15 
16 #include "gtest/gtest.h"
17 
18 #include "../../utilities/test/vector_comparison_predicates.hpp" /* FIXME: relative path is fragile!! */
19 
20 #include "accumulator_generator.hpp"
21 
22 namespace aa=alps::accumulators;
23 namespace aat=aa::testing;
24 namespace at=alps::testing;
25 
26 // enum test_errbar_flag_type { TEST_ERRBAR, DONT_TEST_ERRBAR };
27 
28 // handy type shortcuts
29 typedef std::vector<float> v_float;
30 typedef std::vector<double> v_double;
31 typedef std::vector<long double> v_ldouble;
32 
33 // Proxy template to pass accumulator type, generator, number of tests, and tolerance as 10^-E
34 template <typename A, typename G, std::size_t N, int E=8>
35 struct generator {
36     typedef aat::AccResultGenerator<A,N,G> generator_type;
37     static const int TOLEXP=E;
38 };
39 
40 // GoogleTest fixture parametrized over data generator, via the proxy template above
41 template <typename G>
42 struct AccumulatorStatTest : public testing::Test {
43     typedef typename G::generator_type generator_type;
44     typedef typename generator_type::named_acc_type acc_type;
45     typedef typename generator_type::value_type value_type;
46 
47     static const std::size_t NPOINTS=generator_type::NPOINTS;
48     static const bool is_mean_acc=aat::is_same_accumulator<acc_type, aa::MeanAccumulator>::value;
49 
tolAccumulatorStatTest50     static double tol() { return std::pow(10.,-G::TOLEXP); }
51 
expected_errAccumulatorStatTest52     value_type expected_err() { return aat::gen_data<value_type>(gen.expected_err()); }
expected_meanAccumulatorStatTest53     value_type expected_mean() { return aat::gen_data<value_type>(gen.expected_mean()); }
54 
55     generator_type gen;
56 
testCountAccumulatorStatTest57     void testCount() {
58         std::size_t ac=count(gen.accumulator());
59         EXPECT_EQ(NPOINTS+0, ac) << "Accumulator count differs";
60         std::size_t rc=count(gen.accumulator());
61         EXPECT_EQ(NPOINTS+0, rc) << "Result count differs";
62     }
63 
testMeanAccumulatorStatTest64     void testMean() {
65         value_type amean=gen.accumulator().template mean<value_type>();
66         // aat::compare_near(expected_mean(), amean, tol(), "Accumulator mean");
67 	EXPECT_TRUE(at::is_near(expected_mean(), amean, tol())) << "Accumulator mean";
68 
69         value_type rmean=gen.result().template mean<value_type>();
70         // aat::compare_near(expected_mean(), rmean, tol(), "Result mean");
71 	EXPECT_TRUE(at::is_near(expected_mean(), rmean, tol())) << "Result mean";
72     }
73 
74     // This "naive" test is correct only for non-binning accumulators or for a large random data stream
testErrorAccumulatorStatTest75     void testError() {
76         if (is_mean_acc) {
77 #if defined(__APPLE__) && defined(__INTEL_COMPILER)
78             //we were testing fore exceptions here. OSX/ICPC fails when doing this.
79             EXPECT_ANY_THROW( value_type aerr=gen.accumulator().template error<value_type>() );
80             EXPECT_ANY_THROW( value_type rerr=gen.result().template error<value_type>() );
81 #endif
82             return;
83         }
84         value_type aerr=gen.accumulator().template error<value_type>();
85         // aat::compare_near(expected_err(), aerr, tol(), "Accumulator error bar");
86 	EXPECT_TRUE(at::is_near(expected_err(), aerr, tol())) << "Accumulator error bar";
87 
88         value_type rerr=gen.result().template error<value_type>();
89         // aat::compare_near(expected_err(), rerr, tol(), "Result error bar");
90 	EXPECT_TRUE(at::is_near(expected_err(), rerr, tol())) << "Result error bar";
91     }
92 };
93 
94 // Test set for "naive" error testing.
95 
96 TYPED_TEST_CASE_P(AccumulatorStatTest);
97 
98 #define DECLARE_TEST(_name_) TYPED_TEST_P(AccumulatorStatTest, _name_) { this->TestFixture::_name_(); }
99 DECLARE_TEST(testCount);
100 DECLARE_TEST(testMean);
101 DECLARE_TEST(testError);
102 #undef DECLARE_TEST
103 
104 REGISTER_TYPED_TEST_CASE_P(AccumulatorStatTest, testCount, testMean, testError);
105 
106 
107 typedef ::testing::Types<
108     generator<aa::MeanAccumulator<double>, aat::ConstantData, 2>,
109     generator<aa::MeanAccumulator<double>, aat::ConstantData, 100>,
110     generator<aa::MeanAccumulator<double>, aat::ConstantData, 20000>,
111     generator<aa::MeanAccumulator<double>, aat::AlternatingData, 2>,
112     generator<aa::MeanAccumulator<double>, aat::AlternatingData, 100>,
113     generator<aa::MeanAccumulator<double>, aat::AlternatingData, 20000>,
114     generator<aa::MeanAccumulator<double>, aat::LinearData, 2>,
115     generator<aa::MeanAccumulator<double>, aat::LinearData, 100>,
116     generator<aa::MeanAccumulator<double>, aat::LinearData, 20000>,
117     generator<aa::MeanAccumulator<double>, aat::RandomData, 100000, 3>,
118 
119     generator<aa::MeanAccumulator<v_double>, aat::ConstantData, 2>,
120     generator<aa::MeanAccumulator<v_double>, aat::ConstantData, 100>,
121     generator<aa::MeanAccumulator<v_double>, aat::ConstantData, 20000>,
122     generator<aa::MeanAccumulator<v_double>, aat::AlternatingData, 2>,
123     generator<aa::MeanAccumulator<v_double>, aat::AlternatingData, 100>,
124     generator<aa::MeanAccumulator<v_double>, aat::AlternatingData, 20000>,
125     generator<aa::MeanAccumulator<v_double>, aat::LinearData, 2>,
126     generator<aa::MeanAccumulator<v_double>, aat::LinearData, 100>,
127     generator<aa::MeanAccumulator<v_double>, aat::LinearData, 20000>,
128     generator<aa::MeanAccumulator<v_double>, aat::RandomData, 100000, 3>
129     > double_mean_types;
130 INSTANTIATE_TYPED_TEST_CASE_P(DoubleMean, AccumulatorStatTest, double_mean_types);
131 
132 typedef ::testing::Types<
133     generator<aa::MeanAccumulator<float>, aat::ConstantData, 2>,
134     generator<aa::MeanAccumulator<float>, aat::ConstantData, 100>,
135     generator<aa::MeanAccumulator<float>, aat::ConstantData, 20000>,
136     generator<aa::MeanAccumulator<float>, aat::AlternatingData, 2>,
137     generator<aa::MeanAccumulator<float>, aat::AlternatingData, 100>,
138     generator<aa::MeanAccumulator<float>, aat::AlternatingData, 20000>,
139     generator<aa::MeanAccumulator<float>, aat::LinearData, 2>,
140     generator<aa::MeanAccumulator<float>, aat::LinearData, 100>,
141     // generator<aa::MeanAccumulator<float>, aat::LinearData, 10000>,
142     generator<aa::MeanAccumulator<float>, aat::RandomData, 100000, 3>,
143 
144     generator<aa::MeanAccumulator<v_float>, aat::ConstantData, 2>,
145     generator<aa::MeanAccumulator<v_float>, aat::ConstantData, 100>,
146     generator<aa::MeanAccumulator<v_float>, aat::ConstantData, 20000>,
147     generator<aa::MeanAccumulator<v_float>, aat::AlternatingData, 2>,
148     generator<aa::MeanAccumulator<v_float>, aat::AlternatingData, 100>,
149     generator<aa::MeanAccumulator<v_float>, aat::AlternatingData, 20000>,
150     generator<aa::MeanAccumulator<v_float>, aat::LinearData, 2>,
151     generator<aa::MeanAccumulator<v_float>, aat::LinearData, 100>,
152     // generator<aa::MeanAccumulator<v_float>, aat::LinearData, 10000>,
153     generator<aa::MeanAccumulator<v_float>, aat::RandomData, 100000, 3>
154     > float_mean_types;
155 INSTANTIATE_TYPED_TEST_CASE_P(FloatMean, AccumulatorStatTest, float_mean_types);
156 
157 typedef ::testing::Types<
158     generator<aa::NoBinningAccumulator<double>, aat::ConstantData, 2>,
159     generator<aa::NoBinningAccumulator<double>, aat::ConstantData, 100>,
160     generator<aa::NoBinningAccumulator<double>, aat::ConstantData, 20000>,
161     generator<aa::NoBinningAccumulator<double>, aat::AlternatingData, 2>,
162     generator<aa::NoBinningAccumulator<double>, aat::AlternatingData, 100>,
163     generator<aa::NoBinningAccumulator<double>, aat::AlternatingData, 20000>,
164     generator<aa::NoBinningAccumulator<double>, aat::LinearData, 2>,
165     generator<aa::NoBinningAccumulator<double>, aat::LinearData, 100>,
166     generator<aa::NoBinningAccumulator<double>, aat::LinearData, 20000>,
167     generator<aa::NoBinningAccumulator<double>, aat::RandomData, 100000, 3>,
168 
169     generator<aa::NoBinningAccumulator<v_double>, aat::ConstantData, 2>,
170     generator<aa::NoBinningAccumulator<v_double>, aat::ConstantData, 100>,
171     generator<aa::NoBinningAccumulator<v_double>, aat::ConstantData, 20000>,
172     generator<aa::NoBinningAccumulator<v_double>, aat::AlternatingData, 2>,
173     generator<aa::NoBinningAccumulator<v_double>, aat::AlternatingData, 100>,
174     generator<aa::NoBinningAccumulator<v_double>, aat::AlternatingData, 20000>,
175     generator<aa::NoBinningAccumulator<v_double>, aat::LinearData, 2>,
176     generator<aa::NoBinningAccumulator<v_double>, aat::LinearData, 100>,
177     generator<aa::NoBinningAccumulator<v_double>, aat::LinearData, 20000>,
178     generator<aa::NoBinningAccumulator<v_double>, aat::RandomData, 100000, 3>
179     > double_nobin_types;
180 INSTANTIATE_TYPED_TEST_CASE_P(DoubleNobin, AccumulatorStatTest, double_nobin_types);
181 
182 typedef ::testing::Types<
183     generator<aa::NoBinningAccumulator<float>, aat::ConstantData, 2>,
184     generator<aa::NoBinningAccumulator<float>, aat::ConstantData, 100>,
185     generator<aa::NoBinningAccumulator<float>, aat::ConstantData, 20000>,
186     generator<aa::NoBinningAccumulator<float>, aat::AlternatingData, 2>,
187     generator<aa::NoBinningAccumulator<float>, aat::AlternatingData, 100>,
188     generator<aa::NoBinningAccumulator<float>, aat::AlternatingData, 20000>,
189     generator<aa::NoBinningAccumulator<float>, aat::LinearData, 2>,
190     generator<aa::NoBinningAccumulator<float>, aat::LinearData, 100>,
191     // generator<aa::NoBinningAccumulator<float>, aat::LinearData, 10000>,
192     generator<aa::NoBinningAccumulator<float>, aat::RandomData, 100000, 3>,
193 
194     generator<aa::NoBinningAccumulator<v_float>, aat::ConstantData, 2>,
195     generator<aa::NoBinningAccumulator<v_float>, aat::ConstantData, 100>,
196     generator<aa::NoBinningAccumulator<v_float>, aat::ConstantData, 20000>,
197     generator<aa::NoBinningAccumulator<v_float>, aat::AlternatingData, 2>,
198     generator<aa::NoBinningAccumulator<v_float>, aat::AlternatingData, 100>,
199     generator<aa::NoBinningAccumulator<v_float>, aat::AlternatingData, 20000>,
200     generator<aa::NoBinningAccumulator<v_float>, aat::LinearData, 2>,
201     generator<aa::NoBinningAccumulator<v_float>, aat::LinearData, 100>,
202     // generator<aa::NoBinningAccumulator<v_float>, aat::LinearData, 10000>,
203     generator<aa::NoBinningAccumulator<v_float>, aat::RandomData, 100000, 3>
204     > float_nobin_types;
205 INSTANTIATE_TYPED_TEST_CASE_P(FloatNobin, AccumulatorStatTest, float_nobin_types);
206 
207 typedef ::testing::Types<
208     generator<aa::LogBinningAccumulator<double>, aat::RandomData, 100000, 3>,
209     generator<aa::FullBinningAccumulator<double>, aat::RandomData, 100000, 3>,
210 
211     generator<aa::LogBinningAccumulator<v_double>, aat::RandomData, 100000, 3>,
212     generator<aa::FullBinningAccumulator<v_double>, aat::RandomData, 100000, 3>
213     > double_random_bin_types;
214 INSTANTIATE_TYPED_TEST_CASE_P(DoubleLogbin, AccumulatorStatTest, double_random_bin_types);
215 
216 
217 // Now, another set of tests that expect error bar to be infinite
218 template <typename G>
219 struct AccumulatorStatInfErrTest : public AccumulatorStatTest<G> {
220     typedef AccumulatorStatTest<G> base_type;
221     typedef typename base_type::value_type value_type;
222 
223     template <typename T>
is_infAccumulatorStatInfErrTest224     static bool is_inf(const T& val) { return (boost::math::isinf)(val); }
225 
226     template <typename T>
is_infAccumulatorStatInfErrTest227     static bool is_inf(const std::vector<T>& val) {
228         EXPECT_FALSE(val.empty()) << "Error vector is empty!!";
229         if (val.empty()) return false;
230         BOOST_FOREACH(const T& elem, val) {
231             if (!is_inf(elem)) return false;
232         }
233         return true;
234     }
235 
236 
testErrorAccumulatorStatInfErrTest237     void testError() {
238         value_type rerr=this->gen.result().template error<value_type>();
239         EXPECT_TRUE(is_inf(rerr)) << "Result error bar is incorrect";
240     }
241 };
242 
243 TYPED_TEST_CASE_P(AccumulatorStatInfErrTest);
244 
245 #define DECLARE_TEST(_name_) TYPED_TEST_P(AccumulatorStatInfErrTest, _name_) { this->TestFixture::_name_(); }
246 DECLARE_TEST(testCount);
247 DECLARE_TEST(testMean);
248 DECLARE_TEST(testError);
249 #undef DECLARE_TEST
250 
251 REGISTER_TYPED_TEST_CASE_P(AccumulatorStatInfErrTest, testCount, testMean, testError);
252 
253 
254 typedef ::testing::Types<
255     generator<aa::NoBinningAccumulator<double>, aat::ConstantData, 1>,
256     generator<aa::LogBinningAccumulator<double>, aat::ConstantData, 1>,
257     generator<aa::FullBinningAccumulator<double>, aat::ConstantData, 1>,
258 
259     generator<aa::LogBinningAccumulator<double>, aat::ConstantData, 100>,
260     generator<aa::LogBinningAccumulator<double>, aat::AlternatingData, 100>,
261     generator<aa::LogBinningAccumulator<double>, aat::LinearData, 100>
262     > double_short_types;
263 
264 INSTANTIATE_TYPED_TEST_CASE_P(DoubleShort, AccumulatorStatInfErrTest, double_short_types);
265 
266 typedef ::testing::Types<
267     generator<aa::NoBinningAccumulator<v_double>, aat::ConstantData, 1>,
268     generator<aa::LogBinningAccumulator<v_double>, aat::ConstantData, 1>,
269     generator<aa::FullBinningAccumulator<v_double>, aat::ConstantData, 1>,
270 
271     generator<aa::LogBinningAccumulator<v_double>, aat::ConstantData, 100>,
272     generator<aa::LogBinningAccumulator<v_double>, aat::AlternatingData, 100>,
273     generator<aa::LogBinningAccumulator<v_double>, aat::LinearData, 100>
274     > doublevec_short_types;
275 
276 INSTANTIATE_TYPED_TEST_CASE_P(DoubleVectorShort, AccumulatorStatInfErrTest, doublevec_short_types);
277 
278