annotate DEPENDENCIES/generic/include/boost/math/bindings/rr.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright John Maddock 2007.
Chris@16 2 // Use, modification and distribution are subject to the
Chris@16 3 // Boost Software License, Version 1.0. (See accompanying file
Chris@16 4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #ifndef BOOST_MATH_NTL_RR_HPP
Chris@16 7 #define BOOST_MATH_NTL_RR_HPP
Chris@16 8
Chris@16 9 #include <boost/config.hpp>
Chris@16 10 #include <boost/limits.hpp>
Chris@16 11 #include <boost/math/tools/real_cast.hpp>
Chris@16 12 #include <boost/math/tools/precision.hpp>
Chris@16 13 #include <boost/math/constants/constants.hpp>
Chris@16 14 #include <boost/math/tools/roots.hpp>
Chris@16 15 #include <boost/math/special_functions/fpclassify.hpp>
Chris@16 16 #include <boost/math/bindings/detail/big_digamma.hpp>
Chris@16 17 #include <boost/math/bindings/detail/big_lanczos.hpp>
Chris@16 18
Chris@16 19 #include <ostream>
Chris@16 20 #include <istream>
Chris@16 21 #include <boost/config/no_tr1/cmath.hpp>
Chris@16 22 #include <NTL/RR.h>
Chris@16 23
Chris@16 24 namespace boost{ namespace math{
Chris@16 25
Chris@16 26 namespace ntl
Chris@16 27 {
Chris@16 28
Chris@16 29 class RR;
Chris@16 30
Chris@16 31 RR ldexp(RR r, int exp);
Chris@16 32 RR frexp(RR r, int* exp);
Chris@16 33
Chris@16 34 class RR
Chris@16 35 {
Chris@16 36 public:
Chris@16 37 // Constructors:
Chris@16 38 RR() {}
Chris@16 39 RR(const ::NTL::RR& c) : m_value(c){}
Chris@16 40 RR(char c)
Chris@16 41 {
Chris@16 42 m_value = c;
Chris@16 43 }
Chris@16 44 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
Chris@16 45 RR(wchar_t c)
Chris@16 46 {
Chris@16 47 m_value = c;
Chris@16 48 }
Chris@16 49 #endif
Chris@16 50 RR(unsigned char c)
Chris@16 51 {
Chris@16 52 m_value = c;
Chris@16 53 }
Chris@16 54 RR(signed char c)
Chris@16 55 {
Chris@16 56 m_value = c;
Chris@16 57 }
Chris@16 58 RR(unsigned short c)
Chris@16 59 {
Chris@16 60 m_value = c;
Chris@16 61 }
Chris@16 62 RR(short c)
Chris@16 63 {
Chris@16 64 m_value = c;
Chris@16 65 }
Chris@16 66 RR(unsigned int c)
Chris@16 67 {
Chris@16 68 assign_large_int(c);
Chris@16 69 }
Chris@16 70 RR(int c)
Chris@16 71 {
Chris@16 72 assign_large_int(c);
Chris@16 73 }
Chris@16 74 RR(unsigned long c)
Chris@16 75 {
Chris@16 76 assign_large_int(c);
Chris@16 77 }
Chris@16 78 RR(long c)
Chris@16 79 {
Chris@16 80 assign_large_int(c);
Chris@16 81 }
Chris@16 82 #ifdef BOOST_HAS_LONG_LONG
Chris@16 83 RR(boost::ulong_long_type c)
Chris@16 84 {
Chris@16 85 assign_large_int(c);
Chris@16 86 }
Chris@16 87 RR(boost::long_long_type c)
Chris@16 88 {
Chris@16 89 assign_large_int(c);
Chris@16 90 }
Chris@16 91 #endif
Chris@16 92 RR(float c)
Chris@16 93 {
Chris@16 94 m_value = c;
Chris@16 95 }
Chris@16 96 RR(double c)
Chris@16 97 {
Chris@16 98 m_value = c;
Chris@16 99 }
Chris@16 100 RR(long double c)
Chris@16 101 {
Chris@16 102 assign_large_real(c);
Chris@16 103 }
Chris@16 104
Chris@16 105 // Assignment:
Chris@16 106 RR& operator=(char c) { m_value = c; return *this; }
Chris@16 107 RR& operator=(unsigned char c) { m_value = c; return *this; }
Chris@16 108 RR& operator=(signed char c) { m_value = c; return *this; }
Chris@16 109 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
Chris@16 110 RR& operator=(wchar_t c) { m_value = c; return *this; }
Chris@16 111 #endif
Chris@16 112 RR& operator=(short c) { m_value = c; return *this; }
Chris@16 113 RR& operator=(unsigned short c) { m_value = c; return *this; }
Chris@16 114 RR& operator=(int c) { assign_large_int(c); return *this; }
Chris@16 115 RR& operator=(unsigned int c) { assign_large_int(c); return *this; }
Chris@16 116 RR& operator=(long c) { assign_large_int(c); return *this; }
Chris@16 117 RR& operator=(unsigned long c) { assign_large_int(c); return *this; }
Chris@16 118 #ifdef BOOST_HAS_LONG_LONG
Chris@16 119 RR& operator=(boost::long_long_type c) { assign_large_int(c); return *this; }
Chris@16 120 RR& operator=(boost::ulong_long_type c) { assign_large_int(c); return *this; }
Chris@16 121 #endif
Chris@16 122 RR& operator=(float c) { m_value = c; return *this; }
Chris@16 123 RR& operator=(double c) { m_value = c; return *this; }
Chris@16 124 RR& operator=(long double c) { assign_large_real(c); return *this; }
Chris@16 125
Chris@16 126 // Access:
Chris@16 127 NTL::RR& value(){ return m_value; }
Chris@16 128 NTL::RR const& value()const{ return m_value; }
Chris@16 129
Chris@16 130 // Member arithmetic:
Chris@16 131 RR& operator+=(const RR& other)
Chris@16 132 { m_value += other.value(); return *this; }
Chris@16 133 RR& operator-=(const RR& other)
Chris@16 134 { m_value -= other.value(); return *this; }
Chris@16 135 RR& operator*=(const RR& other)
Chris@16 136 { m_value *= other.value(); return *this; }
Chris@16 137 RR& operator/=(const RR& other)
Chris@16 138 { m_value /= other.value(); return *this; }
Chris@16 139 RR operator-()const
Chris@16 140 { return -m_value; }
Chris@16 141 RR const& operator+()const
Chris@16 142 { return *this; }
Chris@16 143
Chris@16 144 // RR compatibity:
Chris@16 145 const ::NTL::ZZ& mantissa() const
Chris@16 146 { return m_value.mantissa(); }
Chris@16 147 long exponent() const
Chris@16 148 { return m_value.exponent(); }
Chris@16 149
Chris@16 150 static void SetPrecision(long p)
Chris@16 151 { ::NTL::RR::SetPrecision(p); }
Chris@16 152
Chris@16 153 static long precision()
Chris@16 154 { return ::NTL::RR::precision(); }
Chris@16 155
Chris@16 156 static void SetOutputPrecision(long p)
Chris@16 157 { ::NTL::RR::SetOutputPrecision(p); }
Chris@16 158 static long OutputPrecision()
Chris@16 159 { return ::NTL::RR::OutputPrecision(); }
Chris@16 160
Chris@16 161
Chris@16 162 private:
Chris@16 163 ::NTL::RR m_value;
Chris@16 164
Chris@16 165 template <class V>
Chris@16 166 void assign_large_real(const V& a)
Chris@16 167 {
Chris@16 168 using std::frexp;
Chris@16 169 using std::ldexp;
Chris@16 170 using std::floor;
Chris@16 171 if (a == 0) {
Chris@16 172 clear(m_value);
Chris@16 173 return;
Chris@16 174 }
Chris@16 175
Chris@16 176 if (a == 1) {
Chris@16 177 NTL::set(m_value);
Chris@16 178 return;
Chris@16 179 }
Chris@16 180
Chris@16 181 if (!(boost::math::isfinite)(a))
Chris@16 182 {
Chris@16 183 throw std::overflow_error("Cannot construct an instance of NTL::RR with an infinite value.");
Chris@16 184 }
Chris@16 185
Chris@16 186 int e;
Chris@16 187 long double f, term;
Chris@16 188 ::NTL::RR t;
Chris@16 189 clear(m_value);
Chris@16 190
Chris@16 191 f = frexp(a, &e);
Chris@16 192
Chris@16 193 while(f)
Chris@16 194 {
Chris@16 195 // extract 30 bits from f:
Chris@16 196 f = ldexp(f, 30);
Chris@16 197 term = floor(f);
Chris@16 198 e -= 30;
Chris@16 199 conv(t.x, (int)term);
Chris@16 200 t.e = e;
Chris@16 201 m_value += t;
Chris@16 202 f -= term;
Chris@16 203 }
Chris@16 204 }
Chris@16 205
Chris@16 206 template <class V>
Chris@16 207 void assign_large_int(V a)
Chris@16 208 {
Chris@16 209 #ifdef BOOST_MSVC
Chris@16 210 #pragma warning(push)
Chris@16 211 #pragma warning(disable:4146)
Chris@16 212 #endif
Chris@16 213 clear(m_value);
Chris@16 214 int exp = 0;
Chris@16 215 NTL::RR t;
Chris@16 216 bool neg = a < V(0) ? true : false;
Chris@16 217 if(neg)
Chris@16 218 a = -a;
Chris@16 219 while(a)
Chris@16 220 {
Chris@16 221 t = static_cast<double>(a & 0xffff);
Chris@16 222 m_value += ldexp(RR(t), exp).value();
Chris@16 223 a >>= 16;
Chris@16 224 exp += 16;
Chris@16 225 }
Chris@16 226 if(neg)
Chris@16 227 m_value = -m_value;
Chris@16 228 #ifdef BOOST_MSVC
Chris@16 229 #pragma warning(pop)
Chris@16 230 #endif
Chris@16 231 }
Chris@16 232 };
Chris@16 233
Chris@16 234 // Non-member arithmetic:
Chris@16 235 inline RR operator+(const RR& a, const RR& b)
Chris@16 236 {
Chris@16 237 RR result(a);
Chris@16 238 result += b;
Chris@16 239 return result;
Chris@16 240 }
Chris@16 241 inline RR operator-(const RR& a, const RR& b)
Chris@16 242 {
Chris@16 243 RR result(a);
Chris@16 244 result -= b;
Chris@16 245 return result;
Chris@16 246 }
Chris@16 247 inline RR operator*(const RR& a, const RR& b)
Chris@16 248 {
Chris@16 249 RR result(a);
Chris@16 250 result *= b;
Chris@16 251 return result;
Chris@16 252 }
Chris@16 253 inline RR operator/(const RR& a, const RR& b)
Chris@16 254 {
Chris@16 255 RR result(a);
Chris@16 256 result /= b;
Chris@16 257 return result;
Chris@16 258 }
Chris@16 259
Chris@16 260 // Comparison:
Chris@16 261 inline bool operator == (const RR& a, const RR& b)
Chris@16 262 { return a.value() == b.value() ? true : false; }
Chris@16 263 inline bool operator != (const RR& a, const RR& b)
Chris@16 264 { return a.value() != b.value() ? true : false;}
Chris@16 265 inline bool operator < (const RR& a, const RR& b)
Chris@16 266 { return a.value() < b.value() ? true : false; }
Chris@16 267 inline bool operator <= (const RR& a, const RR& b)
Chris@16 268 { return a.value() <= b.value() ? true : false; }
Chris@16 269 inline bool operator > (const RR& a, const RR& b)
Chris@16 270 { return a.value() > b.value() ? true : false; }
Chris@16 271 inline bool operator >= (const RR& a, const RR& b)
Chris@16 272 { return a.value() >= b.value() ? true : false; }
Chris@16 273
Chris@16 274 #if 0
Chris@16 275 // Non-member mixed compare:
Chris@16 276 template <class T>
Chris@16 277 inline bool operator == (const T& a, const RR& b)
Chris@16 278 {
Chris@16 279 return a == b.value();
Chris@16 280 }
Chris@16 281 template <class T>
Chris@16 282 inline bool operator != (const T& a, const RR& b)
Chris@16 283 {
Chris@16 284 return a != b.value();
Chris@16 285 }
Chris@16 286 template <class T>
Chris@16 287 inline bool operator < (const T& a, const RR& b)
Chris@16 288 {
Chris@16 289 return a < b.value();
Chris@16 290 }
Chris@16 291 template <class T>
Chris@16 292 inline bool operator > (const T& a, const RR& b)
Chris@16 293 {
Chris@16 294 return a > b.value();
Chris@16 295 }
Chris@16 296 template <class T>
Chris@16 297 inline bool operator <= (const T& a, const RR& b)
Chris@16 298 {
Chris@16 299 return a <= b.value();
Chris@16 300 }
Chris@16 301 template <class T>
Chris@16 302 inline bool operator >= (const T& a, const RR& b)
Chris@16 303 {
Chris@16 304 return a >= b.value();
Chris@16 305 }
Chris@16 306 #endif // Non-member mixed compare:
Chris@16 307
Chris@16 308 // Non-member functions:
Chris@16 309 /*
Chris@16 310 inline RR acos(RR a)
Chris@16 311 { return ::NTL::acos(a.value()); }
Chris@16 312 */
Chris@16 313 inline RR cos(RR a)
Chris@16 314 { return ::NTL::cos(a.value()); }
Chris@16 315 /*
Chris@16 316 inline RR asin(RR a)
Chris@16 317 { return ::NTL::asin(a.value()); }
Chris@16 318 inline RR atan(RR a)
Chris@16 319 { return ::NTL::atan(a.value()); }
Chris@16 320 inline RR atan2(RR a, RR b)
Chris@16 321 { return ::NTL::atan2(a.value(), b.value()); }
Chris@16 322 */
Chris@16 323 inline RR ceil(RR a)
Chris@16 324 { return ::NTL::ceil(a.value()); }
Chris@16 325 /*
Chris@16 326 inline RR fmod(RR a, RR b)
Chris@16 327 { return ::NTL::fmod(a.value(), b.value()); }
Chris@16 328 inline RR cosh(RR a)
Chris@16 329 { return ::NTL::cosh(a.value()); }
Chris@16 330 */
Chris@16 331 inline RR exp(RR a)
Chris@16 332 { return ::NTL::exp(a.value()); }
Chris@16 333 inline RR fabs(RR a)
Chris@16 334 { return ::NTL::fabs(a.value()); }
Chris@16 335 inline RR abs(RR a)
Chris@16 336 { return ::NTL::abs(a.value()); }
Chris@16 337 inline RR floor(RR a)
Chris@16 338 { return ::NTL::floor(a.value()); }
Chris@16 339 /*
Chris@16 340 inline RR modf(RR a, RR* ipart)
Chris@16 341 {
Chris@16 342 ::NTL::RR ip;
Chris@16 343 RR result = modf(a.value(), &ip);
Chris@16 344 *ipart = ip;
Chris@16 345 return result;
Chris@16 346 }
Chris@16 347 inline RR frexp(RR a, int* expon)
Chris@16 348 { return ::NTL::frexp(a.value(), expon); }
Chris@16 349 inline RR ldexp(RR a, int expon)
Chris@16 350 { return ::NTL::ldexp(a.value(), expon); }
Chris@16 351 */
Chris@16 352 inline RR log(RR a)
Chris@16 353 { return ::NTL::log(a.value()); }
Chris@16 354 inline RR log10(RR a)
Chris@16 355 { return ::NTL::log10(a.value()); }
Chris@16 356 /*
Chris@16 357 inline RR tan(RR a)
Chris@16 358 { return ::NTL::tan(a.value()); }
Chris@16 359 */
Chris@16 360 inline RR pow(RR a, RR b)
Chris@16 361 { return ::NTL::pow(a.value(), b.value()); }
Chris@16 362 inline RR pow(RR a, int b)
Chris@16 363 { return ::NTL::power(a.value(), b); }
Chris@16 364 inline RR sin(RR a)
Chris@16 365 { return ::NTL::sin(a.value()); }
Chris@16 366 /*
Chris@16 367 inline RR sinh(RR a)
Chris@16 368 { return ::NTL::sinh(a.value()); }
Chris@16 369 */
Chris@16 370 inline RR sqrt(RR a)
Chris@16 371 { return ::NTL::sqrt(a.value()); }
Chris@16 372 /*
Chris@16 373 inline RR tanh(RR a)
Chris@16 374 { return ::NTL::tanh(a.value()); }
Chris@16 375 */
Chris@16 376 inline RR pow(const RR& r, long l)
Chris@16 377 {
Chris@16 378 return ::NTL::power(r.value(), l);
Chris@16 379 }
Chris@16 380 inline RR tan(const RR& a)
Chris@16 381 {
Chris@16 382 return sin(a)/cos(a);
Chris@16 383 }
Chris@16 384 inline RR frexp(RR r, int* exp)
Chris@16 385 {
Chris@16 386 *exp = r.value().e;
Chris@16 387 r.value().e = 0;
Chris@16 388 while(r >= 1)
Chris@16 389 {
Chris@16 390 *exp += 1;
Chris@16 391 r.value().e -= 1;
Chris@16 392 }
Chris@16 393 while(r < 0.5)
Chris@16 394 {
Chris@16 395 *exp -= 1;
Chris@16 396 r.value().e += 1;
Chris@16 397 }
Chris@16 398 BOOST_ASSERT(r < 1);
Chris@16 399 BOOST_ASSERT(r >= 0.5);
Chris@16 400 return r;
Chris@16 401 }
Chris@16 402 inline RR ldexp(RR r, int exp)
Chris@16 403 {
Chris@16 404 r.value().e += exp;
Chris@16 405 return r;
Chris@16 406 }
Chris@16 407
Chris@16 408 // Streaming:
Chris@16 409 template <class charT, class traits>
Chris@16 410 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const RR& a)
Chris@16 411 {
Chris@16 412 return os << a.value();
Chris@16 413 }
Chris@16 414 template <class charT, class traits>
Chris@16 415 inline std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& is, RR& a)
Chris@16 416 {
Chris@16 417 ::NTL::RR v;
Chris@16 418 is >> v;
Chris@16 419 a = v;
Chris@16 420 return is;
Chris@16 421 }
Chris@16 422
Chris@16 423 } // namespace ntl
Chris@16 424
Chris@16 425 namespace lanczos{
Chris@16 426
Chris@16 427 struct ntl_lanczos
Chris@16 428 {
Chris@16 429 static ntl::RR lanczos_sum(const ntl::RR& z)
Chris@16 430 {
Chris@16 431 unsigned long p = ntl::RR::precision();
Chris@16 432 if(p <= 72)
Chris@16 433 return lanczos13UDT::lanczos_sum(z);
Chris@16 434 else if(p <= 120)
Chris@16 435 return lanczos22UDT::lanczos_sum(z);
Chris@16 436 else if(p <= 170)
Chris@16 437 return lanczos31UDT::lanczos_sum(z);
Chris@16 438 else //if(p <= 370) approx 100 digit precision:
Chris@16 439 return lanczos61UDT::lanczos_sum(z);
Chris@16 440 }
Chris@16 441 static ntl::RR lanczos_sum_expG_scaled(const ntl::RR& z)
Chris@16 442 {
Chris@16 443 unsigned long p = ntl::RR::precision();
Chris@16 444 if(p <= 72)
Chris@16 445 return lanczos13UDT::lanczos_sum_expG_scaled(z);
Chris@16 446 else if(p <= 120)
Chris@16 447 return lanczos22UDT::lanczos_sum_expG_scaled(z);
Chris@16 448 else if(p <= 170)
Chris@16 449 return lanczos31UDT::lanczos_sum_expG_scaled(z);
Chris@16 450 else //if(p <= 370) approx 100 digit precision:
Chris@16 451 return lanczos61UDT::lanczos_sum_expG_scaled(z);
Chris@16 452 }
Chris@16 453 static ntl::RR lanczos_sum_near_1(const ntl::RR& z)
Chris@16 454 {
Chris@16 455 unsigned long p = ntl::RR::precision();
Chris@16 456 if(p <= 72)
Chris@16 457 return lanczos13UDT::lanczos_sum_near_1(z);
Chris@16 458 else if(p <= 120)
Chris@16 459 return lanczos22UDT::lanczos_sum_near_1(z);
Chris@16 460 else if(p <= 170)
Chris@16 461 return lanczos31UDT::lanczos_sum_near_1(z);
Chris@16 462 else //if(p <= 370) approx 100 digit precision:
Chris@16 463 return lanczos61UDT::lanczos_sum_near_1(z);
Chris@16 464 }
Chris@16 465 static ntl::RR lanczos_sum_near_2(const ntl::RR& z)
Chris@16 466 {
Chris@16 467 unsigned long p = ntl::RR::precision();
Chris@16 468 if(p <= 72)
Chris@16 469 return lanczos13UDT::lanczos_sum_near_2(z);
Chris@16 470 else if(p <= 120)
Chris@16 471 return lanczos22UDT::lanczos_sum_near_2(z);
Chris@16 472 else if(p <= 170)
Chris@16 473 return lanczos31UDT::lanczos_sum_near_2(z);
Chris@16 474 else //if(p <= 370) approx 100 digit precision:
Chris@16 475 return lanczos61UDT::lanczos_sum_near_2(z);
Chris@16 476 }
Chris@16 477 static ntl::RR g()
Chris@16 478 {
Chris@16 479 unsigned long p = ntl::RR::precision();
Chris@16 480 if(p <= 72)
Chris@16 481 return lanczos13UDT::g();
Chris@16 482 else if(p <= 120)
Chris@16 483 return lanczos22UDT::g();
Chris@16 484 else if(p <= 170)
Chris@16 485 return lanczos31UDT::g();
Chris@16 486 else //if(p <= 370) approx 100 digit precision:
Chris@16 487 return lanczos61UDT::g();
Chris@16 488 }
Chris@16 489 };
Chris@16 490
Chris@16 491 template<class Policy>
Chris@16 492 struct lanczos<ntl::RR, Policy>
Chris@16 493 {
Chris@16 494 typedef ntl_lanczos type;
Chris@16 495 };
Chris@16 496
Chris@16 497 } // namespace lanczos
Chris@16 498
Chris@16 499 namespace tools
Chris@16 500 {
Chris@16 501
Chris@16 502 template<>
Chris@16 503 inline int digits<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 504 {
Chris@16 505 return ::NTL::RR::precision();
Chris@16 506 }
Chris@16 507
Chris@16 508 template <>
Chris@16 509 inline float real_cast<float, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 510 {
Chris@16 511 double r;
Chris@16 512 conv(r, t.value());
Chris@16 513 return static_cast<float>(r);
Chris@16 514 }
Chris@16 515 template <>
Chris@16 516 inline double real_cast<double, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 517 {
Chris@16 518 double r;
Chris@16 519 conv(r, t.value());
Chris@16 520 return r;
Chris@16 521 }
Chris@16 522
Chris@16 523 namespace detail{
Chris@16 524
Chris@16 525 template<class I>
Chris@16 526 void convert_to_long_result(NTL::RR const& r, I& result)
Chris@16 527 {
Chris@16 528 result = 0;
Chris@16 529 I last_result(0);
Chris@16 530 NTL::RR t(r);
Chris@16 531 double term;
Chris@16 532 do
Chris@16 533 {
Chris@16 534 conv(term, t);
Chris@16 535 last_result = result;
Chris@16 536 result += static_cast<I>(term);
Chris@16 537 t -= term;
Chris@16 538 }while(result != last_result);
Chris@16 539 }
Chris@16 540
Chris@16 541 }
Chris@16 542
Chris@16 543 template <>
Chris@16 544 inline long double real_cast<long double, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 545 {
Chris@16 546 long double result(0);
Chris@16 547 detail::convert_to_long_result(t.value(), result);
Chris@16 548 return result;
Chris@16 549 }
Chris@16 550 template <>
Chris@16 551 inline boost::math::ntl::RR real_cast<boost::math::ntl::RR, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 552 {
Chris@16 553 return t;
Chris@16 554 }
Chris@16 555 template <>
Chris@16 556 inline unsigned real_cast<unsigned, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 557 {
Chris@16 558 unsigned result;
Chris@16 559 detail::convert_to_long_result(t.value(), result);
Chris@16 560 return result;
Chris@16 561 }
Chris@16 562 template <>
Chris@16 563 inline int real_cast<int, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 564 {
Chris@16 565 int result;
Chris@16 566 detail::convert_to_long_result(t.value(), result);
Chris@16 567 return result;
Chris@16 568 }
Chris@16 569 template <>
Chris@16 570 inline long real_cast<long, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 571 {
Chris@16 572 long result;
Chris@16 573 detail::convert_to_long_result(t.value(), result);
Chris@16 574 return result;
Chris@16 575 }
Chris@16 576 template <>
Chris@16 577 inline long long real_cast<long long, boost::math::ntl::RR>(boost::math::ntl::RR t)
Chris@16 578 {
Chris@16 579 long long result;
Chris@16 580 detail::convert_to_long_result(t.value(), result);
Chris@16 581 return result;
Chris@16 582 }
Chris@16 583
Chris@16 584 template <>
Chris@16 585 inline boost::math::ntl::RR max_value<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 586 {
Chris@16 587 static bool has_init = false;
Chris@16 588 static NTL::RR val;
Chris@16 589 if(!has_init)
Chris@16 590 {
Chris@16 591 val = 1;
Chris@16 592 val.e = NTL_OVFBND-20;
Chris@16 593 has_init = true;
Chris@16 594 }
Chris@16 595 return val;
Chris@16 596 }
Chris@16 597
Chris@16 598 template <>
Chris@16 599 inline boost::math::ntl::RR min_value<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 600 {
Chris@16 601 static bool has_init = false;
Chris@16 602 static NTL::RR val;
Chris@16 603 if(!has_init)
Chris@16 604 {
Chris@16 605 val = 1;
Chris@16 606 val.e = -NTL_OVFBND+20;
Chris@16 607 has_init = true;
Chris@16 608 }
Chris@16 609 return val;
Chris@16 610 }
Chris@16 611
Chris@16 612 template <>
Chris@16 613 inline boost::math::ntl::RR log_max_value<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 614 {
Chris@16 615 static bool has_init = false;
Chris@16 616 static NTL::RR val;
Chris@16 617 if(!has_init)
Chris@16 618 {
Chris@16 619 val = 1;
Chris@16 620 val.e = NTL_OVFBND-20;
Chris@16 621 val = log(val);
Chris@16 622 has_init = true;
Chris@16 623 }
Chris@16 624 return val;
Chris@16 625 }
Chris@16 626
Chris@16 627 template <>
Chris@16 628 inline boost::math::ntl::RR log_min_value<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 629 {
Chris@16 630 static bool has_init = false;
Chris@16 631 static NTL::RR val;
Chris@16 632 if(!has_init)
Chris@16 633 {
Chris@16 634 val = 1;
Chris@16 635 val.e = -NTL_OVFBND+20;
Chris@16 636 val = log(val);
Chris@16 637 has_init = true;
Chris@16 638 }
Chris@16 639 return val;
Chris@16 640 }
Chris@16 641
Chris@16 642 template <>
Chris@16 643 inline boost::math::ntl::RR epsilon<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 644 {
Chris@16 645 return ldexp(boost::math::ntl::RR(1), 1-boost::math::policies::digits<boost::math::ntl::RR, boost::math::policies::policy<> >());
Chris@16 646 }
Chris@16 647
Chris@16 648 } // namespace tools
Chris@16 649
Chris@16 650 //
Chris@16 651 // The number of digits precision in RR can vary with each call
Chris@16 652 // so we need to recalculate these with each call:
Chris@16 653 //
Chris@16 654 namespace constants{
Chris@16 655
Chris@16 656 template<> inline boost::math::ntl::RR pi<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 657 {
Chris@16 658 NTL::RR result;
Chris@16 659 ComputePi(result);
Chris@16 660 return result;
Chris@16 661 }
Chris@16 662 template<> inline boost::math::ntl::RR e<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
Chris@16 663 {
Chris@16 664 NTL::RR result;
Chris@16 665 result = 1;
Chris@16 666 return exp(result);
Chris@16 667 }
Chris@16 668
Chris@16 669 } // namespace constants
Chris@16 670
Chris@16 671 namespace ntl{
Chris@16 672 //
Chris@16 673 // These are some fairly brain-dead versions of the math
Chris@16 674 // functions that NTL fails to provide.
Chris@16 675 //
Chris@16 676
Chris@16 677
Chris@16 678 //
Chris@16 679 // Inverse trig functions:
Chris@16 680 //
Chris@16 681 struct asin_root
Chris@16 682 {
Chris@16 683 asin_root(RR const& target) : t(target){}
Chris@16 684
Chris@16 685 boost::math::tuple<RR, RR, RR> operator()(RR const& p)
Chris@16 686 {
Chris@16 687 RR f0 = sin(p);
Chris@16 688 RR f1 = cos(p);
Chris@16 689 RR f2 = -f0;
Chris@16 690 f0 -= t;
Chris@16 691 return boost::math::make_tuple(f0, f1, f2);
Chris@16 692 }
Chris@16 693 private:
Chris@16 694 RR t;
Chris@16 695 };
Chris@16 696
Chris@16 697 inline RR asin(RR z)
Chris@16 698 {
Chris@16 699 double r;
Chris@16 700 conv(r, z.value());
Chris@16 701 return boost::math::tools::halley_iterate(
Chris@16 702 asin_root(z),
Chris@16 703 RR(std::asin(r)),
Chris@16 704 RR(-boost::math::constants::pi<RR>()/2),
Chris@16 705 RR(boost::math::constants::pi<RR>()/2),
Chris@16 706 NTL::RR::precision());
Chris@16 707 }
Chris@16 708
Chris@16 709 struct acos_root
Chris@16 710 {
Chris@16 711 acos_root(RR const& target) : t(target){}
Chris@16 712
Chris@16 713 boost::math::tuple<RR, RR, RR> operator()(RR const& p)
Chris@16 714 {
Chris@16 715 RR f0 = cos(p);
Chris@16 716 RR f1 = -sin(p);
Chris@16 717 RR f2 = -f0;
Chris@16 718 f0 -= t;
Chris@16 719 return boost::math::make_tuple(f0, f1, f2);
Chris@16 720 }
Chris@16 721 private:
Chris@16 722 RR t;
Chris@16 723 };
Chris@16 724
Chris@16 725 inline RR acos(RR z)
Chris@16 726 {
Chris@16 727 double r;
Chris@16 728 conv(r, z.value());
Chris@16 729 return boost::math::tools::halley_iterate(
Chris@16 730 acos_root(z),
Chris@16 731 RR(std::acos(r)),
Chris@16 732 RR(-boost::math::constants::pi<RR>()/2),
Chris@16 733 RR(boost::math::constants::pi<RR>()/2),
Chris@16 734 NTL::RR::precision());
Chris@16 735 }
Chris@16 736
Chris@16 737 struct atan_root
Chris@16 738 {
Chris@16 739 atan_root(RR const& target) : t(target){}
Chris@16 740
Chris@16 741 boost::math::tuple<RR, RR, RR> operator()(RR const& p)
Chris@16 742 {
Chris@16 743 RR c = cos(p);
Chris@16 744 RR ta = tan(p);
Chris@16 745 RR f0 = ta - t;
Chris@16 746 RR f1 = 1 / (c * c);
Chris@16 747 RR f2 = 2 * ta / (c * c);
Chris@16 748 return boost::math::make_tuple(f0, f1, f2);
Chris@16 749 }
Chris@16 750 private:
Chris@16 751 RR t;
Chris@16 752 };
Chris@16 753
Chris@16 754 inline RR atan(RR z)
Chris@16 755 {
Chris@16 756 double r;
Chris@16 757 conv(r, z.value());
Chris@16 758 return boost::math::tools::halley_iterate(
Chris@16 759 atan_root(z),
Chris@16 760 RR(std::atan(r)),
Chris@16 761 -boost::math::constants::pi<RR>()/2,
Chris@16 762 boost::math::constants::pi<RR>()/2,
Chris@16 763 NTL::RR::precision());
Chris@16 764 }
Chris@16 765
Chris@16 766 inline RR atan2(RR y, RR x)
Chris@16 767 {
Chris@16 768 if(x > 0)
Chris@16 769 return atan(y / x);
Chris@16 770 if(x < 0)
Chris@16 771 {
Chris@16 772 return y < 0 ? atan(y / x) - boost::math::constants::pi<RR>() : atan(y / x) + boost::math::constants::pi<RR>();
Chris@16 773 }
Chris@16 774 return y < 0 ? -boost::math::constants::half_pi<RR>() : boost::math::constants::half_pi<RR>() ;
Chris@16 775 }
Chris@16 776
Chris@16 777 inline RR sinh(RR z)
Chris@16 778 {
Chris@16 779 return (expm1(z.value()) - expm1(-z.value())) / 2;
Chris@16 780 }
Chris@16 781
Chris@16 782 inline RR cosh(RR z)
Chris@16 783 {
Chris@16 784 return (exp(z) + exp(-z)) / 2;
Chris@16 785 }
Chris@16 786
Chris@16 787 inline RR tanh(RR z)
Chris@16 788 {
Chris@16 789 return sinh(z) / cosh(z);
Chris@16 790 }
Chris@16 791
Chris@16 792 inline RR fmod(RR x, RR y)
Chris@16 793 {
Chris@16 794 // This is a really crummy version of fmod, we rely on lots
Chris@16 795 // of digits to get us out of trouble...
Chris@16 796 RR factor = floor(x/y);
Chris@16 797 return x - factor * y;
Chris@16 798 }
Chris@16 799
Chris@16 800 template <class Policy>
Chris@16 801 inline int iround(RR const& x, const Policy& pol)
Chris@16 802 {
Chris@16 803 return tools::real_cast<int>(round(x, pol));
Chris@16 804 }
Chris@16 805
Chris@16 806 template <class Policy>
Chris@16 807 inline long lround(RR const& x, const Policy& pol)
Chris@16 808 {
Chris@16 809 return tools::real_cast<long>(round(x, pol));
Chris@16 810 }
Chris@16 811
Chris@16 812 template <class Policy>
Chris@16 813 inline long long llround(RR const& x, const Policy& pol)
Chris@16 814 {
Chris@16 815 return tools::real_cast<long long>(round(x, pol));
Chris@16 816 }
Chris@16 817
Chris@16 818 template <class Policy>
Chris@16 819 inline int itrunc(RR const& x, const Policy& pol)
Chris@16 820 {
Chris@16 821 return tools::real_cast<int>(trunc(x, pol));
Chris@16 822 }
Chris@16 823
Chris@16 824 template <class Policy>
Chris@16 825 inline long ltrunc(RR const& x, const Policy& pol)
Chris@16 826 {
Chris@16 827 return tools::real_cast<long>(trunc(x, pol));
Chris@16 828 }
Chris@16 829
Chris@16 830 template <class Policy>
Chris@16 831 inline long long lltrunc(RR const& x, const Policy& pol)
Chris@16 832 {
Chris@16 833 return tools::real_cast<long long>(trunc(x, pol));
Chris@16 834 }
Chris@16 835
Chris@16 836 } // namespace ntl
Chris@16 837
Chris@16 838 namespace detail{
Chris@16 839
Chris@16 840 template <class Policy>
Chris@16 841 ntl::RR digamma_imp(ntl::RR x, const mpl::int_<0>* , const Policy& pol)
Chris@16 842 {
Chris@16 843 //
Chris@16 844 // This handles reflection of negative arguments, and all our
Chris@16 845 // error handling, then forwards to the T-specific approximation.
Chris@16 846 //
Chris@16 847 BOOST_MATH_STD_USING // ADL of std functions.
Chris@16 848
Chris@16 849 ntl::RR result = 0;
Chris@16 850 //
Chris@16 851 // Check for negative arguments and use reflection:
Chris@16 852 //
Chris@16 853 if(x < 0)
Chris@16 854 {
Chris@16 855 // Reflect:
Chris@16 856 x = 1 - x;
Chris@16 857 // Argument reduction for tan:
Chris@16 858 ntl::RR remainder = x - floor(x);
Chris@16 859 // Shift to negative if > 0.5:
Chris@16 860 if(remainder > 0.5)
Chris@16 861 {
Chris@16 862 remainder -= 1;
Chris@16 863 }
Chris@16 864 //
Chris@16 865 // check for evaluation at a negative pole:
Chris@16 866 //
Chris@16 867 if(remainder == 0)
Chris@16 868 {
Chris@16 869 return policies::raise_pole_error<ntl::RR>("boost::math::digamma<%1%>(%1%)", 0, (1-x), pol);
Chris@16 870 }
Chris@16 871 result = constants::pi<ntl::RR>() / tan(constants::pi<ntl::RR>() * remainder);
Chris@16 872 }
Chris@16 873 result += big_digamma(x);
Chris@16 874 return result;
Chris@16 875 }
Chris@16 876
Chris@16 877 } // namespace detail
Chris@16 878
Chris@16 879 } // namespace math
Chris@16 880 } // namespace boost
Chris@16 881
Chris@16 882 #endif // BOOST_MATH_REAL_CONCEPT_HPP
Chris@16 883
Chris@16 884