]>
Commit | Line | Data |
---|---|---|
1 | // Copyright John Maddock 2006. | |
2 | // Copyright Paul A. Bristow 2007. | |
3 | ||
4 | // Use, modification and distribution are subject to the | |
5 | // Boost Software License, Version 1.0. | |
6 | // (See accompanying file LICENSE_1_0.txt | |
7 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 | ||
9 | // test_exponential_dist.cpp | |
10 | ||
11 | #include <boost/math/tools/test.hpp> | |
12 | #include <boost/math/concepts/real_concept.hpp> // for real_concept | |
13 | #include <boost/math/distributions/exponential.hpp> | |
14 | using boost::math::exponential_distribution; | |
15 | ||
16 | #define BOOST_TEST_MAIN | |
17 | #include <boost/test/unit_test.hpp> // Boost.Test | |
18 | #include <boost/test/tools/floating_point_comparison.hpp> | |
19 | #include "test_out_of_range.hpp" | |
20 | ||
21 | #include <iostream> | |
22 | using std::cout; | |
23 | using std::endl; | |
24 | using std::setprecision; | |
25 | ||
26 | template <class RealType> | |
27 | void test_spot(RealType l, RealType x, RealType p, RealType q, RealType tolerance) | |
28 | { | |
29 | BOOST_CHECK_CLOSE( | |
30 | ::boost::math::cdf( | |
31 | exponential_distribution<RealType>(l), | |
32 | x), | |
33 | p, | |
34 | tolerance); // % | |
35 | BOOST_CHECK_CLOSE( | |
36 | ::boost::math::cdf( | |
37 | complement(exponential_distribution<RealType>(l), | |
38 | x)), | |
39 | q, | |
40 | tolerance); // % | |
41 | if(p < 0.999) | |
42 | { | |
43 | BOOST_CHECK_CLOSE( | |
44 | ::boost::math::quantile( | |
45 | exponential_distribution<RealType>(l), | |
46 | p), | |
47 | x, | |
48 | tolerance); // % | |
49 | } | |
50 | if(q < 0.999) | |
51 | { | |
52 | BOOST_CHECK_CLOSE( | |
53 | ::boost::math::quantile( | |
54 | complement(exponential_distribution<RealType>(l), | |
55 | q)), | |
56 | x, | |
57 | tolerance); // % | |
58 | } | |
59 | } | |
60 | ||
61 | template <class RealType> | |
62 | void test_spots(RealType T) | |
63 | { | |
64 | // Basic sanity checks. | |
65 | // 50 eps as a percentage, up to a maximum of double precision | |
66 | // (that's the limit of our test data: obtained by punching | |
67 | // numbers into a calculator). | |
68 | RealType tolerance = (std::max)( | |
69 | static_cast<RealType>(boost::math::tools::epsilon<double>()), | |
70 | boost::math::tools::epsilon<RealType>()); | |
71 | tolerance *= 50 * 100; | |
72 | // # pragma warning(disable: 4100) // unreferenced formal parameter. | |
73 | // prevent his spurious warning. | |
74 | if (T != 0) | |
75 | { | |
76 | cout << "Expect parameter T == 0!" << endl; | |
77 | } | |
78 | cout << "Tolerance for type " << typeid(T).name() << " is " << tolerance << " %" << endl; | |
79 | ||
80 | test_spot( | |
81 | static_cast<RealType>(0.5), // lambda | |
82 | static_cast<RealType>(0.125), // x | |
83 | static_cast<RealType>(0.060586937186524213880289175377695L), // p | |
84 | static_cast<RealType>(0.93941306281347578611971082462231L), //q | |
85 | tolerance); | |
86 | test_spot( | |
87 | static_cast<RealType>(0.5), // lambda | |
88 | static_cast<RealType>(5), // x | |
89 | static_cast<RealType>(0.91791500137610120483047132553284L), // p | |
90 | static_cast<RealType>(0.08208499862389879516952867446716L), //q | |
91 | tolerance); | |
92 | test_spot( | |
93 | static_cast<RealType>(2), // lambda | |
94 | static_cast<RealType>(0.125), // x | |
95 | static_cast<RealType>(0.22119921692859513175482973302168L), // p | |
96 | static_cast<RealType>(0.77880078307140486824517026697832L), //q | |
97 | tolerance); | |
98 | test_spot( | |
99 | static_cast<RealType>(2), // lambda | |
100 | static_cast<RealType>(5), // x | |
101 | static_cast<RealType>(0.99995460007023751514846440848444L), // p | |
102 | static_cast<RealType>(4.5399929762484851535591515560551e-5L), //q | |
103 | tolerance); | |
104 | ||
105 | // | |
106 | // Some spot tests generated by MathCAD pexp(x,r): | |
107 | // | |
108 | test_spot( | |
109 | static_cast<RealType>(1), // lambda | |
110 | static_cast<RealType>(1), // x | |
111 | static_cast<RealType>(6.321205588285580E-001L), // p | |
112 | static_cast<RealType>(1-6.321205588285580E-001L), //q | |
113 | tolerance); | |
114 | test_spot( | |
115 | static_cast<RealType>(2), // lambda | |
116 | static_cast<RealType>(1), // x | |
117 | static_cast<RealType>(8.646647167633870E-001L), // p | |
118 | static_cast<RealType>(1-8.646647167633870E-001L), //q | |
119 | tolerance); | |
120 | test_spot( | |
121 | static_cast<RealType>(1), // lambda | |
122 | static_cast<RealType>(0.5), // x | |
123 | static_cast<RealType>(3.934693402873670E-001L), // p | |
124 | static_cast<RealType>(1-3.934693402873670E-001L), //q | |
125 | tolerance); | |
126 | test_spot( | |
127 | static_cast<RealType>(0.1), // lambda | |
128 | static_cast<RealType>(1), // x | |
129 | static_cast<RealType>(9.516258196404040E-002L), // p | |
130 | static_cast<RealType>(1-9.516258196404040E-002L), //q | |
131 | tolerance); | |
132 | test_spot( | |
133 | static_cast<RealType>(10), // lambda | |
134 | static_cast<RealType>(1), // x | |
135 | static_cast<RealType>(9.999546000702380E-001L), // p | |
136 | static_cast<RealType>(1-9.999546000702380E-001L), //q | |
137 | tolerance*10000); // we loose four digits to cancellation | |
138 | test_spot( | |
139 | static_cast<RealType>(0.1), // lambda | |
140 | static_cast<RealType>(10), // x | |
141 | static_cast<RealType>(6.321205588285580E-001L), // p | |
142 | static_cast<RealType>(1-6.321205588285580E-001L), //q | |
143 | tolerance); | |
144 | test_spot( | |
145 | static_cast<RealType>(1), // lambda | |
146 | static_cast<RealType>(0.01), // x | |
147 | static_cast<RealType>(9.950166250831950E-003L), // p | |
148 | static_cast<RealType>(1-9.950166250831950E-003L), //q | |
149 | tolerance); | |
150 | test_spot( | |
151 | static_cast<RealType>(1), // lambda | |
152 | static_cast<RealType>(0.0001), // x | |
153 | static_cast<RealType>(9.999500016666250E-005L), // p | |
154 | static_cast<RealType>(1-9.999500016666250E-005L), //q | |
155 | tolerance); | |
156 | /* | |
157 | // This test data appears to be erroneous, MathCad appears | |
158 | // to suffer from cancellation error as x -> 0 | |
159 | test_spot( | |
160 | static_cast<RealType>(1), // lambda | |
161 | static_cast<RealType>(0.0000001), // x | |
162 | static_cast<RealType>(9.999999499998730E-008L), // p | |
163 | static_cast<RealType>(1-9.999999499998730E-008L), //q | |
164 | tolerance); | |
165 | */ | |
166 | ||
167 | BOOST_CHECK_CLOSE( | |
168 | ::boost::math::pdf( | |
169 | exponential_distribution<RealType>(0.5), | |
170 | static_cast<RealType>(0.125)), // x | |
171 | static_cast<RealType>(0.46970653140673789305985541231115L), // probability. | |
172 | tolerance); // % | |
173 | BOOST_CHECK_CLOSE( | |
174 | ::boost::math::pdf( | |
175 | exponential_distribution<RealType>(0.5), | |
176 | static_cast<RealType>(5)), // x | |
177 | static_cast<RealType>(0.04104249931194939758476433723358L), // probability. | |
178 | tolerance); // % | |
179 | BOOST_CHECK_CLOSE( | |
180 | ::boost::math::pdf( | |
181 | exponential_distribution<RealType>(2), | |
182 | static_cast<RealType>(0.125)), // x | |
183 | static_cast<RealType>(1.5576015661428097364903405339566L), // probability. | |
184 | tolerance); // % | |
185 | BOOST_CHECK_CLOSE( | |
186 | ::boost::math::pdf( | |
187 | exponential_distribution<RealType>(2), | |
188 | static_cast<RealType>(5)), // x | |
189 | static_cast<RealType>(9.0799859524969703071183031121101e-5L), // probability. | |
190 | tolerance); // % | |
191 | ||
192 | BOOST_CHECK_CLOSE( | |
193 | ::boost::math::mean( | |
194 | exponential_distribution<RealType>(2)), | |
195 | static_cast<RealType>(0.5), | |
196 | tolerance); // % | |
197 | BOOST_CHECK_CLOSE( | |
198 | ::boost::math::standard_deviation( | |
199 | exponential_distribution<RealType>(2)), | |
200 | static_cast<RealType>(0.5), | |
201 | tolerance); // % | |
202 | BOOST_CHECK_CLOSE( | |
203 | ::boost::math::mode( | |
204 | exponential_distribution<RealType>(2)), | |
205 | static_cast<RealType>(0), | |
206 | tolerance); // % | |
207 | ||
208 | BOOST_CHECK_CLOSE( | |
209 | ::boost::math::median( | |
210 | exponential_distribution<RealType>(4)), | |
211 | static_cast<RealType>(0.693147180559945309417232121458176568075500134360255254) / 4, | |
212 | tolerance); // % | |
213 | ||
214 | BOOST_CHECK_CLOSE( | |
215 | ::boost::math::skewness( | |
216 | exponential_distribution<RealType>(2)), | |
217 | static_cast<RealType>(2), | |
218 | tolerance); // % | |
219 | BOOST_CHECK_CLOSE( | |
220 | ::boost::math::kurtosis( | |
221 | exponential_distribution<RealType>(2)), | |
222 | static_cast<RealType>(9), | |
223 | tolerance); // % | |
224 | BOOST_CHECK_CLOSE( | |
225 | ::boost::math::kurtosis_excess( | |
226 | exponential_distribution<RealType>(2)), | |
227 | static_cast<RealType>(6), | |
228 | tolerance); // % | |
229 | ||
230 | using std::log; | |
231 | BOOST_CHECK_CLOSE( | |
232 | ::boost::math::entropy( | |
233 | exponential_distribution<RealType>(2)), | |
234 | static_cast<RealType>(1-log(RealType(2))), | |
235 | tolerance); // % | |
236 | ||
237 | // | |
238 | // Things that are errors: | |
239 | // | |
240 | exponential_distribution<RealType> dist(0.5); | |
241 | BOOST_MATH_CHECK_THROW( | |
242 | quantile(dist, RealType(1.0)), | |
243 | std::overflow_error); | |
244 | BOOST_MATH_CHECK_THROW( | |
245 | quantile(complement(dist, RealType(0.0))), | |
246 | std::overflow_error); | |
247 | BOOST_MATH_CHECK_THROW( | |
248 | pdf(dist, RealType(-1)), | |
249 | std::domain_error); | |
250 | BOOST_MATH_CHECK_THROW( | |
251 | cdf(dist, RealType(-1)), | |
252 | std::domain_error); | |
253 | BOOST_MATH_CHECK_THROW( | |
254 | cdf(exponential_distribution<RealType>(-1), RealType(1)), | |
255 | std::domain_error); | |
256 | BOOST_MATH_CHECK_THROW( | |
257 | quantile(dist, RealType(-1)), | |
258 | std::domain_error); | |
259 | BOOST_MATH_CHECK_THROW( | |
260 | quantile(dist, RealType(2)), | |
261 | std::domain_error); | |
262 | ||
263 | check_out_of_range<exponential_distribution<RealType> >(2); | |
264 | BOOST_MATH_CHECK_THROW(exponential_distribution<RealType>(0), std::domain_error); | |
265 | BOOST_MATH_CHECK_THROW(exponential_distribution<RealType>(-1), std::domain_error); | |
266 | if(std::numeric_limits<RealType>::has_infinity) | |
267 | { | |
268 | RealType inf = std::numeric_limits<RealType>::infinity(); | |
269 | BOOST_CHECK_EQUAL(pdf(exponential_distribution<RealType>(2), inf), 0); | |
270 | BOOST_CHECK_EQUAL(cdf(exponential_distribution<RealType>(2), inf), 1); | |
271 | BOOST_CHECK_EQUAL(cdf(complement(exponential_distribution<RealType>(2), inf)), 0); | |
272 | } | |
273 | } // template <class RealType>void test_spots(RealType) | |
274 | ||
275 | BOOST_AUTO_TEST_CASE( test_main ) | |
276 | { | |
277 | // Check that can generate exponential distribution using the two convenience methods: | |
278 | boost::math::exponential mycexp1(1.); // Using typedef | |
279 | exponential_distribution<> myexp2(1.); // Using default RealType double. | |
280 | ||
281 | // Basic sanity-check spot values. | |
282 | // (Parameter value, arbitrarily zero, only communicates the floating point type). | |
283 | test_spots(0.0F); // Test float. OK at decdigits = 0 tolerance = 0.0001 % | |
284 | test_spots(0.0); // Test double. OK at decdigits 7, tolerance = 1e07 % | |
285 | #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | |
286 | test_spots(0.0L); // Test long double. | |
287 | #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x582)) && !defined(BOOST_MATH_NO_REAL_CONCEPT_TESTS) | |
288 | test_spots(boost::math::concepts::real_concept(0.)); // Test real concept. | |
289 | #endif | |
290 | #else | |
291 | std::cout << "<note>The long double tests have been disabled on this platform " | |
292 | "either because the long double overloads of the usual math functions are " | |
293 | "not available at all, or because they are too inaccurate for these tests " | |
294 | "to pass.</note>" << std::endl; | |
295 | #endif | |
296 | ||
297 | } // BOOST_AUTO_TEST_CASE( test_main ) | |
298 | ||
299 | /* | |
300 | ||
301 | Output is: | |
302 | ||
303 | Running 1 test case... | |
304 | Tolerance for type float is 0.000596046 % | |
305 | Tolerance for type double is 1.11022e-012 % | |
306 | Tolerance for type long double is 1.11022e-012 % | |
307 | Tolerance for type class boost::math::concepts::real_concept is 1.11022e-012 % | |
308 | *** No errors detected | |
309 | ||
310 | */ |