private static MultiPrecision <N> BesselJNearZero(MultiPrecision <N> nu, MultiPrecision <N> z) { Consts.BesselNearZeroCoef table = Consts.Bessel.NearZeroCoef(nu); MultiPrecision <Double <N> > z_ex = z.Convert <Double <N> >(); MultiPrecision <Double <N> > u = 1; MultiPrecision <Double <N> > w = z_ex * z_ex, ww = w * w; MultiPrecision <Double <N> > x = 0; bool probably_convergenced = false; for (int k = 0; k < int.MaxValue - 1; k += 2, u *= ww) { MultiPrecision <Double <N> > c = u * (table.Value(k) - w * table.Value(k + 1)); x += c; if (c.IsZero || x.Exponent - c.Exponent > MultiPrecision <Plus1 <N> > .Bits) { if (probably_convergenced) { break; } else { probably_convergenced = true; continue; } } probably_convergenced = false; if (k >= Bits && Math.Max(x.Exponent, c.Exponent) < -Bits * 2) { return(0); } } MultiPrecision <Plus1 <N> > p; if (nu == Truncate(nu)) { int n = (int)nu; p = MultiPrecision <Plus1 <N> > .Pow(z.Convert <Plus1 <N> >() / 2, n); } else { p = MultiPrecision <Plus1 <N> > .Pow(z.Convert <Plus1 <N> >() / 2, nu.Convert <Plus1 <N> >()); } MultiPrecision <Plus1 <N> > y = x.Convert <Plus1 <N> >() * p; return(y.Convert <N>()); }
private static MultiPrecision <N> BesselYNonIntegerNu(MultiPrecision <N> nu, MultiPrecision <N> z) { Consts.BesselNearZeroCoef table_pos = Consts.Bessel.NearZeroCoef(nu); Consts.BesselNearZeroCoef table_neg = Consts.Bessel.NearZeroCoef(-nu); MultiPrecision <Double <N> > z_ex = z.Convert <Double <N> >(), nu_ex = nu.Convert <Double <N> >(); MultiPrecision <Double <N> > p = MultiPrecision <Double <N> > .Pow(z_ex / 2, nu_ex); MultiPrecision <Double <N> > cos = MultiPrecision <Double <N> > .Consts.Bessel.SinCos(nu_ex).cos; MultiPrecision <Double <N> > u = p * cos, v = 1 / p; MultiPrecision <Double <N> > w = z_ex * z_ex, ww = w * w; MultiPrecision <Double <N> > x = 0; bool probably_convergenced = false; for (int k = 0; k < int.MaxValue - 1; k += 2, u *= ww, v *= ww) { MultiPrecision <Double <N> > c_pos = u * (table_pos.Value(k) - w * table_pos.Value(k + 1)); MultiPrecision <Double <N> > c_neg = v * (table_neg.Value(k) - w * table_neg.Value(k + 1)); MultiPrecision <Double <N> > c = c_pos - c_neg; x += c; if (c.IsZero || x.Exponent - c.Exponent > MultiPrecision <Plus1 <N> > .Bits) { if (probably_convergenced) { break; } else { probably_convergenced = true; continue; } } probably_convergenced = false; if (k >= Bits && Math.Max(x.Exponent, c.Exponent) < -Bits * 2) { return(0); } } MultiPrecision <Plus1 <N> > sin = MultiPrecision <Plus1 <N> > .Consts.Bessel.SinCos(nu.Convert <Plus1 <N> >()).sin; MultiPrecision <Plus1 <N> > y = x.Convert <Plus1 <N> >() / sin; return(y.Convert <N>()); }
private static MultiPrecision <Plus1 <N> > BesselJNearZero(MultiPrecision <N> nu, MultiPrecision <N> z) { Consts.BesselNearZeroCoef table = Consts.Bessel.NearZeroCoef(nu); MultiPrecision <Double <N> > z_ex = z.Convert <Double <N> >(); MultiPrecision <Double <N> > u = 1; MultiPrecision <Double <N> > w = z_ex * z_ex; MultiPrecision <Double <N> > x = 0; Sign sign = Sign.Plus; for (int k = 0; k < int.MaxValue; k++, u *= w) { MultiPrecision <Double <N> > c = u * table.Value(k); if (sign == Sign.Plus) { x += c; sign = Sign.Minus; } else { x -= c; sign = Sign.Plus; } if (c.IsZero || x.Exponent - c.Exponent > MultiPrecision <Plus1 <N> > .Bits) { break; } if (k >= MultiPrecision <N> .Bits && Math.Max(x.Exponent, c.Exponent) < -MultiPrecision <N> .Bits * 8) { return(0); } } MultiPrecision <Double <N> > p; if (nu == MultiPrecision <N> .Truncate(nu)) { int n = (int)nu; p = MultiPrecision <Double <N> > .Pow(z_ex / 2, n); } else { p = MultiPrecision <Double <N> > .Pow(z_ex / 2, nu.Convert <Double <N> >()); } MultiPrecision <Double <N> > y = x * p; return(y.Convert <Plus1 <N> >()); }
private static MultiPrecision <N> BesselKNonIntegerNu(MultiPrecision <N> nu, MultiPrecision <N> z) { Consts.BesselNearZeroCoef table_pos = Consts.Bessel.NearZeroCoef(nu); Consts.BesselNearZeroCoef table_neg = Consts.Bessel.NearZeroCoef(-nu); MultiPrecision <Double <N> > z_ex = z.Convert <Double <N> >(); MultiPrecision <Double <N> > p = MultiPrecision <Double <N> > .Pow(z_ex / 2, nu.Convert <Double <N> >()); MultiPrecision <Double <N> > u = p, v = 1 / p; MultiPrecision <Double <N> > w = z_ex * z_ex; MultiPrecision <Double <N> > x = 0; bool probably_convergenced = false; for (int k = 0; k < int.MaxValue; k++, u *= w, v *= w) { MultiPrecision <Double <N> > c_pos = u * table_pos.Value(k), c_neg = v * table_neg.Value(k); MultiPrecision <Double <N> > c = c_neg - c_pos; x += c; if (c.IsZero || x.Exponent - c.Exponent > MultiPrecision <Plus1 <N> > .Bits) { if (probably_convergenced) { break; } else { probably_convergenced = true; continue; } } probably_convergenced = false; } MultiPrecision <Plus1 <N> > sin = MultiPrecision <Plus1 <N> > .Consts.Bessel.SinCos(nu.Convert <Plus1 <N> >()).sin; MultiPrecision <Plus1 <N> > y = (x.Convert <Plus1 <N> >() * MultiPrecision <Plus1 <N> > .PI) / (2 * sin); return(y.Convert <N>()); }
private static MultiPrecision <N> BesselINearZero(MultiPrecision <N> nu, MultiPrecision <N> z) { Consts.BesselNearZeroCoef table = Consts.Bessel.NearZeroCoef(nu); MultiPrecision <Double <N> > z_ex = z.Convert <Double <N> >(); MultiPrecision <Double <N> > u = 1; MultiPrecision <Double <N> > w = z_ex * z_ex; MultiPrecision <Double <N> > x = 0; for (int k = 0; k < int.MaxValue; k++, u *= w) { MultiPrecision <Double <N> > c = u * table.Value(k); x += c; if (c.IsZero || x.Exponent - c.Exponent > MultiPrecision <Plus1 <N> > .Bits) { break; } } MultiPrecision <Plus1 <N> > p; if (nu == Truncate(nu)) { int n = (int)nu; p = MultiPrecision <Plus1 <N> > .Pow(z.Convert <Plus1 <N> >() / 2, n); } else { p = MultiPrecision <Plus1 <N> > .Pow(z.Convert <Plus1 <N> >() / 2, nu.Convert <Plus1 <N> >()); } MultiPrecision <Plus1 <N> > y = x.Convert <Plus1 <N> >() * p; return(y.Convert <N>()); }
private static MultiPrecision <N> BesselKIntegerNuNearZero(int n, MultiPrecision <N> z) { Consts.BesselNearZeroCoef nearzero_table = Consts.Bessel.NearZeroCoef(n); Consts.BesselIntegerFiniteTermCoef finite_table = Consts.Bessel.IntegerFiniteTermCoef(n); Consts.BesselIntegerConvergenceTermCoef convergence_table = Consts.Bessel.IntegerConvergenceTermCoef(n); MultiPrecision <Double <N> > z_ex = z.Convert <Double <N> >(); MultiPrecision <Double <N> > m = MultiPrecision <Double <N> > .Pow(z_ex / 2, n), inv_mm = 1 / (m * m); MultiPrecision <Double <N> > u = m, v = 2 * m * MultiPrecision <Double <N> > .Log(z_ex / 2); MultiPrecision <Double <N> > w = z_ex * z_ex; MultiPrecision <Double <N> > x = 0; bool probably_convergenced = false; Sign sign = Sign.Plus; for (int k = 0; k < int.MaxValue; k++, u *= w, v *= w) { MultiPrecision <Double <N> > c_pos = u * convergence_table.Value(k); MultiPrecision <Double <N> > c_neg = v * nearzero_table.Value(k); MultiPrecision <Double <N> > c = c_pos - c_neg; if ((n & 1) == 0) { x += c; } else { x -= c; } if (k < n) { MultiPrecision <Double <N> > d = u * inv_mm * finite_table.Value(k); if (sign == Sign.Plus) { x += d; sign = Sign.Minus; } else { x -= d; sign = Sign.Plus; } } else { if (c.IsZero || x.Exponent - c.Exponent > MultiPrecision <Plus1 <N> > .Bits) { if (probably_convergenced) { break; } else { probably_convergenced = true; continue; } } probably_convergenced = false; } } MultiPrecision <N> y = x.Convert <N>() / 2; return(y); }