#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);
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);
}}}
Эти алгоритмы предназначены для сумации бесконечной серии.
Каждый из алгоритмов принимает объект нулевой функции в качестве первого аргумента: объект функции будет неоднократно ссылаться, чтобы вытащить последовательные термины из серии суммируемых.
Второй аргумент - требуемая точность, суммирование остановится, когда следующий термин меньше терпимость умножит результат. Ухудшенные версии sum_series принимают огромное количество битов здесь - внутри они просто конвертируют это в толерантность и передают вызов.
Третий аргумент max_terms устанавливает верхний предел количества терминов серии для оценки. Кроме того, при выходе функция установит max_terms до фактического количества терминов серии, которые были оценены: это особенно полезно для профилирования свойств конвергенции новой серии.
Окончательный необязательный аргумент init_value является первоначальным значением суммы, к которой должны быть добавлены условия серии. Это полезно в двух ситуациях:
- Там, где первое значение серии имеет другую формулу к последовательным терминам. В этом случае первое значение в серии может быть передано как последний аргумент, и логика объекта функции может затем быть упрощена, чтобы вернуть последующие термины.
- Когда сериал добавляется (или вычитается) из какого-либо другого значения: прекращение серии, вероятно, произойдет гораздо быстрее, если это другое значение будет передано в качестве последнего аргумента. Например, существует несколько функций, которые могут быть выражены как 1 - S(z), где S(z) является бесконечной серией. В этом случае проход -1 как последний аргумент, а затем отменяет результат суммирования, чтобы получить результат 1 - S(z).
Два варианта kahan_sum_series этих алгоритмов поддерживают переносной термин, который исправляет затухшую ошибку во время суммирования. Они вдохновлены формулой Kahan Summation, которая появляется в Что каждый компьютерный ученый должен знать об арифметике Floating-Point. Однако следует отметить, что существует очень мало серий, которые требуют суммирования таким образом.
Предположим, мы хотим реализовать log(1+x) через его бесконечные серии,

Мы начинаем с написания небольшого функционального объекта, чтобы вернуть последовательные условия серии:
template <class T>
struct log1p_series
{
typedef T result_type;
log1p_series(T x)
: k(0), m_mult(-x), m_prod(-1){}
T operator()()
{
m_prod *= m_mult;
return m_prod / ++k;
}
private:
int k;
const T m_mult;
T m_prod;
};
Внедрение log(1+x) теперь довольно тривиально:
template <class T>
T log1p(T x)
{
assert(std::fabs(x) < 1);
log1p_series<T> s(x);
boost::uintmax_t max_iter = 1000;
return tools::sum_series(s, std::numeric_limits<T>::epsilon(), max_iter);
}