mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-18 10:01:57 -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).
|
||
|
]
|