/// <summary> /// Computes the Riemann zeta function for complex values. /// </summary> /// <param name="z">The argument.</param> /// <returns>The value of ζ(z).</returns> /// <remarks> /// <para>As the imaginary part of the argument increases, the computation of the zeta function becomes slower and more difficult. /// The computation time is approximately proportional to the imaginary part of z. The result also slowly looses accuracy for arguments with /// very large imaginary parts; for arguments with z.Im of order 10^d, approximately the last d digits of the result are suspect.</para> /// <para>The image below shows the complex Γ function near the origin using domain coloring. You can see the first non-trivial /// zeros at (1/2, ±14.13...) as well as the trivial zeros along the negative real axis.</para> /// <img src="../images/ComplexRiemannZetaPlot.png" /> /// </remarks> public static Complex RiemannZeta(Complex z) { // Use conjugation and reflection symmetry to move to the first quadrant. if (z.Im < 0.0) { return(RiemannZeta(z.Conjugate).Conjugate); } if (z.Re < 0.0) { Complex zp = Complex.One - z; return(2.0 * ComplexMath.Pow(Global.TwoPI, -zp) * ComplexMath.Cos(Global.HalfPI * zp) * AdvancedComplexMath.Gamma(zp) * RiemannZeta(zp)); } // Close to pole, use Laurent series. Complex zm1 = z - Complex.One; if (ComplexMath.Abs(zm1) < 0.50) { return(RiemannZeta_LaurentSeries(zm1)); } // Fall back to Euler-Maclaurin summation. int n = RiemannZeta_EulerMaclaurin_N(z.Re, z.Im); return(RiemannZeta_EulerMaclaurin(z, n)); }
public void Cos() { Complex cd1 = new Complex(1.1, -2.2); Complex cd2 = new Complex(0, -2.2); Complex cd3 = new Complex(1.1, 0); Complex cd4 = new Complex(-1.1, 2.2); ComplexFloat cf1 = new ComplexFloat(1.1f, -2.2f); ComplexFloat cf2 = new ComplexFloat(0, -2.2f); ComplexFloat cf3 = new ComplexFloat(1.1f, 0); ComplexFloat cf4 = new ComplexFloat(-1.1f, 2.2f); Complex cdt = ComplexMath.Cos(cd1); Assert.AreEqual(cdt.Real, 2.072, TOLERENCE); Assert.AreEqual(cdt.Imag, 3.972, TOLERENCE); cdt = ComplexMath.Cos(cd2); Assert.AreEqual(cdt.Real, 4.568, TOLERENCE); Assert.AreEqual(cdt.Imag, 0, TOLERENCE); cdt = ComplexMath.Cos(cd3); Assert.AreEqual(cdt.Real, 0.454, TOLERENCE); Assert.AreEqual(cdt.Imag, 0, TOLERENCE); cdt = ComplexMath.Cos(cd4); Assert.AreEqual(cdt.Real, 2.072, TOLERENCE); Assert.AreEqual(cdt.Imag, 3.972, TOLERENCE); ComplexFloat cft = ComplexMath.Cos(cf1); Assert.AreEqual(cft.Real, 2.072, TOLERENCE); Assert.AreEqual(cft.Imag, 3.972, TOLERENCE); cft = ComplexMath.Cos(cf2); Assert.AreEqual(cft.Real, 4.568, TOLERENCE); Assert.AreEqual(cft.Imag, 0, TOLERENCE); cft = ComplexMath.Cos(cf3); Assert.AreEqual(cft.Real, 0.454, TOLERENCE); Assert.AreEqual(cft.Imag, 0, TOLERENCE); cft = ComplexMath.Cos(cf4); Assert.AreEqual(cft.Real, 2.072, TOLERENCE); Assert.AreEqual(cft.Imag, 3.972, TOLERENCE); }
public static Complex AiryAi_Asymptotic(Complex z) { Debug.Assert(ComplexMath.Abs(z) >= 9.0); if (z.Re >= 0.0) { Complex xi = 2.0 / 3.0 * ComplexMath.Pow(z, 3.0 / 2.0); Airy_Asymptotic_Subseries(xi, out Complex u0, out Complex v0, out Complex u1, out Complex v1); Complex e = ComplexMath.Exp(xi); Complex q = ComplexMath.Pow(z, 1.0 / 4.0); return(0.5 / Global.SqrtPI / q / e * u1); } else { z = -z; Complex xi = 2.0 / 3.0 * ComplexMath.Pow(z, 3.0 / 2.0); Airy_Asymptotic_Subseries(xi, out Complex u0, out Complex v0, out Complex u1, out Complex v1); Complex c = ComplexMath.Cos(xi); Complex s = ComplexMath.Sin(xi); throw new NotImplementedException(); } }