1 // Special functions -*- C++ -*- 2 3 // Copyright (C) 2006-2013 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 // 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file tr1/ell_integral.tcc 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{tr1/cmath} 28 */ 29 30 // 31 // ISO C++ 14882 TR1: 5.2 Special functions 32 // 33 34 // Written by Edward Smith-Rowland based on: 35 // (1) B. C. Carlson Numer. Math. 33, 1 (1979) 36 // (2) B. C. Carlson, Special Functions of Applied Mathematics (1977) 37 // (3) The Gnu Scientific Library, http://www.gnu.org/software/gsl 38 // (4) Numerical Recipes in C, 2nd ed, by W. H. Press, S. A. Teukolsky, 39 // W. T. Vetterling, B. P. Flannery, Cambridge University Press 40 // (1992), pp. 261-269 41 42 #ifndef _GLIBCXX_TR1_ELL_INTEGRAL_TCC 43 #define _GLIBCXX_TR1_ELL_INTEGRAL_TCC 1 44 45 namespace std _GLIBCXX_VISIBILITY(default) 46 { 47 namespace tr1 48 { 49 // [5.2] Special functions 50 51 // Implementation-space details. 52 namespace __detail 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 /** 57 * @brief Return the Carlson elliptic function @f$ R_F(x,y,z) @f$ 58 * of the first kind. 59 * 60 * The Carlson elliptic function of the first kind is defined by: 61 * @f[ 62 * R_F(x,y,z) = \frac{1}{2} \int_0^\infty 63 * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}} 64 * @f] 65 * 66 * @param __x The first of three symmetric arguments. 67 * @param __y The second of three symmetric arguments. 68 * @param __z The third of three symmetric arguments. 69 * @return The Carlson elliptic function of the first kind. 70 */ 71 template<typename _Tp> 72 _Tp 73 __ellint_rf(_Tp __x, _Tp __y, _Tp __z) 74 { 75 const _Tp __min = std::numeric_limits<_Tp>::min(); 76 const _Tp __max = std::numeric_limits<_Tp>::max(); 77 const _Tp __lolim = _Tp(5) * __min; 78 const _Tp __uplim = __max / _Tp(5); 79 80 if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0)) 81 std::__throw_domain_error(__N("Argument less than zero " 82 "in __ellint_rf.")); 83 else if (__x + __y < __lolim || __x + __z < __lolim 84 || __y + __z < __lolim) 85 std::__throw_domain_error(__N("Argument too small in __ellint_rf")); 86 else 87 { 88 const _Tp __c0 = _Tp(1) / _Tp(4); 89 const _Tp __c1 = _Tp(1) / _Tp(24); 90 const _Tp __c2 = _Tp(1) / _Tp(10); 91 const _Tp __c3 = _Tp(3) / _Tp(44); 92 const _Tp __c4 = _Tp(1) / _Tp(14); 93 94 _Tp __xn = __x; 95 _Tp __yn = __y; 96 _Tp __zn = __z; 97 98 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 99 const _Tp __errtol = std::pow(__eps, _Tp(1) / _Tp(6)); 100 _Tp __mu; 101 _Tp __xndev, __yndev, __zndev; 102 103 const unsigned int __max_iter = 100; 104 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 105 { 106 __mu = (__xn + __yn + __zn) / _Tp(3); 107 __xndev = 2 - (__mu + __xn) / __mu; 108 __yndev = 2 - (__mu + __yn) / __mu; 109 __zndev = 2 - (__mu + __zn) / __mu; 110 _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); 111 __epsilon = std::max(__epsilon, std::abs(__zndev)); 112 if (__epsilon < __errtol) 113 break; 114 const _Tp __xnroot = std::sqrt(__xn); 115 const _Tp __ynroot = std::sqrt(__yn); 116 const _Tp __znroot = std::sqrt(__zn); 117 const _Tp __lambda = __xnroot * (__ynroot + __znroot) 118 + __ynroot * __znroot; 119 __xn = __c0 * (__xn + __lambda); 120 __yn = __c0 * (__yn + __lambda); 121 __zn = __c0 * (__zn + __lambda); 122 } 123 124 const _Tp __e2 = __xndev * __yndev - __zndev * __zndev; 125 const _Tp __e3 = __xndev * __yndev * __zndev; 126 const _Tp __s = _Tp(1) + (__c1 * __e2 - __c2 - __c3 * __e3) * __e2 127 + __c4 * __e3; 128 129 return __s / std::sqrt(__mu); 130 } 131 } 132 133 134 /** 135 * @brief Return the complete elliptic integral of the first kind 136 * @f$ K(k) @f$ by series expansion. 137 * 138 * The complete elliptic integral of the first kind is defined as 139 * @f[ 140 * K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta} 141 * {\sqrt{1 - k^2sin^2\theta}} 142 * @f] 143 * 144 * This routine is not bad as long as |k| is somewhat smaller than 1 145 * but is not is good as the Carlson elliptic integral formulation. 146 * 147 * @param __k The argument of the complete elliptic function. 148 * @return The complete elliptic function of the first kind. 149 */ 150 template<typename _Tp> 151 _Tp 152 __comp_ellint_1_series(_Tp __k) 153 { 154 155 const _Tp __kk = __k * __k; 156 157 _Tp __term = __kk / _Tp(4); 158 _Tp __sum = _Tp(1) + __term; 159 160 const unsigned int __max_iter = 1000; 161 for (unsigned int __i = 2; __i < __max_iter; ++__i) 162 { 163 __term *= (2 * __i - 1) * __kk / (2 * __i); 164 if (__term < std::numeric_limits<_Tp>::epsilon()) 165 break; 166 __sum += __term; 167 } 168 169 return __numeric_constants<_Tp>::__pi_2() * __sum; 170 } 171 172 173 /** 174 * @brief Return the complete elliptic integral of the first kind 175 * @f$ K(k) @f$ using the Carlson formulation. 176 * 177 * The complete elliptic integral of the first kind is defined as 178 * @f[ 179 * K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta} 180 * {\sqrt{1 - k^2 sin^2\theta}} 181 * @f] 182 * where @f$ F(k,\phi) @f$ is the incomplete elliptic integral of the 183 * first kind. 184 * 185 * @param __k The argument of the complete elliptic function. 186 * @return The complete elliptic function of the first kind. 187 */ 188 template<typename _Tp> 189 _Tp 190 __comp_ellint_1(_Tp __k) 191 { 192 193 if (__isnan(__k)) 194 return std::numeric_limits<_Tp>::quiet_NaN(); 195 else if (std::abs(__k) >= _Tp(1)) 196 return std::numeric_limits<_Tp>::quiet_NaN(); 197 else 198 return __ellint_rf(_Tp(0), _Tp(1) - __k * __k, _Tp(1)); 199 } 200 201 202 /** 203 * @brief Return the incomplete elliptic integral of the first kind 204 * @f$ F(k,\phi) @f$ using the Carlson formulation. 205 * 206 * The incomplete elliptic integral of the first kind is defined as 207 * @f[ 208 * F(k,\phi) = \int_0^{\phi}\frac{d\theta} 209 * {\sqrt{1 - k^2 sin^2\theta}} 210 * @f] 211 * 212 * @param __k The argument of the elliptic function. 213 * @param __phi The integral limit argument of the elliptic function. 214 * @return The elliptic function of the first kind. 215 */ 216 template<typename _Tp> 217 _Tp 218 __ellint_1(_Tp __k, _Tp __phi) 219 { 220 221 if (__isnan(__k) || __isnan(__phi)) 222 return std::numeric_limits<_Tp>::quiet_NaN(); 223 else if (std::abs(__k) > _Tp(1)) 224 std::__throw_domain_error(__N("Bad argument in __ellint_1.")); 225 else 226 { 227 // Reduce phi to -pi/2 < phi < +pi/2. 228 const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() 229 + _Tp(0.5L)); 230 const _Tp __phi_red = __phi 231 - __n * __numeric_constants<_Tp>::__pi(); 232 233 const _Tp __s = std::sin(__phi_red); 234 const _Tp __c = std::cos(__phi_red); 235 236 const _Tp __F = __s 237 * __ellint_rf(__c * __c, 238 _Tp(1) - __k * __k * __s * __s, _Tp(1)); 239 240 if (__n == 0) 241 return __F; 242 else 243 return __F + _Tp(2) * __n * __comp_ellint_1(__k); 244 } 245 } 246 247 248 /** 249 * @brief Return the complete elliptic integral of the second kind 250 * @f$ E(k) @f$ by series expansion. 251 * 252 * The complete elliptic integral of the second kind is defined as 253 * @f[ 254 * E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta} 255 * @f] 256 * 257 * This routine is not bad as long as |k| is somewhat smaller than 1 258 * but is not is good as the Carlson elliptic integral formulation. 259 * 260 * @param __k The argument of the complete elliptic function. 261 * @return The complete elliptic function of the second kind. 262 */ 263 template<typename _Tp> 264 _Tp 265 __comp_ellint_2_series(_Tp __k) 266 { 267 268 const _Tp __kk = __k * __k; 269 270 _Tp __term = __kk; 271 _Tp __sum = __term; 272 273 const unsigned int __max_iter = 1000; 274 for (unsigned int __i = 2; __i < __max_iter; ++__i) 275 { 276 const _Tp __i2m = 2 * __i - 1; 277 const _Tp __i2 = 2 * __i; 278 __term *= __i2m * __i2m * __kk / (__i2 * __i2); 279 if (__term < std::numeric_limits<_Tp>::epsilon()) 280 break; 281 __sum += __term / __i2m; 282 } 283 284 return __numeric_constants<_Tp>::__pi_2() * (_Tp(1) - __sum); 285 } 286 287 288 /** 289 * @brief Return the Carlson elliptic function of the second kind 290 * @f$ R_D(x,y,z) = R_J(x,y,z,z) @f$ where 291 * @f$ R_J(x,y,z,p) @f$ is the Carlson elliptic function 292 * of the third kind. 293 * 294 * The Carlson elliptic function of the second kind is defined by: 295 * @f[ 296 * R_D(x,y,z) = \frac{3}{2} \int_0^\infty 297 * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{3/2}} 298 * @f] 299 * 300 * Based on Carlson's algorithms: 301 * - B. C. Carlson Numer. Math. 33, 1 (1979) 302 * - B. C. Carlson, Special Functions of Applied Mathematics (1977) 303 * - Numerical Recipes in C, 2nd ed, pp. 261-269, 304 * by Press, Teukolsky, Vetterling, Flannery (1992) 305 * 306 * @param __x The first of two symmetric arguments. 307 * @param __y The second of two symmetric arguments. 308 * @param __z The third argument. 309 * @return The Carlson elliptic function of the second kind. 310 */ 311 template<typename _Tp> 312 _Tp 313 __ellint_rd(_Tp __x, _Tp __y, _Tp __z) 314 { 315 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 316 const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6)); 317 const _Tp __min = std::numeric_limits<_Tp>::min(); 318 const _Tp __max = std::numeric_limits<_Tp>::max(); 319 const _Tp __lolim = _Tp(2) / std::pow(__max, _Tp(2) / _Tp(3)); 320 const _Tp __uplim = std::pow(_Tp(0.1L) * __errtol / __min, _Tp(2) / _Tp(3)); 321 322 if (__x < _Tp(0) || __y < _Tp(0)) 323 std::__throw_domain_error(__N("Argument less than zero " 324 "in __ellint_rd.")); 325 else if (__x + __y < __lolim || __z < __lolim) 326 std::__throw_domain_error(__N("Argument too small " 327 "in __ellint_rd.")); 328 else 329 { 330 const _Tp __c0 = _Tp(1) / _Tp(4); 331 const _Tp __c1 = _Tp(3) / _Tp(14); 332 const _Tp __c2 = _Tp(1) / _Tp(6); 333 const _Tp __c3 = _Tp(9) / _Tp(22); 334 const _Tp __c4 = _Tp(3) / _Tp(26); 335 336 _Tp __xn = __x; 337 _Tp __yn = __y; 338 _Tp __zn = __z; 339 _Tp __sigma = _Tp(0); 340 _Tp __power4 = _Tp(1); 341 342 _Tp __mu; 343 _Tp __xndev, __yndev, __zndev; 344 345 const unsigned int __max_iter = 100; 346 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 347 { 348 __mu = (__xn + __yn + _Tp(3) * __zn) / _Tp(5); 349 __xndev = (__mu - __xn) / __mu; 350 __yndev = (__mu - __yn) / __mu; 351 __zndev = (__mu - __zn) / __mu; 352 _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); 353 __epsilon = std::max(__epsilon, std::abs(__zndev)); 354 if (__epsilon < __errtol) 355 break; 356 _Tp __xnroot = std::sqrt(__xn); 357 _Tp __ynroot = std::sqrt(__yn); 358 _Tp __znroot = std::sqrt(__zn); 359 _Tp __lambda = __xnroot * (__ynroot + __znroot) 360 + __ynroot * __znroot; 361 __sigma += __power4 / (__znroot * (__zn + __lambda)); 362 __power4 *= __c0; 363 __xn = __c0 * (__xn + __lambda); 364 __yn = __c0 * (__yn + __lambda); 365 __zn = __c0 * (__zn + __lambda); 366 } 367 368 // Note: __ea is an SPU badname. 369 _Tp __eaa = __xndev * __yndev; 370 _Tp __eb = __zndev * __zndev; 371 _Tp __ec = __eaa - __eb; 372 _Tp __ed = __eaa - _Tp(6) * __eb; 373 _Tp __ef = __ed + __ec + __ec; 374 _Tp __s1 = __ed * (-__c1 + __c3 * __ed 375 / _Tp(3) - _Tp(3) * __c4 * __zndev * __ef 376 / _Tp(2)); 377 _Tp __s2 = __zndev 378 * (__c2 * __ef 379 + __zndev * (-__c3 * __ec - __zndev * __c4 - __eaa)); 380 381 return _Tp(3) * __sigma + __power4 * (_Tp(1) + __s1 + __s2) 382 / (__mu * std::sqrt(__mu)); 383 } 384 } 385 386 387 /** 388 * @brief Return the complete elliptic integral of the second kind 389 * @f$ E(k) @f$ using the Carlson formulation. 390 * 391 * The complete elliptic integral of the second kind is defined as 392 * @f[ 393 * E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta} 394 * @f] 395 * 396 * @param __k The argument of the complete elliptic function. 397 * @return The complete elliptic function of the second kind. 398 */ 399 template<typename _Tp> 400 _Tp 401 __comp_ellint_2(_Tp __k) 402 { 403 404 if (__isnan(__k)) 405 return std::numeric_limits<_Tp>::quiet_NaN(); 406 else if (std::abs(__k) == 1) 407 return _Tp(1); 408 else if (std::abs(__k) > _Tp(1)) 409 std::__throw_domain_error(__N("Bad argument in __comp_ellint_2.")); 410 else 411 { 412 const _Tp __kk = __k * __k; 413 414 return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1)) 415 - __kk * __ellint_rd(_Tp(0), _Tp(1) - __kk, _Tp(1)) / _Tp(3); 416 } 417 } 418 419 420 /** 421 * @brief Return the incomplete elliptic integral of the second kind 422 * @f$ E(k,\phi) @f$ using the Carlson formulation. 423 * 424 * The incomplete elliptic integral of the second kind is defined as 425 * @f[ 426 * E(k,\phi) = \int_0^{\phi} \sqrt{1 - k^2 sin^2\theta} 427 * @f] 428 * 429 * @param __k The argument of the elliptic function. 430 * @param __phi The integral limit argument of the elliptic function. 431 * @return The elliptic function of the second kind. 432 */ 433 template<typename _Tp> 434 _Tp 435 __ellint_2(_Tp __k, _Tp __phi) 436 { 437 438 if (__isnan(__k) || __isnan(__phi)) 439 return std::numeric_limits<_Tp>::quiet_NaN(); 440 else if (std::abs(__k) > _Tp(1)) 441 std::__throw_domain_error(__N("Bad argument in __ellint_2.")); 442 else 443 { 444 // Reduce phi to -pi/2 < phi < +pi/2. 445 const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() 446 + _Tp(0.5L)); 447 const _Tp __phi_red = __phi 448 - __n * __numeric_constants<_Tp>::__pi(); 449 450 const _Tp __kk = __k * __k; 451 const _Tp __s = std::sin(__phi_red); 452 const _Tp __ss = __s * __s; 453 const _Tp __sss = __ss * __s; 454 const _Tp __c = std::cos(__phi_red); 455 const _Tp __cc = __c * __c; 456 457 const _Tp __E = __s 458 * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1)) 459 - __kk * __sss 460 * __ellint_rd(__cc, _Tp(1) - __kk * __ss, _Tp(1)) 461 / _Tp(3); 462 463 if (__n == 0) 464 return __E; 465 else 466 return __E + _Tp(2) * __n * __comp_ellint_2(__k); 467 } 468 } 469 470 471 /** 472 * @brief Return the Carlson elliptic function 473 * @f$ R_C(x,y) = R_F(x,y,y) @f$ where @f$ R_F(x,y,z) @f$ 474 * is the Carlson elliptic function of the first kind. 475 * 476 * The Carlson elliptic function is defined by: 477 * @f[ 478 * R_C(x,y) = \frac{1}{2} \int_0^\infty 479 * \frac{dt}{(t + x)^{1/2}(t + y)} 480 * @f] 481 * 482 * Based on Carlson's algorithms: 483 * - B. C. Carlson Numer. Math. 33, 1 (1979) 484 * - B. C. Carlson, Special Functions of Applied Mathematics (1977) 485 * - Numerical Recipes in C, 2nd ed, pp. 261-269, 486 * by Press, Teukolsky, Vetterling, Flannery (1992) 487 * 488 * @param __x The first argument. 489 * @param __y The second argument. 490 * @return The Carlson elliptic function. 491 */ 492 template<typename _Tp> 493 _Tp 494 __ellint_rc(_Tp __x, _Tp __y) 495 { 496 const _Tp __min = std::numeric_limits<_Tp>::min(); 497 const _Tp __max = std::numeric_limits<_Tp>::max(); 498 const _Tp __lolim = _Tp(5) * __min; 499 const _Tp __uplim = __max / _Tp(5); 500 501 if (__x < _Tp(0) || __y < _Tp(0) || __x + __y < __lolim) 502 std::__throw_domain_error(__N("Argument less than zero " 503 "in __ellint_rc.")); 504 else 505 { 506 const _Tp __c0 = _Tp(1) / _Tp(4); 507 const _Tp __c1 = _Tp(1) / _Tp(7); 508 const _Tp __c2 = _Tp(9) / _Tp(22); 509 const _Tp __c3 = _Tp(3) / _Tp(10); 510 const _Tp __c4 = _Tp(3) / _Tp(8); 511 512 _Tp __xn = __x; 513 _Tp __yn = __y; 514 515 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 516 const _Tp __errtol = std::pow(__eps / _Tp(30), _Tp(1) / _Tp(6)); 517 _Tp __mu; 518 _Tp __sn; 519 520 const unsigned int __max_iter = 100; 521 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 522 { 523 __mu = (__xn + _Tp(2) * __yn) / _Tp(3); 524 __sn = (__yn + __mu) / __mu - _Tp(2); 525 if (std::abs(__sn) < __errtol) 526 break; 527 const _Tp __lambda = _Tp(2) * std::sqrt(__xn) * std::sqrt(__yn) 528 + __yn; 529 __xn = __c0 * (__xn + __lambda); 530 __yn = __c0 * (__yn + __lambda); 531 } 532 533 _Tp __s = __sn * __sn 534 * (__c3 + __sn*(__c1 + __sn * (__c4 + __sn * __c2))); 535 536 return (_Tp(1) + __s) / std::sqrt(__mu); 537 } 538 } 539 540 541 /** 542 * @brief Return the Carlson elliptic function @f$ R_J(x,y,z,p) @f$ 543 * of the third kind. 544 * 545 * The Carlson elliptic function of the third kind is defined by: 546 * @f[ 547 * R_J(x,y,z,p) = \frac{3}{2} \int_0^\infty 548 * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}(t + p)} 549 * @f] 550 * 551 * Based on Carlson's algorithms: 552 * - B. C. Carlson Numer. Math. 33, 1 (1979) 553 * - B. C. Carlson, Special Functions of Applied Mathematics (1977) 554 * - Numerical Recipes in C, 2nd ed, pp. 261-269, 555 * by Press, Teukolsky, Vetterling, Flannery (1992) 556 * 557 * @param __x The first of three symmetric arguments. 558 * @param __y The second of three symmetric arguments. 559 * @param __z The third of three symmetric arguments. 560 * @param __p The fourth argument. 561 * @return The Carlson elliptic function of the fourth kind. 562 */ 563 template<typename _Tp> 564 _Tp 565 __ellint_rj(_Tp __x, _Tp __y, _Tp __z, _Tp __p) 566 { 567 const _Tp __min = std::numeric_limits<_Tp>::min(); 568 const _Tp __max = std::numeric_limits<_Tp>::max(); 569 const _Tp __lolim = std::pow(_Tp(5) * __min, _Tp(1)/_Tp(3)); 570 const _Tp __uplim = _Tp(0.3L) 571 * std::pow(_Tp(0.2L) * __max, _Tp(1)/_Tp(3)); 572 573 if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0)) 574 std::__throw_domain_error(__N("Argument less than zero " 575 "in __ellint_rj.")); 576 else if (__x + __y < __lolim || __x + __z < __lolim 577 || __y + __z < __lolim || __p < __lolim) 578 std::__throw_domain_error(__N("Argument too small " 579 "in __ellint_rj")); 580 else 581 { 582 const _Tp __c0 = _Tp(1) / _Tp(4); 583 const _Tp __c1 = _Tp(3) / _Tp(14); 584 const _Tp __c2 = _Tp(1) / _Tp(3); 585 const _Tp __c3 = _Tp(3) / _Tp(22); 586 const _Tp __c4 = _Tp(3) / _Tp(26); 587 588 _Tp __xn = __x; 589 _Tp __yn = __y; 590 _Tp __zn = __z; 591 _Tp __pn = __p; 592 _Tp __sigma = _Tp(0); 593 _Tp __power4 = _Tp(1); 594 595 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 596 const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6)); 597 598 _Tp __lambda, __mu; 599 _Tp __xndev, __yndev, __zndev, __pndev; 600 601 const unsigned int __max_iter = 100; 602 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 603 { 604 __mu = (__xn + __yn + __zn + _Tp(2) * __pn) / _Tp(5); 605 __xndev = (__mu - __xn) / __mu; 606 __yndev = (__mu - __yn) / __mu; 607 __zndev = (__mu - __zn) / __mu; 608 __pndev = (__mu - __pn) / __mu; 609 _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); 610 __epsilon = std::max(__epsilon, std::abs(__zndev)); 611 __epsilon = std::max(__epsilon, std::abs(__pndev)); 612 if (__epsilon < __errtol) 613 break; 614 const _Tp __xnroot = std::sqrt(__xn); 615 const _Tp __ynroot = std::sqrt(__yn); 616 const _Tp __znroot = std::sqrt(__zn); 617 const _Tp __lambda = __xnroot * (__ynroot + __znroot) 618 + __ynroot * __znroot; 619 const _Tp __alpha1 = __pn * (__xnroot + __ynroot + __znroot) 620 + __xnroot * __ynroot * __znroot; 621 const _Tp __alpha2 = __alpha1 * __alpha1; 622 const _Tp __beta = __pn * (__pn + __lambda) 623 * (__pn + __lambda); 624 __sigma += __power4 * __ellint_rc(__alpha2, __beta); 625 __power4 *= __c0; 626 __xn = __c0 * (__xn + __lambda); 627 __yn = __c0 * (__yn + __lambda); 628 __zn = __c0 * (__zn + __lambda); 629 __pn = __c0 * (__pn + __lambda); 630 } 631 632 // Note: __ea is an SPU badname. 633 _Tp __eaa = __xndev * (__yndev + __zndev) + __yndev * __zndev; 634 _Tp __eb = __xndev * __yndev * __zndev; 635 _Tp __ec = __pndev * __pndev; 636 _Tp __e2 = __eaa - _Tp(3) * __ec; 637 _Tp __e3 = __eb + _Tp(2) * __pndev * (__eaa - __ec); 638 _Tp __s1 = _Tp(1) + __e2 * (-__c1 + _Tp(3) * __c3 * __e2 / _Tp(4) 639 - _Tp(3) * __c4 * __e3 / _Tp(2)); 640 _Tp __s2 = __eb * (__c2 / _Tp(2) 641 + __pndev * (-__c3 - __c3 + __pndev * __c4)); 642 _Tp __s3 = __pndev * __eaa * (__c2 - __pndev * __c3) 643 - __c2 * __pndev * __ec; 644 645 return _Tp(3) * __sigma + __power4 * (__s1 + __s2 + __s3) 646 / (__mu * std::sqrt(__mu)); 647 } 648 } 649 650 651 /** 652 * @brief Return the complete elliptic integral of the third kind 653 * @f$ \Pi(k,\nu) = \Pi(k,\nu,\pi/2) @f$ using the 654 * Carlson formulation. 655 * 656 * The complete elliptic integral of the third kind is defined as 657 * @f[ 658 * \Pi(k,\nu) = \int_0^{\pi/2} 659 * \frac{d\theta} 660 * {(1 - \nu \sin^2\theta)\sqrt{1 - k^2 \sin^2\theta}} 661 * @f] 662 * 663 * @param __k The argument of the elliptic function. 664 * @param __nu The second argument of the elliptic function. 665 * @return The complete elliptic function of the third kind. 666 */ 667 template<typename _Tp> 668 _Tp 669 __comp_ellint_3(_Tp __k, _Tp __nu) 670 { 671 672 if (__isnan(__k) || __isnan(__nu)) 673 return std::numeric_limits<_Tp>::quiet_NaN(); 674 else if (__nu == _Tp(1)) 675 return std::numeric_limits<_Tp>::infinity(); 676 else if (std::abs(__k) > _Tp(1)) 677 std::__throw_domain_error(__N("Bad argument in __comp_ellint_3.")); 678 else 679 { 680 const _Tp __kk = __k * __k; 681 682 return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1)) 683 - __nu 684 * __ellint_rj(_Tp(0), _Tp(1) - __kk, _Tp(1), _Tp(1) + __nu) 685 / _Tp(3); 686 } 687 } 688 689 690 /** 691 * @brief Return the incomplete elliptic integral of the third kind 692 * @f$ \Pi(k,\nu,\phi) @f$ using the Carlson formulation. 693 * 694 * The incomplete elliptic integral of the third kind is defined as 695 * @f[ 696 * \Pi(k,\nu,\phi) = \int_0^{\phi} 697 * \frac{d\theta} 698 * {(1 - \nu \sin^2\theta) 699 * \sqrt{1 - k^2 \sin^2\theta}} 700 * @f] 701 * 702 * @param __k The argument of the elliptic function. 703 * @param __nu The second argument of the elliptic function. 704 * @param __phi The integral limit argument of the elliptic function. 705 * @return The elliptic function of the third kind. 706 */ 707 template<typename _Tp> 708 _Tp 709 __ellint_3(_Tp __k, _Tp __nu, _Tp __phi) 710 { 711 712 if (__isnan(__k) || __isnan(__nu) || __isnan(__phi)) 713 return std::numeric_limits<_Tp>::quiet_NaN(); 714 else if (std::abs(__k) > _Tp(1)) 715 std::__throw_domain_error(__N("Bad argument in __ellint_3.")); 716 else 717 { 718 // Reduce phi to -pi/2 < phi < +pi/2. 719 const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() 720 + _Tp(0.5L)); 721 const _Tp __phi_red = __phi 722 - __n * __numeric_constants<_Tp>::__pi(); 723 724 const _Tp __kk = __k * __k; 725 const _Tp __s = std::sin(__phi_red); 726 const _Tp __ss = __s * __s; 727 const _Tp __sss = __ss * __s; 728 const _Tp __c = std::cos(__phi_red); 729 const _Tp __cc = __c * __c; 730 731 const _Tp __Pi = __s 732 * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1)) 733 - __nu * __sss 734 * __ellint_rj(__cc, _Tp(1) - __kk * __ss, _Tp(1), 735 _Tp(1) + __nu * __ss) / _Tp(3); 736 737 if (__n == 0) 738 return __Pi; 739 else 740 return __Pi + _Tp(2) * __n * __comp_ellint_3(__k, __nu); 741 } 742 } 743 744 _GLIBCXX_END_NAMESPACE_VERSION 745 } // namespace std::tr1::__detail 746 } 747 } 748 749 #endif // _GLIBCXX_TR1_ELL_INTEGRAL_TCC 750 751