• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Boost pow_test.cpp test file
2 //  Tests the pow function
3 
4 //  (C) Copyright Bruno Lalande 2008.
5 //  Distributed under the Boost Software License, Version 1.0.
6 //  (See accompanying file LICENSE_1_0.txt or copy at
7 //  http://www.boost.org/LICENSE_1_0.txt)
8 
9 #include <cmath>
10 #include <string>
11 #include <iostream>
12 
13 #include <boost/math/concepts/real_concept.hpp>
14 #include <boost/math/tools/test.hpp>
15 #define BOOST_TEST_MAIN
16 #include <boost/test/unit_test.hpp>
17 #include <boost/test/tools/floating_point_comparison.hpp>
18 
19 #include <boost/typeof/typeof.hpp>
20 #include <boost/type_traits/is_same.hpp>
21 #include <boost/static_assert.hpp>
22 
23 #include <boost/math/special_functions/pow.hpp>
24 
25 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
26 BOOST_TYPEOF_REGISTER_TYPE(boost::math::concepts::real_concept)
27 
28 using namespace boost;
29 using namespace boost::math;
30 
31 template <int N, class T>
test_pow(T base)32 void test_pow(T base)
33 {
34     typedef typename tools::promote_args<T>::type result_type;
35 
36     BOOST_MATH_STD_USING
37 
38     if ((base == 0) && N < 0)
39     {
40        BOOST_MATH_CHECK_THROW(math::pow<N>(base), std::overflow_error);
41     }
42     else
43     {
44        BOOST_CHECK_CLOSE(math::pow<N>(base),
45               pow(static_cast<result_type>(base), static_cast<result_type>(N)),
46               boost::math::tools::epsilon<result_type>() * 100 * 400); // 400 eps as a %
47     }
48 }
49 
50 template <int N, class T>
test_with_big_bases()51 void test_with_big_bases()
52 {
53     for (T base = T(); base < T(1000); ++base)
54         test_pow<N>(base);
55 }
56 
57 template <int N, class T>
test_with_small_bases()58 void test_with_small_bases()
59 {
60     T base = 0.9f;
61     for (int i = 0; i < 10; ++i)
62     {
63         base += base/50;
64         test_pow<N>(base);
65     }
66 }
67 
68 template <class T, int Factor>
test_with_small_exponents()69 void test_with_small_exponents()
70 {
71     test_with_big_bases<0, T>();
72     test_with_big_bases<Factor*1, T>();
73     test_with_big_bases<Factor*2, T>();
74     test_with_big_bases<Factor*3, T>();
75     test_with_big_bases<Factor*5, T>();
76     test_with_big_bases<Factor*6, T>();
77     test_with_big_bases<Factor*7, T>();
78     test_with_big_bases<Factor*8, T>();
79     test_with_big_bases<Factor*9, T>();
80     test_with_big_bases<Factor*10, T>();
81     test_with_big_bases<Factor*11, T>();
82     test_with_big_bases<Factor*12, T>();
83 }
84 
85 template <class T, int Factor>
test_with_big_exponents()86 void test_with_big_exponents()
87 {
88     test_with_small_bases<Factor*50, T>();
89     test_with_small_bases<Factor*100, T>();
90     test_with_small_bases<Factor*150, T>();
91     test_with_small_bases<Factor*200, T>();
92     test_with_small_bases<Factor*250, T>();
93     test_with_small_bases<Factor*300, T>();
94     test_with_small_bases<Factor*350, T>();
95     test_with_small_bases<Factor*400, T>();
96     test_with_small_bases<Factor*450, T>();
97     test_with_small_bases<Factor*500, T>();
98 }
99 
100 
test_return_types()101 void test_return_types()
102 {
103     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>('\1')), double>::value));
104     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(L'\2')), double>::value));
105     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(3)), double>::value));
106     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(4u)), double>::value));
107     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(5ul)), double>::value));
108     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(6.0f)), float>::value));
109     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(7.0)), double>::value));
110 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
111     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(7.0l)), long double>::value));
112 #endif
113 }
114 
115 
116 namespace boost { namespace math { namespace policies {
117 template <class T>
user_overflow_error(const char *,const char *,const T &)118 T user_overflow_error(const char*, const char*, const T&)
119 { return T(123.45); }
120 }}}
121 
122 namespace boost { namespace math { namespace policies {
123 template <class T>
user_indeterminate_result_error(const char *,const char *,const T &)124 T user_indeterminate_result_error(const char*, const char*, const T&)
125 { return T(456.78); }
126 }}}
127 
128 
test_error_policy()129 void test_error_policy()
130 {
131     using namespace policies;
132 
133     BOOST_CHECK(pow<-2>(
134                     0.0,
135                     policy< ::boost::math::policies::overflow_error<user_error> >()
136                 )
137                 == 123.45);
138 
139     BOOST_CHECK(pow<0>(
140                     0.0,
141                     policy< ::boost::math::policies::indeterminate_result_error<user_error> >()
142                 )
143                 == 456.78);
144 }
145 
BOOST_AUTO_TEST_CASE(test_main)146 BOOST_AUTO_TEST_CASE( test_main )
147 {
148     using namespace std;
149 
150     cout << "Testing with integral bases and positive small exponents" << endl;
151     test_with_small_exponents<int, 1>();
152     cout << "Testing with integral bases and negative small exponents" << endl;
153     test_with_small_exponents<int, -1>();
154 
155     cout << "Testing with float precision bases and positive small exponents" << endl;
156     test_with_small_exponents<float, 1>();
157     cout << "Testing with float precision bases and negative small exponents" << endl;
158     test_with_small_exponents<float, -1>();
159 
160     cout << "Testing with float precision bases and positive big exponents" << endl;
161     test_with_big_exponents<float, 1>();
162     cout << "Testing with float precision bases and negative big exponents" << endl;
163     test_with_big_exponents<float, -1>();
164 
165      cout << "Testing with double precision bases and positive small exponents" << endl;
166     test_with_small_exponents<double, 1>();
167     cout << "Testing with double precision bases and negative small exponents" << endl;
168     test_with_small_exponents<double, -1>();
169 
170     cout << "Testing with double precision bases and positive big exponents" << endl;
171     test_with_big_exponents<double, 1>();
172     cout << "Testing with double precision bases and negative big exponents" << endl;
173     test_with_big_exponents<double, -1>();
174 
175 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
176     cout << "Testing with long double precision bases and positive small exponents" << endl;
177     test_with_small_exponents<long double, 1>();
178     cout << "Testing with long double precision bases and negative small exponents" << endl;
179     test_with_small_exponents<long double, -1>();
180 
181     cout << "Testing with long double precision bases and positive big exponents" << endl;
182     test_with_big_exponents<long double, 1>();
183     cout << "Testing with long double precision bases and negative big exponents" << endl;
184     test_with_big_exponents<long double, -1>();
185 
186     cout << "Testing with concepts::real_concept precision bases and positive small exponents" << endl;
187     test_with_small_exponents<boost::math::concepts::real_concept, 1>();
188     cout << "Testing with concepts::real_concept precision bases and negative small exponents" << endl;
189     test_with_small_exponents<boost::math::concepts::real_concept, -1>();
190 
191     cout << "Testing with concepts::real_concept precision bases and positive big exponents" << endl;
192     test_with_big_exponents<boost::math::concepts::real_concept, 1>();
193     cout << "Testing with concepts::real_concept precision bases and negative big exponents" << endl;
194     test_with_big_exponents<boost::math::concepts::real_concept, -1>();
195 #endif
196 
197     test_return_types();
198 
199     test_error_policy();
200 }
201 
202 /*
203 
204   Running 1 test case...
205   Testing with integral bases and positive small exponents
206   Testing with integral bases and negative small exponents
207   Testing with float precision bases and positive small exponents
208   Testing with float precision bases and negative small exponents
209   Testing with float precision bases and positive big exponents
210   Testing with float precision bases and negative big exponents
211   Testing with double precision bases and positive small exponents
212   Testing with double precision bases and negative small exponents
213   Testing with double precision bases and positive big exponents
214   Testing with double precision bases and negative big exponents
215   Testing with long double precision bases and positive small exponents
216   Testing with long double precision bases and negative small exponents
217   Testing with long double precision bases and positive big exponents
218   Testing with long double precision bases and negative big exponents
219   Testing with concepts::real_concept precision bases and positive small exponents
220   Testing with concepts::real_concept precision bases and negative small exponents
221   Testing with concepts::real_concept precision bases and positive big exponents
222   Testing with concepts::real_concept precision bases and negative big exponents
223 
224   *** No errors detected
225 
226   */
227