Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / math / test / test_logistic_dist.cpp
1 // Copyright 2008 Gautam Sewani
2 // Copyright 2013 Paul A. Bristow
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 #ifdef _MSC_VER
10 #  pragma warning (disable : 4127) // conditional expression is constant.
11 #  pragma warning (disable : 4512) // assignment operator could not be generated.
12 #endif
13
14 #include <boost/config.hpp>
15 #ifndef BOOST_NO_EXCEPTIONS
16 #define BOOST_MATH_UNDERFLOW_ERROR_POLICY throw_on_error
17 #define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error
18 #endif
19 #include <boost/math/tools/test.hpp>
20 #include <boost/math/concepts/real_concept.hpp> // for real_concept
21 #include <boost/math/distributions/logistic.hpp>
22     using boost::math::logistic_distribution;
23
24 #define BOOST_TEST_MAIN
25 #include <boost/test/unit_test.hpp> // Boost.Test
26 #include <boost/test/tools/floating_point_comparison.hpp>
27 #include "test_out_of_range.hpp"
28
29 #include <iostream>
30    using std::cout;
31    using std::endl;
32    using std::setprecision;
33
34 template <class RealType>
35 void test_spot(RealType location, RealType scale, RealType x, RealType p, RealType q, RealType tolerance)
36 {
37    BOOST_CHECK_CLOSE(
38       ::boost::math::cdf(
39       logistic_distribution<RealType>(location,scale),      
40       x),
41       p,
42       tolerance); // %
43    BOOST_CHECK_CLOSE(
44       ::boost::math::cdf(
45       complement(logistic_distribution<RealType>(location,scale),      
46       x)),
47       q,
48       tolerance); // %
49    if(p < 0.999)
50    {
51       BOOST_CHECK_CLOSE(
52          ::boost::math::quantile(
53          logistic_distribution<RealType>(location,scale),      
54          p),
55          x,
56          tolerance); // %
57    }
58    if(q < 0.999)
59    {
60       BOOST_CHECK_CLOSE(
61          ::boost::math::quantile(
62          complement(logistic_distribution<RealType>(location,scale),      
63          q)),
64          x,
65          2 * tolerance); // %
66    }
67 }
68
69
70 template <class RealType>
71 void test_spots(RealType T)
72 {
73    // Basic sanity checks.
74    // 50 eps as a percentage, up to a maximum of double precision
75    // Test data taken from Mathematica 6
76    RealType tolerance = (std::max)(
77       static_cast<RealType>(1e-33L),
78       boost::math::tools::epsilon<RealType>());
79    cout<<"Absolute tolerance:"<<tolerance<<endl;
80
81    tolerance *= 50 * 100; 
82    // #  pragma warning(disable: 4100) // unreferenced formal parameter.
83    // prevent his spurious warning.
84    if (T != 0)
85    {
86       cout << "Expect parameter T == 0!" << endl;
87    }
88    cout << "Tolerance for type " << typeid(T).name()  << " is " << tolerance << " %" << endl;
89
90    test_spot(
91       static_cast<RealType>(1), // location
92       static_cast<RealType>(0.5L), // scale
93       static_cast<RealType>(0.1L), // x
94       static_cast<RealType>(0.141851064900487789594278108470953L), // p
95       static_cast<RealType>(0.858148935099512210405721891529047L), //q
96       tolerance);
97
98    test_spot(
99       static_cast<RealType>(5), // location
100       static_cast<RealType>(2), // scale
101       static_cast<RealType>(3.123123123L),//x 
102       static_cast<RealType>(0.281215878622547904873088053477813L), // p
103       static_cast<RealType>(0.718784121377452095126911946522187L), //q
104       tolerance);
105
106    test_spot(
107       static_cast<RealType>(1.2345L), // location
108       static_cast<RealType>(0.12345L), // scale
109       static_cast<RealType>(3.123123123L),//x
110       static_cast<RealType>(0.999999773084685079723328282229357L), // p
111       static_cast<RealType>(2.26915314920276671717770643005212e-7L), //q
112       tolerance);
113
114
115    //High probability
116    test_spot(
117       static_cast<RealType>(1), // location
118       static_cast<RealType>(0.5L), // scale
119       static_cast<RealType>(10), // x
120       static_cast<RealType>(0.99999998477002048723965105559179L), // p  
121       static_cast<RealType>(1.5229979512760348944408208801237e-8L), //q
122       tolerance);
123
124    //negative x
125    test_spot(
126       static_cast<RealType>(5), // location
127       static_cast<RealType>(2), // scale
128       static_cast<RealType>(-0.1L), // scale
129       static_cast<RealType>(0.0724264853615177178439235061476928L), // p
130       static_cast<RealType>(0.927573514638482282156076493852307L), //q
131       tolerance);
132
133
134    test_spot(
135       static_cast<RealType>(5), // location
136       static_cast<RealType>(2), // scale
137       static_cast<RealType>(-20), // x
138       static_cast<RealType>(3.72663928418656138608800947863869e-6L), // p
139       static_cast<RealType>(0.999996273360715813438613911990521L), //q
140       tolerance);
141
142
143    // Test value to check cancellation error in straight/complemented quantile.
144    // The subtraction in the formula location-scale*log term introduces catastrophic
145    // cancellation error if location and scale*log term are close.
146    // For these values, the tests fail at tolerance, but work at 100*tolerance.
147    test_spot(
148       static_cast<RealType>(-1.2345L), // location
149       static_cast<RealType>(1.4555L), // scale
150       static_cast<RealType>(-0.00125796420642514024493852425918807L),// x
151       static_cast<RealType>(0.7L), // p
152       static_cast<RealType>(0.3L), //q
153       80*tolerance);   
154
155    test_spot(
156       static_cast<RealType>(1.2345L), // location
157       static_cast<RealType>(0.12345L), // scale
158       static_cast<RealType>(0.0012345L), // x
159       static_cast<RealType>(0.0000458541039469413343331170952855318L), // p
160       static_cast<RealType>(0.999954145896053058665666882904714L), //q
161       80*tolerance);
162
163
164
165    test_spot(
166       static_cast<RealType>(5L), // location
167       static_cast<RealType>(2L), // scale
168       static_cast<RealType>(0.0012345L), // x
169       static_cast<RealType>(0.0759014628704232983512906076564256L), // p
170       static_cast<RealType>(0.924098537129576701648709392343574L), //q
171       80*tolerance);
172
173    //negative location
174    test_spot(
175       static_cast<RealType>(-123.123123L), // location
176       static_cast<RealType>(2.123L), // scale
177       static_cast<RealType>(3), // x
178       static_cast<RealType>(0.999999999999999999999999984171276L), // p
179       static_cast<RealType>(1.58287236765203121622150720373972e-26L), //q
180       tolerance);
181    //PDF Testing
182    BOOST_CHECK_CLOSE(
183       ::boost::math::pdf(
184       logistic_distribution<RealType>(5,2),      
185          static_cast<RealType>(0.125L) ),//x
186          static_cast<RealType>(0.0369500730133475464584898192104821L),              // probability
187       tolerance); // %
188
189    BOOST_CHECK_CLOSE(
190       ::boost::math::pdf(
191          logistic_distribution<RealType>(static_cast<RealType>(1.2345L), static_cast<RealType>(0.12345L)),      
192          static_cast<RealType>(0.0012345L) ),//x
193          static_cast<RealType>(0.000371421639109700748742498671686243L),              // probability
194       tolerance); // %
195    BOOST_CHECK_CLOSE(
196       ::boost::math::pdf(
197       logistic_distribution<RealType>(2,1),      
198          static_cast<RealType>(2L) ),//x
199          static_cast<RealType>(0.25L),              // probability
200       tolerance); // %
201
202    //Extreme value testing
203
204    if(std::numeric_limits<RealType>::has_infinity)
205    {
206       BOOST_CHECK_EQUAL(pdf(logistic_distribution<RealType>(), +std::numeric_limits<RealType>::infinity()), 0); // x = + infinity, pdf = 0
207       BOOST_CHECK_EQUAL(pdf(logistic_distribution<RealType>(), -std::numeric_limits<RealType>::infinity()), 0); // x = - infinity, pdf = 0
208       BOOST_CHECK_EQUAL(cdf(logistic_distribution<RealType>(), +std::numeric_limits<RealType>::infinity()), 1); // x = + infinity, cdf = 1
209       BOOST_CHECK_EQUAL(cdf(logistic_distribution<RealType>(), -std::numeric_limits<RealType>::infinity()), 0); // x = - infinity, cdf = 0
210       BOOST_CHECK_EQUAL(cdf(complement(logistic_distribution<RealType>(), +std::numeric_limits<RealType>::infinity())), 0); // x = + infinity, c cdf = 0
211       BOOST_CHECK_EQUAL(cdf(complement(logistic_distribution<RealType>(), -std::numeric_limits<RealType>::infinity())), 1); // x = - infinity, c cdf = 1
212    }
213    BOOST_MATH_CHECK_THROW(quantile(logistic_distribution<RealType>(), static_cast<RealType>(1)), std::overflow_error); // x = + infinity, cdf = 1
214    BOOST_MATH_CHECK_THROW(quantile(logistic_distribution<RealType>(), static_cast<RealType>(0)), std::overflow_error); // x = - infinity, cdf = 0
215    BOOST_MATH_CHECK_THROW(quantile(complement(logistic_distribution<RealType>(), static_cast<RealType>(1))), std::overflow_error); // x = - infinity, cdf = 0
216    BOOST_MATH_CHECK_THROW(quantile(complement(logistic_distribution<RealType>(), static_cast<RealType>(0))), std::overflow_error); // x = + infinity, cdf = 1
217    BOOST_CHECK_EQUAL(cdf(logistic_distribution<RealType>(), +boost::math::tools::max_value<RealType>()), 1); // x = + infinity, cdf = 1
218    BOOST_CHECK_EQUAL(cdf(logistic_distribution<RealType>(), -boost::math::tools::max_value<RealType>()), 0); // x = - infinity, cdf = 0
219    BOOST_CHECK_EQUAL(cdf(complement(logistic_distribution<RealType>(), +boost::math::tools::max_value<RealType>())), 0); // x = + infinity, c cdf = 0
220    BOOST_CHECK_EQUAL(cdf(complement(logistic_distribution<RealType>(), -boost::math::tools::max_value<RealType>())), 1); // x = - infinity, c cdf = 1
221    BOOST_CHECK_EQUAL(pdf(logistic_distribution<RealType>(), +boost::math::tools::max_value<RealType>()), 0); // x = + infinity, pdf = 0
222    BOOST_CHECK_EQUAL(pdf(logistic_distribution<RealType>(), -boost::math::tools::max_value<RealType>()), 0); // x = - infinity, pdf = 0
223
224    //
225    // Things that are errors:
226    // 1. Domain errors for scale and location.
227    // 2. x being NAN.
228    // 3. Probabilies being outside (0,1).
229    check_out_of_range<logistic_distribution<RealType> >(0, 1);
230    if(std::numeric_limits<RealType>::has_infinity)
231    {
232       RealType inf = std::numeric_limits<RealType>::infinity();
233       BOOST_CHECK_EQUAL(pdf(logistic_distribution<RealType>(0, 1), inf), 0);
234       BOOST_CHECK_EQUAL(pdf(logistic_distribution<RealType>(0, 1), -inf), 0);
235       BOOST_CHECK_EQUAL(cdf(logistic_distribution<RealType>(0, 1), inf), 1);
236       BOOST_CHECK_EQUAL(cdf(logistic_distribution<RealType>(0, 1), -inf), 0);
237       BOOST_CHECK_EQUAL(cdf(complement(logistic_distribution<RealType>(0, 1), inf)), 0);
238       BOOST_CHECK_EQUAL(cdf(complement(logistic_distribution<RealType>(0, 1), -inf)), 1);
239    }
240
241    // location/scale can't be infinity.
242    if(std::numeric_limits<RealType>::has_infinity)
243    {
244 #ifndef BOOST_NO_EXCEPTIONS
245       BOOST_MATH_CHECK_THROW(
246          logistic_distribution<RealType> dist(std::numeric_limits<RealType>::infinity(), 0.5),
247          std::domain_error);
248       BOOST_MATH_CHECK_THROW(
249          logistic_distribution<RealType> dist(0.5, std::numeric_limits<RealType>::infinity()),
250          std::domain_error);
251 #else
252       BOOST_MATH_CHECK_THROW(
253          logistic_distribution<RealType>(std::numeric_limits<RealType>::infinity(), 0.5),
254          std::domain_error);
255       BOOST_MATH_CHECK_THROW(
256          logistic_distribution<RealType>(0.5, std::numeric_limits<RealType>::infinity()),
257          std::domain_error);
258 #endif
259    }
260    // scale can't be negative or 0.
261 #ifndef BOOST_NO_EXCEPTIONS
262    BOOST_MATH_CHECK_THROW(
263       logistic_distribution<RealType> dist(0.5, -0.5),
264       std::domain_error);
265    BOOST_MATH_CHECK_THROW(
266       logistic_distribution<RealType> dist(0.5, 0),
267       std::domain_error);
268 #else
269    BOOST_MATH_CHECK_THROW(
270       logistic_distribution<RealType>(0.5, -0.5),
271       std::domain_error);
272    BOOST_MATH_CHECK_THROW(
273       logistic_distribution<RealType>(0.5, 0),
274       std::domain_error);
275 #endif
276
277    logistic_distribution<RealType> dist(0.5, 0.5);
278    // x can't be NaN, p can't be NaN.
279
280    if (std::numeric_limits<RealType>::has_quiet_NaN)
281    {
282       // No longer allow x to be NaN, then these tests should throw.
283       BOOST_MATH_CHECK_THROW(pdf(dist, +std::numeric_limits<RealType>::quiet_NaN()), std::domain_error); // x = NaN
284       BOOST_MATH_CHECK_THROW(cdf(dist, +std::numeric_limits<RealType>::quiet_NaN()), std::domain_error); // x = NaN
285       BOOST_MATH_CHECK_THROW(cdf(complement(dist, +std::numeric_limits<RealType>::quiet_NaN())), std::domain_error); // x = + infinity
286       BOOST_MATH_CHECK_THROW(quantile(dist, +std::numeric_limits<RealType>::quiet_NaN()), std::domain_error); // p = + infinity
287       BOOST_MATH_CHECK_THROW(quantile(complement(dist, +std::numeric_limits<RealType>::quiet_NaN())), std::domain_error); // p = + infinity
288    }
289    if (std::numeric_limits<RealType>::has_infinity)
290    {
291   // Added test for Trac https://svn.boost.org/trac/boost/ticket/9126#comment:1
292      logistic_distribution<RealType> dist(0., 0.5);
293      BOOST_CHECK_EQUAL(pdf(dist, +std::numeric_limits<RealType>::infinity()), static_cast<RealType>(0) ); // x = infinity
294
295    }
296
297
298    // p can't be outside (0,1).
299    BOOST_MATH_CHECK_THROW(quantile(dist, static_cast<RealType>(1.1)), std::domain_error); 
300    BOOST_MATH_CHECK_THROW(quantile(dist, static_cast<RealType>(-0.1)), std::domain_error);
301    BOOST_MATH_CHECK_THROW(quantile(dist, static_cast<RealType>(1)), std::overflow_error); 
302    BOOST_MATH_CHECK_THROW(quantile(dist, static_cast<RealType>(0)), std::overflow_error);
303
304    BOOST_MATH_CHECK_THROW(quantile(complement(dist, static_cast<RealType>(1.1))), std::domain_error); 
305    BOOST_MATH_CHECK_THROW(quantile(complement(dist, static_cast<RealType>(-0.1))), std::domain_error);
306    BOOST_MATH_CHECK_THROW(quantile(complement(dist, static_cast<RealType>(1))), std::overflow_error); 
307    BOOST_MATH_CHECK_THROW(quantile(complement(dist, static_cast<RealType>(0))), std::overflow_error); 
308
309    // Tests for mean,mode,median,variance,skewness,kurtosis.
310    //mean
311    BOOST_CHECK_CLOSE(
312       ::boost::math::mean(
313       logistic_distribution<RealType>(2,1)      
314       ),//x
315       static_cast<RealType>(2),              // probability
316       tolerance); // %
317    //median
318    BOOST_CHECK_CLOSE(
319       ::boost::math::median(
320       logistic_distribution<RealType>(2,1)      
321       ),//x
322       static_cast<RealType>(2),              // probability
323       tolerance);
324    //mode
325    BOOST_CHECK_CLOSE(
326       ::boost::math::mode(
327       logistic_distribution<RealType>(2,1)      
328       ),//x
329       static_cast<RealType>(2),              // probability
330       tolerance);
331    //variance
332    BOOST_CHECK_CLOSE(
333       ::boost::math::variance(
334       logistic_distribution<RealType>(2,1)      
335       ),//x
336       static_cast<RealType>(3.28986813369645287294483033329205L),  // probability
337       tolerance);
338    //skewness
339    BOOST_CHECK_CLOSE(
340       ::boost::math::skewness(
341       logistic_distribution<RealType>(2,1)      
342       ),//x
343       static_cast<RealType>(0),              // probability
344       tolerance);
345    BOOST_CHECK_CLOSE(
346       ::boost::math::kurtosis_excess(
347       logistic_distribution<RealType>(2,1)      
348       ),//x
349       static_cast<RealType>(1.2L),              // probability
350       tolerance);
351
352 } // template <class RealType>void test_spots(RealType)
353
354
355 BOOST_AUTO_TEST_CASE( test_main )
356 {
357   // Check that can generate logistic distribution using the two convenience methods:
358    boost::math::logistic mycexp1(1.); // Using typedef
359    logistic_distribution<> myexp2(1.); // Using default RealType double.
360
361    // Basic sanity-check spot values.
362    // (Parameter value, arbitrarily zero, only communicates the floating point type).
363   test_spots(0.0F); // Test float. OK at decdigits = 0 tolerance = 0.0001 %
364   test_spots(0.0); // Test double. OK at decdigits 7, tolerance = 1e07 %
365 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
366   test_spots(0.0L); // Test long double.
367 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
368   test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
369 #endif
370 #else
371    std::cout << "<note>The long double tests have been disabled on this platform "
372       "either because the long double overloads of the usual math functions are "
373       "not available at all, or because they are too inaccurate for these tests "
374       "to pass.</note>" << std::endl;
375 #endif
376    
377 } // BOOST_AUTO_TEST_CASE( test_main )
378