_Tp __ellint_2(const _Tp __k, const _Tp __phi) { if (std::isnan(__k) || std::isnan(__phi)) return std::numeric_limits<_Tp>::quiet_NaN(); else if (std::abs(__k) > _Tp(1)) throw std::domain_error("Bad argument in __ellint_2."); else { // Reduce phi to -pi/2 < phi < +pi/2. const int __n = std::floor(__phi / _Tp(M_PI) + _Tp(0.5L)); const _Tp __phi_red = __phi - __n * _Tp(M_PI); const _Tp __kk = __k * __k; const _Tp __s = std::sin(__phi_red); const _Tp __ss = __s * __s; const _Tp __sss = __ss * __s; const _Tp __c = std::cos(__phi_red); const _Tp __cc = __c * __c; const _Tp __E = __s * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1)) - __kk * __sss * __ellint_rd(__cc, _Tp(1) - __kk * __ss, _Tp(1)) / _Tp(3); if (__n == 0) return __E; else return __E + _Tp(2) * __n * __comp_ellint_2(__k); } }
_Tp __comp_ellint_1(const _Tp __k) { if (std::isnan(__k)) return std::numeric_limits<_Tp>::quiet_NaN(); else if (std::abs(__k) >= _Tp(1)) return std::numeric_limits<_Tp>::quiet_NaN(); else return __ellint_rf(_Tp(0), _Tp(1) - __k * __k, _Tp(1)); }
_Tp __log_bincoef(unsigned int __n, unsigned int __k) { // Max e exponent before overflow. static const _Tp __max_bincoeff = std::numeric_limits<_Tp>::max_exponent10 * std::log(_Tp(10)) - _Tp(1); _Tp __coeff = __log_gamma(_Tp(1 + __n)) - __log_gamma(_Tp(1 + __k)) - __log_gamma(_Tp(1 + __n - __k)); }
_Tp __bincoef(unsigned int __n, unsigned int __k) { // Max e exponent before overflow. static const _Tp __max_bincoeff = std::numeric_limits<_Tp>::max_exponent10 * std::log(_Tp(10)) - _Tp(1); const _Tp __log_coeff = __log_bincoef<_Tp>(__n, __k); if (__log_coeff > __max_bincoeff) return std::numeric_limits<_Tp>::quiet_NaN(); else return std::exp(__log_coeff); }
_Tp __log_gamma_lanczos(_Tp __x) { typedef typename __ellint_traits<_Tp>::__value_type _Val; const _Tp __xm1 = __x - _Tp(1); static const _Val __lanczos_cheb_7[9] = { _Val( 0.99999999999980993227684700473478L), _Val( 676.520368121885098567009190444019L), _Val(-1259.13921672240287047156078755283L), _Val( 771.3234287776530788486528258894L), _Val(-176.61502916214059906584551354L), _Val( 12.507343278686904814458936853L), _Val(-0.13857109526572011689554707L), _Val( 9.984369578019570859563e-6L), _Val( 1.50563273514931155834e-7L) }; static const _Val __LOGROOT2PI = _Val(0.9189385332046727417803297364056176L); _Tp __sum = _Tp(__lanczos_cheb_7[0]); for(unsigned int __k = 1; __k < 9; ++__k) __sum += _Tp(__lanczos_cheb_7[__k]) / (__xm1 + _Tp(__k)); const _Tp __term1 = (__xm1 + _Tp(0.5L)) * std::log((__xm1 + _Tp(7.5L)) / __numeric_constants<_Val>::__euler()); const _Tp __term2 = _Tp(__LOGROOT2PI) + std::log(__sum); const _Tp __result = __term1 + (__term2 - _Tp(7)); return __result; }
_Tp __bernoulli_series(unsigned int __n) { constexpr _Tp __bernoulli_numbers[24] { _Tp{1UL}, -_Tp{1UL} / _Tp{2UL}, _Tp{1UL} / _Tp{6UL}, _Tp{0UL}, -_Tp{1UL} / _Tp{30UL}, _Tp{0UL}, _Tp{1UL} / _Tp{42UL}, _Tp{0UL}, -_Tp{1UL} / _Tp{30UL}, _Tp{0UL}, _Tp{5UL} / _Tp{66UL}, _Tp{0UL}, -_Tp{691UL} / _Tp{2730UL}, _Tp{0UL}, _Tp{7UL} / _Tp{6UL}, _Tp{0UL}, -_Tp{3617UL} / _Tp{510UL}, _Tp{0UL}, _Tp{43867UL} / _Tp{798UL}, _Tp{0UL}, -_Tp{174611UL} / _Tp{330UL}, _Tp{0UL}, _Tp{854513UL} / _Tp{138UL}, _Tp{0UL} }; if (__n == 0) return _Tp{1}; else if (__n == 1) return -_Tp{1} / _Tp{2}; else if (__n % 2 == 1) // Take care of the rest of the odd ones. return _Tp{0}; else if (__n < 28) // Return small evens that are painful for the series. return __bernoulli_numbers[__n]; else { _Tp __fact = _Tp{1}; if ((__n / 2) % 2 == 0) __fact *= -_Tp{1}; for (unsigned int __k = 1; __k <= __n; ++__k) __fact *= __k / (_Tp{2} * __gnu_cxx::__math_constants<_Tp>::__pi); __fact *= _Tp{2}; _Tp __sum = _Tp{0}; for (unsigned int __i = 1; __i < 1000; ++__i) { _Tp __term = std::pow(_Tp(__i), -_Tp(__n)); if (__term < std::numeric_limits<_Tp>::epsilon()) break; __sum += __term; } return __fact * __sum; } }
_Tp __polygamma_series(unsigned int __n, _Tp __x) { constexpr int _S_max_iter = 1000; const auto _S_eps = __gnu_cxx::__epsilon(__x); auto __sum = _Tp{0}; for (int __k = 0; __k < _S_max_iter; ++__k) { auto __term = std::pow(__x + _Tp(__k), _Tp(__n + 1)); __sum += __term; if (std::abs(__term) < _S_eps * std::abs(__sum)) break; } return (__n & 1 ? +1 : -1) * __gnu_cxx::factorial<_Tp>(__n) * __sum; }
inline void __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp*, _Compare __comp) { __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, _STLP_DISTANCE_TYPE(__first, _RandomAccessIterator)); }
inline void __push_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance*, _Tp*) { __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), _Tp(*(__last - 1))); }
template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::resize(size_t _size) { if (_size <= sz) { sz = _size; return; } size_t i, prevsize = sz, minsize = MIN(prevsize, _size); _Tp* prevptr = ptr; ptr = _size > fixed_size ? new _Tp[_size] : buf; sz = _size; if (ptr != prevptr) { for (i = 0; i < minsize; i++) { ptr[i] = prevptr[i]; } } for (i = prevsize; i < _size; i++) { ptr[i] = _Tp(); } if (prevptr != buf) { delete[] prevptr; } }
_Tp my_vector_sum(const _Tp* __f, const _Tp* __l) { _Tp __r = _Tp(); while (__f != __l) __r += *__f++; return __r; }
inline void __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp*) { __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __DISTANCE_TYPE(__first)); }
void _M_construct_node(_Node_* __p, _Tp const __V = _Tp(), _Base_ptr const __PARENT = NULL, _Base_ptr const __LEFT = NULL, _Base_ptr const __RIGHT = NULL) { new (__p) _Node_(__V, __PARENT, __LEFT, __RIGHT); }
_Tp __p(unsigned int __k, _Tp __g) { const auto _S_pi = _Tp{3.1415926535897932384626433832795029L}; auto __fact = std::sqrt(_Tp{2} / _S_pi); auto __sum = __c(2 * __k + 1, 1) * __fact * std::exp(__g + 0.5) / std::sqrt(__g + 0.5); for (int __a = 1; __a <= __k; ++__a) { __fact *= _Tp(2 * __a - 1) / 2; __sum += __c(2 * __k + 1, 2 * __a + 1) * __fact * std::pow(__a + __g + 0.5L, -_Tp(__a + 0.5L)) * std::exp(__a + __g + 0.5L); } return __sum; }
static complex<_Tp> powT(const complex<_Tp>& z_in, int n) { complex<_Tp> z = z_in; z = _STLP_PRIV __power(z, (n < 0 ? -n : n), multiplies< complex<_Tp> >()); if (n < 0) return _Tp(1.0) / z; else return z; }
_Tp __hurwitz_zeta_glob(_Tp __s, _Tp __a) { const auto _S_eps = std::numeric_limits<_Tp>::epsilon(); // Max before overflow? const auto _S_max = std::numeric_limits<_Tp>::max(); const auto _S_inf = std::numeric_limits<_Tp>::infinity(); //std::cout.precision(std::numeric_limits<_Tp>::max_digits10); if (__s == +_Tp{0}) return _S_inf; constexpr unsigned int _S_maxit = 10000; // Zeroth order contribution already calculated. auto __zeta = _Tp{0.5L}; for (unsigned int __n = 1; __n < _S_maxit; ++__n) { bool __punt = false; auto __term = _Tp{1}; // Again, the zeroth order. auto __bincoeff = _Tp{1}; for (unsigned int __k = 1; __k <= __n; ++__k) { __bincoeff *= -_Tp(__n - __k + 1) / _Tp(__k); if (std::abs(__bincoeff) > _S_max) { __punt = true; break; } __term += __bincoeff * std::pow(_Tp(__k + __a), _Tp{1} - __s); //std::cout << " " << __k << ' ' << __bincoeff << ' ' << __term << '\n'; } if (__punt) break; __term /= _Tp(__n + 1); __zeta += __term; if (std::abs(__term / __zeta) < _S_eps) break; //std::cout << " " << __n << ' ' << __term << ' ' << __zeta << '\n'; } __zeta /= __s - _Tp{1}; return __zeta; }
_Tp __log_gamma(_Tp __x) { typedef typename __ellint_traits<_Tp>::__value_type _Val; if (std::real(__x) > _Val(0.5L)) return __log_gamma_lanczos(__x); else { const _Tp __sin_fact = std::abs(std::sin(__numeric_constants<_Val>::__pi() * __x)); if (__sin_fact == _Tp(0)) std::__throw_domain_error(__N("Argument is nonpositive integer " "in __log_gamma")); return __numeric_constants<_Val>::__lnpi() - std::log(__sin_fact) - __log_gamma_lanczos(_Tp(1) - __x); } }
inline void __push_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance*, _Tp*) { //__last - __first) - 1表示插入后元素的个数,也是容器的最后一个下标数字 //新插入的元素必须位于容器的末尾 __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), _Tp(*(__last - 1))); }
_Tp __tetragamma_cont_frac(_Tp __x) { const auto _S_2pi = __gnu_cxx::__const_2_pi(__x); const auto _S_8pi2 = _Tp{1} / _S_2pi / _S_2pi / _Tp{2}; auto __a = [_S_8pi2](std::size_t __k, _Tp) { if (__k == 1) return _S_8pi2; else { auto __j = __k & 1 ? (__k - 1) / 2 : __k / 2; auto __aa = _Tp(__j) * _Tp(__j + 1) / _Tp{2} / _Tp(2 * __j + 1); return (__k & 1 ? __aa * _Tp(__j + 1) : __aa * _Tp(__j)); } }; using _AFun = decltype(__a); auto __b = [](std::size_t __k, _Tp __x) { return __k == 0 ? _Tp{0} : (__k & 1 ? __x * __x : _Tp{1}); }; using _BFun = decltype(__b); auto __w = [__a, __b](std::size_t __k, _Tp __x) { auto __arg = _Tp{4} * __a(__k + 1, __x) / __x / __x + _Tp{1}; return __b(__k, __x) * (std::sqrt(__arg) - _Tp{1}) / _Tp{2}; }; using _WFun = decltype(__w); _LentzContinuedFraction<_Tp, _AFun, _BFun, _WFun> G2Frac(__a, __b, __w); auto __g2 = G2Frac(__x); auto __fg = _S_2pi / __x; auto __xm2 = _Tp{1} / (__x * __x); return -__xm2 - __xm2 / __x - __fg * __fg * __g2; }
_Tp __comp_ellint_1_series(const _Tp __k) { const _Tp __kk = __k * __k; _Tp __term = __kk / _Tp(4); _Tp __sum = _Tp(1) + __term; const unsigned int __max_iter = 1000; for (unsigned int __i = 2; __i < __max_iter; ++__i) { __term *= (2 * __i - 1) * __kk / (2 * __i); if (__term < std::numeric_limits<_Tp>::epsilon()) break; __sum += __term; } return _Tp(0.5 * M_PI) * __sum; }
_Tp __comp_ellint_3(const _Tp __k, const _Tp __nu) { if (std::isnan(__k) || std::isnan(__nu)) return std::numeric_limits<_Tp>::quiet_NaN(); else if (__nu == _Tp(1)) return std::numeric_limits<_Tp>::infinity(); else if (std::abs(__k) > _Tp(1)) throw std::domain_error("Bad argument in __comp_ellint_3."); else { const _Tp __kk = __k * __k; return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1)) - __nu * __ellint_rj(_Tp(0), _Tp(1) - __kk, _Tp(1), _Tp(1) + __nu) / _Tp(3); } }
_Tp __comp_ellint_2(const _Tp __k) { if (std::isnan(__k)) return std::numeric_limits<_Tp>::quiet_NaN(); else if (std::abs(__k) == 1) return _Tp(1); else if (std::abs(__k) > _Tp(1)) throw std::domain_error("Bad argument in __comp_ellint_2."); else { const _Tp __kk = __k * __k; return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1)) - __kk * __ellint_rd(_Tp(0), _Tp(1) - __kk, _Tp(1)) / _Tp(3); } }
_Tp __comp_ellint_2_series(const _Tp __k) { const _Tp __kk = __k * __k; _Tp __term = __kk; _Tp __sum = __term; const unsigned int __max_iter = 1000; for (unsigned int __i = 2; __i < __max_iter; ++__i) { const _Tp __i2m = 2 * __i - 1; const _Tp __i2 = 2 * __i; __term *= __i2m * __i2m * __kk / (__i2 * __i2); if (__term < std::numeric_limits<_Tp>::epsilon()) break; __sum += __term / __i2m; } return _Tp(0.5 * M_PI) * (_Tp(1) - __sum); }
void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp*, _Distance*) { if (__last - __first < 2) return; _Distance __len = __last - __first; _Distance __parent = (__len - 2)/2; while (true) { __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); if (__parent == 0) return; __parent--; } }
void run_sin_cosh_pi(_Tp proto = _Tp{}) { const _Tp _S_pi = __gnu_cxx::__const_pi<_Tp>(proto); std::cout.precision(__gnu_cxx::__digits10(proto)); std::cout << std::showpoint << std::scientific; auto width = 10 + std::cout.precision(); std::cout << std::endl; std::cout << std::setw(width) << " x" << std::setw(width) << " sinh_pi (GCC)" << std::setw(width) << " delta sinh(pi x)" << std::setw(width) << " cosh_pi (GCC)" << std::setw(width) << " delta cosh(pi x)" << std::setw(width) << " tanh_pi (GCC)" << std::setw(width) << " delta tanh(pi x)" << '\n'; std::cout << std::setw(width) << " ===============" << std::setw(width) << " ===============" << std::setw(width) << " ===============" << std::setw(width) << " ===============" << std::setw(width) << " ===============" << std::setw(width) << " ===============" << std::setw(width) << " ===============" << '\n'; for (int i = -1600; i <= +1600; ++i) { auto x = _Tp(0.1Q * i); auto sinh_pi_g = __gnu_cxx::sinh_pi(x); auto cosh_pi_g = __gnu_cxx::cosh_pi(x); auto tanh_pi_g = __gnu_cxx::tanh_pi(x); std::cout << ' ' << std::setw(width) << x << ' ' << std::setw(width) << sinh_pi_g << ' ' << std::setw(width) << sinh_pi_g - std::sinh(_S_pi * x) << ' ' << std::setw(width) << cosh_pi_g << ' ' << std::setw(width) << cosh_pi_g - std::cosh(_S_pi * x) << ' ' << std::setw(width) << tanh_pi_g << ' ' << std::setw(width) << tanh_pi_g - std::tanh(_S_pi * x) << '\n'; } std::cout << std::endl; }
_Tp __lommel_2_asymp(_Tp __mu, _Tp __nu, _Tp __z) { const auto _S_eps = __gnu_cxx::__epsilon(__z); const unsigned int _S_max_iter = 100000u; const auto __zm2 = _Tp{1} / (__z * __z); const auto __nu2 = __nu * __nu; auto __term = _Tp{1}; auto _S2 = __term; for (auto __k = 1; __k < _S_max_iter; ++__k) { const auto __mu1 = -__mu + _Tp(2 * __k - 1); __term *= -(__mu1 * __mu1 - __nu2) * __zm2; _S2 += __term; if (std::abs(__term) < _S_eps * std::abs(_S2)) break; } _S2 *= std::pow(__z, __mu - 1); }
void test_sinc(_Tp proto = _Tp{}) { std::cout.precision(__gnu_cxx::__digits10(proto)); std::cout << std::showpoint << std::scientific; auto width = 8 + std::cout.precision(); const auto pi = __gnu_cxx::__const_pi(proto); std::cout << std::endl; std::cout << std::setw(width) << "x" << std::setw(width) << "sinc" << std::setw(width) << "sinc GSL" << std::setw(width) << "sinc Boost" << std::setw(width) << "delta GSL" << std::setw(width) << "delta Boost" << '\n'; std::cout << std::setw(width) << "===============" << std::setw(width) << "===============" << std::setw(width) << "===============" << std::setw(width) << "===============" << std::setw(width) << "===============" << std::setw(width) << "===============" << '\n'; for (int i = -40; i <= +40; ++i) { auto x = _Tp(0.1Q * i) * pi; auto sinc = __gnu_cxx::sinc(x); auto sinc_gsl = gsl::sinc(x); auto sinc_boost = beast::sinc(x); auto delta_gsl = sinc - sinc_gsl; auto delta_boost = sinc - sinc_boost; std::cout << std::setw(width) << x << std::setw(width) << sinc << std::setw(width) << sinc_gsl << std::setw(width) << sinc_boost << std::setw(width) << delta_gsl << std::setw(width) << delta_boost << '\n'; } }
_Tp __lommel_1_series(_Tp __mu, _Tp __nu, _Tp __z) { const auto _S_eps = __gnu_cxx::__epsilon(__z); const unsigned int _S_max_iter = 100000u; const auto __z2 = __z * __z; const auto __nu2 = __nu * __nu; auto __term = _Tp{1}; auto _S1 = __term; for (auto __k = 1u; __k < _S_max_iter; ++__k) { const auto __mu1 = __mu + _Tp(2 * __k - 1); __term *= -__z2 / (__mu1 * __mu1 - __nu2); _S1 += __term; if (std::abs(__term) < _S_eps * std::abs(_S1)) break; } _S1 *= std::pow(__z, __mu + 1); return _S1; }
_Tp __trigamma_cont_frac(_Tp __x) { const auto _S_2pi = __gnu_cxx::__const_2_pi(__x); const auto _S_12pi = _Tp{1} / _S_2pi / _Tp{6}; auto __a = [_S_12pi](std::size_t __k, _Tp) { if (__k == 1) return _S_12pi; else { auto __kk = _Tp(__k * __k); return __kk * (__kk - _Tp{1}) / _Tp{4} / (_Tp{4} * __kk - _Tp{1}); } }; using _AFun = decltype(__a); auto __b = [](std::size_t __k, _Tp __x) { return __k == 0 ? _Tp{0} : (__k & 1 ? __x * __x : _Tp{1}); }; using _BFun = decltype(__b); auto __w = [__a, __b](std::size_t __k, _Tp __x) { auto __arg = _Tp{4} * __a(__k + 1, __x) / __x / __x + _Tp{1}; return __b(__k, __x) * (std::sqrt(__arg) - _Tp{1}) / _Tp{2}; }; using _WFun = decltype(__w); _LentzContinuedFraction<_Tp, _AFun, _BFun, _WFun> G1Frac(__a, __b, __w); auto __g1 = G1Frac(__x); auto __rx = _Tp{1} / __x; return __rx + __rx * __rx / _Tp{2} + _S_2pi * __rx * __g1; }
template<typename _Tp> _Tp gComDivisor(_Tp* b, unsigned int size_b){ switch (size_b) { case 0: return _Tp(); break; case 1: return b[0]; break; case 2: return gComDivisor<_Tp>(b[0],b[1]); break; case 3: return gComDivisor<_Tp>(gComDivisor<_Tp>(b[0],b[1]),b[2]); break; case 4: return gComDivisor<_Tp>(gComDivisor<_Tp>(b[0],b[1]), gComDivisor<_Tp>(b[2],b[3])); break; default: return gComDivisor<_Tp>(gComDivisor<_Tp>(b,size_b/2), gComDivisor<_Tp>(b+(size_b)/2,(size_b+1)/2)); break; } };