public void IntegerBesselSpecialCase() { Assert.IsTrue(AdvancedMath.BesselJ(0, 0.0) == 1.0); Assert.IsTrue(AdvancedMath.BesselJ(1, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.BesselY(0, 0.0) == Double.NegativeInfinity); Assert.IsTrue(AdvancedMath.BesselY(1, 0.0) == Double.NegativeInfinity); }
public void BesselAtZero() { // Normal Bessel \nu = 0 Assert.IsTrue(AdvancedMath.BesselJ(0, 0.0) == 1.0); Assert.IsTrue(AdvancedMath.BesselJ(0.0, 0.0) == 1.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(0, 0.0))); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(0.0, 0.0))); SolutionPair jy0 = AdvancedMath.Bessel(0.0, 0.0); Assert.IsTrue(jy0.FirstSolutionValue == 1.0); Assert.IsTrue(jy0.FirstSolutionDerivative == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(jy0.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jy0.SecondSolutionDerivative)); // Normal Bessel 0 < \nu < 1 Assert.IsTrue(AdvancedMath.BesselJ(0.1, 0.0) == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(0.1, 0.0))); SolutionPair jyf = AdvancedMath.Bessel(0.9, 0.0); Assert.IsTrue(jyf.FirstSolutionValue == 0.0); Assert.IsTrue(jyf.FirstSolutionDerivative == Double.PositiveInfinity); Assert.IsTrue(Double.IsNegativeInfinity(jyf.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jyf.SecondSolutionDerivative)); // Normal Bessel \nu = 1 Assert.IsTrue(AdvancedMath.BesselJ(1, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.BesselJ(1.0, 0.0) == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(1, 0.0))); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(1.0, 0.0))); SolutionPair jy1 = AdvancedMath.Bessel(1.0, 0.0); Assert.IsTrue(jy1.FirstSolutionValue == 0.0); Assert.IsTrue(jy1.FirstSolutionDerivative == 0.5); Assert.IsTrue(Double.IsNegativeInfinity(jy1.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jy1.SecondSolutionDerivative)); // Normal Bessel \nu > 1 Assert.IsTrue(AdvancedMath.BesselJ(2, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.BesselJ(1.2, 0.0) == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(2, 0.0))); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(1.2, 0.0))); SolutionPair jy2 = AdvancedMath.Bessel(1.7, 0.0); Assert.IsTrue(jy2.FirstSolutionValue == 0.0); Assert.IsTrue(jy2.FirstSolutionDerivative == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(jy2.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jy2.SecondSolutionDerivative)); }
public void BesselInflectionValue() { // Abromowitz derived a series for J_{\nu}(\nu) and Y_{\nu}(\nu), // the value at the inflection point. // These appear in A&S 9.3.31 - 9.3.34 with numerical values for the coefficients. // Symbolic values for the coefficients appear in Jentschura & Loetstedt 2011 // (https://arxiv.org/abs/1112.0072) // This is a fairly onerous test to code, but it is a good one, because // the Bessel functions are difficult to calculate in this region. double A = Math.Pow(2.0, 1.0 / 3.0) / Math.Pow(3.0, 2.0 / 3.0) / AdvancedMath.Gamma(2.0 / 3.0); double B = Math.Pow(2.0, 2.0 / 3.0) / Math.Pow(3.0, 1.0 / 3.0) / AdvancedMath.Gamma(1.0 / 3.0); double[] a = new double[] { 1.0, -1.0 / 225.0, 151439.0 / 218295000.0, -887278009.0 / 2504935125000.0, 1374085664813273149.0 / 3633280647121125000000.0 }; double[] b = new double[] { 1.0 / 70.0, -1213.0 / 1023750.0, 16542537833.0 / 37743205500000.0, -9597171184603.0 / 25476663712500000.0, 53299328587804322691259.0 / 91182706744837207500000000.0 }; foreach (double nu in TestUtilities.GenerateRealValues(10.0, 100.0, 8)) { double Af = A / Math.Pow(nu, 1.0 / 3.0); double Bf = B / Math.Pow(nu, 5.0 / 3.0); double J = 0.0; double dJ = 0.0; for (int k = 0; k < Math.Min(a.Length, b.Length); k++) { double nuk = MoreMath.Pow(nu, 2 * k); dJ = Af * a[k] / nuk; J += dJ; dJ = Bf * b[k] / nuk; J -= dJ; } EvaluationSettings e = new EvaluationSettings() { RelativePrecision = TestUtilities.TargetPrecision, AbsolutePrecision = Math.Abs(dJ) }; TestUtilities.IsNearlyEqual(AdvancedMath.BesselJ(nu, nu), J, e); } }
public void BesselModifiedBesselRelationship() { // This is a very interesting test because it relates (normal Bessel) J and (modified Bessel) I // I_{\nu}(x) = \sum_{k=0}^{\infty} J_{\nu + k}(x) \frac{x^k}{k!} // We want x not too big, so that \frac{x^k}{k!} converges, and x <~ \nu, so that J_{\nu+k} decreases rapidly foreach (double nu in TestUtilities.GenerateRealValues(0.1, 10.0, 4)) { foreach (double x in TestUtilities.GenerateRealValues(0.1, nu, 4)) { double I = 0.0; for (int k = 0; k < 100; k++) { double I_old = I; I += AdvancedMath.BesselJ(nu + k, x) * MoreMath.Pow(x, k) / AdvancedIntegerMath.Factorial(k); if (I == I_old) { goto Test; } } throw new NonconvergenceException(); Test: Assert.IsTrue(TestUtilities.IsNearlyEqual(I, AdvancedMath.ModifiedBesselI(nu, x))); } } }
public void BesselWeberIntegral() { Func <double, double> f = delegate(double t) { return(Math.Exp(-t * t) * AdvancedMath.BesselJ(0, t) * t); }; Interval r = Interval.FromEndpoints(0.0, Double.PositiveInfinity); Assert.IsTrue(TestUtilities.IsNearlyEqual(FunctionMath.Integrate(f, r).Estimate.Value, Math.Exp(-1.0 / 4.0) / 2.0)); }
public void RootOfJ0() { Func <double, double> f = delegate(double x) { return(AdvancedMath.BesselJ(0, x)); }; double y = FunctionMath.FindZero(f, Interval.FromEndpoints(2.0, 4.0)); Assert.IsTrue(TestUtilities.IsNearlyEqual(y, 2.40482555769577276862)); }
public void BesselLipshitzIntegral() { // \int_{0}^{\infty} e^{-x} J_0(x) \, dx = \frac{1}{\sqrt{2}} Func <double, double> f = delegate(double t) { return(Math.Exp(-t) * AdvancedMath.BesselJ(0, t)); }; Interval r = Interval.FromEndpoints(0.0, Double.PositiveInfinity); Assert.IsTrue(TestUtilities.IsNearlyEqual(FunctionMath.Integrate(f, r).Estimate.Value, 1.0 / Math.Sqrt(2.0))); }
public void IntegerBesselNegativeArgument() { foreach (int n in TestUtilities.GenerateIntegerValues(1, 1000, 4)) { foreach (double x in TestUtilities.GenerateRealValues(1.0E-4, 1.0E6, 8)) { int s = (n % 2 == 0) ? +1 : -1; Assert.IsTrue(AdvancedMath.BesselJ(n, -x) == s * AdvancedMath.BesselJ(n, x)); } } }
public void BesselKapteynIntegral() { foreach (double x in TestUtilities.GenerateRealValues(1.0E-2, 1.0E2, 8)) { Func <double, double> f = delegate(double t) { return(Math.Cos(x - t) * AdvancedMath.BesselJ(0, t)); }; Interval r = Interval.FromEndpoints(0.0, x); Assert.IsTrue(TestUtilities.IsNearlyEqual(x * AdvancedMath.BesselJ(0, x), FunctionMath.Integrate(f, r).Estimate.Value)); } }
public void BesselJZeros() { foreach (double nu in new double[] { 0.0, 0.5, 1.0, 4.25, 16.0, 124.0 }) { foreach (int k in new int[] { 1, 2, 4, 64, 256 }) { double j = AdvancedMath.BesselJZero(nu, k); double J = AdvancedMath.BesselJ(nu, j); Assert.IsTrue(TestUtilities.IsNearlyEqual(J, 0.0, 4.0E-16 * 3 * k)); } } }
public void ZeroOrderBesselFunction() { double minThreshold = 1e-5; double[] JzeroZeros = { 2.40482, 5.5201, 8.6537, 11.7915, 14.9309 }; for (int i = 0; i < JzeroZeros.Length; i++) { Assert.Less(Math.Abs(AdvancedMath.BesselJ(0, JzeroZeros[i])), minThreshold, "Error occured at i = {0}", i); } }
private double PointChargeRadialElectricComponentIntegrand( double fourierFrequency_per_fm, double effectiveTime_fm, double radialDistance_fm, double conductivity_MeV ) { CalculateShorthands(fourierFrequency_per_fm, effectiveTime_fm, conductivity_MeV, out double x, out double exponentialPart); return(AdvancedMath.BesselJ(1, fourierFrequency_per_fm * radialDistance_fm) * fourierFrequency_per_fm * fourierFrequency_per_fm / x * exponentialPart); }
public void IntegerBesselRecurrence() { foreach (int n in TestUtilities.GenerateIntegerValues(1, 1000, 4)) { foreach (double x in TestUtilities.GenerateRealValues(1.0E-4, 1.0E6, 16)) { Assert.IsTrue(TestUtilities.IsSumNearlyEqual( AdvancedMath.BesselJ(n - 1, x), AdvancedMath.BesselJ(n + 1, x), 2 * n / x * AdvancedMath.BesselJ(n, x) )); Assert.IsTrue(TestUtilities.IsSumNearlyEqual( AdvancedMath.BesselY(n - 1, x), AdvancedMath.BesselY(n + 1, x), 2 * n / x * AdvancedMath.BesselY(n, x) )); } } }
/// <summary> /// Calculate the Hankel Transform using a discrete Riemann middle sum /// </summary> /// <param name="rho">vector of discrete rho values</param> /// <param name="ROfRho">vector of discrete R(rho) values</param> /// <param name="drho">delta rho</param> /// <param name="fx">the spatial frequency at which to evaluate</param> /// <returns></returns> public static double GetHankelTransform(double[] rho, double[] ROfRho, double drho, double fx) { if (rho.Length != ROfRho.Length) { //throw new ArgumentOutOfRangeException(); throw new Meta.Numerics.DimensionMismatchException(); } double sum = 0.0; for (int i = 0; i < rho.Length; i++) { sum += rho[i] * AdvancedMath.BesselJ(0, 2 * Math.PI * fx * rho[i]) * ROfRho[i] * drho; } return(2 * Math.PI * sum); }
public void BesselJ0Integral() { // Abromowitz & Stegun 9.1.18 // J_0(x) = \int_{0}^{\pi} \cos( x \sin(t) ) \, dt // don't let x get too big, or the integral becomes too oscillatory to do accurately Interval r = Interval.FromEndpoints(0.0, Math.PI); foreach (double x in TestUtilities.GenerateRealValues(1.0E-2, 1.0E2, 8)) { Func <double, double> f = delegate(double t) { return(Math.Cos(x * Math.Sin(t))); }; double J0 = FunctionMath.Integrate(f, r).Estimate.Value / Math.PI; Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.BesselJ(0, x), J0)); } }
public void SphericalBesselRealBesselAgreement() { foreach (int n in TestUtilities.GenerateIntegerValues(1, 100, 8)) { foreach (double x in TestUtilities.GenerateRealValues(1.0E-4, 1.0E4, 16)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.SphericalBesselJ(n, x), Math.Sqrt(Math.PI / 2.0 / x) * AdvancedMath.BesselJ(n + 0.5, x) )); Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.SphericalBesselY(n, x), Math.Sqrt(Math.PI / 2.0 / x) * AdvancedMath.BesselY(n + 0.5, x) )); } } }
public void ZernikeBessel() { // \int_0^{1} \! R^{m}_{n}(\rho) J_{m}(x \rho) \rho \, d\rho = (-1)^{(n-m)/2} J_{n+1}(x) / x foreach (int n in TestUtilities.GenerateIntegerValues(2, 32, 4)) { foreach (int m in TestUtilities.GenerateUniformIntegerValues(0, n, 2)) { if ((m % 2) != (n % 2)) { continue; // skip trivial cases } foreach (double x in TestUtilities.GenerateRealValues(1.0, 10.0, 4)) { Console.WriteLine("{0} {1} {2}", n, m, x); Func <double, double> f = delegate(double rho) { return( OrthogonalPolynomials.ZernikeR(n, m, rho) * AdvancedMath.BesselJ(m, x * rho) * rho ); }; double I = FunctionMath.Integrate(f, Interval.FromEndpoints(0.0, 1.0)); double J = AdvancedMath.BesselJ(n + 1, x) / x; if ((n - m) / 2 % 2 != 0) { J = -J; } Console.WriteLine(" {0} {1}", I, J); // Near-zero integrals result from delicate cancelations, and thus // cannot be expected to achieve the relative target precision; // they can achieve the absolute target precisions, though. Assert.IsTrue(TestUtilities.IsNearlyEqual(I, J, new EvaluationSettings() { RelativePrecision = 0.0, AbsolutePrecision = TestUtilities.TargetPrecision })); } } } }
public void IntegerBesselCrossProduct() { foreach (int n in TestUtilities.GenerateIntegerValues(1, 1000, 4)) { foreach (double x in TestUtilities.GenerateRealValues(1.0E-4, 1.0E6, 8)) { double Jn = AdvancedMath.BesselJ(n, x); double Jp = AdvancedMath.BesselJ(n + 1, x); double Yn = AdvancedMath.BesselY(n, x); double Yp = AdvancedMath.BesselY(n + 1, x); if (Double.IsInfinity(Yn)) { continue; } Assert.IsTrue(TestUtilities.IsSumNearlyEqual( Jp * Yn, -Jn * Yp, 2.0 / Math.PI / x )); } } }
public void ZernikeBessel() { foreach (int n in TestUtilities.GenerateIntegerValues(1, 30, 6)) { foreach (int m in TestUtilities.GenerateUniformIntegerValues(0, n, 6)) { //int m = n; if ((m % 2) != (n % 2)) { continue; // skip trivial cases } foreach (double x in TestUtilities.GenerateRealValues(1.0, 10.0, 4)) { Console.WriteLine("{0} {1} {2}", n, m, x); Func <double, double> f = delegate(double rho) { return( OrthogonalPolynomials.ZernikeR(n, m, rho) * AdvancedMath.BesselJ(m, x * rho) * rho ); }; double I = FunctionMath.Integrate(f, Interval.FromEndpoints(0.0, 1.0)); double J = AdvancedMath.BesselJ(n + 1, x) / x; if ((n - m) / 2 % 2 != 0) { J = -J; } Console.WriteLine(" {0} {1}", I, J); // near-zero integrals result from delicate cancelations, and thus // cannot be expected to achieve the relative target precision; // the can achieve the absolute target precisions, so translate Assert.IsTrue(TestUtilities.IsNearlyEqual(I, J, Math.Abs(TestUtilities.TargetPrecision / J))); } } } }
public void IntegerBesselJIntegral() { // Abromowitz & Stegun 9.1.21 IntegrationSettings settings = new IntegrationSettings() { AbsolutePrecision = 2.5E-15, RelativePrecision = 0.0 }; foreach (double x in TestUtilities.GenerateRealValues(0.1, 10.0, 8)) { foreach (int n in TestUtilities.GenerateIntegerValues(1, 10, 4)) { double J = FunctionMath.Integrate( t => MoreMath.Cos(x * MoreMath.Sin(t) - n * t), 0.0, Math.PI, settings ).Estimate.Value / Math.PI; Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.BesselJ(n, x), J, settings ), $"n={n}, x={x}, J={J}"); // The integral can produce significant cancelation, so use an absolute criterion. } } }