/// <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 proprotional 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 Evaluate(double[] X, double[] P, double[] Y) { double x = X[0]; if (_useFrequencyInsteadOmega) { x *= (2 * Math.PI); } Complex result = P[0] + P[1] / ComplexMath.Pow(1 + ComplexMath.Pow(Complex.I * x * P[2], P[3]), P[4]); Y[0] = result.Re; if (this._useFlowTerm) { if (this._isDielectricData) { Y[1] = -result.Im + P[5] / (x * 8.854187817e-12); } else { Y[1] = -result.Im + P[5] / (x); } } else { Y[1] = -result.Im; } }
private static void CalcClx(string param, StreamWriter writer) { var x = new Complex(param); var ans = ComplexMath.Pow(x, x) - x * x + 1; writer.WriteLine(ans.ToString()); }
public void Evaluate(double[] X, double[] P, double[] Y) { double x = X[0]; if (_useFrequencyInsteadOmega) { x *= (2 * Math.PI); } Complex result = 1 / ComplexMath.Pow(1 + ComplexMath.Pow(Complex.I * x * P[2], P[3]), P[4]); result = P[1] + (P[0] - P[1]) * result; if (_useFlowTerm) { result = 1 / ((1 / result) - Complex.I * P[5] / x); } if (_logarithmizeResults) { Y[0] = Math.Log10(result.Re); Y[1] = Math.Log10(result.Im); } else { Y[0] = result.Re; Y[1] = result.Im; } }
public void Evaluate(double[] X, double[] P, double[] Y) { double x = X[0]; if (_useFrequencyInsteadOmega) { x *= (2 * Math.PI); } // Model this first as compliance Complex result = 1 / ComplexMath.Pow(1 + ComplexMath.Pow(Complex.I * x * P[2], P[3]), P[4]); result = (1 / P[1]) + ((1 / P[0]) - (1 / P[1])) * result; if (_useFlowTerm) { result -= Complex.I * P[5] / x; } result = 1 / result; // but now convert to modulus if (_logarithmizeResults) { Y[0] = Math.Log10(result.Re); Y[1] = Math.Log10(result.Im); } else { Y[0] = result.Re; Y[1] = result.Im; } }
public static Complex Gamma(Complex z) { Complex t = z + LanczosGP; return( Global.SqrtTwoPI * ComplexMath.Pow(t / Math.E, z - 0.5) * LanczosExpG * Sum(z) ); }
// Euler-Maclaurin summation approximates a sum by an integral. // \sum_{k=a}^{b} f(k) = \int_a^b \! f(x) \, dx - B_1 \left[ f(b) + f(a) \right] + // \sum_{j=0}^{\infty} \frac{B_{2j}}{(2j)!} \left[ f^{(2j-1)}(b) - f^{(2j-1)}(a) \right] private static Complex RiemannZeta_EulerMaclaurin(Complex z, int n) { Complex f = 0.0; // Sum terms up to (n-1)^{-z} for (int k = 1; k < n; k++) { f += ComplexMath.Pow(k, -z); } // Integral term Complex f_old = f; Complex zm1 = z - Complex.One; f += ComplexMath.Pow(n, -zm1) / zm1; if (f == f_old) { return(f); } // B_1 term f_old = f; Complex df = ComplexMath.Pow(n, -z) / 2.0; f += df; if (f == f_old) { return(f); } // B_2 term df *= z / n; f += AdvancedIntegerMath.BernoulliNumber(2) * df; if (f == f_old) { return(f); } // Higher Bernoulli terms for (int k = 4; k < 2 * AdvancedIntegerMath.Bernoulli.Length; k += 2) { f_old = f; df *= (z + (k - 2)) / n * (z + (k - 3)) / n / k / (k - 1); f += AdvancedIntegerMath.Bernoulli[k / 2] * df; if (f == f_old) { return(f); } } throw new NonconvergenceException(); }
public void Evaluate(double[] X, double[] P, double[] Y) { double x = X[0]; if (_useFrequencyInsteadOmega) { x *= (2 * Math.PI); } Complex result = P[0]; int i, j; for (i = 0, j = 1; i < _numberOfTerms; ++i, j += 4) { result += P[j] / ComplexMath.Pow(1 + ComplexMath.Pow(Complex.I * x * P[1 + j], P[2 + j]), P[3 + j]); } // note: because it is a susceptiblity, the imaginary part is still negative if (_useFlowTerm) { if (_isDielectricData) { result.Im -= P[j] / (x * 8.854187817e-12); } else if (_invertViscosity) { result.Im -= P[j] / (x); } else { result.Im -= 1 / (P[j] * x); } } if (_invertResult) { result = 1 / result; // if we invert, i.e. we calculate the modulus, the imaginary part is now positive } else { result.Im = -result.Im; // else if we don't invert, i.e. we calculate susceptibility, we negate the imaginary part to make it positive } if (_logarithmizeResults) { result.Re = Math.Log10(result.Re); result.Im = Math.Log10(result.Im); } Y[0] = result.Re; Y[1] = result.Im; }
public static Complex Riemann_Euler(Complex z) { Complex f = 1.0; for (int k = 0; k < primes.Length; k++) { Complex f_old = f; Complex fk = 1.0 - ComplexMath.Pow(primes[k], -z); f = f * fk; if (f == f_old) { return(1.0 / f); } } throw new NonconvergenceException(); }
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(); } }
public void EvaluateGradient(double[] X, double[] P, double[][] DY) { double x = X[0]; if (_useFrequencyInsteadOmega) { x *= (2 * Math.PI); } DY[0][0] = 1; DY[1][0] = 0; Complex OneByDenom = 1 / ComplexMath.Pow(1 + ComplexMath.Pow(Complex.I * x * P[2], P[3]), P[4]); DY[0][1] = OneByDenom.Re; DY[1][1] = -OneByDenom.Im; Complex IXP2 = Complex.I * x * P[2]; Complex IXP2PowP3 = ComplexMath.Pow(IXP2, P[3]); Complex der2 = OneByDenom * -P[1] * P[2] * P[4] * IXP2PowP3 / (P[2] * (1 + IXP2PowP3)); DY[0][2] = der2.Re; DY[1][2] = -der2.Im; Complex der3 = OneByDenom * -P[1] * P[4] * IXP2PowP3 *ComplexMath.Log(IXP2) / (1 + IXP2PowP3); DY[0][3] = der3.Re; DY[1][3] = -der3.Im; Complex der4 = OneByDenom * -P[1] * ComplexMath.Log(1 + IXP2PowP3); DY[0][4] = der4.Re; DY[1][4] = -der4.Im; if (_useFlowTerm) { DY[0][5] = 0; DY[1][5] = _isDielectricData ? 1 / (x * 8.854187817e-12) : 1 / x; } }