29 double KelvinFunctions::fgMin = 20;
30 double KelvinFunctions::fgEpsilon = 1.e-20;
32 double kSqrt2 = 1.4142135623730950488016887242097;
33 double kPi = 3.14159265358979323846;
34 double kEulerGamma = 0.577215664901532860606512090082402431042;
72 double KelvinFunctions::Ber(
double x)
74 if (fabs(x) < fgEpsilon)
return 1;
76 if (fabs(x) < fgMin) {
77 double sum, factorial = 1, n = 1;
78 double term = 1, x_factor = x * x * x * x * 0.0625;
83 factorial = 4 * n * n * (2 * n - 1) * (2 * n - 1);
84 term *= (-1) / factorial * x_factor;
88 }
while (fabs(term) > fgEpsilon * sum);
92 double alpha = x / kSqrt2 - kPi / 8;
93 double value = F1(x) * cos(alpha) + G1(x) * sin(alpha);
94 value *= exp(x / kSqrt2) / sqrt(2 * kPi * x);
95 value -= Kei(x) / kPi;
130 double KelvinFunctions::Bei(
double x)
133 if (fabs(x) < fgEpsilon)
return 0;
135 if (fabs(x) < fgMin) {
136 double sum, factorial = 1, n = 1;
137 double term = x * x * 0.25, x_factor = term * term;
142 factorial = 4 * n * n * (2 * n + 1) * (2 * n + 1);
143 term *= (-1) / factorial * x_factor;
147 }
while (fabs(term) > fgEpsilon * sum);
151 double alpha = x / kSqrt2 - kPi / 8;
152 double value = F1(x) * sin(alpha) + G1(x) * cos(alpha);
153 value *= exp(x / kSqrt2) / sqrt(2 * kPi * x);
154 value += Ker(x) / kPi;
195 double KelvinFunctions::Ker(
double x)
197 if (fabs(x) < fgEpsilon)
return 1E+100;
199 if (fabs(x) < fgMin) {
200 double term = 1, x_factor = x * x * x * x * 0.0625;
201 double factorial = 1, harmonic = 0, n = 1, sum;
203 if(x < 0) delta = kPi;
205 sum = - (log(fabs(x) * 0.5) + kEulerGamma) * Ber(x) + (kPi * 0.25 - delta) * Bei(x);
208 factorial = 4 * n * n * (2 * n - 1) * (2 * n - 1);
209 term *= (-1) / factorial * x_factor;
210 harmonic += 1 / (2 * n - 1 ) + 1 / (2 * n);
211 sum += term * harmonic;
214 }
while (fabs(term * harmonic) > fgEpsilon * sum);
218 double beta = x / kSqrt2 + kPi / 8;
219 double value = F2(x) * cos(beta) - G2(x) * sin(beta);
220 value *= sqrt(kPi / (2 * x)) * exp(- x / kSqrt2);
262 double KelvinFunctions::Kei(
double x)
264 if (fabs(x) < fgEpsilon)
return (-0.25 * kPi);
266 if (fabs(x) < fgMin) {
267 double term = x * x * 0.25, x_factor = term * term;
268 double factorial = 1, harmonic = 1, n = 1, sum;
270 if(x < 0) delta = kPi;
272 sum = term - (log(fabs(x) * 0.5) + kEulerGamma) * Bei(x) - (kPi * 0.25 - delta) * Ber(x);
275 factorial = 4 * n * n * (2 * n + 1) * (2 * n + 1);
276 term *= (-1) / factorial * x_factor;
277 harmonic += 1 / (2 * n) + 1 / (2 * n + 1);
278 sum += term * harmonic;
281 }
while (fabs(term * harmonic) > fgEpsilon * sum);
285 double beta = x / kSqrt2 + kPi / 8;
286 double value = - F2(x) * sin(beta) - G2(x) * cos(beta);
287 value *= sqrt(kPi / (2 * x)) * exp(- x / kSqrt2);
314 double KelvinFunctions::DBer(
double x)
316 if (fabs(x) < fgEpsilon)
return 0;
318 if (fabs(x) < fgMin) {
319 double sum, factorial = 1, n = 1;
320 double term = - x * x * x * 0.0625, x_factor = - term * x;
325 factorial = 4 * n * (n + 1) * (2 * n + 1) * (2 * n + 1);
326 term *= (-1) / factorial * x_factor;
330 }
while (fabs(term) > fgEpsilon * sum);
334 else return (M(x) * sin(Theta(x) - kPi / 4));
359 double KelvinFunctions::DBei(
double x)
361 if (fabs(x) < fgEpsilon)
return 0;
363 if (fabs(x) < fgMin) {
364 double sum, factorial = 1, n = 1;
365 double term = x * 0.5, x_factor = x * x * x * x * 0.0625;
370 factorial = 4 * n * n * (2 * n - 1) * (2 * n + 1);
371 term *= (-1) * x_factor / factorial;
375 }
while (fabs(term) > fgEpsilon * sum);
379 else return (M(x) * cos(Theta(x) - kPi / 4));
404 double KelvinFunctions::DKer(
double x)
406 if (fabs(x) < fgEpsilon)
return -1E+100;
408 if (fabs(x) < fgMin) {
409 double term = - x * x * x * 0.0625, x_factor = - term * x;
410 double factorial = 1, harmonic = 1.5, n = 1, sum;
412 if(x < 0) delta = kPi;
414 sum = 1.5 * term - Ber(x) / x - (log(fabs(x) * 0.5) + kEulerGamma) * DBer(x) + (0.25 * kPi - delta) * DBei(x);
417 factorial = 4 * n * (n + 1) * (2 * n + 1) * (2 * n + 1);
418 term *= (-1) / factorial * x_factor;
419 harmonic += 1 / (2 * n + 1 ) + 1 / (2 * n + 2);
420 sum += term * harmonic;
423 }
while (fabs(term * harmonic) > fgEpsilon * sum);
427 else return N(x) * sin(Phi(x) - kPi / 4);
452 double KelvinFunctions::DKei(
double x)
454 if (fabs(x) < fgEpsilon)
return 0;
456 if (fabs(x) < fgMin) {
457 double term = 0.5 * x, x_factor = x * x * x * x * 0.0625;
458 double factorial = 1, harmonic = 1, n = 1, sum;
460 if(x < 0) delta = kPi;
462 sum = term - Bei(x) / x - (log(fabs(x) * 0.5) + kEulerGamma) * DBei(x) - (kPi * 0.25 - delta) * DBer(x);
465 factorial = 4 * n * n * (2 * n - 1) * (2 * n + 1);
466 term *= (-1) / factorial * x_factor;
467 harmonic += 1 / (2 * n) + 1 / (2 * n + 1);
468 sum += term * harmonic;
471 }
while (fabs(term * harmonic) > fgEpsilon * sum);
475 else return N(x) * cos(Phi(x) - kPi / 4);
487 double KelvinFunctions::F1(
double x)
490 double prod = 1, x_factor = 8 * x, factorial = 1, n = 2;
492 sum = kSqrt2 / (16 * x);
496 prod *= (2 * n - 1) * (2 * n - 1);
498 term = prod / (factorial * x_factor) * cos(0.25 * n * kPi);
502 }
while (fabs(term) > fgEpsilon * sum);
516 double KelvinFunctions::F2(
double x)
519 double prod = 1, x_factor = 8 * x, factorial = 1, n = 2;
521 sum = kSqrt2 / (16 * x);
525 prod *= (2 * n - 1) * (2 * n - 1);
527 term = (prod / (factorial * x_factor)) * cos(0.25 * n * kPi);
531 }
while (fabs(term) > fgEpsilon * sum);
547 double KelvinFunctions::G1(
double x)
550 double prod = 1, x_factor = 8 * x, factorial = 1, n = 2;
552 sum = kSqrt2 / (16 * x);
556 prod *= (2 * n - 1) * (2 * n - 1);
558 term = prod / (factorial * x_factor) * sin(0.25 * n * kPi);
562 }
while (fabs(term) > fgEpsilon * sum);
574 double KelvinFunctions::G2(
double x)
577 double prod = 1, x_factor = 8 * x, factorial = 1, n = 2;
579 sum = kSqrt2 / (16 * x);
583 prod *= (2 * n - 1) * (2 * n - 1);
585 term = prod / (factorial * x_factor) * sin(0.25 * n * kPi);
589 }
while (fabs(term) > fgEpsilon * sum);
603 double KelvinFunctions::M(
double x)
605 double value = 1 + 1 / (8 * kSqrt2 * x) + 1 / (256 * x * x) - 399 / (6144 * kSqrt2 * x * x * x);
606 value *= exp(x / kSqrt2) / sqrt(2 * kPi * x);
619 double KelvinFunctions::Theta(
double x)
621 double value = x / kSqrt2 - kPi / 8;
622 value -= 1 / (8 * kSqrt2 * x) + 1 / (16 * x * x) + 25 / (384 * kSqrt2 * x * x * x);
635 double KelvinFunctions::N(
double x)
637 double value = 1 - 1 / (8 * kSqrt2 * x) + 1 / (256 * x * x) + 399 / (6144 * kSqrt2 * x * x * x);
638 value *= exp(- x / kSqrt2) * sqrt(kPi / (2 * x));
651 double KelvinFunctions::Phi(
double x)
653 double value = - x / kSqrt2 - kPi / 8;
654 value += 1 / (8 * kSqrt2 * x) - 1 / (16 * x * x) + 25 / (384 * kSqrt2 * x * x * x);