Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/math/tools/toms748_solve.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
14 #include <boost/math/policies/error_handling.hpp> | 14 #include <boost/math/policies/error_handling.hpp> |
15 #include <boost/math/tools/config.hpp> | 15 #include <boost/math/tools/config.hpp> |
16 #include <boost/math/special_functions/sign.hpp> | 16 #include <boost/math/special_functions/sign.hpp> |
17 #include <boost/cstdint.hpp> | 17 #include <boost/cstdint.hpp> |
18 #include <limits> | 18 #include <limits> |
19 | |
20 #ifdef BOOST_MATH_LOG_ROOT_ITERATIONS | |
21 # define BOOST_MATH_LOGGER_INCLUDE <boost/math/tools/iteration_logger.hpp> | |
22 # include BOOST_MATH_LOGGER_INCLUDE | |
23 # undef BOOST_MATH_LOGGER_INCLUDE | |
24 #else | |
25 # define BOOST_MATH_LOG_COUNT(count) | |
26 #endif | |
19 | 27 |
20 namespace boost{ namespace math{ namespace tools{ | 28 namespace boost{ namespace math{ namespace tools{ |
21 | 29 |
22 template <class T> | 30 template <class T> |
23 class eps_tolerance | 31 class eps_tolerance |
296 | 304 |
297 // initialise a, b and fa, fb: | 305 // initialise a, b and fa, fb: |
298 a = ax; | 306 a = ax; |
299 b = bx; | 307 b = bx; |
300 if(a >= b) | 308 if(a >= b) |
301 policies::raise_domain_error( | 309 return boost::math::detail::pair_from_single(policies::raise_domain_error( |
302 function, | 310 function, |
303 "Parameters a and b out of order: a=%1%", a, pol); | 311 "Parameters a and b out of order: a=%1%", a, pol)); |
304 fa = fax; | 312 fa = fax; |
305 fb = fbx; | 313 fb = fbx; |
306 | 314 |
307 if(tol(a, b) || (fa == 0) || (fb == 0)) | 315 if(tol(a, b) || (fa == 0) || (fb == 0)) |
308 { | 316 { |
313 a = b; | 321 a = b; |
314 return std::make_pair(a, b); | 322 return std::make_pair(a, b); |
315 } | 323 } |
316 | 324 |
317 if(boost::math::sign(fa) * boost::math::sign(fb) > 0) | 325 if(boost::math::sign(fa) * boost::math::sign(fb) > 0) |
318 policies::raise_domain_error( | 326 return boost::math::detail::pair_from_single(policies::raise_domain_error( |
319 function, | 327 function, |
320 "Parameters a and b do not bracket the root: a=%1%", a, pol); | 328 "Parameters a and b do not bracket the root: a=%1%", a, pol)); |
321 // dummy value for fd, e and fe: | 329 // dummy value for fd, e and fe: |
322 fe = e = fd = 1e5F; | 330 fe = e = fd = 1e5F; |
323 | 331 |
324 if(fa != 0) | 332 if(fa != 0) |
325 { | 333 { |
450 } | 458 } |
451 else if(fb == 0) | 459 else if(fb == 0) |
452 { | 460 { |
453 a = b; | 461 a = b; |
454 } | 462 } |
463 BOOST_MATH_LOG_COUNT(max_iter) | |
455 return std::make_pair(a, b); | 464 return std::make_pair(a, b); |
456 } | 465 } |
457 | 466 |
458 template <class F, class T, class Tol> | 467 template <class F, class T, class Tol> |
459 inline std::pair<T, T> toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, boost::uintmax_t& max_iter) | 468 inline std::pair<T, T> toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, boost::uintmax_t& max_iter) |
491 // | 500 // |
492 // Set up invocation count: | 501 // Set up invocation count: |
493 // | 502 // |
494 boost::uintmax_t count = max_iter - 1; | 503 boost::uintmax_t count = max_iter - 1; |
495 | 504 |
505 int step = 32; | |
506 | |
496 if((fa < 0) == (guess < 0 ? !rising : rising)) | 507 if((fa < 0) == (guess < 0 ? !rising : rising)) |
497 { | 508 { |
498 // | 509 // |
499 // Zero is to the right of b, so walk upwards | 510 // Zero is to the right of b, so walk upwards |
500 // until we find it: | 511 // until we find it: |
501 // | 512 // |
502 while((boost::math::sign)(fb) == (boost::math::sign)(fa)) | 513 while((boost::math::sign)(fb) == (boost::math::sign)(fa)) |
503 { | 514 { |
504 if(count == 0) | 515 if(count == 0) |
505 policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol); | 516 return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol)); |
506 // | 517 // |
507 // Heuristic: every 20 iterations we double the growth factor in case the | 518 // Heuristic: normally it's best not to increase the step sizes as we'll just end up |
508 // initial guess was *really* bad ! | 519 // with a really wide range to search for the root. However, if the initial guess was *really* |
509 // | 520 // bad then we need to speed up the search otherwise we'll take forever if we're orders of |
510 if((max_iter - count) % 20 == 0) | 521 // magnitude out. This happens most often if the guess is a small value (say 1) and the result |
522 // we're looking for is close to std::numeric_limits<T>::min(). | |
523 // | |
524 if((max_iter - count) % step == 0) | |
525 { | |
511 factor *= 2; | 526 factor *= 2; |
527 if(step > 1) step /= 2; | |
528 } | |
512 // | 529 // |
513 // Now go ahead and move our guess by "factor": | 530 // Now go ahead and move our guess by "factor": |
514 // | 531 // |
515 a = b; | 532 a = b; |
516 fa = fb; | 533 fa = fb; |
534 max_iter -= count; | 551 max_iter -= count; |
535 max_iter += 1; | 552 max_iter += 1; |
536 return a > 0 ? std::make_pair(T(0), T(a)) : std::make_pair(T(a), T(0)); | 553 return a > 0 ? std::make_pair(T(0), T(a)) : std::make_pair(T(a), T(0)); |
537 } | 554 } |
538 if(count == 0) | 555 if(count == 0) |
539 policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol); | 556 return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol)); |
540 // | 557 // |
541 // Heuristic: every 20 iterations we double the growth factor in case the | 558 // Heuristic: normally it's best not to increase the step sizes as we'll just end up |
542 // initial guess was *really* bad ! | 559 // with a really wide range to search for the root. However, if the initial guess was *really* |
543 // | 560 // bad then we need to speed up the search otherwise we'll take forever if we're orders of |
544 if((max_iter - count) % 20 == 0) | 561 // magnitude out. This happens most often if the guess is a small value (say 1) and the result |
562 // we're looking for is close to std::numeric_limits<T>::min(). | |
563 // | |
564 if((max_iter - count) % step == 0) | |
565 { | |
545 factor *= 2; | 566 factor *= 2; |
567 if(step > 1) step /= 2; | |
568 } | |
546 // | 569 // |
547 // Now go ahead and move are guess by "factor": | 570 // Now go ahead and move are guess by "factor": |
548 // | 571 // |
549 b = a; | 572 b = a; |
550 fb = fa; | 573 fb = fa; |
565 tol, | 588 tol, |
566 count, | 589 count, |
567 pol); | 590 pol); |
568 max_iter += count; | 591 max_iter += count; |
569 BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); | 592 BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); |
593 BOOST_MATH_LOG_COUNT(max_iter) | |
570 return r; | 594 return r; |
571 } | 595 } |
572 | 596 |
573 template <class F, class T, class Tol> | 597 template <class F, class T, class Tol> |
574 inline std::pair<T, T> bracket_and_solve_root(F f, const T& guess, const T& factor, bool rising, Tol tol, boost::uintmax_t& max_iter) | 598 inline std::pair<T, T> bracket_and_solve_root(F f, const T& guess, const T& factor, bool rising, Tol tol, boost::uintmax_t& max_iter) |