123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- // Copyright John Maddock 2014
- // Use, modification and distribution are subject to the
- // Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt
- // or copy at http://www.boost.org/LICENSE_1_0.txt)
- #define BOOST_TEST_MAIN
- #include <boost/test/unit_test.hpp> // Boost.Test
- #include <boost/test/results_collector.hpp>
- #include <boost/test/unit_test.hpp>
- #include <boost/test/tools/floating_point_comparison.hpp>
- #include <boost/tuple/tuple.hpp>
- #include <boost/fusion/include/tuple.hpp>
- #include <boost/fusion/include/std_pair.hpp>
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- #include <tuple>
- #endif
- #include <iostream>
- #include <iomanip>
- using std::cout;
- using std::endl;
- using std::setprecision;
- #include <boost/math/tools/roots.hpp>
- //
- // We'll use cbrt as an example:
- //
- struct cbtr_functor_1
- {
- cbtr_functor_1(double x) : m_target(x) {}
- double operator()(double x)
- {
- return x * x * x - m_target;
- }
- private:
- double m_target;
- };
- struct cbtr_functor_2a
- {
- cbtr_functor_2a(double x) : m_target(x) {}
- std::pair<double, double> operator()(double x)
- {
- return std::make_pair(x * x * x - m_target, 3 * x * x);
- }
- private:
- double m_target;
- };
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- struct cbtr_functor_2b
- {
- cbtr_functor_2b(double x) : m_target(x) {}
- std::tuple<double, double> operator()(double x)
- {
- return std::tuple<double, double>(x * x * x - m_target, 3 * x * x);
- }
- private:
- double m_target;
- };
- #endif
- struct cbtr_functor_2c
- {
- cbtr_functor_2c(double x) : m_target(x) {}
- boost::tuple<double, double> operator()(double x)
- {
- return boost::tuple<double, double>(x * x * x - m_target, 3 * x * x);
- }
- private:
- double m_target;
- };
- struct cbtr_functor_2d
- {
- cbtr_functor_2d(double x) : m_target(x) {}
- boost::fusion::tuple<double, double> operator()(double x)
- {
- return boost::fusion::tuple<double, double>(x * x * x - m_target, 3 * x * x);
- }
- private:
- double m_target;
- };
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- struct cbtr_functor_3b
- {
- cbtr_functor_3b(double x) : m_target(x) {}
- std::tuple<double, double, double> operator()(double x)
- {
- return std::tuple<double, double, double>(x * x * x - m_target, 3 * x * x, 6 * x);
- }
- private:
- double m_target;
- };
- #endif
- struct cbtr_functor_3c
- {
- cbtr_functor_3c(double x) : m_target(x) {}
- boost::tuple<double, double, double> operator()(double x)
- {
- return boost::tuple<double, double, double>(x * x * x - m_target, 3 * x * x, 6 * x);
- }
- private:
- double m_target;
- };
- struct cbtr_functor_3d
- {
- cbtr_functor_3d(double x) : m_target(x) {}
- boost::fusion::tuple<double, double, double> operator()(double x)
- {
- return boost::fusion::tuple<double, double, double>(x * x * x - m_target, 3 * x * x, 6 * x);
- }
- private:
- double m_target;
- };
- BOOST_AUTO_TEST_CASE( test_main )
- {
- double x = 27;
- double expected = 3;
- double result;
- double tolerance = std::numeric_limits<double>::epsilon() * 5;
- std::pair<double, double> p;
- //
- // Start by trying the unary functors, bisect first:
- //
- cbtr_functor_1 f1(x);
- boost::math::tools::eps_tolerance<double> t(std::numeric_limits<double>::digits - 1);
- p = boost::math::tools::bisect(f1, 0.0, x, t);
- result = (p.first + p.second) / 2;
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- //
- // bracket_and_solve_root:
- //
- boost::uintmax_t max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
- p = boost::math::tools::bracket_and_solve_root(f1, x, 2.0, true, t, max_iter);
- result = (p.first + p.second) / 2;
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- //
- // toms748_solve:
- //
- max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
- p = boost::math::tools::toms748_solve(f1, 0.0, x, t, max_iter);
- result = (p.first + p.second) / 2;
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #ifndef BOOST_NO_CXX11_LAMBDAS
- //
- // Now try again with C++11 lambda's
- //
- p = boost::math::tools::bisect([x](double z){ return z * z * z - x; }, 0.0, x, t);
- result = (p.first + p.second) / 2;
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- //
- // bracket_and_solve_root:
- //
- max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
- p = boost::math::tools::bracket_and_solve_root([x](double z){ return z * z * z - x; }, x, 2.0, true, t, max_iter);
- result = (p.first + p.second) / 2;
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- //
- // toms748_solve:
- //
- max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
- p = boost::math::tools::toms748_solve([x](double z){ return z * z * z - x; }, 0.0, x, t, max_iter);
- result = (p.first + p.second) / 2;
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- cbtr_functor_2a f2(x);
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- cbtr_functor_2b f3(x);
- #endif
- cbtr_functor_2c f4(x);
- cbtr_functor_2d f5(x);
- //
- // Binary Functors - newton_raphson_iterate - test each possible tuple type:
- //
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- result = boost::math::tools::newton_raphson_iterate(f2, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- result = boost::math::tools::newton_raphson_iterate(f3, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- result = boost::math::tools::newton_raphson_iterate(f4, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- result = boost::math::tools::newton_raphson_iterate(f5, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- //
- // And again but with lambdas:
- //
- #ifndef BOOST_NO_CXX11_LAMBDAS
- result = boost::math::tools::newton_raphson_iterate([x](double z){ return std::make_pair(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- result = boost::math::tools::newton_raphson_iterate([x](double z){ return std::make_tuple(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- result = boost::math::tools::newton_raphson_iterate([x](double z){ return boost::tuple<double, double>(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- result = boost::math::tools::newton_raphson_iterate([x](double z){ return boost::fusion::tuple<double, double>(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- cbtr_functor_3b f6(x);
- #endif
- cbtr_functor_3c f7(x);
- cbtr_functor_3d f8(x);
- //
- // Ternary functors:
- //
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- result = boost::math::tools::halley_iterate(f6, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- result = boost::math::tools::halley_iterate(f7, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- result = boost::math::tools::halley_iterate(f8, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #ifndef BOOST_NO_CXX11_LAMBDAS
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- result = boost::math::tools::halley_iterate([x](double z){ return std::make_tuple(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- result = boost::math::tools::halley_iterate([x](double z){ return boost::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- result = boost::math::tools::halley_iterate([x](double z){ return boost::fusion::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- result = boost::math::tools::schroder_iterate(f6, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- result = boost::math::tools::schroder_iterate(f7, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- result = boost::math::tools::schroder_iterate(f8, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #ifndef BOOST_NO_CXX11_LAMBDAS
- #ifndef BOOST_NO_CXX11_HDR_TUPLE
- result = boost::math::tools::schroder_iterate([x](double z){ return std::make_tuple(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- result = boost::math::tools::schroder_iterate([x](double z){ return boost::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- result = boost::math::tools::schroder_iterate([x](double z){ return boost::fusion::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
- BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
- #endif
- } // BOOST_AUTO_TEST_CASE( test_main )
|