mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 21:40:52 -05:00 
			
		
		
		
	
		
			
	
	
		
			142 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			142 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								[section:series_evaluation Series Evaluation]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h4 Synopsis]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								``
							 | 
						||
| 
								 | 
							
								#include <boost/math/tools/series.hpp>
							 | 
						||
| 
								 | 
							
								``
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   namespace boost{ namespace math{ namespace tools{
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   template <class Functor, class U, class V>
							 | 
						||
| 
								 | 
							
								   inline typename Functor::result_type sum_series(Functor& func, const U& tolerance, boost::uintmax_t& max_terms, const V& init_value);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   template <class Functor, class U, class V>
							 | 
						||
| 
								 | 
							
								   inline typename Functor::result_type sum_series(Functor& func, const U& tolerance, boost::uintmax_t& max_terms);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //
							 | 
						||
| 
								 | 
							
								   // The following interfaces are now deprecated:
							 | 
						||
| 
								 | 
							
								   //   
							 | 
						||
| 
								 | 
							
								   template <class Functor>
							 | 
						||
| 
								 | 
							
								   typename Functor::result_type sum_series(Functor& func, int bits);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   template <class Functor>
							 | 
						||
| 
								 | 
							
								   typename Functor::result_type sum_series(Functor& func, int bits, boost::uintmax_t& max_terms);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   template <class Functor, class U>
							 | 
						||
| 
								 | 
							
								   typename Functor::result_type sum_series(Functor& func, int bits, U init_value);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   template <class Functor, class U>
							 | 
						||
| 
								 | 
							
								   typename Functor::result_type sum_series(Functor& func, int bits, boost::uintmax_t& max_terms, U init_value);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   template <class Functor>
							 | 
						||
| 
								 | 
							
								   typename Functor::result_type kahan_sum_series(Functor& func, int bits);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   template <class Functor>
							 | 
						||
| 
								 | 
							
								   typename Functor::result_type kahan_sum_series(Functor& func, int bits, boost::uintmax_t& max_terms);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   }}} // namespaces
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h4 Description]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These algorithms are intended for the
							 | 
						||
| 
								 | 
							
								[@http://en.wikipedia.org/wiki/Series_%28mathematics%29 summation of infinite series].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Each of the algorithms takes a nullary-function object as the first argument:
							 | 
						||
| 
								 | 
							
								the function object will be repeatedly invoked to pull successive terms from
							 | 
						||
| 
								 | 
							
								the series being summed.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The second argument is the precision required, 
							 | 
						||
| 
								 | 
							
								summation will stop when the next term is less than
							 | 
						||
| 
								 | 
							
								/tolerance/ times the result.  The deprecated versions of sum_series
							 | 
						||
| 
								 | 
							
								take an integer number of bits here - internally they just convert this to
							 | 
						||
| 
								 | 
							
								a tolerance and forward the call.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The third argument /max_terms/ sets an upper limit on the number
							 | 
						||
| 
								 | 
							
								of terms of the series to evaluate. In addition, on exit the function will
							 | 
						||
| 
								 | 
							
								set /max_terms/ to the actual number of terms of the series that were 
							 | 
						||
| 
								 | 
							
								evaluated: this is particularly useful for profiling the convergence
							 | 
						||
| 
								 | 
							
								properties of a new series.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The final optional argument /init_value/ is the initial value of the sum
							 | 
						||
| 
								 | 
							
								to which the terms of the series should be added.  This is useful in two situations:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* Where the first value of the series has a different formula to successive
							 | 
						||
| 
								 | 
							
								terms.  In this case the first value in the series can be passed as the
							 | 
						||
| 
								 | 
							
								last argument and the logic of the function object can then be simplified 
							 | 
						||
| 
								 | 
							
								to return subsequent terms.
							 | 
						||
| 
								 | 
							
								* Where the series is being added (or subtracted) from some other value:
							 | 
						||
| 
								 | 
							
								termination of the series will likely occur much more rapidly if that other 
							 | 
						||
| 
								 | 
							
								value is passed as the last argument.  For example, there are several functions
							 | 
						||
| 
								 | 
							
								that can be expressed as /1 - S(z)/ where S(z) is an infinite series.  In this
							 | 
						||
| 
								 | 
							
								case, pass -1 as the last argument and then negate the result of the summation
							 | 
						||
| 
								 | 
							
								to get the result of /1 - S(z)/.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The two /kahan_sum_series/ variants of these algorithms maintain a carry term
							 | 
						||
| 
								 | 
							
								that corrects for roundoff error during summation.  
							 | 
						||
| 
								 | 
							
								They are inspired by the
							 | 
						||
| 
								 | 
							
								[@http://en.wikipedia.org/wiki/Kahan_Summation_Algorithm /Kahan Summation Formula/]
							 | 
						||
| 
								 | 
							
								that appears in
							 | 
						||
| 
								 | 
							
								[@http://docs.sun.com/source/806-3568/ncg_goldberg.html What Every Computer Scientist Should Know About Floating-Point Arithmetic].
							 | 
						||
| 
								 | 
							
								However, it should be pointed out that there are very few series that require
							 | 
						||
| 
								 | 
							
								summation in this way.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[h4 Example]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Let's suppose we want to implement /log(1+x)/ via its infinite series,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[equation log1pseries]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								We begin by writing a small function object to return successive terms
							 | 
						||
| 
								 | 
							
								of the series:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class T>
							 | 
						||
| 
								 | 
							
								   struct log1p_series
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      // we must define a result_type typedef:
							 | 
						||
| 
								 | 
							
								      typedef T result_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      log1p_series(T x)
							 | 
						||
| 
								 | 
							
								         : k(0), m_mult(-x), m_prod(-1){}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      T operator()()
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         // This is the function operator invoked by the summation
							 | 
						||
| 
								 | 
							
								         // algorithm, the first call to this operator should return
							 | 
						||
| 
								 | 
							
								         // the first term of the series, the second call the second 
							 | 
						||
| 
								 | 
							
								         // term and so on.
							 | 
						||
| 
								 | 
							
								         m_prod *= m_mult;
							 | 
						||
| 
								 | 
							
								         return m_prod / ++k; 
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   private:
							 | 
						||
| 
								 | 
							
								      int k;
							 | 
						||
| 
								 | 
							
								      const T m_mult;
							 | 
						||
| 
								 | 
							
								      T m_prod;
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Implementing log(1+x) is now fairly trivial:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class T>
							 | 
						||
| 
								 | 
							
								   T log1p(T x)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      // We really should add some error checking on x here!
							 | 
						||
| 
								 | 
							
								      assert(std::fabs(x) < 1);
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      // Construct the series functor:
							 | 
						||
| 
								 | 
							
								      log1p_series<T> s(x);
							 | 
						||
| 
								 | 
							
								      // Set a limit on how many iterations we permit:
							 | 
						||
| 
								 | 
							
								      boost::uintmax_t max_iter = 1000;
							 | 
						||
| 
								 | 
							
								      // Add it up, with enough precision for full machine precision:
							 | 
						||
| 
								 | 
							
								      return tools::sum_series(s, std::numeric_limits<T>::epsilon(), max_iter);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[endsect][/section Series 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).
							 | 
						||
| 
								 | 
							
								]
							 |