1 // Copyright (C) Eric Niebler 2008.
2 // Copyright (C) Pieter Bastiaan Ober 2014.
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #include <boost/test/unit_test.hpp>
8 #include <boost/test/floating_point_comparison.hpp>
9 #include <boost/mpl/assert.hpp>
10 #include <boost/type_traits/is_same.hpp>
11 #include <boost/accumulators/accumulators.hpp>
12 #include <boost/accumulators/statistics/stats.hpp>
13 #include <boost/accumulators/statistics/rolling_mean.hpp>
14 #include <sstream>
15 #include <boost/archive/text_oarchive.hpp>
16 #include <boost/archive/text_iarchive.hpp>
17
18 using namespace boost;
19 using namespace unit_test;
20 using namespace accumulators;
21
22 template<typename T>
assert_is_double(T const &)23 void assert_is_double(T const &)
24 {
25 BOOST_MPL_ASSERT((is_same<T, double>));
26 }
27
28 // test_rolling_mean_test_impl
29 // implements a test for window_size = 5
30 size_t window_size = 5;
31
32 template<typename accumulator_set_type>
33 void
test_rolling_mean_test_impl(accumulator_set_type & acc)34 test_rolling_mean_test_impl(accumulator_set_type& acc)
35 {
36 acc(1);
37 BOOST_CHECK_CLOSE(1., rolling_mean(acc), 1e-5);
38
39 acc(2);
40 BOOST_CHECK_CLOSE(1.5, rolling_mean(acc), 1e-5);
41
42 acc(3);
43 BOOST_CHECK_CLOSE(2., rolling_mean(acc), 1e-5);
44
45 acc(4);
46 BOOST_CHECK_CLOSE(2.5, rolling_mean(acc), 1e-5);
47
48 acc(5);
49 BOOST_CHECK_CLOSE(3., rolling_mean(acc), 1e-5);
50
51 acc(6);
52 BOOST_CHECK_CLOSE(4., rolling_mean(acc), 1e-5);
53
54 acc(7);
55 BOOST_CHECK_CLOSE(5., rolling_mean(acc), 1e-5);
56
57 assert_is_double(rolling_mean(acc));
58 }
59
60 template<typename accumulator_set_type>
61 void
test_rolling_mean_unsigned_test_impl(accumulator_set_type & acc)62 test_rolling_mean_unsigned_test_impl(accumulator_set_type& acc)
63 {
64 acc(7U);
65 BOOST_CHECK_CLOSE(7., rolling_mean(acc), 1e-5);
66
67 acc(6U);
68 BOOST_CHECK_CLOSE(6.5, rolling_mean(acc), 1e-5);
69
70 acc(5U);
71 BOOST_CHECK_CLOSE(6., rolling_mean(acc), 1e-5);
72
73 acc(4U);
74 BOOST_CHECK_CLOSE(5.5, rolling_mean(acc), 1e-5);
75
76 acc(3U);
77 BOOST_CHECK_CLOSE(5., rolling_mean(acc), 1e-5);
78
79 acc(2U);
80 BOOST_CHECK_CLOSE(4., rolling_mean(acc), 1e-5);
81
82 acc(1U);
83 BOOST_CHECK_CLOSE(3., rolling_mean(acc), 1e-5);
84
85 assert_is_double(rolling_mean(acc));
86 }
87
88 ///////////////////////////////////////////////////////////////////////////////
89 // test_persistency_impl
90 //
91 template<typename accumulator_set_type>
test_persistency_impl(accumulator_set_type & acc)92 void test_persistency_impl(accumulator_set_type& acc)
93 {
94 std::stringstream ss;
95 {
96 acc(1);
97 acc(2);
98 acc(3);
99 acc(4);
100 acc(5);
101 acc(6);
102 acc(7);
103 BOOST_CHECK_CLOSE(5., rolling_mean(acc), 1e-5);
104 boost::archive::text_oarchive oa(ss);
105 acc.serialize(oa, 0);
106 }
107 // initialize from acc to make sure all values are passed
108 accumulator_set_type other_acc = acc;
109 // accumulate more, to make sure that deserialization set the right value
110 // and not the copy ctor
111 other_acc(100);
112 other_acc(100);
113 other_acc(100);
114 other_acc(100);
115 other_acc(100);
116 boost::archive::text_iarchive ia(ss);
117 other_acc.serialize(ia, 0);
118 BOOST_CHECK_CLOSE(5., rolling_mean(other_acc), 1e-5);
119 }
120
121 ///////////////////////////////////////////////////////////////////////////////
122 // test_rolling_mean
test_rolling_mean()123 void test_rolling_mean()
124 {
125 accumulator_set<int,stats<tag::immediate_rolling_mean> >
126 acc_immediate_rolling_mean(tag::immediate_rolling_mean::window_size = window_size),
127 acc_immediate_rolling_mean2(tag::immediate_rolling_mean::window_size = window_size, sample = 0);
128
129 accumulator_set<int,stats<tag::rolling_mean(immediate)> >
130 acc_immediate_rolling_mean3(tag::immediate_rolling_mean::window_size = window_size);
131
132 accumulator_set<int,stats<tag::lazy_rolling_mean> >
133 acc_lazy_rolling_mean(tag::lazy_rolling_mean::window_size = window_size),
134 acc_lazy_rolling_mean2(tag::lazy_rolling_mean::window_size = window_size, sample = 0);
135
136 accumulator_set<int,stats<tag::rolling_mean(lazy)> >
137 acc_lazy_rolling_mean3(tag::lazy_rolling_mean::window_size = window_size);
138
139 accumulator_set<int,stats<tag::rolling_mean> >
140 acc_default_rolling_mean(tag::rolling_mean::window_size = window_size),
141 acc_default_rolling_mean2(tag::rolling_mean::window_size = window_size, sample = 0);
142
143 //// test the different implementations
144 test_rolling_mean_test_impl(acc_lazy_rolling_mean);
145 test_rolling_mean_test_impl(acc_default_rolling_mean);
146 test_rolling_mean_test_impl(acc_immediate_rolling_mean);
147
148 test_rolling_mean_test_impl(acc_lazy_rolling_mean2);
149 test_rolling_mean_test_impl(acc_default_rolling_mean2);
150 test_rolling_mean_test_impl(acc_immediate_rolling_mean2);
151
152 test_rolling_mean_test_impl(acc_lazy_rolling_mean3);
153 test_rolling_mean_test_impl(acc_immediate_rolling_mean3);
154
155 //// test that the default implementation is the 'immediate' computation
156 BOOST_REQUIRE(sizeof(acc_lazy_rolling_mean) != sizeof(acc_immediate_rolling_mean));
157 BOOST_CHECK (sizeof(acc_default_rolling_mean) == sizeof(acc_immediate_rolling_mean));
158
159 //// test the equivalence of the different ways to indicate a feature
160 BOOST_CHECK (sizeof(acc_lazy_rolling_mean) == sizeof(acc_lazy_rolling_mean2));
161 BOOST_CHECK (sizeof(acc_lazy_rolling_mean) == sizeof(acc_lazy_rolling_mean3));
162 BOOST_CHECK (sizeof(acc_immediate_rolling_mean) == sizeof(acc_immediate_rolling_mean2));
163 BOOST_CHECK (sizeof(acc_immediate_rolling_mean) == sizeof(acc_immediate_rolling_mean3));
164
165 //// test unsigned int with both implementations
166 accumulator_set<unsigned int,stats<tag::immediate_rolling_mean> >
167 acc_immediate_rolling_mean4(tag::immediate_rolling_mean::window_size = window_size),
168 acc_immediate_rolling_mean5(tag::immediate_rolling_mean::window_size = window_size, sample = 0);
169
170 test_rolling_mean_unsigned_test_impl(acc_immediate_rolling_mean4);
171 test_rolling_mean_unsigned_test_impl(acc_immediate_rolling_mean5);
172 }
173
174 ///////////////////////////////////////////////////////////////////////////////
175 // test_persistency
test_persistency()176 void test_persistency()
177 {
178 accumulator_set<int,stats<tag::immediate_rolling_mean> >
179 acc_immediate_rolling_mean(tag::immediate_rolling_mean::window_size = window_size),
180 acc_immediate_rolling_mean2(tag::immediate_rolling_mean::window_size = window_size, sample = 0);
181
182 accumulator_set<int,stats<tag::rolling_mean(immediate)> >
183 acc_immediate_rolling_mean3(tag::immediate_rolling_mean::window_size = window_size);
184
185 accumulator_set<int,stats<tag::lazy_rolling_mean> >
186 acc_lazy_rolling_mean(tag::lazy_rolling_mean::window_size = window_size),
187 acc_lazy_rolling_mean2(tag::lazy_rolling_mean::window_size = window_size, sample = 0);
188
189 accumulator_set<int,stats<tag::rolling_mean(lazy)> >
190 acc_lazy_rolling_mean3(tag::lazy_rolling_mean::window_size = window_size);
191
192 accumulator_set<int,stats<tag::rolling_mean> >
193 acc_default_rolling_mean(tag::rolling_mean::window_size = window_size),
194 acc_default_rolling_mean2(tag::rolling_mean::window_size = window_size, sample = 0);
195
196 //// test the different implementations
197 test_persistency_impl(acc_lazy_rolling_mean);
198 test_persistency_impl(acc_default_rolling_mean);
199 test_persistency_impl(acc_immediate_rolling_mean);
200
201 test_persistency_impl(acc_lazy_rolling_mean2);
202 test_persistency_impl(acc_default_rolling_mean2);
203 test_persistency_impl(acc_immediate_rolling_mean2);
204
205 test_persistency_impl(acc_lazy_rolling_mean3);
206 test_persistency_impl(acc_immediate_rolling_mean3);
207 }
208 ///////////////////////////////////////////////////////////////////////////////
209 // init_unit_test_suite
210 //
init_unit_test_suite(int argc,char * argv[])211 test_suite* init_unit_test_suite( int argc, char* argv[] )
212 {
213 test_suite *test = BOOST_TEST_SUITE("rolling mean test");
214
215 test->add(BOOST_TEST_CASE(&test_rolling_mean));
216 test->add(BOOST_TEST_CASE(&test_persistency));
217
218 return test;
219 }
220