mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 12:30:23 -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). | ||
|  | ] | ||
|  | 
 |