1

Boost (C++ ライブラリ) から BesselK メソッドを実装しようとしています。Boost メソッドは 2 つの double を受け取り、double を返します。(以下では cyl_bessel_k として実装しています。)

私がこれをモデル化した方程式は、Boosts のドキュメントから来てい ます。

また、Wolfram に対して値をチェックしています: http://www.wolframalpha.com/input/?i=BesselK%283%2C1%29

「v」に整数以外の正の値を渡すと、Boost メソッドからの出力を一致させることができます。ただし、整数が渡されると、出力が大幅にオフになります。したがって、明らかな不連続性の問題があります。これを読んでみると、この問題は負の整数をガンマ関数に渡すことから発生しているようです。ここで Bessel_I メソッドを使用すると、どういうわけかリフレクションが機能しますが、私の数学スキルセットは終わりに近づいています。

1.) これを機能させるには、リフレクションを使用する bessel_i メソッドに何が必要ですか?

2.) 現在、部分和アプローチを行っています。Boost は、連続分数アプローチを使用します。収束を考慮してこれを変更するにはどうすればよいですか?

どんな入力でも大歓迎です!ありがとうございました!

    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;
    }
4

1 に答える 1

1

多くのリファクタリングとうまくいかないことを試した後、これが私が思いついたものです。C# に適応および変換されたのは、主に Boost ロジックです。

ただし、完全ではありません(丸め、精度などが原因である可能性があります)。どんな改善でも大歓迎です!Wolfram からの真の Bessel_K 値と私の適応した方法との間の最大誤差は 0.0000001926% です。これは、パラメーター 'v' が整数の場合に発生します。私の目的では、これで十分でした。

フィドルへのリンク: https://dotnetfiddle.net/QIYzK6

うまくいけば、それは誰かの頭痛の種を救うでしょう。

于 2015-07-22T20:08:15.067 に答える