File indexing completed on 2025-09-15 08: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
0014 #include <boost/math/tools/config.hpp>
0015 #include <boost/math/tools/numeric_limits.hpp>
0016 #include <boost/math/tools/cstdint.hpp>
0017 #include <boost/math/tools/type_traits.hpp>
0018
0019 namespace boost{ namespace math{ namespace tools{
0020
0021
0022
0023
0024 template <class Functor, class U, class V>
0025 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, const U& factor, boost::math::uintmax_t& max_terms, const V& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0026 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0027 && noexcept(std::declval<Functor>()())
0028 #endif
0029 )
0030 {
0031 BOOST_MATH_STD_USING
0032
0033 typedef typename Functor::result_type result_type;
0034
0035 boost::math::uintmax_t counter = max_terms;
0036
0037 result_type result = init_value;
0038 result_type next_term;
0039 do{
0040 next_term = func();
0041 result += next_term;
0042 }
0043 while((abs(factor * result) < abs(next_term)) && --counter);
0044
0045
0046 max_terms = max_terms - counter;
0047
0048 return result;
0049 }
0050
0051 template <class Functor, class U>
0052 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, const U& factor, boost::math::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0053 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0054 && noexcept(std::declval<Functor>()())
0055 #endif
0056 )
0057 {
0058 typename Functor::result_type init_value = 0;
0059 return sum_series(func, factor, max_terms, init_value);
0060 }
0061
0062 template <class Functor, class U>
0063 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits, boost::math::uintmax_t& max_terms, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0064 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0065 && noexcept(std::declval<Functor>()())
0066 #endif
0067 )
0068 {
0069 BOOST_MATH_STD_USING
0070 typedef typename Functor::result_type result_type;
0071 result_type factor = ldexp(result_type(1), 1 - bits);
0072 return sum_series(func, factor, max_terms, init_value);
0073 }
0074
0075 template <class Functor>
0076 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0077 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0078 && noexcept(std::declval<Functor>()())
0079 #endif
0080 )
0081 {
0082 BOOST_MATH_STD_USING
0083 typedef typename Functor::result_type result_type;
0084 boost::math::uintmax_t iters = (boost::math::numeric_limits<boost::math::uintmax_t>::max)();
0085 result_type init_val = 0;
0086 return sum_series(func, bits, iters, init_val);
0087 }
0088
0089 template <class Functor>
0090 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits, boost::math::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0091 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0092 && noexcept(std::declval<Functor>()())
0093 #endif
0094 )
0095 {
0096 BOOST_MATH_STD_USING
0097 typedef typename Functor::result_type result_type;
0098 result_type init_val = 0;
0099 return sum_series(func, bits, max_terms, init_val);
0100 }
0101
0102 template <class Functor, class U>
0103 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0104 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0105 && noexcept(std::declval<Functor>()())
0106 #endif
0107 )
0108 {
0109 BOOST_MATH_STD_USING
0110 boost::math::uintmax_t iters = (boost::math::numeric_limits<boost::math::uintmax_t>::max)();
0111 return sum_series(func, bits, iters, init_value);
0112 }
0113
0114
0115
0116 template <class Functor, class U, class V>
0117 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type checked_sum_series(Functor& func, const U& factor, boost::math::uintmax_t& max_terms, const V& init_value, V& norm) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0118 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0119 && noexcept(std::declval<Functor>()())
0120 #endif
0121 )
0122 {
0123 BOOST_MATH_STD_USING
0124
0125 typedef typename Functor::result_type result_type;
0126
0127 boost::math::uintmax_t counter = max_terms;
0128
0129 result_type result = init_value;
0130 result_type next_term;
0131 do {
0132 next_term = func();
0133 result += next_term;
0134 norm += fabs(next_term);
0135 } while ((abs(factor * result) < abs(next_term)) && --counter);
0136
0137
0138 max_terms = max_terms - counter;
0139
0140 return result;
0141 }
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 template <class Functor>
0157 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type kahan_sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0158 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0159 && noexcept(std::declval<Functor>()())
0160 #endif
0161 )
0162 {
0163 BOOST_MATH_STD_USING
0164
0165 typedef typename Functor::result_type result_type;
0166
0167 result_type factor = pow(result_type(2), result_type(bits));
0168 result_type result = func();
0169 result_type next_term, y, t;
0170 result_type carry = 0;
0171 do{
0172 next_term = func();
0173 y = next_term - carry;
0174 t = result + y;
0175 carry = t - result;
0176 carry -= y;
0177 result = t;
0178 }
0179 while(fabs(result) < fabs(factor * next_term));
0180 return result;
0181 }
0182
0183 template <class Functor>
0184 BOOST_MATH_GPU_ENABLED inline typename Functor::result_type kahan_sum_series(Functor& func, int bits, boost::math::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type)
0185 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0186 && noexcept(std::declval<Functor>()())
0187 #endif
0188 )
0189 {
0190 BOOST_MATH_STD_USING
0191
0192 typedef typename Functor::result_type result_type;
0193
0194 boost::math::uintmax_t counter = max_terms;
0195
0196 result_type factor = ldexp(result_type(1), bits);
0197 result_type result = func();
0198 result_type next_term, y, t;
0199 result_type carry = 0;
0200 do{
0201 next_term = func();
0202 y = next_term - carry;
0203 t = result + y;
0204 carry = t - result;
0205 carry -= y;
0206 result = t;
0207 }
0208 while((fabs(result) < fabs(factor * next_term)) && --counter);
0209
0210
0211 max_terms = max_terms - counter;
0212
0213 return result;
0214 }
0215
0216 }
0217 }
0218 }
0219
0220 #endif
0221