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