// Return Exp(-Abs(x)) * I(v, z) where x = z.Real public static Complex ScaledCbesi(double v, Complex z) { if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) { return(new Complex(double.NaN, double.NaN)); } int sign = 1; if (v < 0) { v = -v; sign = -1; } int n = 1; int kode = 2; int nz = 0; int ierr = 0; double[] cyir = new double[n]; double[] cyii = new double[n]; for (int i = 0; i < n; i++) { cyir[i] = double.NaN; cyii[i] = double.NaN; } AmosHelper.zbesi(z.Real, z.Imaginary, v, kode, n, cyir, cyii, ref nz, ref ierr); Complex cyi = new Complex(cyir[0], cyii[0]); if (sign == -1) { if (!ReflectI(cyi, v)) { double[] cykr = new double[n]; double[] cyki = new double[n]; AmosHelper.zbesk(z.Real, z.Imaginary, v, kode, n, cykr, cyki, ref nz, ref ierr); Complex cyk = new Complex(cykr[0], cyki[0]); //adjust scaling to match zbesi cyk = Rotate(cyk, -z.Imaginary / Math.PI); if (z.Real > 0) { cyk = new Complex(cyk.Real * Math.Exp(-2 * z.Real), cyk.Imaginary * Math.Exp(-2 * z.Real)); } //v -> -v cyi = RotateI(cyi, cyk, v); } } return(cyi); }
// Returns K(v, z) public static Complex Cbesk(double v, Complex z) { if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) { return(new Complex(double.NaN, double.NaN)); } if (v < 0) { //K_v == K_{-v} even for non-integer v v = -v; } int n = 1; int kode = 1; int nz = 0; int ierr = 0; double[] cykr = new double[n]; double[] cyki = new double[n]; for (int i = 0; i < n; i++) { cykr[i] = double.NaN; cyki[i] = double.NaN; } AmosHelper.zbesk(z.Real, z.Imaginary, v, kode, n, cykr, cyki, ref nz, ref ierr); Complex cyk = new Complex(cykr[0], cyki[0]); if (ierr == 1) { if (z.Real == 0.0 && z.Imaginary == 0.0) { cyk = new Complex(double.PositiveInfinity, 0); } } else if (ierr == 2) { if (z.Real >= 0 && z.Imaginary == 0) { //overflow cyk = new Complex(double.PositiveInfinity, 0); } } return(cyk); }
// Returns I(v, z) public static Complex Cbesi(double v, Complex z) { if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) { return(new Complex(double.NaN, double.NaN)); } int sign = 1; if (v < 0) { v = -v; sign = -1; } int n = 1; int kode = 1; int nz = 0; int ierr = 0; double[] cyir = new double[n]; double[] cyii = new double[n]; for (int i = 0; i < n; i++) { cyir[i] = double.NaN; cyii[i] = double.NaN; } AmosHelper.zbesi(z.Real, z.Imaginary, v, kode, n, cyir, cyii, ref nz, ref ierr); Complex cyi = new Complex(cyir[0], cyii[0]); if (ierr == 2) { //overflow if (z.Imaginary == 0 && (z.Real >= 0 || v == Math.Floor(v))) { if (z.Real < 0 && v / 2 != Math.Floor(v / 2)) { cyi = new Complex(double.NegativeInfinity, 0); } else { cyi = new Complex(double.PositiveInfinity, 0); } } else { cyi = ScaledCbesi(v * sign, z); cyi = new Complex(cyi.Real * double.PositiveInfinity, cyi.Imaginary * double.PositiveInfinity); } } if (sign == -1) { if (!ReflectI(cyi, v)) { double[] cykr = new double[n]; double[] cyki = new double[n]; AmosHelper.zbesk(z.Real, z.Imaginary, v, kode, n, cykr, cyki, ref nz, ref ierr); Complex cyk = new Complex(cykr[0], cyki[0]); cyi = RotateI(cyi, cyk, v); } } return(cyi); }