public void CosTest() { foreach (MultiPrecision <Pow2.N8> x in TestTool.ShortRangeSet <Pow2.N8>()) { MultiPrecision <Pow2.N8> y = MultiPrecision <Pow2.N8> .Cos(x); Console.WriteLine(x); Console.WriteLine(y); TestTool.Tolerance(Math.Cos((double)x), y, minerr: 1e-5, ignore_sign: true); } }
private static MultiPrecision <Plus1 <N> > BesselJLimit(MultiPrecision <N> nu, MultiPrecision <N> z) { Consts.BesselLimitCoef table = Consts.Bessel.LimitCoef(nu); MultiPrecision <Plus4 <N> > z_ex = z.Convert <Plus4 <N> >(); MultiPrecision <Plus4 <N> > v = 1 / z_ex; MultiPrecision <Plus4 <N> > w = v * v; MultiPrecision <Plus4 <N> > x = 0, y = 0, p = 1, q = v; Sign sign = Sign.Plus; for (int k = 0; k <= Consts.BesselJY.LimitApproxTerms; k++, p *= w, q *= w) { MultiPrecision <Plus4 <N> > c = p * table.Value(k * 2); MultiPrecision <Plus4 <N> > s = q * table.Value(k * 2 + 1); if (sign == Sign.Plus) { x += c; y += s; sign = Sign.Minus; } else { x -= c; y -= s; sign = Sign.Plus; } if (!c.IsZero && x.Exponent - c.Exponent <= MultiPrecision <Plus1 <N> > .Bits) { continue; } if (!s.IsZero && y.Exponent - s.Exponent <= MultiPrecision <Plus1 <N> > .Bits) { continue; } break; } MultiPrecision <Plus4 <N> > omega = z_ex - (2 * nu.Convert <Plus4 <N> >() + 1) * MultiPrecision <Plus4 <N> > .PI / 4; MultiPrecision <Plus4 <N> > m = x * MultiPrecision <Plus4 <N> > .Cos(omega) - y * MultiPrecision <Plus4 <N> > .Sin(omega); MultiPrecision <Plus4 <N> > t = m * MultiPrecision <Plus4 <N> > .Sqrt(2 / (MultiPrecision <Plus4 <N> > .PI *z_ex)); return(t.Convert <Plus1 <N> >()); }
public static MultiPrecision <N> BesselY(MultiPrecision <N> nu, MultiPrecision <N> x) { if (MultiPrecision <N> .Abs(nu) > 64) { throw new ArgumentOutOfRangeException( nameof(nu), "In the calculation of the Bessel function, nu with an absolute value greater than 64 is not supported." ); } if (nu.IsNaN || x.IsNaN) { return(MultiPrecision <N> .NaN); } if (x.Sign == Sign.Minus) { if (nu != MultiPrecision <N> .Truncate(nu)) { return(MultiPrecision <N> .NaN); } long n = (long)nu; return(((n & 1L) == 0) ? BesselY(nu, MultiPrecision <N> .Abs(x)) : -BesselY(nu, MultiPrecision <N> .Abs(x))); } if (!x.IsFinite) { return(0); } if (x.IsZero) { return(MultiPrecision <N> .NegativeInfinity); } if (nu.Sign == Sign.Minus && nu == MultiPrecision <N> .Truncate(nu)) { long n = (long)nu; return(((n & 1L) == 0) ? BesselY(MultiPrecision <N> .Abs(nu), x) : -BesselY(MultiPrecision <N> .Abs(nu), x)); } if (nu - MultiPrecision <N> .Point5 == MultiPrecision <N> .Floor(nu)) { long n = (long)MultiPrecision <N> .Floor(nu); if (n >= -2 && n < 2) { MultiPrecision <Plus1 <N> > x_ex = x.Convert <Plus1 <N> >(); MultiPrecision <Plus1 <N> > envelope = MultiPrecision <Plus1 <N> > .Sqrt(2 / (MultiPrecision <Plus1 <N> > .PI *x_ex)); if (n == -2) { MultiPrecision <N> y = -(envelope * (MultiPrecision <Plus1 <N> > .Sin(x_ex) / x_ex - MultiPrecision <Plus1 <N> > .Cos(x_ex))).Convert <N>(); return(y.IsNormal ? y : 0); } if (n == -1) { MultiPrecision <N> y = (envelope * MultiPrecision <Plus1 <N> > .Sin(x_ex)).Convert <N>(); return(y.IsNormal ? y : 0); } if (n == 0) { return(-(envelope * MultiPrecision <Plus1 <N> > .Cos(x_ex)).Convert <N>()); } if (n == 1) { return(-(envelope * (MultiPrecision <Plus1 <N> > .Cos(x_ex) / x_ex + MultiPrecision <Plus1 <N> > .Sin(x_ex))).Convert <N>()); } } } if (MultiPrecision <N> .Length <= 4) { return(MultiPrecisionSandbox <Plus1 <N> > .BesselY(nu.Convert <Plus1 <N> >(), x.Convert <Plus1 <N> >()).Convert <N>()); } if (x < Consts.BesselJY.ApproxThreshold) { return(BesselYNearZero(nu, x)); } else { return(BesselYLimit(nu, x).Convert <N>()); } }