| 1 |
/** |
|---|
| 2 |
* Elliptic integrals. |
|---|
| 3 |
* The functions are named similarly to the names used in Mathematica. |
|---|
| 4 |
* |
|---|
| 5 |
* License: BSD style: $(LICENSE) |
|---|
| 6 |
* Copyright: Based on the CEPHES math library, which is |
|---|
| 7 |
* Copyright (C) 1994 Stephen L. Moshier (moshier@world.std.com). |
|---|
| 8 |
* Authors: Stephen L. Moshier (original C code). Conversion to D by Don Clugston |
|---|
| 9 |
* |
|---|
| 10 |
* References: |
|---|
| 11 |
* $(LINK http://en.wikipedia.org/wiki/Elliptic_integral) |
|---|
| 12 |
* |
|---|
| 13 |
* Eric W. Weisstein. "Elliptic Integral of the First Kind." From MathWorld--A Wolfram Web Resource. $(LINK http://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html) |
|---|
| 14 |
* |
|---|
| 15 |
* $(LINK http://www.netlib.org/cephes/ldoubdoc.html) |
|---|
| 16 |
* |
|---|
| 17 |
* Macros: |
|---|
| 18 |
* TABLE_SV = <table border=1 cellpadding=4 cellspacing=0> |
|---|
| 19 |
* <caption>Special Values</caption> |
|---|
| 20 |
* $0</table> |
|---|
| 21 |
* SVH = $(TR $(TH $1) $(TH $2)) |
|---|
| 22 |
* SV = $(TR $(TD $1) $(TD $2)) |
|---|
| 23 |
* GAMMA = Γ |
|---|
| 24 |
* INTEGRATE = $(BIG ∫<sub>$(SMALL $1)</sub><sup>$2</sup>) |
|---|
| 25 |
* POWER = $1<sup>$2</sup> |
|---|
| 26 |
* NAN = $(RED NAN) |
|---|
| 27 |
*/ |
|---|
| 28 |
/** |
|---|
| 29 |
* Macros: |
|---|
| 30 |
* TABLE_SV = <table border=1 cellpadding=4 cellspacing=0> |
|---|
| 31 |
* <caption>Special Values</caption> |
|---|
| 32 |
* $0</table> |
|---|
| 33 |
* SVH = $(TR $(TH $1) $(TH $2)) |
|---|
| 34 |
* SV = $(TR $(TD $1) $(TD $2)) |
|---|
| 35 |
* |
|---|
| 36 |
* NAN = $(RED NAN) |
|---|
| 37 |
* SUP = <span style="vertical-align:super;font-size:smaller">$0</span> |
|---|
| 38 |
* GAMMA = Γ |
|---|
| 39 |
* INTEGRAL = ∫ |
|---|
| 40 |
* INTEGRATE = $(BIG ∫<sub>$(SMALL $1)</sub><sup>$2</sup>) |
|---|
| 41 |
* POWER = $1<sup>$2</sup> |
|---|
| 42 |
* BIGSUM = $(BIG Σ <sup>$2</sup><sub>$(SMALL $1)</sub>) |
|---|
| 43 |
* CHOOSE = $(BIG () <sup>$(SMALL $1)</sup><sub>$(SMALL $2)</sub> $(BIG )) |
|---|
| 44 |
*/ |
|---|
| 45 |
|
|---|
| 46 |
module tango.math.Elliptic; |
|---|
| 47 |
|
|---|
| 48 |
import tango.math.Math; |
|---|
| 49 |
import tango.math.IEEE; |
|---|
| 50 |
|
|---|
| 51 |
/* These functions are based on code from: |
|---|
| 52 |
Cephes Math Library, Release 2.3: October, 1995 |
|---|
| 53 |
Copyright 1984, 1987, 1995 by Stephen L. Moshier |
|---|
| 54 |
*/ |
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 |
/** |
|---|
| 58 |
* Incomplete elliptic integral of the first kind |
|---|
| 59 |
* |
|---|
| 60 |
* Approximates the integral |
|---|
| 61 |
* F(phi | m) = $(INTEGRATE 0, phi) dt/ (sqrt( 1- m $(POWER sin, 2) t)) |
|---|
| 62 |
* |
|---|
| 63 |
* of amplitude phi and modulus m, using the arithmetic - |
|---|
| 64 |
* geometric mean algorithm. |
|---|
| 65 |
*/ |
|---|
| 66 |
|
|---|
| 67 |
real ellipticF(real phi, real m ) |
|---|
| 68 |
{ |
|---|
| 69 |
real a, b, c, e, temp, t, K; |
|---|
| 70 |
int d, mod, sign, npio2; |
|---|
| 71 |
|
|---|
| 72 |
if( m == 0.0L ) |
|---|
| 73 |
return phi; |
|---|
| 74 |
a = 1.0L - m; |
|---|
| 75 |
if( a == 0.0L ) { |
|---|
| 76 |
if ( fabs(phi) >= PI_2 ) return real.infinity; |
|---|
| 77 |
return log( tan( 0.5L*(PI_2 + phi) ) ); |
|---|
| 78 |
} |
|---|
| 79 |
npio2 = cast(int)floor( phi/PI_2 ); |
|---|
| 80 |
if ( npio2 & 1 ) |
|---|
| 81 |
npio2 += 1; |
|---|
| 82 |
if ( npio2 ) { |
|---|
| 83 |
K = ellipticKComplete( a ); |
|---|
| 84 |
phi = phi - npio2 * PI_2; |
|---|
| 85 |
} else |
|---|
| 86 |
K = 0.0L; |
|---|
| 87 |
if( phi < 0.0L ){ |
|---|
| 88 |
phi = -phi; |
|---|
| 89 |
sign = -1; |
|---|
| 90 |
} else sign = 0; |
|---|
| 91 |
b = sqrt(a); |
|---|
| 92 |
t = tan( phi ); |
|---|
| 93 |
if( fabs(t) > 10.0L ) { |
|---|
| 94 |
/* Transform the amplitude */ |
|---|
| 95 |
e = 1.0L/(b*t); |
|---|
| 96 |
/* ... but avoid multiple recursions. */ |
|---|
| 97 |
if( fabs(e) < 10.0L ){ |
|---|
| 98 |
e = atan(e); |
|---|
| 99 |
if( npio2 == 0 ) |
|---|
| 100 |
K = ellipticKComplete( a ); |
|---|
| 101 |
temp = K - ellipticF( e, m ); |
|---|
| 102 |
goto done; |
|---|
| 103 |
} |
|---|
| 104 |
} |
|---|
| 105 |
a = 1.0L; |
|---|
| 106 |
c = sqrt(m); |
|---|
| 107 |
d = 1; |
|---|
| 108 |
mod = 0; |
|---|
| 109 |
|
|---|
| 110 |
while( fabs(c/a) > real.epsilon ) { |
|---|
| 111 |
temp = b/a; |
|---|
| 112 |
phi = phi + atan(t*temp) + mod * PI; |
|---|
| 113 |
mod = cast(int)((phi + PI_2)/PI); |
|---|
| 114 |
t = t * ( 1.0L + temp )/( 1.0L - temp * t * t ); |
|---|
| 115 |
c = 0.5L * ( a - b ); |
|---|
| 116 |
temp = sqrt( a * b ); |
|---|
| 117 |
a = 0.5L * ( a + b ); |
|---|
| 118 |
b = temp; |
|---|
| 119 |
d += d; |
|---|
| 120 |
} |
|---|
| 121 |
temp = (atan(t) + mod * PI)/(d * a); |
|---|
| 122 |
|
|---|
| 123 |
done: |
|---|
| 124 |
if ( sign < 0 ) |
|---|
| 125 |
temp = -temp; |
|---|
| 126 |
temp += npio2 * K; |
|---|
| 127 |
return temp; |
|---|
| 128 |
} |
|---|
| 129 |
|
|---|
| 130 |
|
|---|
| 131 |
/** |
|---|
| 132 |
* Incomplete elliptic integral of the second kind |
|---|
| 133 |
* |
|---|
| 134 |
* Approximates the integral |
|---|
| 135 |
* |
|---|
| 136 |
* E(phi | m) = $(INTEGRATE 0, phi) sqrt( 1- m $(POWER sin, 2) t) dt |
|---|
| 137 |
* |
|---|
| 138 |
* of amplitude phi and modulus m, using the arithmetic - |
|---|
| 139 |
* geometric mean algorithm. |
|---|
| 140 |
*/ |
|---|
| 141 |
|
|---|
| 142 |
real ellipticE(real phi, real m) |
|---|
| 143 |
{ |
|---|
| 144 |
real a, b, c, e, temp, t, E; |
|---|
| 145 |
int d, mod, npio2, sign; |
|---|
| 146 |
|
|---|
| 147 |
if ( m == 0.0L ) return phi; |
|---|
| 148 |
real lphi = phi; |
|---|
| 149 |
npio2 = cast(int)floor( lphi/PI_2 ); |
|---|
| 150 |
if( npio2 & 1 ) |
|---|
| 151 |
npio2 += 1; |
|---|
| 152 |
lphi = lphi - npio2 * PI_2; |
|---|
| 153 |
if( lphi < 0.0L ){ |
|---|
| 154 |
lphi = -lphi; |
|---|
| 155 |
sign = -1; |
|---|
| 156 |
} else { |
|---|
| 157 |
sign = 1; |
|---|
| 158 |
} |
|---|
| 159 |
a = 1.0L - m; |
|---|
| 160 |
E = ellipticEComplete( a ); |
|---|
| 161 |
if( a == 0.0L ) { |
|---|
| 162 |
temp = sin( lphi ); |
|---|
| 163 |
goto done; |
|---|
| 164 |
} |
|---|
| 165 |
t = tan( lphi ); |
|---|
| 166 |
b = sqrt(a); |
|---|
| 167 |
if ( fabs(t) > 10.0L ) { |
|---|
| 168 |
/* Transform the amplitude */ |
|---|
| 169 |
e = 1.0L/(b*t); |
|---|
| 170 |
/* ... but avoid multiple recursions. */ |
|---|
| 171 |
if( fabs(e) < 10.0L ){ |
|---|
| 172 |
e = atan(e); |
|---|
| 173 |
temp = E + m * sin( lphi ) * sin( e ) - ellipticE( e, m ); |
|---|
| 174 |
goto done; |
|---|
| 175 |
} |
|---|
| 176 |
} |
|---|
| 177 |
c = sqrt(m); |
|---|
| 178 |
a = 1.0L; |
|---|
| 179 |
d = 1; |
|---|
| 180 |
e = 0.0L; |
|---|
| 181 |
mod = 0; |
|---|
| 182 |
|
|---|
| 183 |
while( fabs(c/a) > real.epsilon ) { |
|---|
| 184 |
temp = b/a; |
|---|
| 185 |
lphi = lphi + atan(t*temp) + mod * PI; |
|---|
| 186 |
mod = cast(int)((lphi + PI_2)/PI); |
|---|
| 187 |
t = t * ( 1.0L + temp )/( 1.0L - temp * t * t ); |
|---|
| 188 |
c = 0.5L*( a - b ); |
|---|
| 189 |
temp = sqrt( a * b ); |
|---|
| 190 |
a = 0.5L*( a + b ); |
|---|
| 191 |
b = temp; |
|---|
| 192 |
d += d; |
|---|
| 193 |
e += c * sin(lphi); |
|---|
| 194 |
} |
|---|
| 195 |
|
|---|
| 196 |
temp = E / ellipticKComplete( 1.0L - m ); |
|---|
| 197 |
temp *= (atan(t) + mod * PI)/(d * a); |
|---|
| 198 |
temp += e; |
|---|
| 199 |
|
|---|
| 200 |
done: |
|---|
| 201 |
if( sign < 0 ) |
|---|
| 202 |
temp = -temp; |
|---|
| 203 |
temp += npio2 * E; |
|---|
| 204 |
return temp; |
|---|
| 205 |
} |
|---|
| 206 |
|
|---|
| 207 |
|
|---|
| 208 |
/** |
|---|
| 209 |
* Complete elliptic integral of the first kind |
|---|
| 210 |
* |
|---|
| 211 |
* Approximates the integral |
|---|
| 212 |
* |
|---|
| 213 |
* K(m) = $(INTEGRATE 0, π/2) dt/ (sqrt( 1- m $(POWER sin, 2) t)) |
|---|
| 214 |
* |
|---|
| 215 |
* where m = 1 - x, using the approximation |
|---|
| 216 |
* |
|---|
| 217 |
* P(x) - log x Q(x). |
|---|
| 218 |
* |
|---|
| 219 |
* The argument x is used rather than m so that the logarithmic |
|---|
| 220 |
* singularity at x = 1 will be shifted to the origin; this |
|---|
| 221 |
* preserves maximum accuracy. |
|---|
| 222 |
* |
|---|
| 223 |
* x must be in the range |
|---|
| 224 |
* 0 <= x <= 1 |
|---|
| 225 |
* |
|---|
| 226 |
* This is equivalent to ellipticF(PI_2, 1-x). |
|---|
| 227 |
* |
|---|
| 228 |
* K(0) = π/2. |
|---|
| 229 |
*/ |
|---|
| 230 |
|
|---|
| 231 |
real ellipticKComplete(real x) |
|---|
| 232 |
in { |
|---|
| 233 |
// assert(x>=0.0L && x<=1.0L); |
|---|
| 234 |
} |
|---|
| 235 |
body{ |
|---|
| 236 |
|
|---|
| 237 |
const real [] P = [ |
|---|
| 238 |
0x1.62e42fefa39ef35ap+0, // 1.3862943611198906189 |
|---|
| 239 |
0x1.8b90bfbe8ed811fcp-4, // 0.096573590279993142323 |
|---|
| 240 |
0x1.fa05af797624c586p-6, // 0.030885144578720423267 |
|---|
| 241 |
0x1.e979cdfac7249746p-7, // 0.01493761594388688915 |
|---|
| 242 |
0x1.1f4cc8890cff803cp-7, // 0.0087676982094322259125 |
|---|
| 243 |
0x1.7befb3bb1fa978acp-8, // 0.0057973684116620276454 |
|---|
| 244 |
0x1.2c2566aa1d5fe6b8p-8, // 0.0045798659940508010431 |
|---|
| 245 |
0x1.7333514e7fe57c98p-8, // 0.0056640695097481470287 |
|---|
| 246 |
0x1.09292d1c8621348cp-7, // 0.0080920667906392630755 |
|---|
| 247 |
0x1.b89ab5fe793a6062p-8, // 0.0067230886765842542487 |
|---|
| 248 |
0x1.28e9c44dc5e26e66p-9, // 0.002265267575136470585 |
|---|
| 249 |
0x1.c2c43245d445addap-13, // 0.00021494216542320112406 |
|---|
| 250 |
0x1.4ee247035a03e13p-20 // 1.2475397291548388385e-06 |
|---|
| 251 |
]; |
|---|
| 252 |
|
|---|
| 253 |
const real [] Q = [ |
|---|
| 254 |
0x1p-1, // 0.5 |
|---|
| 255 |
0x1.fffffffffff635eap-4, // 0.12499999999999782631 |
|---|
| 256 |
0x1.1fffffff8a2bea1p-4, // 0.070312499993302227507 |
|---|
| 257 |
0x1.8ffffe6f40ec2078p-5, // 0.04882812208418620146 |
|---|
| 258 |
0x1.323f4dbf7f4d0c2ap-5, // 0.037383701182969303058 |
|---|
| 259 |
0x1.efe8a028541b50bp-6, // 0.030267864612427881354 |
|---|
| 260 |
0x1.9d58c49718d6617cp-6, // 0.025228683455123323041 |
|---|
| 261 |
0x1.4d1a8d2292ff6e2ep-6, // 0.020331037356569904872 |
|---|
| 262 |
0x1.b637687027d664aap-7, // 0.013373304362459048444 |
|---|
| 263 |
0x1.687a640ae5c71332p-8, // 0.0055004591221382442135 |
|---|
| 264 |
0x1.0f9c30a94a1dcb4ep-10, // 0.001036110372590318803 |
|---|
| 265 |
0x1.d321746708e92d48p-15 // 5.568631677757315399e-05 |
|---|
| 266 |
]; |
|---|
| 267 |
|
|---|
| 268 |
const real LOG4 = 0x1.62e42fefa39ef358p+0; // log(4) |
|---|
| 269 |
|
|---|
| 270 |
if( x > real.epsilon ) |
|---|
| 271 |
return poly(x,P) - log(x) * poly(x,Q); |
|---|
| 272 |
if ( x == 0.0L ) |
|---|
| 273 |
return real.infinity; |
|---|
| 274 |
return LOG4 - 0.5L * log(x); |
|---|
| 275 |
} |
|---|
| 276 |
|
|---|
| 277 |
/** |
|---|
| 278 |
* Complete elliptic integral of the second kind |
|---|
| 279 |
* |
|---|
| 280 |
* Approximates the integral |
|---|
| 281 |
* |
|---|
| 282 |
* E(m) = $(INTEGRATE 0, π/2) sqrt( 1- m $(POWER sin, 2) t) dt |
|---|
| 283 |
* |
|---|
| 284 |
* where m = 1 - x, using the approximation |
|---|
| 285 |
* |
|---|
| 286 |
* P(x) - x log x Q(x). |
|---|
| 287 |
* |
|---|
| 288 |
* Though there are no singularities, the argument m1 is used |
|---|
| 289 |
* rather than m for compatibility with ellipticKComplete(). |
|---|
| 290 |
* |
|---|
| 291 |
* E(1) = 1; E(0) = π/2. |
|---|
| 292 |
* m must be in the range 0 <= m <= 1. |
|---|
| 293 |
*/ |
|---|
| 294 |
|
|---|
| 295 |
real ellipticEComplete(real x) |
|---|
| 296 |
in { |
|---|
| 297 |
assert(x>=0 && x<=1.0); |
|---|
| 298 |
} |
|---|
| 299 |
body { |
|---|
| 300 |
const real [] P = [ |
|---|
| 301 |
0x1.c5c85fdf473f78f2p-2, // 0.44314718055994670505 |
|---|
| 302 |
0x1.d1591f9e9a66477p-5, // 0.056805192715569305834 |
|---|
| 303 |
0x1.65af6a7a61f587cp-6, // 0.021831373198011179718 |
|---|
| 304 |
0x1.7a4d48ed00d5745ap-7, // 0.011544857605264509506 |
|---|
| 305 |
0x1.d4f5fe4f93b60688p-8, // 0.0071557756305783152481 |
|---|
| 306 |
0x1.4cb71c73bac8656ap-8, // 0.0050768322432573952962 |
|---|
| 307 |
0x1.4a9167859a1d0312p-8, // 0.0050440671671840438539 |
|---|
| 308 |
0x1.dd296daa7b1f5b7ap-8, // 0.0072809117068399675418 |
|---|
| 309 |
0x1.04f2c29224ba99b6p-7, // 0.0079635095646944542686 |
|---|
| 310 |
0x1.0f5820e2d80194d8p-8, // 0.0041403847015715420009 |
|---|
| 311 |
0x1.95ee634752ca69b6p-11, // 0.00077425232385887751162 |
|---|
| 312 |
0x1.0c58aa9ab404f4fp-15 // 3.1989378120323412946e-05 |
|---|
| 313 |
]; |
|---|
| 314 |
|
|---|
| 315 |
const real [] Q = [ |
|---|
| 316 |
0x1.ffffffffffffb1cep-3, // 0.24999999999999986434 |
|---|
| 317 |
0x1.7ffffffff29eaa0cp-4, // 0.093749999999239422678 |
|---|
| 318 |
0x1.dfffffbd51eb098p-5, // 0.058593749514839092674 |
|---|
| 319 |
0x1.5dffd791cb834c92p-5, // 0.04272453406734691973 |
|---|
| 320 |
0x1.1397b63c2f09a8ep-5, // 0.033641677787700181541 |
|---|
| 321 |
0x1.c567cde5931e75bcp-6, // 0.02767367465121309044 |
|---|
| 322 |
0x1.75e0cae852be9ddcp-6, // 0.022819708015315777007 |
|---|
| 323 |
0x1.12bb968236d4e434p-6, // 0.016768357258894633433 |
|---|
| 324 |
0x1.1f6572c1c402d07cp-7, // 0.0087706384979640787504 |
|---|
| 325 |
0x1.452c6909f88b8306p-9, // 0.0024808767529843311337 |
|---|
| 326 |
0x1.1f7504e72d664054p-12, // 0.00027414045912208516032 |
|---|
| 327 |
0x1.ad17054dc46913e2p-18 // 6.3939381343012054851e-06 |
|---|
| 328 |
]; |
|---|
| 329 |
if (x==0) |
|---|
| 330 |
return 1.0L; |
|---|
| 331 |
return 1.0L + x * poly(x,P) - log(x) * (x * poly(x,Q) ); |
|---|
| 332 |
} |
|---|
| 333 |
|
|---|
| 334 |
debug (UnitTest) |
|---|
| 335 |
{ |
|---|
| 336 |
unittest { |
|---|
| 337 |
assert( ellipticF(1, 0)==1); |
|---|
| 338 |
assert(ellipticEComplete(0)==1); |
|---|
| 339 |
assert(ellipticEComplete(1)==PI_2); |
|---|
| 340 |
assert(feqrel(ellipticKComplete(1),PI_2)>= real.mant_dig-1); |
|---|
| 341 |
assert(ellipticKComplete(0)==real.infinity); |
|---|
| 342 |
// assert(ellipticKComplete(1)==0); //-real.infinity); |
|---|
| 343 |
|
|---|
| 344 |
real x=0.5653L; |
|---|
| 345 |
assert(ellipticKComplete(1-x) == ellipticF(PI_2, x) ); |
|---|
| 346 |
assert(ellipticEComplete(1-x) == ellipticE(PI_2, x) ); |
|---|
| 347 |
} |
|---|
| 348 |
} |
|---|
| 349 |
|
|---|
| 350 |
|
|---|
| 351 |
/** |
|---|
| 352 |
* Incomplete elliptic integral of the third kind |
|---|
| 353 |
* |
|---|
| 354 |
* Approximates the integral |
|---|
| 355 |
* |
|---|
| 356 |
* PI(n; phi | m) = $(INTEGRATE t=0, phi) dt/((1 - n $(POWER sin,2)t) * sqrt( 1- m $(POWER sin, 2) t)) |
|---|
| 357 |
* |
|---|
| 358 |
* of amplitude phi, modulus m, and characteristic n using Gauss-Legendre |
|---|
| 359 |
* quadrature. |
|---|
| 360 |
* |
|---|
| 361 |
* Note that ellipticPi(PI_2, m, 1) is infinite for any m. |
|---|
| 362 |
*/ |
|---|
| 363 |
real ellipticPi(real phi, real m, real n) |
|---|
| 364 |
{ |
|---|
| 365 |
// BUGS: This implementation suffers from poor precision. |
|---|
| 366 |
const double [] t = [ |
|---|
| 367 |
0.9931285991850949, 0.9639719272779138, |
|---|
| 368 |
0.9122344282513259, 0.8391169718222188, |
|---|
| 369 |
0.7463319064601508, 0.6360536807265150, |
|---|
| 370 |
0.5108670019508271, 0.3737060887154195, |
|---|
| 371 |
0.2277858511416451, 0.7652652113349734e-1 |
|---|
| 372 |
]; |
|---|
| 373 |
const double [] w =[ |
|---|
| 374 |
0.1761400713915212e-1, 0.4060142980038694e-1, |
|---|
| 375 |
0.6267204833410907e-1, 0.8327674157670475e-1, |
|---|
| 376 |
0.1019301198172404, 0.1181945319615184, |
|---|
| 377 |
0.1316886384491766, 0.1420961093183820, |
|---|
| 378 |
0.1491729864726037, 0.1527533871307258 |
|---|
| 379 |
]; |
|---|
| 380 |
bool b1 = (m==1) && abs(phi-90)<=1e-8; |
|---|
| 381 |
bool b2 = (n==1) && abs(phi-90)<=1e-8; |
|---|
| 382 |
if (b1 || b2) return real.infinity; |
|---|
| 383 |
real c1 = 0.87266462599716e-2 * phi; |
|---|
| 384 |
real c2 = c1; |
|---|
| 385 |
double x = 0; |
|---|
| 386 |
for (int i=0; i< t.length; ++i) { |
|---|
| 387 |
real c0 = c2 * t[i]; |
|---|
| 388 |
real t1 = c1 + c0; |
|---|
| 389 |
real t2 = c1 - c0; |
|---|
| 390 |
real s1 = sin(t1); // sin(c1 * (1 + t[i])) |
|---|
| 391 |
real s2 = sin(t2); // sin(c1 * (1 - t[i])) |
|---|
| 392 |
real f1 = 1.0 / ((1.0 - n * s1 * s1) * sqrt(1.0 - m * s1 * s1)); |
|---|
| 393 |
real f2 = 1.0 / ((1.0 - n * s2 * s2) * sqrt(1.0 - m * s2 * s2)); |
|---|
| 394 |
x+= w[i]*(f1+f2); |
|---|
| 395 |
} |
|---|
| 396 |
return c1 * x; |
|---|
| 397 |
} |
|---|
| 398 |
|
|---|
| 399 |
/** |
|---|
| 400 |
* Complete elliptic integral of the third kind |
|---|
| 401 |
*/ |
|---|
| 402 |
real ellipticPiComplete(real m, real n) |
|---|
| 403 |
in { |
|---|
| 404 |
assert(m>=-1.0 && m<=1.0); |
|---|
| 405 |
} |
|---|
| 406 |
body { |
|---|
| 407 |
return ellipticPi(PI_2, m, n); |
|---|
| 408 |
} |
|---|