mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-26 02:20:20 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			178 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| [section:cf Continued Fraction Evaluation]
 | |
| 
 | |
| [h4 Synopsis]
 | |
| 
 | |
| ``
 | |
| #include <boost/math/tools/fraction.hpp>
 | |
| ``
 | |
| 
 | |
|    namespace boost{ namespace math{ namespace tools{
 | |
|    
 | |
|    template <class Gen, class U>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_b(Gen& g, const U& tolerance, boost::uintmax_t& max_terms)
 | |
| 
 | |
|    template <class Gen, class U>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_b(Gen& g, const U& tolerance)
 | |
| 
 | |
|    template <class Gen, class U>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_a(Gen& g, const U& tolerance, boost::uintmax_t& max_terms)
 | |
| 
 | |
|    template <class Gen, class U>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_a(Gen& g, const U& tolerance)
 | |
| 
 | |
|    //
 | |
|    // These interfaces are present for legacy reasons, and are now deprecated:
 | |
|    //
 | |
|    template <class Gen>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_b(Gen& g, int bits);
 | |
| 
 | |
|    template <class Gen>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_b(Gen& g, int bits, boost::uintmax_t& max_terms);
 | |
| 
 | |
|    template <class Gen>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_a(Gen& g, int bits);
 | |
|       
 | |
|    template <class Gen>
 | |
|    typename detail::fraction_traits<Gen>::result_type 
 | |
|       continued_fraction_a(Gen& g, int bits, boost::uintmax_t& max_terms);
 | |
|       
 | |
|    }}} // namespaces
 | |
| 
 | |
| [h4 Description]
 | |
| 
 | |
| [@http://en.wikipedia.org/wiki/Continued_fraction Continued fractions are a common method of approximation. ]
 | |
| These functions all evaluate the continued fraction described by the /generator/
 | |
| type argument.  The functions with an "_a" suffix evaluate the fraction:
 | |
| 
 | |
| [equation fraction2]
 | |
| 
 | |
| and those with a "_b" suffix evaluate the fraction:
 | |
| 
 | |
| [equation fraction1]
 | |
| 
 | |
| This latter form is somewhat more natural in that it corresponds with the usual
 | |
| definition of a continued fraction, but note that the first /a/ value returned by
 | |
| the generator is discarded.  Further, often the first /a/ and /b/ values in a 
 | |
| continued fraction have different defining equations to the remaining terms, which
 | |
| may make the "_a" suffixed form more appropriate.
 | |
| 
 | |
| The generator type should be a function object which supports the following
 | |
| operations:
 | |
| 
 | |
| [table
 | |
| [[Expression] [Description]]
 | |
| [[Gen::result_type] [The type that is the result of invoking operator().
 | |
|   This can be either an arithmetic type, or a std::pair<> of arithmetic types.]]
 | |
| [[g()] [Returns an object of type Gen::result_type.
 | |
| 
 | |
| Each time this operator is called then the next pair of /a/ and /b/
 | |
|     values is returned.  Or, if result_type is an arithmetic type,
 | |
|     then the next /b/ value is returned and all the /a/ values
 | |
|     are assumed to 1.]]
 | |
| ]
 | |
| 
 | |
| In all the continued fraction evaluation functions the /tolerance/ parameter is the
 | |
| precision desired in the result, evaluation of the fraction will
 | |
| continue until the last term evaluated leaves the relative error in the result
 | |
| less than /tolerance/.  The deprecated interfaces take a number of digits precision
 | |
| here, internally they just convert this to a tolerance and forward call.
 | |
| 
 | |
| If the optional /max_terms/ parameter is specified then no more than /max_terms/ 
 | |
| calls to the generator will be made, and on output, 
 | |
| /max_terms/ will be set to actual number of
 | |
| calls made.  This facility is particularly useful when profiling a continued
 | |
| fraction for convergence.
 | |
| 
 | |
| [h4 Implementation]
 | |
| 
 | |
| Internally these algorithms all use the modified Lentz algorithm: refer to
 | |
| Numeric Recipes in C++, W. H. Press et all, chapter 5,
 | |
| (especially 5.2 Evaluation of continued fractions, p 175 - 179)
 | |
| for more information, also
 | |
| Lentz, W.J. 1976, Applied Optics, vol. 15, pp. 668-671.
 | |
| 
 | |
| [h4 Examples]
 | |
| 
 | |
| The [@http://en.wikipedia.org/wiki/Golden_ratio golden ratio phi = 1.618033989...]
 | |
| can be computed from the simplest continued fraction of all:
 | |
| 
 | |
| [equation fraction3]
 | |
| 
 | |
| We begin by defining a generator function:
 | |
| 
 | |
|    template <class T>
 | |
|    struct golden_ratio_fraction
 | |
|    {
 | |
|       typedef T result_type;
 | |
|       
 | |
|       result_type operator()
 | |
|       {
 | |
|          return 1;
 | |
|       }
 | |
|    };
 | |
| 
 | |
| The golden ratio can then be computed to double precision using:
 | |
| 
 | |
|    continued_fraction_a(
 | |
|       golden_ratio_fraction<double>(),
 | |
|       std::numeric_limits<double>::epsilon());
 | |
| 
 | |
| It's more usual though to have to define both the /a/'s and the /b/'s
 | |
| when evaluating special functions by continued fractions, for example
 | |
| the tan function is defined by:
 | |
| 
 | |
| [equation fraction4]
 | |
| 
 | |
| So its generator object would look like:
 | |
| 
 | |
|    template <class T>
 | |
|    struct tan_fraction
 | |
|    {
 | |
|    private:
 | |
|       T a, b;
 | |
|    public:
 | |
|       tan_fraction(T v)
 | |
|          : a(-v*v), b(-1)
 | |
|       {}
 | |
| 
 | |
|       typedef std::pair<T,T> result_type;
 | |
| 
 | |
|       std::pair<T,T> operator()()
 | |
|       {
 | |
|          b += 2;
 | |
|          return std::make_pair(a, b);
 | |
|       }
 | |
|    };
 | |
| 
 | |
| Notice that if the continuant is subtracted from the /b/ terms,
 | |
| as is the case here, then all the /a/ terms returned by the generator
 | |
| will be negative.  The tangent function can now be evaluated using:
 | |
| 
 | |
|    template <class T>
 | |
|    T tan(T a)
 | |
|    {
 | |
|       tan_fraction<T> fract(a);
 | |
|       return a / continued_fraction_b(fract, std::numeric_limits<T>::epsilon());
 | |
|    }
 | |
| 
 | |
| Notice that this time we're using the "_b" suffixed version to evaluate
 | |
| the fraction: we're removing the leading /a/ term during fraction evaluation
 | |
| as it's different from all the others.
 | |
| 
 | |
| [endsect][/section:cf Continued Fraction Evaluation]
 | |
| 
 | |
| [/ 
 | |
|   Copyright 2006 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).
 | |
| ]
 | |
| 
 |