/// <summary> /// Asserts that the expected value and the actual value are equal. /// </summary> /// <param name="expected">The expected value.</param> /// <param name="actual">The actual value.</param> public static void AreEqual(Complex expected, Complex actual) { if (expected.IsNaN() && actual.IsNaN()) { return; } if (expected.IsInfinity() && expected.IsInfinity()) { return; } bool pass = expected.Real.AlmostEqual(actual.Real); if (!pass) { Assert.Fail("Real components are not equal. Expected:{0}; Actual:{1}", expected.Real, actual.Real); } pass = expected.Imaginary.AlmostEqual(actual.Imaginary); if (!pass) { Assert.Fail("Imaginary components are not equal. Expected:{0}; Actual:{1}", expected.Imaginary, actual.Imaginary); } }
public static void AlmostEqual(Complex expected, Complex actual) { if (expected.IsNaN() && actual.IsNaN() || expected.IsInfinity() && expected.IsInfinity()) { return; } if (!expected.Real.AlmostEqual(actual.Real)) { Assert.Fail("Real components are not equal. Expected:{0}; Actual:{1}", expected.Real, actual.Real); } if (!expected.Imaginary.AlmostEqual(actual.Imaginary)) { Assert.Fail("Imaginary components are not equal. Expected:{0}; Actual:{1}", expected.Imaginary, actual.Imaginary); } }
/// <summary> /// Returns the derivative of a complex function at a point x by Ridders' method of polynomial /// extrapolation. The value h is input as an estimated initial stepsize; it need not be small, but /// rather should be an increment in x over which func changes substantially. An estimate of the /// error in the derivative is returned as err. /// </summary> /// <param name="function">A target complex function.</param> /// <param name="difference">A complex function represents the difference quotient.</param> /// <param name="x">A point at which the derivative is calculated.</param> /// <param name="h">An estimated initial stepsize.</param> /// <param name="err">An estimate of the error.</param> /// <returns>Numerical approximation of the value of the derivative of function at point x.</returns> private static Complex RidersDerivation(Func <Complex, Complex> function, DifferenceQuotient difference, Complex x, double h, out double err) { if (Complex.IsNaN(function(x)) || Complex.IsInfinity(function(x))) { err = double.MaxValue; return(double.NaN); } int i, j; double errt, fac, hh; Complex ans = Complex.Zero; if (h == 0.0) { throw new ArgumentException("h must be nonzero."); } hh = h; a[0, 0] = difference(function, x, hh); err = big; for (i = 1; i < ntab; i++) { // Successive columns in the Neville tableau will go to smaller stepsizes and higher orders of // extrapolation. hh /= con; a[0, i] = difference(function, x, hh); // Try new, smaller stepsize. fac = con2; // Compute extrapolations of various orders, requiring no new function evaluations. for (j = 1; j <= i; j++) { a[j, i] = (a[j - 1, i] * fac - a[j - 1, i - 1]) / (fac - 1.0); fac = con2 * fac; errt = Math.Max(Complex.Abs(a[j, i] - a[j - 1, i]), Complex.Abs(a[j, i] - a[j - 1, i - 1])); // The error strategy is to compare each new extrapolation to one order lower, both // at the present stepsize and the previous one. // If error is decreased, save the improved answer. if (errt <= err) { err = errt; ans = a[j, i]; } } // If higher order is worse by a significant factor SAFE, then quit early. if (Complex.Abs(a[i, i] - a[i - 1, i - 1]) >= safe * err && err <= _tol * Complex.Abs(ans)) { return(ans); } } throw new NotConvergenceException("Calculation does not converge to a solution."); }
/// <summary> /// Returns the numerical value of the definite integral complex function of one variable. /// </summary> /// <returns>Approximate value of the definite integral.</returns> /// <exception cref="NotConvergenceException"> /// The algorithm does not converged for a certain number of iterations. /// </exception> public override Complex Integrate(Func <Complex, Complex> integrand, double lowerBound, double upperBound) { if (lowerBound == upperBound) { return(Complex.Zero); } double tol = Tolerance; // Testing the limits to infinity if (double.IsInfinity(lowerBound) || double.IsInfinity(upperBound)) { throw new NotConvergenceException("The limits of integration can not be infinite."); } Complex fa = integrand(lowerBound); Complex fb = integrand(upperBound); // Testing the endpoints to singularity if (Complex.IsInfinity(fa) || Complex.IsNaN(fa) || Complex.IsInfinity(fb) || Complex.IsNaN(fb)) { throw new NotConvergenceException("Calculation does not converge to a solution."); } R[0, 0] = 0.5 * (upperBound - lowerBound) * (integrand(lowerBound) + integrand(upperBound)); int n; for (n = 1; n < MaxIterations; n++) { double h = (upperBound - lowerBound) / Math.Pow(2.0, n); Complex sum = Complex.Zero; for (int k = 1; k <= Math.Pow(2, n - 1); k++) { sum += integrand(lowerBound + (2 * k - 1) * h); } R[n, 0] = 0.5 * R[n - 1, 0] + h * sum; for (int m = 1; m <= n; m++) { R[n, m] = R[n, m - 1] + (R[n, m - 1] - R[n - 1, m - 1]) / (Math.Pow(4, m) - 1); } double relativeError = Complex.Abs(R[n, n - 1] - R[n, n]); if (relativeError < tol) { IterationsNeeded = n; return(R[n, n]); } } throw new NotConvergenceException("Calculation does not converge to a solution."); }
public void CanDetermineIfInfinity() { var complex = new Complex(double.PositiveInfinity, 1); Assert.IsTrue(complex.IsInfinity(), "Real part is infinity."); complex = new Complex(1, double.NegativeInfinity); Assert.IsTrue(complex.IsInfinity(), "Imaginary part is infinity."); complex = new Complex(double.NegativeInfinity, double.PositiveInfinity); Assert.IsTrue(complex.IsInfinity(), "Both parts are infinity."); }
public void InfinityTest() { var cd = new Complex(double.NegativeInfinity, 1.1); Assert.IsTrue(cd.IsInfinity()); cd = new Complex(1.1, double.NegativeInfinity); Assert.IsTrue(cd.IsInfinity()); cd = new Complex(double.PositiveInfinity, 1.1); Assert.IsTrue(cd.IsInfinity()); cd = new Complex(1.1, double.PositiveInfinity); Assert.IsTrue(cd.IsInfinity()); cd = new Complex(1.1, 2.2); Assert.IsFalse(cd.IsInfinity()); }
public static void Infinity() { Assert.True(Complex.IsInfinity(new Complex(double.PositiveInfinity, double.PositiveInfinity))); Assert.True(Complex.IsInfinity(new Complex(1, double.PositiveInfinity))); Assert.True(Complex.IsInfinity(new Complex(double.PositiveInfinity, 1))); Assert.True(Complex.IsInfinity(new Complex(double.NegativeInfinity, double.NegativeInfinity))); Assert.True(Complex.IsInfinity(new Complex(1, double.NegativeInfinity))); Assert.True(Complex.IsInfinity(new Complex(double.NegativeInfinity, 1))); Assert.True(Complex.IsInfinity(Complex.Infinity)); Assert.False(Complex.IsInfinity(Complex.NaN)); VerifyRealImaginaryProperties(Complex.Infinity, double.PositiveInfinity, double.PositiveInfinity); VerifyMagnitudePhaseProperties(Complex.Infinity, double.PositiveInfinity, Math.PI / 4); }
public static bool cIsInf(Complex value) { return(Complex.IsInfinity(value)); }