...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Since all the root finding functions accept a function-object, they can be made to work (often in a lot less code) with C++11 lambda's. Here's the much reduced code for our "toy" cube root function:
template <class T> T cbrt_2deriv_lambda(T x) { // return cube root of x using 1st and 2nd derivatives and Halley. //using namespace std; // Help ADL of std functions. using namespace boost::math::tools; int exponent; frexp(x, &exponent); // Get exponent of z (ignore mantissa). T guess = ldexp(1., exponent / 3); // Rough guess is to divide the exponent by three. T min = ldexp(0.5, exponent / 3); // Minimum possible value is half our guess. T max = ldexp(2., exponent / 3); // Maximum possible value is twice our guess. const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T. // digits used to control how accurate to try to make the result. int get_digits = static_cast<int>(digits * 0.4); // Accuracy triples with each step, so stop when just // over one third of the digits are correct. std::uintmax_t maxit = 20; T result = halley_iterate( // lambda function: [x](const T& g){ return std::make_tuple(g * g * g - x, 3 * g * g, 6 * g); }, guess, min, max, get_digits, maxit); return result; }
Full code of this example is at root_finding_example.cpp,