mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 21:40:52 -05:00 
			
		
		
		
	
		
			
	
	
		
			499 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			499 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								[section:roots_noderiv Root Finding Without Derivatives]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h4 Synopsis]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								``
							 | 
						||
| 
								 | 
							
								#include <boost/math/tools/roots.hpp>
							 | 
						||
| 
								 | 
							
								``
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   namespace boost { namespace math {
							 | 
						||
| 
								 | 
							
								   namespace tools { // Note namespace boost::math::tools.
							 | 
						||
| 
								 | 
							
								   // Bisection
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      bisect(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         T min,
							 | 
						||
| 
								 | 
							
								         T max,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      bisect(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         T min,
							 | 
						||
| 
								 | 
							
								         T max,
							 | 
						||
| 
								 | 
							
								         Tol tol);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      bisect(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         T min,
							 | 
						||
| 
								 | 
							
								         T max,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Bracket and Solve Root
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   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,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// TOMS 748 algorithm
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         const T& fa,
							 | 
						||
| 
								 | 
							
								         const T& fb,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         const T& fa,
							 | 
						||
| 
								 | 
							
								         const T& fb,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   // Termination conditions:
							 | 
						||
| 
								 | 
							
								   template <class T>
							 | 
						||
| 
								 | 
							
								   struct eps_tolerance;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   struct equal_floor;
							 | 
						||
| 
								 | 
							
								   struct equal_ceil;
							 | 
						||
| 
								 | 
							
								   struct equal_nearest_integer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   }}} // boost::math::tools namespaces
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h4 Description]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These functions solve the root of some function ['f(x)] -
							 | 
						||
| 
								 | 
							
								['without the need for any derivatives of ['f(x)]].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The `bracket_and_solve_root` functions use __root_finding_TOMS748
							 | 
						||
| 
								 | 
							
								by Alefeld, Potra and Shi that is asymptotically the most efficient known,
							 | 
						||
| 
								 | 
							
								and has been shown to be optimal for a certain classes of smooth functions.
							 | 
						||
| 
								 | 
							
								Variants with and without __policy_section are provided.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Alternatively, __bisect is a simple __bisection_wikipedia routine which can be useful
							 | 
						||
| 
								 | 
							
								in its own right in some situations, or alternatively for narrowing
							 | 
						||
| 
								 | 
							
								down the range containing the root, prior to calling a more advanced
							 | 
						||
| 
								 | 
							
								algorithm.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								All the algorithms in this section reduce the diameter of the enclosing
							 | 
						||
| 
								 | 
							
								interval with the same asymptotic efficiency with which they locate the
							 | 
						||
| 
								 | 
							
								root.  This is in contrast to the derivative based methods which may ['never]
							 | 
						||
| 
								 | 
							
								significantly reduce the enclosing interval, even though they rapidly approach
							 | 
						||
| 
								 | 
							
								the root.  This is also in contrast to some other derivative-free methods
							 | 
						||
| 
								 | 
							
								(for example, Brent's method described at
							 | 
						||
| 
								 | 
							
								[@http://en.wikipedia.org/wiki/Brent%27s_method Brent-Dekker)]
							 | 
						||
| 
								 | 
							
								which only reduces the enclosing interval on the final step.
							 | 
						||
| 
								 | 
							
								Therefore these methods return a `std::pair` containing the enclosing interval found,
							 | 
						||
| 
								 | 
							
								and accept a function object specifying the termination condition.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Three function objects are provided for ready-made termination conditions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* ['eps_tolerance] causes termination when the relative error in the enclosing
							 | 
						||
| 
								 | 
							
								interval is below a certain threshold.
							 | 
						||
| 
								 | 
							
								* ['equal_floor] and ['equal_ceil] are useful for certain statistical applications
							 | 
						||
| 
								 | 
							
								where the result is known to be an integer.
							 | 
						||
| 
								 | 
							
								* Other user-defined termination conditions are likely to be used
							 | 
						||
| 
								 | 
							
								only rarely, but may be useful in some specific circumstances.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:bisect Bisection]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      bisect(  // Unlimited iterations.
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         T min,
							 | 
						||
| 
								 | 
							
								         T max,
							 | 
						||
| 
								 | 
							
								         Tol tol);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      bisect(  // Limited iterations.
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         T min,
							 | 
						||
| 
								 | 
							
								         T max,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      bisect( // Specified policy.
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         T min,
							 | 
						||
| 
								 | 
							
								         T max,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These functions locate the root using __bisection_wikipedia.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`bisect` function arguments are:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[variablelist
							 | 
						||
| 
								 | 
							
								[[f]  [A unary functor which is the function ['f(x)] whose root is to be found.]]
							 | 
						||
| 
								 | 
							
								[[min] [The left bracket of the interval known to contain the root.]]
							 | 
						||
| 
								 | 
							
								[[max] [The right bracket of the interval known to contain the root.[br]
							 | 
						||
| 
								 | 
							
								        It is a precondition that ['min < max] and ['f(min)*f(max) <= 0],
							 | 
						||
| 
								 | 
							
								        the function raises an __evaluation_error if these preconditions are violated.
							 | 
						||
| 
								 | 
							
								        The action taken on error is controlled by the __Policy template argument: the default behavior is to
							 | 
						||
| 
								 | 
							
								        throw a ['boost::math::evaluation_error].  If the __Policy is changed to not throw
							 | 
						||
| 
								 | 
							
								        then it returns ['std::pair<T>(min, min)].]]
							 | 
						||
| 
								 | 
							
								[[tol]  [A binary functor that specifies the termination condition: the function
							 | 
						||
| 
								 | 
							
								        will return the current brackets enclosing the root when ['tol(min, max)] becomes true.
							 | 
						||
| 
								 | 
							
								        See also __root_termination.]]
							 | 
						||
| 
								 | 
							
								[[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.]]
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[optional_policy]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[*Returns]: a pair of values ['r] that bracket the root so that:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   f(r.first) * f(r.second) <= 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								and either
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   tol(r.first, r.second) == true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								or
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   max_iter >= m
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								where ['m] is the initial value of ['max_iter] passed to the function.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In other words, it's up to the caller to verify whether termination occurred
							 | 
						||
| 
								 | 
							
								as a result of exceeding ['max_iter] function invocations (easily done by
							 | 
						||
| 
								 | 
							
								checking the updated value of ['max_iter] when the function returns), rather than
							 | 
						||
| 
								 | 
							
								because the termination condition ['tol] was satisfied.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:bracket_solve Bracket and Solve Root]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   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,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`bracket_and_solve_root` is a convenience function that calls __root_finding_TOMS748 internally
							 | 
						||
| 
								 | 
							
								to find the root of ['f(x)].  It is generally much easier to use this function rather than __root_finding_TOMS748, since it
							 | 
						||
| 
								 | 
							
								does the hard work of bracketing the root for you.  It's bracketing routines are quite robust and will
							 | 
						||
| 
								 | 
							
								usually be more foolproof than home-grown routines, unless the function can be analysed to yield tight
							 | 
						||
| 
								 | 
							
								brackets.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note that this routine can only be used when:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* ['f(x)] is monotonic in the half of the real axis containing ['guess].
							 | 
						||
| 
								 | 
							
								* The value of the inital guess must have the same sign as the root: the function
							 | 
						||
| 
								 | 
							
								will ['never cross the origin] when searching for the root.
							 | 
						||
| 
								 | 
							
								* The location of the root should be known at least approximately,
							 | 
						||
| 
								 | 
							
								if the location of the root differs by many orders of magnitude
							 | 
						||
| 
								 | 
							
								from ['guess] then many iterations will be needed to bracket the root in spite of
							 | 
						||
| 
								 | 
							
								the special heuristics used to guard against this very situation.  A typical example would be
							 | 
						||
| 
								 | 
							
								setting the initial guess to 0.1, when the root is at 1e-300.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The `bracket_and_solve_root` parameters are:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[variablelist
							 | 
						||
| 
								 | 
							
								[[f][A unary functor that is the function whose root is to be solved.
							 | 
						||
| 
								 | 
							
								    ['f(x)] must be uniformly increasing or decreasing on ['x].]]
							 | 
						||
| 
								 | 
							
								[[guess][An initial approximation to the root.]]
							 | 
						||
| 
								 | 
							
								[[factor][A scaling factor that is used to bracket the root: the value
							 | 
						||
| 
								 | 
							
								         /guess/ is multiplied (or divided as appropriate) by /factor/
							 | 
						||
| 
								 | 
							
								         until two values are found that bracket the root.  A value
							 | 
						||
| 
								 | 
							
								         such as 2 is a typical choice for ['factor].
							 | 
						||
| 
								 | 
							
								         In addition ['factor] will be multiplied by 2 every 32 iterations:
							 | 
						||
| 
								 | 
							
								         this is to guard against a really very bad initial guess, typically these occur
							 | 
						||
| 
								 | 
							
								         when it's known the result is very large or small, but not the exact order
							 | 
						||
| 
								 | 
							
								         of magnitude.]]
							 | 
						||
| 
								 | 
							
								[[rising][Set to ['true] if ['f(x)] is rising on /x/ and /false/ if ['f(x)]
							 | 
						||
| 
								 | 
							
								         is falling on /x/.  This value is used along with the result
							 | 
						||
| 
								 | 
							
								         of /f(guess)/ to determine if /guess/ is
							 | 
						||
| 
								 | 
							
								         above or below the root.]]
							 | 
						||
| 
								 | 
							
								[[tol]   [A binary functor that determines the termination condition for the search
							 | 
						||
| 
								 | 
							
								         for the root.  /tol/ is passed the current brackets at each step,
							 | 
						||
| 
								 | 
							
								         when it returns true then the current brackets are returned as the pair result.
							 | 
						||
| 
								 | 
							
								         See also __root_termination.]]
							 | 
						||
| 
								 | 
							
								[[max_iter] [The maximum number of function invocations to perform in the search
							 | 
						||
| 
								 | 
							
								            for the root.  On exit is set to the actual number of invocations performed.]]
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[optional_policy]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[*Returns]: a pair of values ['r] that bracket the root so that:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   f(r.first) * f(r.second) <= 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								and either
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   tol(r.first, r.second) == true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								or
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   max_iter >= m
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								where ['m] is the initial value of ['max_iter] passed to the function.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In other words, it's up to the caller to verify whether termination occurred
							 | 
						||
| 
								 | 
							
								as a result of exceeding ['max_iter] function invocations (easily done by
							 | 
						||
| 
								 | 
							
								checking the value of ['max_iter]  when the function returns), rather than
							 | 
						||
| 
								 | 
							
								because the termination condition ['tol] was satisfied.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:TOMS748 Algorithm TOMS 748: Alefeld, Potra and Shi: Enclosing zeros of continuous functions]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         const T& fa,
							 | 
						||
| 
								 | 
							
								         const T& fb,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class F, class T, class Tol, class ``__Policy``>
							 | 
						||
| 
								 | 
							
								   std::pair<T, T>
							 | 
						||
| 
								 | 
							
								      toms748_solve(
							 | 
						||
| 
								 | 
							
								         F f,
							 | 
						||
| 
								 | 
							
								         const T& a,
							 | 
						||
| 
								 | 
							
								         const T& b,
							 | 
						||
| 
								 | 
							
								         const T& fa,
							 | 
						||
| 
								 | 
							
								         const T& fb,
							 | 
						||
| 
								 | 
							
								         Tol tol,
							 | 
						||
| 
								 | 
							
								         boost::uintmax_t& max_iter,
							 | 
						||
| 
								 | 
							
								         const ``__Policy``&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These functions implement TOMS Algorithm 748: it uses a mixture of
							 | 
						||
| 
								 | 
							
								cubic, quadratic and linear (secant) interpolation to locate the root of
							 | 
						||
| 
								 | 
							
								['f(x)].  The two pairs of functions differ only by whether values for ['f(a)] and
							 | 
						||
| 
								 | 
							
								['f(b)] are already available.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Generally speaking it is easier (and often more efficient) to use __bracket_solve
							 | 
						||
| 
								 | 
							
								rather than trying to bracket the root yourself as this function requires.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This function is provided rather than [@http://en.wikipedia.org/wiki/Brent%27s_method Brent's method] as it is known to be more
							 | 
						||
| 
								 | 
							
								effient in many cases (it is asymptotically the most efficient known,
							 | 
						||
| 
								 | 
							
								and has been shown to be optimal for a certain classes of smooth functions).
							 | 
						||
| 
								 | 
							
								It also has the useful property of decreasing the bracket size
							 | 
						||
| 
								 | 
							
								with each step, unlike Brent's method which only shrinks the enclosing interval in the
							 | 
						||
| 
								 | 
							
								final step.  This makes it particularly useful when you need a result where the ends
							 | 
						||
| 
								 | 
							
								of the interval round to the same integer: as often happens in statistical applications
							 | 
						||
| 
								 | 
							
								for example.  In this situation the function is able to exit after a much smaller
							 | 
						||
| 
								 | 
							
								number of iterations than would otherwise be possible.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The __root_finding_TOMS748 parameters are:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[variablelist
							 | 
						||
| 
								 | 
							
								[[f]   [A unary functor that is the function whose root is to be solved.
							 | 
						||
| 
								 | 
							
								       f(x) need not be uniformly increasing or decreasing on ['x] and
							 | 
						||
| 
								 | 
							
								       may have multiple roots.  However, the bounds given must bracket a single root.]]
							 | 
						||
| 
								 | 
							
								[[a]   [The lower bound for the initial bracket of the root.]]
							 | 
						||
| 
								 | 
							
								[[b]   [The upper bound for the initial bracket of the root.
							 | 
						||
| 
								 | 
							
								       It is a precondition that ['a < b] and that ['a] and ['b]
							 | 
						||
| 
								 | 
							
								       bracket the root to find so that ['f(a) * f(b) < 0].]]
							 | 
						||
| 
								 | 
							
								[[fa]  [Optional: the value of ['f(a)].]]
							 | 
						||
| 
								 | 
							
								[[fb]  [Optional: the value of ['f(b)].]]
							 | 
						||
| 
								 | 
							
								[[tol] [A binary functor that determines the termination condition for the search
							 | 
						||
| 
								 | 
							
								        for the root.  ['tol] is passed the current brackets at each step,
							 | 
						||
| 
								 | 
							
								        when it returns true, then the current brackets are returned as the result.
							 | 
						||
| 
								 | 
							
								        See also __root_termination.]]
							 | 
						||
| 
								 | 
							
								[[max_iter] [The maximum number of function invocations to perform in the search
							 | 
						||
| 
								 | 
							
								            for the root.  On exit, ['max_iter] is set to actual number of function
							 | 
						||
| 
								 | 
							
								            invocations used.]]
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[optional_policy]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`toms748_solve` returns: a pair of values ['r] that bracket the root so that:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   f(r.first) * f(r.second) <= 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								and either
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   tol(r.first, r.second) == true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								or
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   max_iter >= m
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								where ['m] is the initial value of ['max_iter] passed to the function.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In other words, it's up to the caller to verify whether termination occurred
							 | 
						||
| 
								 | 
							
								as a result of exceeding ['max_iter]  function invocations (easily done by
							 | 
						||
| 
								 | 
							
								checking the updated value of ['max_iter]
							 | 
						||
| 
								 | 
							
								against its previous value passed as parameter),
							 | 
						||
| 
								 | 
							
								rather than because the termination condition ['tol] was satisfied.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:brent Brent-Decker Algorithm]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The [@http://en.wikipedia.org/wiki/Brent%27s_method Brent-Dekker algorithm], although very well know,
							 | 
						||
| 
								 | 
							
								is not provided by this library as __root_finding_TOMS748 or
							 | 
						||
| 
								 | 
							
								its slightly easier to use variant __bracket_solve are superior and provide equivalent functionality.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:root_termination Termination Condition Functors]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class T>
							 | 
						||
| 
								 | 
							
								   struct eps_tolerance
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      eps_tolerance();
							 | 
						||
| 
								 | 
							
								      eps_tolerance(int bits);
							 | 
						||
| 
								 | 
							
								      bool operator()(const T& a, const T& b)const;
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`eps_tolerance` is the usual termination condition used with these root finding functions.
							 | 
						||
| 
								 | 
							
								Its `operator()` will return true when the relative distance between ['a] and ['b]
							 | 
						||
| 
								 | 
							
								is less than four times the machine epsilon for T, or 2[super 1-bits], whichever is
							 | 
						||
| 
								 | 
							
								the larger.  In other words, you set ['bits] to the number of bits of precision you
							 | 
						||
| 
								 | 
							
								want in the result.  The minimal tolerance of ['four times the machine epsilon of type T] is
							 | 
						||
| 
								 | 
							
								required to ensure that we get back a bracketing interval, since this must clearly
							 | 
						||
| 
								 | 
							
								be at greater than one epsilon in size.  While in theory a maximum distance of twice
							 | 
						||
| 
								 | 
							
								machine epsilon is possible to achieve, in practice this results in a great deal of "thrashing"
							 | 
						||
| 
								 | 
							
								given that the function whose root is being found can only ever be accurate to 1 epsilon at best.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   struct equal_floor
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      equal_floor();
							 | 
						||
| 
								 | 
							
								      template <class T> bool operator()(const T& a, const T& b)const;
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This termination condition is used when you want to find an integer result
							 | 
						||
| 
								 | 
							
								that is the ['floor] of the true root.  It will terminate as soon as both ends
							 | 
						||
| 
								 | 
							
								of the interval have the same ['floor].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   struct equal_ceil
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      equal_ceil();
							 | 
						||
| 
								 | 
							
								      template <class T> bool operator()(const T& a, const T& b)const;
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This termination condition is used when you want to find an integer result
							 | 
						||
| 
								 | 
							
								that is the ['ceil] of the true root.  It will terminate as soon as both ends
							 | 
						||
| 
								 | 
							
								of the interval have the same ['ceil].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   struct equal_nearest_integer
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      equal_nearest_integer();
							 | 
						||
| 
								 | 
							
								      template <class T> bool operator()(const T& a, const T& b)const;
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This termination condition is used when you want to find an integer result
							 | 
						||
| 
								 | 
							
								that is the /closest/ to the true root.  It will terminate as soon as both ends
							 | 
						||
| 
								 | 
							
								of the interval round to the same nearest integer.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[section:implementation Implementation]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The implementation of the bisection algorithm is extremely straightforward
							 | 
						||
| 
								 | 
							
								and not detailed here.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								__TOMS748 is described in detail in:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								['Algorithm 748: Enclosing Zeros of Continuous Functions,
							 | 
						||
| 
								 | 
							
								G. E. Alefeld, F. A. Potra and Yixun Shi,
							 | 
						||
| 
								 | 
							
								ACM Transactions on Mathematica1 Software, Vol. 21. No. 3. September 1995.
							 | 
						||
| 
								 | 
							
								Pages 327-344.]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The implementation here is a faithful translation of this paper into C++.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect]
							 | 
						||
| 
								 | 
							
								[endsect] [/section:roots_noderiv Root Finding Without Derivatives]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[/
							 | 
						||
| 
								 | 
							
								  Copyright 2006, 2010, 2015 John Maddock and Paul A. Bristow.
							 | 
						||
| 
								 | 
							
								  Distributed under 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).
							 | 
						||
| 
								 | 
							
								]
							 |