Java を使用して 2 次ベッセル関数 (Y_v(x)) を計算しようとしています。ここで、ベッセル関数の次数である v は整数ではありません。
Apache には、1 次ベッセル関数 (J_v(x)) を計算する関数があります。
import org.apache.commons.math3.special.BesselJ;
BesselJ bj = new BesselJ(10.5);
double bjr = bj.value(r);
非整数の一次ベッセル関数を計算できます(ただし、負の次数関数は計算できません)。私はそれが二次に相当するとは思わない。
私は、一次関数から二次ベッセル関数を計算する二次ベッセル関数を計算するための公式を見つけました (数値レシピの式 6.4.2 など)。
ただし、この方程式では、一次ベッセル関数が負の v 値を受け入れる必要がありますが、Apache BesselJ 関数では受け入れられません。
数式を使用して負の値を受け入れる BesselJ 関数を計算するプログラムを作成しました (Numerical Recipes 6.4.1)。
import org.apache.commons.math3.special.Gamma;
import org.apache.commons.math3.util.ArithmeticUtils;
private static int lmax;
private static double[][] Gammas;
private static int besselcount;
public static Double Bessel_J(double m, double x){
double BJ = 0.0;
for (int k = 0; k < besselcount;k++){
double kk = (double) k;
double llmm = (double) lmax;
double A = Math.pow(x/2.,(2.*kk)+m);
double B = Gammas[(int) (m+llmm+0.5)][k];
if (B==0.0||B==-0.0){break;}
BJ = BJ + A*B;
}
return BJ;
}
public static void main(String[] args) throws Exception {
besselcount = 80;
lmax = 20;
Gammas = new double[2*lmax+2][besselcount+1];
for (int n = 0;n <= ((2*lmax)+1);n++){
for (int m = 0;m <=besselcount;m++) {
double nn = (double) n;
double mm = (double) m;
double llmm = (double) lmax;
Gammas[n][m] = Math.pow(-1,m)/(ArithmeticUtils.factorialDouble(m)*Gamma.gamma(1.+nn-llmm-0.5+mm));
}
}
for (double x = 0.02; x < 50.0 ; x = x + 0.02){
double bj = Bessel_J(-10.5, x);
System.out.println(x+" "+bj);
}
}
(ガンマを事前に計算して配列に格納するのは、コードの残りの部分でベッセル関数を使用して、不必要に再計算するのを避けるためです)
私が書いた関数は、x の値が低い場合に機能しますが、安定性を失います。v = -10.5 の値については、x = 30 前後で使用しました。図に示すように。
wolfram alpha の Web サイトには、mathematica は同じ方程式を使用してベッセル関数を計算し、mathematica の BesselJ 関数は計算できると書かれています
Show[Plot[BesselJ[-10.5, x], {x, 0, 50}], ImageSize -> Full]
安定性を失うことなく。
私の関数を修正する方法、または Java を使用して 2 次ベッセル関数を計算する別の方法についてアドバイスをいただければ幸いです。
説明が役立つかどうか教えてください。
ありがとうございました



