Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/tr1/ell_integral.tcc
$ cat -n /usr/include/c++/13/tr1/ell_integral.tcc 1 // Special functions -*- C++ -*- 2 3 // Copyright (C) 2006-2023 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 //
. 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 _GLIBCXX_BEGIN_NAMESPACE_VERSION 48 49 #if _GLIBCXX_USE_STD_SPEC_FUNCS 50 #elif defined(_GLIBCXX_TR1_CMATH) 51 namespace tr1 52 { 53 #else 54 # error do not include this header directly, use
or
55 #endif 56 // [5.2] Special functions 57 58 // Implementation-space details. 59 namespace __detail 60 { 61 /** 62 * @brief Return the Carlson elliptic function @f$ R_F(x,y,z) @f$ 63 * of the first kind. 64 * 65 * The Carlson elliptic function of the first kind is defined by: 66 * @f[ 67 * R_F(x,y,z) = \frac{1}{2} \int_0^\infty 68 * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}} 69 * @f] 70 * 71 * @param __x The first of three symmetric arguments. 72 * @param __y The second of three symmetric arguments. 73 * @param __z The third of three symmetric arguments. 74 * @return The Carlson elliptic function of the first kind. 75 */ 76 template
77 _Tp 78 __ellint_rf(_Tp __x, _Tp __y, _Tp __z) 79 { 80 const _Tp __min = std::numeric_limits<_Tp>::min(); 81 const _Tp __lolim = _Tp(5) * __min; 82 83 if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0)) 84 std::__throw_domain_error(__N("Argument less than zero " 85 "in __ellint_rf.")); 86 else if (__x + __y < __lolim || __x + __z < __lolim 87 || __y + __z < __lolim) 88 std::__throw_domain_error(__N("Argument too small in __ellint_rf")); 89 else 90 { 91 const _Tp __c0 = _Tp(1) / _Tp(4); 92 const _Tp __c1 = _Tp(1) / _Tp(24); 93 const _Tp __c2 = _Tp(1) / _Tp(10); 94 const _Tp __c3 = _Tp(3) / _Tp(44); 95 const _Tp __c4 = _Tp(1) / _Tp(14); 96 97 _Tp __xn = __x; 98 _Tp __yn = __y; 99 _Tp __zn = __z; 100 101 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 102 const _Tp __errtol = std::pow(__eps, _Tp(1) / _Tp(6)); 103 _Tp __mu; 104 _Tp __xndev, __yndev, __zndev; 105 106 const unsigned int __max_iter = 100; 107 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 108 { 109 __mu = (__xn + __yn + __zn) / _Tp(3); 110 __xndev = 2 - (__mu + __xn) / __mu; 111 __yndev = 2 - (__mu + __yn) / __mu; 112 __zndev = 2 - (__mu + __zn) / __mu; 113 _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); 114 __epsilon = std::max(__epsilon, std::abs(__zndev)); 115 if (__epsilon < __errtol) 116 break; 117 const _Tp __xnroot = std::sqrt(__xn); 118 const _Tp __ynroot = std::sqrt(__yn); 119 const _Tp __znroot = std::sqrt(__zn); 120 const _Tp __lambda = __xnroot * (__ynroot + __znroot) 121 + __ynroot * __znroot; 122 __xn = __c0 * (__xn + __lambda); 123 __yn = __c0 * (__yn + __lambda); 124 __zn = __c0 * (__zn + __lambda); 125 } 126 127 const _Tp __e2 = __xndev * __yndev - __zndev * __zndev; 128 const _Tp __e3 = __xndev * __yndev * __zndev; 129 const _Tp __s = _Tp(1) + (__c1 * __e2 - __c2 - __c3 * __e3) * __e2 130 + __c4 * __e3; 131 132 return __s / std::sqrt(__mu); 133 } 134 } 135 136 137 /** 138 * @brief Return the complete elliptic integral of the first kind 139 * @f$ K(k) @f$ by series expansion. 140 * 141 * The complete elliptic integral of the first kind is defined as 142 * @f[ 143 * K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta} 144 * {\sqrt{1 - k^2sin^2\theta}} 145 * @f] 146 * 147 * This routine is not bad as long as |k| is somewhat smaller than 1 148 * but is not is good as the Carlson elliptic integral formulation. 149 * 150 * @param __k The argument of the complete elliptic function. 151 * @return The complete elliptic function of the first kind. 152 */ 153 template
154 _Tp 155 __comp_ellint_1_series(_Tp __k) 156 { 157 158 const _Tp __kk = __k * __k; 159 160 _Tp __term = __kk / _Tp(4); 161 _Tp __sum = _Tp(1) + __term; 162 163 const unsigned int __max_iter = 1000; 164 for (unsigned int __i = 2; __i < __max_iter; ++__i) 165 { 166 __term *= (2 * __i - 1) * __kk / (2 * __i); 167 if (__term < std::numeric_limits<_Tp>::epsilon()) 168 break; 169 __sum += __term; 170 } 171 172 return __numeric_constants<_Tp>::__pi_2() * __sum; 173 } 174 175 176 /** 177 * @brief Return the complete elliptic integral of the first kind 178 * @f$ K(k) @f$ using the Carlson formulation. 179 * 180 * The complete elliptic integral of the first kind is defined as 181 * @f[ 182 * K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta} 183 * {\sqrt{1 - k^2 sin^2\theta}} 184 * @f] 185 * where @f$ F(k,\phi) @f$ is the incomplete elliptic integral of the 186 * first kind. 187 * 188 * @param __k The argument of the complete elliptic function. 189 * @return The complete elliptic function of the first kind. 190 */ 191 template
192 _Tp 193 __comp_ellint_1(_Tp __k) 194 { 195 196 if (__isnan(__k)) 197 return std::numeric_limits<_Tp>::quiet_NaN(); 198 else if (std::abs(__k) >= _Tp(1)) 199 return std::numeric_limits<_Tp>::quiet_NaN(); 200 else 201 return __ellint_rf(_Tp(0), _Tp(1) - __k * __k, _Tp(1)); 202 } 203 204 205 /** 206 * @brief Return the incomplete elliptic integral of the first kind 207 * @f$ F(k,\phi) @f$ using the Carlson formulation. 208 * 209 * The incomplete elliptic integral of the first kind is defined as 210 * @f[ 211 * F(k,\phi) = \int_0^{\phi}\frac{d\theta} 212 * {\sqrt{1 - k^2 sin^2\theta}} 213 * @f] 214 * 215 * @param __k The argument of the elliptic function. 216 * @param __phi The integral limit argument of the elliptic function. 217 * @return The elliptic function of the first kind. 218 */ 219 template
220 _Tp 221 __ellint_1(_Tp __k, _Tp __phi) 222 { 223 224 if (__isnan(__k) || __isnan(__phi)) 225 return std::numeric_limits<_Tp>::quiet_NaN(); 226 else if (std::abs(__k) > _Tp(1)) 227 std::__throw_domain_error(__N("Bad argument in __ellint_1.")); 228 else 229 { 230 // Reduce phi to -pi/2 < phi < +pi/2. 231 const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() 232 + _Tp(0.5L)); 233 const _Tp __phi_red = __phi 234 - __n * __numeric_constants<_Tp>::__pi(); 235 236 const _Tp __s = std::sin(__phi_red); 237 const _Tp __c = std::cos(__phi_red); 238 239 const _Tp __F = __s 240 * __ellint_rf(__c * __c, 241 _Tp(1) - __k * __k * __s * __s, _Tp(1)); 242 243 if (__n == 0) 244 return __F; 245 else 246 return __F + _Tp(2) * __n * __comp_ellint_1(__k); 247 } 248 } 249 250 251 /** 252 * @brief Return the complete elliptic integral of the second kind 253 * @f$ E(k) @f$ by series expansion. 254 * 255 * The complete elliptic integral of the second kind is defined as 256 * @f[ 257 * E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta} 258 * @f] 259 * 260 * This routine is not bad as long as |k| is somewhat smaller than 1 261 * but is not is good as the Carlson elliptic integral formulation. 262 * 263 * @param __k The argument of the complete elliptic function. 264 * @return The complete elliptic function of the second kind. 265 */ 266 template
267 _Tp 268 __comp_ellint_2_series(_Tp __k) 269 { 270 271 const _Tp __kk = __k * __k; 272 273 _Tp __term = __kk; 274 _Tp __sum = __term; 275 276 const unsigned int __max_iter = 1000; 277 for (unsigned int __i = 2; __i < __max_iter; ++__i) 278 { 279 const _Tp __i2m = 2 * __i - 1; 280 const _Tp __i2 = 2 * __i; 281 __term *= __i2m * __i2m * __kk / (__i2 * __i2); 282 if (__term < std::numeric_limits<_Tp>::epsilon()) 283 break; 284 __sum += __term / __i2m; 285 } 286 287 return __numeric_constants<_Tp>::__pi_2() * (_Tp(1) - __sum); 288 } 289 290 291 /** 292 * @brief Return the Carlson elliptic function of the second kind 293 * @f$ R_D(x,y,z) = R_J(x,y,z,z) @f$ where 294 * @f$ R_J(x,y,z,p) @f$ is the Carlson elliptic function 295 * of the third kind. 296 * 297 * The Carlson elliptic function of the second kind is defined by: 298 * @f[ 299 * R_D(x,y,z) = \frac{3}{2} \int_0^\infty 300 * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{3/2}} 301 * @f] 302 * 303 * Based on Carlson's algorithms: 304 * - B. C. Carlson Numer. Math. 33, 1 (1979) 305 * - B. C. Carlson, Special Functions of Applied Mathematics (1977) 306 * - Numerical Recipes in C, 2nd ed, pp. 261-269, 307 * by Press, Teukolsky, Vetterling, Flannery (1992) 308 * 309 * @param __x The first of two symmetric arguments. 310 * @param __y The second of two symmetric arguments. 311 * @param __z The third argument. 312 * @return The Carlson elliptic function of the second kind. 313 */ 314 template
315 _Tp 316 __ellint_rd(_Tp __x, _Tp __y, _Tp __z) 317 { 318 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 319 const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6)); 320 const _Tp __max = std::numeric_limits<_Tp>::max(); 321 const _Tp __lolim = _Tp(2) / std::pow(__max, _Tp(2) / _Tp(3)); 322 323 if (__x < _Tp(0) || __y < _Tp(0)) 324 std::__throw_domain_error(__N("Argument less than zero " 325 "in __ellint_rd.")); 326 else if (__x + __y < __lolim || __z < __lolim) 327 std::__throw_domain_error(__N("Argument too small " 328 "in __ellint_rd.")); 329 else 330 { 331 const _Tp __c0 = _Tp(1) / _Tp(4); 332 const _Tp __c1 = _Tp(3) / _Tp(14); 333 const _Tp __c2 = _Tp(1) / _Tp(6); 334 const _Tp __c3 = _Tp(9) / _Tp(22); 335 const _Tp __c4 = _Tp(3) / _Tp(26); 336 337 _Tp __xn = __x; 338 _Tp __yn = __y; 339 _Tp __zn = __z; 340 _Tp __sigma = _Tp(0); 341 _Tp __power4 = _Tp(1); 342 343 _Tp __mu; 344 _Tp __xndev, __yndev, __zndev; 345 346 const unsigned int __max_iter = 100; 347 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 348 { 349 __mu = (__xn + __yn + _Tp(3) * __zn) / _Tp(5); 350 __xndev = (__mu - __xn) / __mu; 351 __yndev = (__mu - __yn) / __mu; 352 __zndev = (__mu - __zn) / __mu; 353 _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); 354 __epsilon = std::max(__epsilon, std::abs(__zndev)); 355 if (__epsilon < __errtol) 356 break; 357 _Tp __xnroot = std::sqrt(__xn); 358 _Tp __ynroot = std::sqrt(__yn); 359 _Tp __znroot = std::sqrt(__zn); 360 _Tp __lambda = __xnroot * (__ynroot + __znroot) 361 + __ynroot * __znroot; 362 __sigma += __power4 / (__znroot * (__zn + __lambda)); 363 __power4 *= __c0; 364 __xn = __c0 * (__xn + __lambda); 365 __yn = __c0 * (__yn + __lambda); 366 __zn = __c0 * (__zn + __lambda); 367 } 368 369 _Tp __ea = __xndev * __yndev; 370 _Tp __eb = __zndev * __zndev; 371 _Tp __ec = __ea - __eb; 372 _Tp __ed = __ea - _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 - __ea)); 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
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
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
493 _Tp 494 __ellint_rc(_Tp __x, _Tp __y) 495 { 496 const _Tp __min = std::numeric_limits<_Tp>::min(); 497 const _Tp __lolim = _Tp(5) * __min; 498 499 if (__x < _Tp(0) || __y < _Tp(0) || __x + __y < __lolim) 500 std::__throw_domain_error(__N("Argument less than zero " 501 "in __ellint_rc.")); 502 else 503 { 504 const _Tp __c0 = _Tp(1) / _Tp(4); 505 const _Tp __c1 = _Tp(1) / _Tp(7); 506 const _Tp __c2 = _Tp(9) / _Tp(22); 507 const _Tp __c3 = _Tp(3) / _Tp(10); 508 const _Tp __c4 = _Tp(3) / _Tp(8); 509 510 _Tp __xn = __x; 511 _Tp __yn = __y; 512 513 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 514 const _Tp __errtol = std::pow(__eps / _Tp(30), _Tp(1) / _Tp(6)); 515 _Tp __mu; 516 _Tp __sn; 517 518 const unsigned int __max_iter = 100; 519 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 520 { 521 __mu = (__xn + _Tp(2) * __yn) / _Tp(3); 522 __sn = (__yn + __mu) / __mu - _Tp(2); 523 if (std::abs(__sn) < __errtol) 524 break; 525 const _Tp __lambda = _Tp(2) * std::sqrt(__xn) * std::sqrt(__yn) 526 + __yn; 527 __xn = __c0 * (__xn + __lambda); 528 __yn = __c0 * (__yn + __lambda); 529 } 530 531 _Tp __s = __sn * __sn 532 * (__c3 + __sn*(__c1 + __sn * (__c4 + __sn * __c2))); 533 534 return (_Tp(1) + __s) / std::sqrt(__mu); 535 } 536 } 537 538 539 /** 540 * @brief Return the Carlson elliptic function @f$ R_J(x,y,z,p) @f$ 541 * of the third kind. 542 * 543 * The Carlson elliptic function of the third kind is defined by: 544 * @f[ 545 * R_J(x,y,z,p) = \frac{3}{2} \int_0^\infty 546 * \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}(t + p)} 547 * @f] 548 * 549 * Based on Carlson's algorithms: 550 * - B. C. Carlson Numer. Math. 33, 1 (1979) 551 * - B. C. Carlson, Special Functions of Applied Mathematics (1977) 552 * - Numerical Recipes in C, 2nd ed, pp. 261-269, 553 * by Press, Teukolsky, Vetterling, Flannery (1992) 554 * 555 * @param __x The first of three symmetric arguments. 556 * @param __y The second of three symmetric arguments. 557 * @param __z The third of three symmetric arguments. 558 * @param __p The fourth argument. 559 * @return The Carlson elliptic function of the fourth kind. 560 */ 561 template
562 _Tp 563 __ellint_rj(_Tp __x, _Tp __y, _Tp __z, _Tp __p) 564 { 565 const _Tp __min = std::numeric_limits<_Tp>::min(); 566 const _Tp __lolim = std::pow(_Tp(5) * __min, _Tp(1)/_Tp(3)); 567 568 if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0)) 569 std::__throw_domain_error(__N("Argument less than zero " 570 "in __ellint_rj.")); 571 else if (__x + __y < __lolim || __x + __z < __lolim 572 || __y + __z < __lolim || __p < __lolim) 573 std::__throw_domain_error(__N("Argument too small " 574 "in __ellint_rj")); 575 else 576 { 577 const _Tp __c0 = _Tp(1) / _Tp(4); 578 const _Tp __c1 = _Tp(3) / _Tp(14); 579 const _Tp __c2 = _Tp(1) / _Tp(3); 580 const _Tp __c3 = _Tp(3) / _Tp(22); 581 const _Tp __c4 = _Tp(3) / _Tp(26); 582 583 _Tp __xn = __x; 584 _Tp __yn = __y; 585 _Tp __zn = __z; 586 _Tp __pn = __p; 587 _Tp __sigma = _Tp(0); 588 _Tp __power4 = _Tp(1); 589 590 const _Tp __eps = std::numeric_limits<_Tp>::epsilon(); 591 const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6)); 592 593 _Tp __mu; 594 _Tp __xndev, __yndev, __zndev, __pndev; 595 596 const unsigned int __max_iter = 100; 597 for (unsigned int __iter = 0; __iter < __max_iter; ++__iter) 598 { 599 __mu = (__xn + __yn + __zn + _Tp(2) * __pn) / _Tp(5); 600 __xndev = (__mu - __xn) / __mu; 601 __yndev = (__mu - __yn) / __mu; 602 __zndev = (__mu - __zn) / __mu; 603 __pndev = (__mu - __pn) / __mu; 604 _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev)); 605 __epsilon = std::max(__epsilon, std::abs(__zndev)); 606 __epsilon = std::max(__epsilon, std::abs(__pndev)); 607 if (__epsilon < __errtol) 608 break; 609 const _Tp __xnroot = std::sqrt(__xn); 610 const _Tp __ynroot = std::sqrt(__yn); 611 const _Tp __znroot = std::sqrt(__zn); 612 const _Tp __lambda = __xnroot * (__ynroot + __znroot) 613 + __ynroot * __znroot; 614 const _Tp __alpha1 = __pn * (__xnroot + __ynroot + __znroot) 615 + __xnroot * __ynroot * __znroot; 616 const _Tp __alpha2 = __alpha1 * __alpha1; 617 const _Tp __beta = __pn * (__pn + __lambda) 618 * (__pn + __lambda); 619 __sigma += __power4 * __ellint_rc(__alpha2, __beta); 620 __power4 *= __c0; 621 __xn = __c0 * (__xn + __lambda); 622 __yn = __c0 * (__yn + __lambda); 623 __zn = __c0 * (__zn + __lambda); 624 __pn = __c0 * (__pn + __lambda); 625 } 626 627 _Tp __ea = __xndev * (__yndev + __zndev) + __yndev * __zndev; 628 _Tp __eb = __xndev * __yndev * __zndev; 629 _Tp __ec = __pndev * __pndev; 630 _Tp __e2 = __ea - _Tp(3) * __ec; 631 _Tp __e3 = __eb + _Tp(2) * __pndev * (__ea - __ec); 632 _Tp __s1 = _Tp(1) + __e2 * (-__c1 + _Tp(3) * __c3 * __e2 / _Tp(4) 633 - _Tp(3) * __c4 * __e3 / _Tp(2)); 634 _Tp __s2 = __eb * (__c2 / _Tp(2) 635 + __pndev * (-__c3 - __c3 + __pndev * __c4)); 636 _Tp __s3 = __pndev * __ea * (__c2 - __pndev * __c3) 637 - __c2 * __pndev * __ec; 638 639 return _Tp(3) * __sigma + __power4 * (__s1 + __s2 + __s3) 640 / (__mu * std::sqrt(__mu)); 641 } 642 } 643 644 645 /** 646 * @brief Return the complete elliptic integral of the third kind 647 * @f$ \Pi(k,\nu) = \Pi(k,\nu,\pi/2) @f$ using the 648 * Carlson formulation. 649 * 650 * The complete elliptic integral of the third kind is defined as 651 * @f[ 652 * \Pi(k,\nu) = \int_0^{\pi/2} 653 * \frac{d\theta} 654 * {(1 - \nu \sin^2\theta)\sqrt{1 - k^2 \sin^2\theta}} 655 * @f] 656 * 657 * @param __k The argument of the elliptic function. 658 * @param __nu The second argument of the elliptic function. 659 * @return The complete elliptic function of the third kind. 660 */ 661 template
662 _Tp 663 __comp_ellint_3(_Tp __k, _Tp __nu) 664 { 665 666 if (__isnan(__k) || __isnan(__nu)) 667 return std::numeric_limits<_Tp>::quiet_NaN(); 668 else if (__nu == _Tp(1)) 669 return std::numeric_limits<_Tp>::infinity(); 670 else if (std::abs(__k) > _Tp(1)) 671 std::__throw_domain_error(__N("Bad argument in __comp_ellint_3.")); 672 else 673 { 674 const _Tp __kk = __k * __k; 675 676 return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1)) 677 + __nu 678 * __ellint_rj(_Tp(0), _Tp(1) - __kk, _Tp(1), _Tp(1) - __nu) 679 / _Tp(3); 680 } 681 } 682 683 684 /** 685 * @brief Return the incomplete elliptic integral of the third kind 686 * @f$ \Pi(k,\nu,\phi) @f$ using the Carlson formulation. 687 * 688 * The incomplete elliptic integral of the third kind is defined as 689 * @f[ 690 * \Pi(k,\nu,\phi) = \int_0^{\phi} 691 * \frac{d\theta} 692 * {(1 - \nu \sin^2\theta) 693 * \sqrt{1 - k^2 \sin^2\theta}} 694 * @f] 695 * 696 * @param __k The argument of the elliptic function. 697 * @param __nu The second argument of the elliptic function. 698 * @param __phi The integral limit argument of the elliptic function. 699 * @return The elliptic function of the third kind. 700 */ 701 template
702 _Tp 703 __ellint_3(_Tp __k, _Tp __nu, _Tp __phi) 704 { 705 706 if (__isnan(__k) || __isnan(__nu) || __isnan(__phi)) 707 return std::numeric_limits<_Tp>::quiet_NaN(); 708 else if (std::abs(__k) > _Tp(1)) 709 std::__throw_domain_error(__N("Bad argument in __ellint_3.")); 710 else 711 { 712 // Reduce phi to -pi/2 < phi < +pi/2. 713 const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi() 714 + _Tp(0.5L)); 715 const _Tp __phi_red = __phi 716 - __n * __numeric_constants<_Tp>::__pi(); 717 718 const _Tp __kk = __k * __k; 719 const _Tp __s = std::sin(__phi_red); 720 const _Tp __ss = __s * __s; 721 const _Tp __sss = __ss * __s; 722 const _Tp __c = std::cos(__phi_red); 723 const _Tp __cc = __c * __c; 724 725 const _Tp __Pi = __s 726 * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1)) 727 + __nu * __sss 728 * __ellint_rj(__cc, _Tp(1) - __kk * __ss, _Tp(1), 729 _Tp(1) - __nu * __ss) / _Tp(3); 730 731 if (__n == 0) 732 return __Pi; 733 else 734 return __Pi + _Tp(2) * __n * __comp_ellint_3(__k, __nu); 735 } 736 } 737 } // namespace __detail 738 #if ! _GLIBCXX_USE_STD_SPEC_FUNCS && defined(_GLIBCXX_TR1_CMATH) 739 } // namespace tr1 740 #endif 741 742 _GLIBCXX_END_NAMESPACE_VERSION 743 } 744 745 #endif // _GLIBCXX_TR1_ELL_INTEGRAL_TCC 746
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™