]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/math/test/naive_monte_carlo_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / math / test / naive_monte_carlo_test.cpp
CommitLineData
11fdf7f2
TL
1/*
2 * Copyright Nick Thompson, 2017
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#define BOOST_TEST_MODULE naive_monte_carlo_test
92f5a8d4 8#define BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES
11fdf7f2
TL
9#include <cmath>
10#include <ostream>
11#include <boost/lexical_cast.hpp>
12#include <boost/type_index.hpp>
13#include <boost/test/included/unit_test.hpp>
14
92f5a8d4 15#include <boost/test/tools/floating_point_comparison.hpp>
11fdf7f2
TL
16#include <boost/math/constants/constants.hpp>
17#include <boost/math/quadrature/naive_monte_carlo.hpp>
18
19using std::abs;
20using std::vector;
21using std::pair;
22using boost::math::constants::pi;
23using boost::math::quadrature::naive_monte_carlo;
24
25
26template<class Real>
27void test_pi_multithreaded()
28{
29 std::cout << "Testing pi is calculated correctly (multithreaded) using Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
30 auto g = [](std::vector<Real> const & x)->Real {
31 Real r = x[0]*x[0]+x[1]*x[1];
32 if (r <= 1) {
33 return 4;
34 }
35 return 0;
36 };
37
38 std::vector<std::pair<Real, Real>> bounds{{Real(0), Real(1)}, {Real(0), Real(1)}};
92f5a8d4
TL
39 Real error_goal = 0.0002;
40 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, error_goal,
41 /*singular =*/ false,/* threads = */ 2, /* seed = */ 18012);
11fdf7f2
TL
42 auto task = mc.integrate();
43 Real pi_estimated = task.get();
44 if (abs(pi_estimated - pi<Real>())/pi<Real>() > 0.005) {
45 std::cout << "Error in estimation of pi too high, function calls: " << mc.calls() << "\n";
92f5a8d4
TL
46 std::cout << "Final error estimate : " << mc.current_error_estimate() << "\n";
47 std::cout << "Error goal : " << error_goal << "\n";
11fdf7f2
TL
48 BOOST_CHECK_CLOSE_FRACTION(pi_estimated, pi<Real>(), 0.005);
49 }
50}
51
52template<class Real>
53void test_pi()
54{
55 std::cout << "Testing pi is calculated correctly using Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
56 auto g = [](std::vector<Real> const & x)->Real
57 {
58 Real r = x[0]*x[0]+x[1]*x[1];
59 if (r <= 1)
60 {
61 return 4;
62 }
63 return 0;
64 };
65
66 std::vector<std::pair<Real, Real>> bounds{{Real(0), Real(1)}, {Real(0), Real(1)}};
92f5a8d4
TL
67 Real error_goal = (Real) 0.0002;
68 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, error_goal,
69 /*singular =*/ false,/* threads = */ 1, /* seed = */ 128402);
11fdf7f2
TL
70 auto task = mc.integrate();
71 Real pi_estimated = task.get();
72 if (abs(pi_estimated - pi<Real>())/pi<Real>() > 0.005)
73 {
74 std::cout << "Error in estimation of pi too high, function calls: " << mc.calls() << "\n";
92f5a8d4
TL
75 std::cout << "Final error estimate : " << mc.current_error_estimate() << "\n";
76 std::cout << "Error goal : " << error_goal << "\n";
11fdf7f2
TL
77 BOOST_CHECK_CLOSE_FRACTION(pi_estimated, pi<Real>(), 0.005);
78 }
79
80}
81
82template<class Real>
83void test_constant()
84{
85 std::cout << "Testing constants are integrated correctly using Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
86 auto g = [](std::vector<Real> const &)->Real
87 {
88 return 1;
89 };
90
91 std::vector<std::pair<Real, Real>> bounds{{Real(0), Real(1)}, { Real(0), Real(1)}};
92 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.0001,
93 /* singular = */ false, /* threads = */ 1, /* seed = */ 87);
94
95 auto task = mc.integrate();
96 Real one = task.get();
97 BOOST_CHECK_CLOSE_FRACTION(one, 1, 0.001);
98 BOOST_CHECK_SMALL(mc.current_error_estimate(), std::numeric_limits<Real>::epsilon());
99 BOOST_CHECK(mc.calls() > 1000);
100}
101
102
103template<class Real>
104void test_exception_from_integrand()
105{
106 std::cout << "Testing that a reasonable action is performed by the Monte-Carlo integrator when the integrand throws an exception on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
107 auto g = [](std::vector<Real> const & x)->Real
108 {
109 if (x[0] > 0.5 && x[0] < 0.5001)
110 {
111 throw std::domain_error("You have done something wrong.\n");
112 }
113 return (Real) 1;
114 };
115
116 std::vector<std::pair<Real, Real>> bounds{{ Real(0), Real(1)}, { Real(0), Real(1)}};
117 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.0001);
118
119 auto task = mc.integrate();
120 bool caught_exception = false;
121 try
122 {
123 Real result = task.get();
124 // Get rid of unused variable warning:
125 std::ostream cnull(0);
126 cnull << result;
127 }
128 catch(std::exception const &)
129 {
130 caught_exception = true;
131 }
132 BOOST_CHECK(caught_exception);
133}
134
135
136template<class Real>
137void test_cancel_and_restart()
138{
139 std::cout << "Testing that cancellation and restarting works on naive Monte-Carlo integration on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
140 Real exact = boost::lexical_cast<Real>("1.3932039296856768591842462603255");
141 BOOST_CONSTEXPR const Real A = 1.0 / (pi<Real>() * pi<Real>() * pi<Real>());
142 auto g = [&](std::vector<Real> const & x)->Real
143 {
144 return A / (1.0 - cos(x[0])*cos(x[1])*cos(x[2]));
145 };
146 vector<pair<Real, Real>> bounds{{ Real(0), pi<Real>()}, { Real(0), pi<Real>()}, { Real(0), pi<Real>()}};
147 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.05, true, 1, 888889);
148
149 auto task = mc.integrate();
150 mc.cancel();
151 double y = task.get();
152 // Super low tolerance; because it got canceled so fast:
153 BOOST_CHECK_CLOSE_FRACTION(y, exact, 1.0);
154
155 mc.update_target_error((Real) 0.01);
156 task = mc.integrate();
157 y = task.get();
158 BOOST_CHECK_CLOSE_FRACTION(y, exact, 0.1);
159}
160
161template<class Real>
162void test_finite_singular_boundary()
163{
164 std::cout << "Testing that finite singular boundaries work on naive Monte-Carlo integration on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
165 using std::pow;
166 using std::log;
167 auto g = [](std::vector<Real> const & x)->Real
168 {
169 // The first term is singular at x = 0.
170 // The second at x = 1:
171 return pow(log(1.0/x[0]), 2) + log1p(-x[0]);
172 };
173 vector<pair<Real, Real>> bounds{{Real(0), Real(1)}};
174 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.01, true, 1, 1922);
175
176 auto task = mc.integrate();
177
178 double y = task.get();
179 BOOST_CHECK_CLOSE_FRACTION(y, 1.0, 0.1);
180}
181
182template<class Real>
183void test_multithreaded_variance()
184{
185 std::cout << "Testing that variance computed by naive Monte-Carlo integration converges to integral formula on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
186 Real exact_variance = (Real) 1/(Real) 12;
187 auto g = [&](std::vector<Real> const & x)->Real
188 {
189 return x[0];
190 };
191 vector<pair<Real, Real>> bounds{{ Real(0), Real(1)}};
192 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.001, false, 2, 12341);
193
194 auto task = mc.integrate();
195 Real y = task.get();
196 BOOST_CHECK_CLOSE_FRACTION(y, 0.5, 0.01);
197 BOOST_CHECK_CLOSE_FRACTION(mc.variance(), exact_variance, 0.05);
198}
199
200template<class Real>
201void test_variance()
202{
203 std::cout << "Testing that variance computed by naive Monte-Carlo integration converges to integral formula on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
204 Real exact_variance = (Real) 1/(Real) 12;
205 auto g = [&](std::vector<Real> const & x)->Real
206 {
207 return x[0];
208 };
209 vector<pair<Real, Real>> bounds{{ Real(0), Real(1)}};
210 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.001, false, 1, 12341);
211
212 auto task = mc.integrate();
213 Real y = task.get();
214 BOOST_CHECK_CLOSE_FRACTION(y, 0.5, 0.01);
215 BOOST_CHECK_CLOSE_FRACTION(mc.variance(), exact_variance, 0.05);
216}
217
92f5a8d4 218template<class Real, uint64_t dimension>
11fdf7f2
TL
219void test_product()
220{
221 std::cout << "Testing that product functions are integrated correctly by naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
222 auto g = [&](std::vector<Real> const & x)->Real
223 {
224 double y = 1;
92f5a8d4 225 for (uint64_t i = 0; i < x.size(); ++i)
11fdf7f2
TL
226 {
227 y *= 2*x[i];
228 }
229 return y;
230 };
231
232 vector<pair<Real, Real>> bounds(dimension);
92f5a8d4 233 for (uint64_t i = 0; i < dimension; ++i)
11fdf7f2
TL
234 {
235 bounds[i] = std::make_pair<Real, Real>(0, 1);
236 }
237 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.001, false, 1, 13999);
238
239 auto task = mc.integrate();
240 Real y = task.get();
241 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
242 using std::pow;
243 Real exact_variance = pow(4.0/3.0, dimension) - 1;
244 BOOST_CHECK_CLOSE_FRACTION(mc.variance(), exact_variance, 0.1);
245}
246
92f5a8d4
TL
247template<class Real, uint64_t dimension>
248void test_alternative_rng_1()
11fdf7f2
TL
249{
250 std::cout << "Testing that alternative RNGs work correctly using naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
251 auto g = [&](std::vector<Real> const & x)->Real
252 {
253 double y = 1;
92f5a8d4 254 for (uint64_t i = 0; i < x.size(); ++i)
11fdf7f2
TL
255 {
256 y *= 2*x[i];
257 }
258 return y;
259 };
260
261 vector<pair<Real, Real>> bounds(dimension);
92f5a8d4 262 for (uint64_t i = 0; i < dimension; ++i)
11fdf7f2
TL
263 {
264 bounds[i] = std::make_pair<Real, Real>(0, 1);
265 }
92f5a8d4 266 std::cout << "Testing std::mt19937" << std::endl;
11fdf7f2 267
92f5a8d4
TL
268 naive_monte_carlo<Real, decltype(g), std::mt19937> mc1(g, bounds, (Real) 0.001, false, 1, 1882);
269
270 auto task = mc1.integrate();
11fdf7f2
TL
271 Real y = task.get();
272 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
273 using std::pow;
274 Real exact_variance = pow(4.0/3.0, dimension) - 1;
92f5a8d4
TL
275 BOOST_CHECK_CLOSE_FRACTION(mc1.variance(), exact_variance, 0.05);
276
277 std::cout << "Testing std::knuth_b" << std::endl;
278 naive_monte_carlo<Real, decltype(g), std::knuth_b> mc2(g, bounds, (Real) 0.001, false, 1, 1883);
279 task = mc2.integrate();
280 y = task.get();
281 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
282
283 std::cout << "Testing std::ranlux48" << std::endl;
284 naive_monte_carlo<Real, decltype(g), std::ranlux48> mc3(g, bounds, (Real) 0.001, false, 1, 1884);
285 task = mc3.integrate();
286 y = task.get();
287 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
288}
289
290template<class Real, uint64_t dimension>
291void test_alternative_rng_2()
292{
293 std::cout << "Testing that alternative RNGs work correctly using naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
294 auto g = [&](std::vector<Real> const & x)->Real
295 {
296 double y = 1;
297 for (uint64_t i = 0; i < x.size(); ++i)
298 {
299 y *= 2*x[i];
300 }
301 return y;
302 };
303
304 vector<pair<Real, Real>> bounds(dimension);
305 for (uint64_t i = 0; i < dimension; ++i)
306 {
307 bounds[i] = std::make_pair<Real, Real>(0, 1);
308 }
309
310 std::cout << "Testing std::default_random_engine" << std::endl;
311 naive_monte_carlo<Real, decltype(g), std::default_random_engine> mc4(g, bounds, (Real) 0.001, false, 1, 1884);
312 auto task = mc4.integrate();
313 Real y = task.get();
314 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
315
316 std::cout << "Testing std::minstd_rand" << std::endl;
317 naive_monte_carlo<Real, decltype(g), std::minstd_rand> mc5(g, bounds, (Real) 0.001, false, 1, 1887);
318 task = mc5.integrate();
319 y = task.get();
320 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
321
322 std::cout << "Testing std::minstd_rand0" << std::endl;
323 naive_monte_carlo<Real, decltype(g), std::minstd_rand0> mc6(g, bounds, (Real) 0.001, false, 1, 1889);
324 task = mc6.integrate();
325 y = task.get();
326 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
327
11fdf7f2
TL
328}
329
330template<class Real>
331void test_upper_bound_infinite()
332{
333 std::cout << "Testing that infinite upper bounds are integrated correctly by naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
334 auto g = [](std::vector<Real> const & x)->Real
335 {
336 return 1.0/(x[0]*x[0] + 1.0);
337 };
338
339 vector<pair<Real, Real>> bounds(1);
92f5a8d4 340 for (uint64_t i = 0; i < bounds.size(); ++i)
11fdf7f2
TL
341 {
342 bounds[i] = std::make_pair<Real, Real>(0, std::numeric_limits<Real>::infinity());
343 }
344 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.001, true, 1, 8765);
345 auto task = mc.integrate();
346 Real y = task.get();
347 BOOST_CHECK_CLOSE_FRACTION(y, boost::math::constants::half_pi<Real>(), 0.01);
348}
349
350template<class Real>
351void test_lower_bound_infinite()
352{
353 std::cout << "Testing that infinite lower bounds are integrated correctly by naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
354 auto g = [](std::vector<Real> const & x)->Real
355 {
356 return 1.0/(x[0]*x[0] + 1.0);
357 };
358
359 vector<pair<Real, Real>> bounds(1);
92f5a8d4 360 for (uint64_t i = 0; i < bounds.size(); ++i)
11fdf7f2
TL
361 {
362 bounds[i] = std::make_pair<Real, Real>(-std::numeric_limits<Real>::infinity(), 0);
363 }
364 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.001, true, 1, 1208);
365
366 auto task = mc.integrate();
367 Real y = task.get();
368 BOOST_CHECK_CLOSE_FRACTION(y, boost::math::constants::half_pi<Real>(), 0.01);
369}
370
371template<class Real>
372void test_lower_bound_infinite2()
373{
374 std::cout << "Testing that infinite lower bounds (2) are integrated correctly by naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
375 auto g = [](std::vector<Real> const & x)->Real
376 {
377 // If x[0] = inf, this should blow up:
378 return (x[0]*x[0])/(x[0]*x[0]*x[0]*x[0] + 1.0);
379 };
380
381 vector<pair<Real, Real>> bounds(1);
92f5a8d4 382 for (uint64_t i = 0; i < bounds.size(); ++i)
11fdf7f2
TL
383 {
384 bounds[i] = std::make_pair<Real, Real>(-std::numeric_limits<Real>::infinity(), 0);
385 }
386 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.001, true, 1, 1208);
387 auto task = mc.integrate();
388 Real y = task.get();
389 BOOST_CHECK_CLOSE_FRACTION(y, boost::math::constants::half_pi<Real>()/boost::math::constants::root_two<Real>(), 0.01);
390}
391
392template<class Real>
393void test_double_infinite()
394{
395 std::cout << "Testing that double infinite bounds are integrated correctly by naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
396 auto g = [](std::vector<Real> const & x)->Real
397 {
398 return 1.0/(x[0]*x[0] + 1.0);
399 };
400
401 vector<pair<Real, Real>> bounds(1);
92f5a8d4 402 for (uint64_t i = 0; i < bounds.size(); ++i)
11fdf7f2
TL
403 {
404 bounds[i] = std::make_pair<Real, Real>(-std::numeric_limits<Real>::infinity(), std::numeric_limits<Real>::infinity());
405 }
406 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, (Real) 0.001, true, 1, 1776);
407
408 auto task = mc.integrate();
409 Real y = task.get();
410 BOOST_CHECK_CLOSE_FRACTION(y, boost::math::constants::pi<Real>(), 0.01);
411}
412
92f5a8d4 413template<class Real, uint64_t dimension>
11fdf7f2
TL
414void test_radovic()
415{
416 // See: Generalized Halton Sequences in 2008: A Comparative Study, function g1:
417 std::cout << "Testing that the Radovic function is integrated correctly by naive Monte-Carlo on type " << boost::typeindex::type_id<Real>().pretty_name() << "\n";
418 auto g = [](std::vector<Real> const & x)->Real
419 {
420 using std::abs;
421 Real alpha = (Real)0.01;
422 Real z = 1;
92f5a8d4 423 for (uint64_t i = 0; i < dimension; ++i)
11fdf7f2
TL
424 {
425 z *= (abs(4*x[i]-2) + alpha)/(1+alpha);
426 }
427 return z;
428 };
429
430 vector<pair<Real, Real>> bounds(dimension);
92f5a8d4 431 for (uint64_t i = 0; i < bounds.size(); ++i)
11fdf7f2
TL
432 {
433 bounds[i] = std::make_pair<Real, Real>(0, 1);
434 }
92f5a8d4 435 Real error_goal = (Real) 0.001;
11fdf7f2
TL
436 naive_monte_carlo<Real, decltype(g)> mc(g, bounds, error_goal, false, 1, 1982);
437
438 auto task = mc.integrate();
439 Real y = task.get();
440 if (abs(y - 1) > 0.01)
441 {
442 std::cout << "Error in estimation of Radovic integral too high, function calls: " << mc.calls() << "\n";
443 std::cout << "Final error estimate: " << mc.current_error_estimate() << std::endl;
444 std::cout << "Error goal : " << error_goal << std::endl;
445 std::cout << "Variance estimate : " << mc.variance() << std::endl;
446 BOOST_CHECK_CLOSE_FRACTION(y, 1, 0.01);
447 }
448}
449
450
451BOOST_AUTO_TEST_CASE(naive_monte_carlo_test)
452{
92f5a8d4 453 std::cout << "Default hardware concurrency = " << std::thread::hardware_concurrency() << std::endl;
11fdf7f2
TL
454#if !defined(TEST) || TEST == 1
455 test_finite_singular_boundary<double>();
456 test_finite_singular_boundary<float>();
457#endif
458#if !defined(TEST) || TEST == 2
459 test_pi<float>();
460 test_pi<double>();
11fdf7f2
TL
461#endif
462#if !defined(TEST) || TEST == 3
92f5a8d4 463 test_pi_multithreaded<float>();
11fdf7f2 464 test_constant<float>();
11fdf7f2 465#endif
92f5a8d4 466 //test_pi<long double>();
11fdf7f2 467#if !defined(TEST) || TEST == 4
92f5a8d4
TL
468 test_constant<double>();
469 //test_constant<long double>();
11fdf7f2 470 test_cancel_and_restart<float>();
92f5a8d4
TL
471#endif
472#if !defined(TEST) || TEST == 5
11fdf7f2
TL
473 test_exception_from_integrand<float>();
474 test_variance<float>();
475#endif
92f5a8d4 476#if !defined(TEST) || TEST == 6
11fdf7f2
TL
477 test_variance<double>();
478 test_multithreaded_variance<double>();
92f5a8d4
TL
479#endif
480#if !defined(TEST) || TEST == 7
11fdf7f2
TL
481 test_product<float, 1>();
482 test_product<float, 2>();
483#endif
92f5a8d4 484#if !defined(TEST) || TEST == 8
11fdf7f2
TL
485 test_product<float, 3>();
486 test_product<float, 4>();
487 test_product<float, 5>();
488#endif
92f5a8d4 489#if !defined(TEST) || TEST == 9
11fdf7f2
TL
490 test_product<float, 6>();
491 test_product<double, 1>();
92f5a8d4
TL
492#endif
493#if !defined(TEST) || TEST == 10
11fdf7f2
TL
494 test_product<double, 2>();
495#endif
92f5a8d4 496#if !defined(TEST) || TEST == 11
11fdf7f2
TL
497 test_product<double, 3>();
498 test_product<double, 4>();
499#endif
92f5a8d4 500#if !defined(TEST) || TEST == 12
11fdf7f2
TL
501 test_upper_bound_infinite<float>();
502 test_upper_bound_infinite<double>();
92f5a8d4
TL
503#endif
504#if !defined(TEST) || TEST == 13
11fdf7f2
TL
505 test_lower_bound_infinite<float>();
506 test_lower_bound_infinite<double>();
92f5a8d4
TL
507#endif
508#if !defined(TEST) || TEST == 14
11fdf7f2
TL
509 test_lower_bound_infinite2<float>();
510#endif
92f5a8d4 511#if !defined(TEST) || TEST == 15
11fdf7f2
TL
512 test_double_infinite<float>();
513 test_double_infinite<double>();
11fdf7f2 514#endif
92f5a8d4
TL
515#if !defined(TEST) || TEST == 16
516 test_radovic<float, 1>();
11fdf7f2 517 test_radovic<float, 2>();
92f5a8d4
TL
518#endif
519#if !defined(TEST) || TEST == 17
11fdf7f2
TL
520 test_radovic<float, 3>();
521 test_radovic<double, 1>();
522#endif
92f5a8d4 523#if !defined(TEST) || TEST == 18
11fdf7f2
TL
524 test_radovic<double, 2>();
525 test_radovic<double, 3>();
92f5a8d4
TL
526#endif
527#if !defined(TEST) || TEST == 19
11fdf7f2
TL
528 test_radovic<double, 4>();
529 test_radovic<double, 5>();
92f5a8d4
TL
530#endif
531#if !defined(TEST) || TEST == 20
532 test_alternative_rng_1<float, 3>();
533#endif
534#if !defined(TEST) || TEST == 21
535 test_alternative_rng_1<double, 3>();
536#endif
537#if !defined(TEST) || TEST == 22
538 test_alternative_rng_2<float, 3>();
539#endif
540#if !defined(TEST) || TEST == 23
541 test_alternative_rng_2<double, 3>();
11fdf7f2
TL
542#endif
543
544}