1[section:roots_noderiv Root Finding Without Derivatives] 2 3[h4 Synopsis] 4 5`` 6#include <boost/math/tools/roots.hpp> 7`` 8 9 namespace boost { namespace math { 10 namespace tools { // Note namespace boost::math::tools. 11 // Bisection 12 template <class F, class T, class Tol> 13 std::pair<T, T> 14 bisect( 15 F f, 16 T min, 17 T max, 18 Tol tol, 19 boost::uintmax_t& max_iter); 20 21 template <class F, class T, class Tol> 22 std::pair<T, T> 23 bisect( 24 F f, 25 T min, 26 T max, 27 Tol tol); 28 29 template <class F, class T, class Tol, class ``__Policy``> 30 std::pair<T, T> 31 bisect( 32 F f, 33 T min, 34 T max, 35 Tol tol, 36 boost::uintmax_t& max_iter, 37 const ``__Policy``&); 38 39 // Bracket and Solve Root 40 template <class F, class T, class Tol> 41 std::pair<T, T> 42 bracket_and_solve_root( 43 F f, 44 const T& guess, 45 const T& factor, 46 bool rising, 47 Tol tol, 48 boost::uintmax_t& max_iter); 49 50 template <class F, class T, class Tol, class ``__Policy``> 51 std::pair<T, T> 52 bracket_and_solve_root( 53 F f, 54 const T& guess, 55 const T& factor, 56 bool rising, 57 Tol tol, 58 boost::uintmax_t& max_iter, 59 const ``__Policy``&); 60 61 // TOMS 748 algorithm 62 template <class F, class T, class Tol> 63 std::pair<T, T> 64 toms748_solve( 65 F f, 66 const T& a, 67 const T& b, 68 Tol tol, 69 boost::uintmax_t& max_iter); 70 71 template <class F, class T, class Tol, class ``__Policy``> 72 std::pair<T, T> 73 toms748_solve( 74 F f, 75 const T& a, 76 const T& b, 77 Tol tol, 78 boost::uintmax_t& max_iter, 79 const ``__Policy``&); 80 81 template <class F, class T, class Tol> 82 std::pair<T, T> 83 toms748_solve( 84 F f, 85 const T& a, 86 const T& b, 87 const T& fa, 88 const T& fb, 89 Tol tol, 90 boost::uintmax_t& max_iter); 91 92 template <class F, class T, class Tol, class ``__Policy``> 93 std::pair<T, T> 94 toms748_solve( 95 F f, 96 const T& a, 97 const T& b, 98 const T& fa, 99 const T& fb, 100 Tol tol, 101 boost::uintmax_t& max_iter, 102 const ``__Policy``&); 103 104 // Termination conditions: 105 template <class T> 106 struct eps_tolerance; 107 108 struct equal_floor; 109 struct equal_ceil; 110 struct equal_nearest_integer; 111 112 }}} // boost::math::tools namespaces 113 114[h4 Description] 115 116These functions solve the root of some function ['f(x)] - 117['without the need for any derivatives of ['f(x)]]. 118 119The `bracket_and_solve_root` functions use __root_finding_TOMS748 120by Alefeld, Potra and Shi that is asymptotically the most efficient known, 121and has been shown to be optimal for a certain classes of smooth functions. 122Variants with and without __policy_section are provided. 123 124Alternatively, __bisect is a simple __bisection_wikipedia routine which can be useful 125in its own right in some situations, or alternatively for narrowing 126down the range containing the root, prior to calling a more advanced 127algorithm. 128 129All the algorithms in this section reduce the diameter of the enclosing 130interval with the same asymptotic efficiency with which they locate the 131root. This is in contrast to the derivative based methods which may ['never] 132significantly reduce the enclosing interval, even though they rapidly approach 133the root. This is also in contrast to some other derivative-free methods 134(for example, Brent's method described at 135[@http://en.wikipedia.org/wiki/Brent%27s_method Brent-Dekker)] 136which only reduces the enclosing interval on the final step. 137Therefore these methods return a `std::pair` containing the enclosing interval found, 138and accept a function object specifying the termination condition. 139 140Three function objects are provided for ready-made termination conditions: 141 142* ['eps_tolerance] causes termination when the relative error in the enclosing 143interval is below a certain threshold. 144* ['equal_floor] and ['equal_ceil] are useful for certain statistical applications 145where the result is known to be an integer. 146* Other user-defined termination conditions are likely to be used 147only rarely, but may be useful in some specific circumstances. 148 149[section:bisect Bisection] 150 151 template <class F, class T, class Tol> 152 std::pair<T, T> 153 bisect( // Unlimited iterations. 154 F f, 155 T min, 156 T max, 157 Tol tol); 158 159 template <class F, class T, class Tol> 160 std::pair<T, T> 161 bisect( // Limited iterations. 162 F f, 163 T min, 164 T max, 165 Tol tol, 166 boost::uintmax_t& max_iter); 167 168 template <class F, class T, class Tol, class ``__Policy``> 169 std::pair<T, T> 170 bisect( // Specified policy. 171 F f, 172 T min, 173 T max, 174 Tol tol, 175 boost::uintmax_t& max_iter, 176 const ``__Policy``&); 177 178These functions locate the root using __bisection_wikipedia. 179 180`bisect` function arguments are: 181 182[variablelist 183[[f] [A unary functor (or C++ lambda) which is the function ['f(x)] whose root is to be found.]] 184[[min] [The left bracket of the interval known to contain the root.]] 185[[max] [The right bracket of the interval known to contain the root.[br] 186 It is a precondition that ['min < max] and ['f(min)*f(max) <= 0], 187 the function raises an __evaluation_error if these preconditions are violated. 188 The action taken on error is controlled by the __Policy template argument: the default behavior is to 189 throw a ['boost::math::evaluation_error]. If the __Policy is changed to not throw 190 then it returns ['std::pair<T>(min, min)].]] 191[[tol] [A binary functor (or C++ lambda) that specifies the termination condition: the function 192 will return the current brackets enclosing the root when ['tol(min, max)] becomes true. 193 See also __root_termination.]] 194[[max_iter][The maximum number of invocations of ['f(x)] to make while searching for the root. On exit, this is updated to the actual number of invocations performed.]] 195] 196 197[optional_policy] 198 199[*Returns]: a pair of values ['r] that bracket the root so that: 200 201[:f(r.first) * f(r.second) <= 0] 202 203and either 204 205[:tol(r.first, r.second) == true] 206 207or 208 209[:max_iter >= m] 210 211where ['m] is the initial value of ['max_iter] passed to the function. 212 213In other words, it's up to the caller to verify whether termination occurred 214as a result of exceeding ['max_iter] function invocations (easily done by 215checking the updated value of ['max_iter] when the function returns), rather than 216because the termination condition ['tol] was satisfied. 217 218[endsect] [/section:bisect Bisection] 219 220[section:bracket_solve Bracket and Solve Root] 221 222 template <class F, class T, class Tol> 223 std::pair<T, T> 224 bracket_and_solve_root( 225 F f, 226 const T& guess, 227 const T& factor, 228 bool rising, 229 Tol tol, 230 boost::uintmax_t& max_iter); 231 232 template <class F, class T, class Tol, class ``__Policy``> 233 std::pair<T, T> 234 bracket_and_solve_root( 235 F f, 236 const T& guess, 237 const T& factor, 238 bool rising, 239 Tol tol, 240 boost::uintmax_t& max_iter, 241 const ``__Policy``&); 242 243`bracket_and_solve_root` is a convenience function that calls __root_finding_TOMS748 internally 244to find the root of ['f(x)]. It is generally much easier to use this function rather than __root_finding_TOMS748, since it 245does the hard work of bracketing the root for you. It's bracketing routines are quite robust and will 246usually be more foolproof than home-grown routines, unless the function can be analysed to yield tight 247brackets. 248 249Note that this routine can only be used when: 250 251* ['f(x)] is monotonic in the half of the real axis containing ['guess]. 252* The value of the initial guess must have the same sign as the root: the function 253will ['never cross the origin] when searching for the root. 254* The location of the root should be known at least approximately, 255if the location of the root differs by many orders of magnitude 256from ['guess] then many iterations will be needed to bracket the root in spite of 257the special heuristics used to guard against this very situation. A typical example would be 258setting the initial guess to 0.1, when the root is at 1e-300. 259 260The `bracket_and_solve_root` parameters are: 261 262[variablelist 263[[f][A unary functor (or C++ lambda) that is the function whose root is to be solved. 264 ['f(x)] must be uniformly increasing or decreasing on ['x].]] 265[[guess][An initial approximation to the root.]] 266[[factor][A scaling factor that is used to bracket the root: the value 267 /guess/ is multiplied (or divided as appropriate) by /factor/ 268 until two values are found that bracket the root. A value 269 such as 2 is a typical choice for ['factor]. 270 In addition ['factor] will be multiplied by 2 every 32 iterations: 271 this is to guard against a really very bad initial guess, typically these occur 272 when it's known the result is very large or small, but not the exact order 273 of magnitude.]] 274[[rising][Set to ['true] if ['f(x)] is rising on /x/ and /false/ if ['f(x)] 275 is falling on /x/. This value is used along with the result 276 of /f(guess)/ to determine if /guess/ is 277 above or below the root.]] 278[[tol] [A binary functor (or C++ lambda) that determines the termination condition for the search 279 for the root. /tol/ is passed the current brackets at each step, 280 when it returns true then the current brackets are returned as the pair result. 281 See also __root_termination.]] 282[[max_iter] [The maximum number of function invocations to perform in the search 283 for the root. On exit is set to the actual number of invocations performed.]] 284] 285 286[optional_policy] 287 288[*Returns]: a pair of values ['r] that bracket the root so that: 289 290[:f(r.first) * f(r.second) <= 0] 291 292and either 293 294[:tol(r.first, r.second) == true] 295 296or 297 298[:max_iter >= m] 299 300where ['m] is the initial value of ['max_iter] passed to the function. 301 302In other words, it's up to the caller to verify whether termination occurred 303as a result of exceeding ['max_iter] function invocations (easily done by 304checking the value of ['max_iter] when the function returns), rather than 305because the termination condition ['tol] was satisfied. 306 307[endsect] [/section:bracket_solve Bracket and Solve Root] 308 309[section:TOMS748 Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions] 310 311 template <class F, class T, class Tol> 312 std::pair<T, T> 313 toms748_solve( 314 F f, 315 const T& a, 316 const T& b, 317 Tol tol, 318 boost::uintmax_t& max_iter); 319 320 template <class F, class T, class Tol, class ``__Policy``> 321 std::pair<T, T> 322 toms748_solve( 323 F f, 324 const T& a, 325 const T& b, 326 Tol tol, 327 boost::uintmax_t& max_iter, 328 const ``__Policy``&); 329 330 template <class F, class T, class Tol> 331 std::pair<T, T> 332 toms748_solve( 333 F f, 334 const T& a, 335 const T& b, 336 const T& fa, 337 const T& fb, 338 Tol tol, 339 boost::uintmax_t& max_iter); 340 341 template <class F, class T, class Tol, class ``__Policy``> 342 std::pair<T, T> 343 toms748_solve( 344 F f, 345 const T& a, 346 const T& b, 347 const T& fa, 348 const T& fb, 349 Tol tol, 350 boost::uintmax_t& max_iter, 351 const ``__Policy``&); 352 353These functions implement TOMS Algorithm 748: it uses a mixture of 354cubic, quadratic and linear (secant) interpolation to locate the root of 355['f(x)]. The two pairs of functions differ only by whether values for ['f(a)] and 356['f(b)] are already available. 357 358Generally speaking it is easier (and often more efficient) to use __bracket_solve 359rather than trying to bracket the root yourself as this function requires. 360 361This function is provided rather than [@http://en.wikipedia.org/wiki/Brent%27s_method Brent's method] as it is known to be more 362efficient in many cases (it is asymptotically the most efficient known, 363and has been shown to be optimal for a certain classes of smooth functions). 364It also has the useful property of decreasing the bracket size 365with each step, unlike Brent's method which only shrinks the enclosing interval in the 366final step. This makes it particularly useful when you need a result where the ends 367of the interval round to the same integer: as often happens in statistical applications, 368for example. In this situation the function is able to exit after a much smaller 369number of iterations than would otherwise be possible. 370 371The __root_finding_TOMS748 parameters are: 372 373[variablelist 374[[f] [A unary functor (or C++ lambda) that is the function whose root is to be solved. 375 f(x) need not be uniformly increasing or decreasing on ['x] and 376 may have multiple roots. However, the bounds given must bracket a single root.]] 377[[a] [The lower bound for the initial bracket of the root.]] 378[[b] [The upper bound for the initial bracket of the root. 379 It is a precondition that ['a < b] and that ['a] and ['b] 380 bracket the root to find so that ['f(a) * f(b) < 0].]] 381[[fa] [Optional: the value of ['f(a)].]] 382[[fb] [Optional: the value of ['f(b)].]] 383[[tol] [A binary functor (or C++ lambda) that determines the termination condition for the search 384 for the root. ['tol] is passed the current brackets at each step, 385 when it returns true, then the current brackets are returned as the result. 386 See also __root_termination.]] 387[[max_iter] [The maximum number of function invocations to perform in the search 388 for the root. On exit, ['max_iter] is set to actual number of function 389 invocations used.]] 390] 391 392[optional_policy] 393 394`toms748_solve` returns: a pair of values ['r] that bracket the root so that: 395 396[:['f(r.first) * f(r.second) <= 0]] 397 398and either 399 400[:['tol(r.first, r.second) == true]] 401 402or 403 404[:['max_iter >= m]] 405 406where ['m] is the initial value of ['max_iter] passed to the function. 407 408In other words, it's up to the caller to verify whether termination occurred 409as a result of exceeding ['max_iter] function invocations (easily done by 410checking the updated value of ['max_iter] 411against its previous value passed as parameter), 412rather than because the termination condition ['tol] was satisfied. 413 414[endsect] [/section:TOMS748 Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions] 415 416[section:brent Brent-Decker Algorithm] 417 418The [@http://en.wikipedia.org/wiki/Brent%27s_method Brent-Dekker algorithm], although very well know, 419is not provided by this library as __root_finding_TOMS748 or 420its slightly easier to use variant __bracket_solve are superior and provide equivalent functionality. 421 422[endsect] [/section:brent Brent-Decker Algorithm] 423 424[section:root_termination Termination Condition Functors] 425 426 template <class T> 427 struct eps_tolerance 428 { 429 eps_tolerance(); 430 eps_tolerance(int bits); 431 bool operator()(const T& a, const T& b)const; 432 }; 433 434`eps_tolerance` is the usual termination condition used with these root finding functions. 435Its `operator()` will return true when the relative distance between ['a] and ['b] 436is less than four times the machine epsilon for T, or 2[super 1-bits], whichever is 437the larger. In other words, you set ['bits] to the number of bits of precision you 438want in the result. The minimal tolerance of ['four times the machine epsilon of type T] is 439required to ensure that we get back a bracketing interval, since this must clearly 440be at greater than one epsilon in size. While in theory a maximum distance of twice 441machine epsilon is possible to achieve, in practice this results in a great deal of "thrashing" 442given that the function whose root is being found can only ever be accurate to 1 epsilon at best. 443 444 struct equal_floor 445 { 446 equal_floor(); 447 template <class T> bool operator()(const T& a, const T& b)const; 448 }; 449 450This termination condition is used when you want to find an integer result 451that is the ['floor] of the true root. It will terminate as soon as both ends 452of the interval have the same ['floor]. 453 454 struct equal_ceil 455 { 456 equal_ceil(); 457 template <class T> bool operator()(const T& a, const T& b)const; 458 }; 459 460This termination condition is used when you want to find an integer result 461that is the ['ceil] of the true root. It will terminate as soon as both ends 462of the interval have the same ['ceil]. 463 464 struct equal_nearest_integer 465 { 466 equal_nearest_integer(); 467 template <class T> bool operator()(const T& a, const T& b)const; 468 }; 469 470This termination condition is used when you want to find an integer result 471that is the /closest/ to the true root. It will terminate as soon as both ends 472of the interval round to the same nearest integer. 473 474[endsect] [/section:root_termination Termination Condition Functors] 475 476[section:implementation Implementation] 477 478The implementation of the bisection algorithm is extremely straightforward 479and not detailed here. 480 481__TOMS748 is described in detail in: 482 483['Algorithm 748: Enclosing Zeros of Continuous Functions, 484G. E. Alefeld, F. A. Potra and Yixun Shi, 485ACM Transactions on Mathematica1 Software, Vol. 21. No. 3. September 1995. 486Pages 327-344.] 487 488The implementation here is a faithful translation of this paper into C++. 489 490[endsect] [/section:implementation Implementation] 491 492[endsect] [/section:roots_noderiv Root Finding Without Derivatives] 493 494[/ 495 Copyright 2006, 2010, 2015 John Maddock and Paul A. Bristow. 496 Distributed under the Boost Software License, Version 1.0. 497 (See accompanying file LICENSE_1_0.txt or copy at 498 http://www.boost.org/LICENSE_1_0.txt). 499] 500