1 //  (C) Copyright John Maddock 2007.
2 //  Use, modification and distribution are subject to the
3 //  Boost Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
7 #include <boost/math/concepts/real_concept.hpp>
8 #define BOOST_TEST_MAIN
9 #include <boost/test/unit_test.hpp>
10 #include <boost/test/floating_point_comparison.hpp>
11 #include <boost/math/special_functions/math_fwd.hpp>
12 #include <boost/type_traits/is_floating_point.hpp>
13 #include <boost/array.hpp>
14 #include "functor.hpp"
15 
16 #include "handle_test_result.hpp"
17 #include "test_bessel_hooks.hpp"
18 #include "table_type.hpp"
19 
20 #ifndef SC_
21 #  define SC_(x) static_cast<typename table_type<T>::type>(BOOST_JOIN(x, L))
22 #endif
23 
24 template <class T>
cyl_bessel_i_int_wrapper(T v,T x)25 T cyl_bessel_i_int_wrapper(T v, T x)
26 {
27    return static_cast<T>(
28       boost::math::cyl_bessel_i(
29       boost::math::itrunc(v), x));
30 }
31 
32 template <class Real, class T>
do_test_cyl_bessel_i(const T & data,const char * type_name,const char * test_name)33 void do_test_cyl_bessel_i(const T& data, const char* type_name, const char* test_name)
34 {
35    typedef Real                   value_type;
36 
37    typedef value_type (*pg)(value_type, value_type);
38 #if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
39    pg funcp = boost::math::cyl_bessel_i<value_type, value_type>;
40 #else
41    pg funcp = boost::math::cyl_bessel_i;
42 #endif
43 
44    boost::math::tools::test_result<value_type> result;
45 
46    std::cout << "Testing " << test_name << " with type " << type_name
47       << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
48 
49    //
50    // test cyl_bessel_i against data:
51    //
52    result = boost::math::tools::test_hetero<Real>(
53       data,
54       bind_func<Real>(funcp, 0, 1),
55       extract_result<Real>(2));
56    handle_test_result(result, data[result.worst()], result.worst(), type_name, "boost::math::cyl_bessel_i", test_name);
57    std::cout << std::endl;
58 
59 #ifdef TEST_OTHER
60    if(boost::is_floating_point<value_type>::value)
61    {
62       funcp = other::cyl_bessel_i;
63 
64       //
65       // test other::cyl_bessel_i against data:
66       //
67       result = boost::math::tools::test(
68          data,
69          boost::lambda::bind(funcp,
70             boost::lambda::ret<value_type>(boost::lambda::_1[0]),
71             boost::lambda::ret<value_type>(boost::lambda::_1[1])),
72          boost::lambda::ret<value_type>(boost::lambda::_1[2]));
73       print_test_result(result, data[result.worst()], result.worst(), type_name, "other::cyl_bessel_i");
74       std::cout << std::endl;
75    }
76 #endif
77 }
78 
79 template <class Real, class T>
do_test_cyl_bessel_i_int(const T & data,const char * type_name,const char * test_name)80 void do_test_cyl_bessel_i_int(const T& data, const char* type_name, const char* test_name)
81 {
82    typedef Real                   value_type;
83 
84    typedef value_type (*pg)(value_type, value_type);
85 #if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
86    pg funcp = cyl_bessel_i_int_wrapper<value_type>;
87 #else
88    pg funcp = cyl_bessel_i_int_wrapper;
89 #endif
90 
91    boost::math::tools::test_result<value_type> result;
92 
93    std::cout << "Testing " << test_name << " with type " << type_name
94       << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
95 
96    //
97    // test cyl_bessel_i against data:
98    //
99    result = boost::math::tools::test_hetero<Real>(
100       data,
101       bind_func<Real>(funcp, 0, 1),
102       extract_result<Real>(2));
103    handle_test_result(result, data[result.worst()], result.worst(), type_name, "boost::math::cyl_bessel_i", test_name);
104    std::cout << std::endl;
105 }
106 
107 template <class T>
test_bessel(T,const char * name)108 void test_bessel(T, const char* name)
109 {
110     // function values calculated on http://functions.wolfram.com/
111     static const boost::array<boost::array<T, 3>, 10> i0_data = {{
112         {{ SC_(0.0), SC_(0.0), SC_(1.0) }},
113         {{ SC_(0.0), SC_(1.0), SC_(1.26606587775200833559824462521471753760767031135496220680814) }},
114         {{ SC_(0.0), SC_(-2.0), SC_(2.27958530233606726743720444081153335328584110278545905407084) }},
115         {{ SC_(0.0), SC_(4.0), SC_(11.3019219521363304963562701832171024974126165944353377060065) }},
116         {{ SC_(0.0), SC_(-7.0), SC_(168.593908510289698857326627187500840376522679234531714193194) }},
117         {{ SC_(0.0), T(1) / 1024, SC_(1.00000023841859331241759166109699567801556273303717896447683) }},
118         {{ SC_(0.0), T(SC_(1.0)) / (1024*1024), SC_(1.00000000000022737367544324498417583090700894607432256476338) }},
119         {{ SC_(0.0), SC_(-1.0), SC_(1.26606587775200833559824462521471753760767031135496220680814) }},
120         {{ SC_(0.0), SC_(100.0), SC_(1.07375170713107382351972085760349466128840319332527279540154e42) }},
121         {{ SC_(0.0), SC_(200.0), SC_(2.03968717340972461954167312677945962233267573614834337894328e85) }},
122     }};
123     static const boost::array<boost::array<T, 3>, 10> i1_data = {{
124         {{ SC_(1.0), SC_(0.0), SC_(0.0) }},
125         {{ SC_(1.0), SC_(1.0), SC_(0.565159103992485027207696027609863307328899621621092009480294) }},
126         {{ SC_(1.0), SC_(-2.0), SC_(-1.59063685463732906338225442499966624795447815949553664713229) }},
127         {{ SC_(1.0), SC_(4.0), SC_(9.75946515370444990947519256731268090005597033325296730692753) }},
128         {{ SC_(1.0), SC_(-8.0), SC_(-399.873136782560098219083086145822754889628443904067647306574) }},
129         {{ SC_(1.0), T(SC_(1.0))/1024, SC_(0.000488281308207663226432087816784315537514225208473395063575150) }},
130         {{ SC_(1.0), T(SC_(1.0))/(1024*1024), SC_(4.76837158203179210108624277276025646653133998635956784292029E-7) }},
131         {{ SC_(1.0), SC_(-10.0), SC_(-2670.98830370125465434103196677215254914574515378753771310849) }},
132         {{ SC_(1.0), SC_(100.0), SC_(1.06836939033816248120614576322429526544612284405623226965918e42) }},
133         {{ SC_(1.0), SC_(200.0), SC_(2.03458154933206270342742797713906950389661161681122964159220e85) }},
134     }};
135     static const boost::array<boost::array<T, 3>, 11> in_data = {{
136         {{ SC_(-2.0), SC_(0.0), SC_(0.0) }},
137         {{ SC_(2.0), T(SC_(1.0))/(1024*1024), SC_(1.13686837721624646204093977095674566928522671779753217215467e-13) }},
138         {{ SC_(5.0), SC_(10.0), SC_(777.188286403259959907293484802339632852674154572666041953297) }},
139         {{ SC_(-5.0), SC_(100.0), SC_(9.47009387303558124618275555002161742321578485033007130107740e41) }},
140         {{ SC_(-5.0), SC_(-1.0), SC_(-0.000271463155956971875181073905153777342383564426758143634974124) }},
141         {{ SC_(10.0), SC_(20.0), SC_(3.54020020901952109905289138244985607057267103782948493874391e6) }},
142         {{ SC_(10.0), SC_(-5.0), SC_(0.00458004441917605126118647027872016953192323139337073320016447) }},
143         {{ SC_(1e+02), SC_(9.0), SC_(2.74306601746058997093587654668959071522869282506446891736820e-93) }},
144         {{ SC_(1e+02), SC_(80.0), SC_(4.65194832850610205318128191404145885093970505338730540776711e8) }},
145         {{ SC_(-100.0), SC_(-200.0), SC_(4.35275044972702191438729017441198257508190719030765213981307e74) }},
146         {{ SC_(10.0), SC_(1e-100), SC_(2.69114445546737213403880070546737213403880070546737213403880e-1010) }},
147     }};
148     static const boost::array<boost::array<T, 3>, 10> iv_data = {{
149         {{ SC_(2.25), T(1)/(1024*1024), SC_(2.34379212133481347189068464680335815256364262507955635911656e-15) }},
150         {{ SC_(5.5), SC_(3.125), SC_(0.0583514045989371500460946536220735787163510569634133670181210) }},
151         {{ T(-5) + T(1)/1024, SC_(2.125), SC_(0.0267920938009571023702933210070984416052633027166975342895062) }},
152         {{ SC_(-5.5), SC_(10.0), SC_(597.577606961369169607937419869926705730305175364662688426534) }},
153         {{ SC_(-5.5), SC_(100.0), SC_(9.22362906144706871737354069133813819358704200689067071415379e41) }},
154         {{ T(-10486074)/(1024*1024), T(1)/1024, SC_(1.41474005665181350367684623930576333542989766867888186478185e35) }},
155         {{ T(-10486074)/(1024*1024), SC_(50.0), SC_(1.07153277202900671531087024688681954238311679648319534644743e20) }},
156         {{ T(144794)/1024, SC_(100.0), SC_(2066.27694757392660413922181531984160871678224178890247540320) }},
157         {{ T(144794)/1024, SC_(200.0), SC_(2.23699739472246928794922868978337381373643889659337595319774e64) }},
158         {{ T(-144794)/1024, SC_(100.0), SC_(2066.27694672763190927440969155740243346136463461655104698748) }},
159     }};
160     static const boost::array<boost::array<T, 3>, 5> iv_large_data = {{
161         // Bug report https://svn.boost.org/trac/boost/ticket/5560:
162         {{ SC_(-1.0), static_cast<T>(ldexp(0.5, -512)), SC_(1.86458518280005168582274132886573345934411788365010172356788e-155) }},
163         {{ SC_(1.0),  static_cast<T>(ldexp(0.5, -512)), SC_(1.86458518280005168582274132886573345934411788365010172356788e-155) }},
164         {{ SC_(-1.125), static_cast<T>(ldexp(0.5, -512)), SC_(-1.34963720853101363690381585556234820027343435206156667634081e173) }},
165         {{ SC_(1.125),  static_cast<T>(ldexp(0.5, -512)), SC_(8.02269390325932403421158766283366891170783955777638875887348e-175) }},
166         {{ SC_(0.5), static_cast<T>(ldexp(0.5, -683)), SC_(8.90597649117647254543282704099383321071493400182381039079219e-104) }},
167     }};
168 
169     do_test_cyl_bessel_i<T>(i0_data, name, "Bessel I0: Mathworld Data");
170     do_test_cyl_bessel_i<T>(i1_data, name, "Bessel I1: Mathworld Data");
171     do_test_cyl_bessel_i<T>(in_data, name, "Bessel In: Mathworld Data");
172 
173     do_test_cyl_bessel_i_int<T>(i0_data, name, "Bessel I0: Mathworld Data (Integer Version)");
174     do_test_cyl_bessel_i_int<T>(i1_data, name, "Bessel I1: Mathworld Data (Integer Version)");
175     do_test_cyl_bessel_i_int<T>(in_data, name, "Bessel In: Mathworld Data (Integer Version)");
176 
177     do_test_cyl_bessel_i<T>(iv_data, name, "Bessel Iv: Mathworld Data");
178 
179 #include "bessel_i_int_data.ipp"
180     do_test_cyl_bessel_i<T>(bessel_i_int_data, name, "Bessel In: Random Data");
181 #include "bessel_i_data.ipp"
182     do_test_cyl_bessel_i<T>(bessel_i_data, name, "Bessel Iv: Random Data");
183 
184     if(0 != static_cast<T>(ldexp(0.5, -700)))
185       do_test_cyl_bessel_i<T>(iv_large_data, name, "Bessel Iv: Mathworld Data (large values)");
186 }
187 
188