Функция BesselK в C #

Я пытаюсь реализовать метод BesselK из Boost (библиотека C ++).
Метод Boost принимает два типа double и возвращает значение типа double. (У меня это реализовано ниже как cyl_bessel_k.)

Уравнение, из которого я смоделировал это, взято из документации Boosts:
http://www.boost.org/doc/libs/1_45_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/bessel/mbessel.html

Я также проверял значения против Вольфрама:
http://www.wolframalpha.com/input/?i=BesselK%283%2C1%29

Я могу сопоставить выходные данные метода Boost при передаче положительного нецелого значения для «v». Однако, когда передается целое число, мой вывод сильно отключен. Итак, существует очевидная проблема разрыва. Читая об этом, кажется, что эта проблема возникает из-за передачи отрицательного целого числа гамма-функции. Каким-то образом рефлексия вступает в игру с методом Bessel_I, но я близок к завершению своего набора математических навыков.

1.) Что должно произойти с методом bessel_i с отражением, чтобы сделать эту работу?

2.) В настоящее время я делаю частичный подход. Повышение использует подход непрерывной дроби. Как я могу изменить это для учета конвергенции?

Любой вклад приветствуется! Спасибо!

    static double cyl_bessel_k(double v, double x)
{
if (v > 0)
{
double iNegativeV = cyl_bessel_i(-v, x);
double iPositiveV = cyl_bessel_i(v, x);
double besselSecondKind = (Math.PI / 2) * ((iNegativeV - iPositiveV ) / (Math.Sin(Math.PI * v)));
return besselSecondKind;
}
else
{
//error handling
}
}

static double cyl_bessel_i(double v, double x)
{
if (x == 0)
{
return 0;
}
double summed = 0;
double a = Math.Pow((0.5d * x), v);
for (double k = 0; k < 10; k++) //how to account for convergence? 10 is arbitrary
{
double b = Math.Pow(0.25d * Math.Pow(x, 2), k);
double kFactorial = SpecialFunctions.Factorial((int)k); //comes from MathNet.Numerics (Nuget)
double gamma = SpecialFunctions.Gamma(v + k + 1); //comes from MathNet.Numerics
summed += b / (kFactorial * gamma);
}
return a * summed;
}

1

Решение

После многих рефакторингов и попыток, которые не сработали, я пришел к этому. В основном это логика Boost, которая была адаптирована и переведена на C #.

Это не идеально, хотя (вероятно, из-за округления, точности и т. Д.). Любые улучшения приветствуются! Максимальная ошибка составляет 0,0000001926% между истинным значением Bessel_K от Wolfram и моим адаптированным методом. Это происходит, когда параметр ‘v’ является целым числом. Для моих целей это было достаточно близко.

Ссылка на скрипку:
https://dotnetfiddle.net/QIYzK6

Надеюсь, это спасет кого-то от головной боли.

1

Другие решения


По вопросам рекламы [email protected]