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/tools/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> |
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 |
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 |
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> |
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 |
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&: acc_lazy_rolling_mean); |
145 | test_rolling_mean_test_impl(acc&: acc_default_rolling_mean); |
146 | test_rolling_mean_test_impl(acc&: acc_immediate_rolling_mean); |
147 | |
148 | test_rolling_mean_test_impl(acc&: acc_lazy_rolling_mean2); |
149 | test_rolling_mean_test_impl(acc&: acc_default_rolling_mean2); |
150 | test_rolling_mean_test_impl(acc&: acc_immediate_rolling_mean2); |
151 | |
152 | test_rolling_mean_test_impl(acc&: acc_lazy_rolling_mean3); |
153 | test_rolling_mean_test_impl(acc&: 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&: acc_immediate_rolling_mean4); |
171 | test_rolling_mean_unsigned_test_impl(acc&: acc_immediate_rolling_mean5); |
172 | } |
173 | |
174 | /////////////////////////////////////////////////////////////////////////////// |
175 | // 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&: acc_lazy_rolling_mean); |
198 | test_persistency_impl(acc&: acc_default_rolling_mean); |
199 | test_persistency_impl(acc&: acc_immediate_rolling_mean); |
200 | |
201 | test_persistency_impl(acc&: acc_lazy_rolling_mean2); |
202 | test_persistency_impl(acc&: acc_default_rolling_mean2); |
203 | test_persistency_impl(acc&: acc_immediate_rolling_mean2); |
204 | |
205 | test_persistency_impl(acc&: acc_lazy_rolling_mean3); |
206 | test_persistency_impl(acc&: acc_immediate_rolling_mean3); |
207 | } |
208 | /////////////////////////////////////////////////////////////////////////////// |
209 | // init_unit_test_suite |
210 | // |
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 | |