File indexing completed on 2025-01-18 09:40:42
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MATH_TOOLS_SERIES_INCLUDED
0007 #define BOOST_MATH_TOOLS_SERIES_INCLUDED
0008
0009 #ifdef _MSC_VER
0010 #pragma once
0011 #endif
0012
0013 #include <cmath>
0014 #include <cstdint>
0015 #include <limits>
0016 #include <boost/math/tools/config.hpp>
0017
0018 namespace boost{ namespace math{ namespace tools{
0019
0020
0021
0022
0023 template <class Functor, class U, class V>
0024 inline typename Functor::result_type sum_series(Functor& func, const U& factor, std::uintmax_t& max_terms, const V& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0025 {
0026 BOOST_MATH_STD_USING
0027
0028 typedef typename Functor::result_type result_type;
0029
0030 std::uintmax_t counter = max_terms;
0031
0032 result_type result = init_value;
0033 result_type next_term;
0034 do{
0035 next_term = func();
0036 result += next_term;
0037 }
0038 while((abs(factor * result) < abs(next_term)) && --counter);
0039
0040
0041 max_terms = max_terms - counter;
0042
0043 return result;
0044 }
0045
0046 template <class Functor, class U>
0047 inline typename Functor::result_type sum_series(Functor& func, const U& factor, std::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0048 {
0049 typename Functor::result_type init_value = 0;
0050 return sum_series(func, factor, max_terms, init_value);
0051 }
0052
0053 template <class Functor, class U>
0054 inline typename Functor::result_type sum_series(Functor& func, int bits, std::uintmax_t& max_terms, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0055 {
0056 BOOST_MATH_STD_USING
0057 typedef typename Functor::result_type result_type;
0058 result_type factor = ldexp(result_type(1), 1 - bits);
0059 return sum_series(func, factor, max_terms, init_value);
0060 }
0061
0062 template <class Functor>
0063 inline typename Functor::result_type sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0064 {
0065 BOOST_MATH_STD_USING
0066 typedef typename Functor::result_type result_type;
0067 std::uintmax_t iters = (std::numeric_limits<std::uintmax_t>::max)();
0068 result_type init_val = 0;
0069 return sum_series(func, bits, iters, init_val);
0070 }
0071
0072 template <class Functor>
0073 inline typename Functor::result_type sum_series(Functor& func, int bits, std::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0074 {
0075 BOOST_MATH_STD_USING
0076 typedef typename Functor::result_type result_type;
0077 result_type init_val = 0;
0078 return sum_series(func, bits, max_terms, init_val);
0079 }
0080
0081 template <class Functor, class U>
0082 inline typename Functor::result_type sum_series(Functor& func, int bits, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0083 {
0084 BOOST_MATH_STD_USING
0085 std::uintmax_t iters = (std::numeric_limits<std::uintmax_t>::max)();
0086 return sum_series(func, bits, iters, init_value);
0087 }
0088
0089
0090
0091 template <class Functor, class U, class V>
0092 inline typename Functor::result_type checked_sum_series(Functor& func, const U& factor, std::uintmax_t& max_terms, const V& init_value, V& norm) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0093 {
0094 BOOST_MATH_STD_USING
0095
0096 typedef typename Functor::result_type result_type;
0097
0098 std::uintmax_t counter = max_terms;
0099
0100 result_type result = init_value;
0101 result_type next_term;
0102 do {
0103 next_term = func();
0104 result += next_term;
0105 norm += fabs(next_term);
0106 } while ((abs(factor * result) < abs(next_term)) && --counter);
0107
0108
0109 max_terms = max_terms - counter;
0110
0111 return result;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 template <class Functor>
0128 inline typename Functor::result_type kahan_sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0129 {
0130 BOOST_MATH_STD_USING
0131
0132 typedef typename Functor::result_type result_type;
0133
0134 result_type factor = pow(result_type(2), result_type(bits));
0135 result_type result = func();
0136 result_type next_term, y, t;
0137 result_type carry = 0;
0138 do{
0139 next_term = func();
0140 y = next_term - carry;
0141 t = result + y;
0142 carry = t - result;
0143 carry -= y;
0144 result = t;
0145 }
0146 while(fabs(result) < fabs(factor * next_term));
0147 return result;
0148 }
0149
0150 template <class Functor>
0151 inline typename Functor::result_type kahan_sum_series(Functor& func, int bits, std::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
0152 {
0153 BOOST_MATH_STD_USING
0154
0155 typedef typename Functor::result_type result_type;
0156
0157 std::uintmax_t counter = max_terms;
0158
0159 result_type factor = ldexp(result_type(1), bits);
0160 result_type result = func();
0161 result_type next_term, y, t;
0162 result_type carry = 0;
0163 do{
0164 next_term = func();
0165 y = next_term - carry;
0166 t = result + y;
0167 carry = t - result;
0168 carry -= y;
0169 result = t;
0170 }
0171 while((fabs(result) < fabs(factor * next_term)) && --counter);
0172
0173
0174 max_terms = max_terms - counter;
0175
0176 return result;
0177 }
0178
0179 }
0180 }
0181 }
0182
0183 #endif
0184