private static void test_boundary() //****************************************************************************80 // // Purpose: // // TEST_BOUNDARY tests wrightomega() near boundaries. // // Discussion: // // This is a test driver to evaluate the Wright Omega function along the // boundaries of the different regions of the approximations. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 17 May 2016 // // Author: // // Piers Lawrence, Robert Corless, David Jeffrey // // Reference: // // Piers Lawrence, Robert Corless, David Jeffrey, // Algorithm 917: Complex Double-Precision Evaluation of the Wright Omega // Function, // ACM Transactions on Mathematical Software, // Volume 38, Number 3, Article 20, April 2012, 17 pages. // { Complex cond = new(); Complex e = new(); const double exp_num = 160.0; const string filename = "results.txt"; List <string> fp = new(); int i; const int n = 100; Complex r = new(); Complex w = new(); double[] x = new double[2]; double[] y = new double[2]; Complex z; Console.WriteLine(""); Console.WriteLine("TEST_BOUNDARY:"); Console.WriteLine(" Test wrightomega_ext() near approximation region boundaries."); Console.WriteLine(" Store results in a file for comparison with benchmark data."); // // We want trailing zeros, to make comparison with benchmark easier. // // // Region 1; // x=(-2.0,1.0] ,y=2*pi // x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); x[1] = 1.0; y[0] = NextAfterNS.NextAfter.nextafter(2.0 * Math.PI, -1.0); double td = (x[1] - x[0]) / n; for (i = 0; i < n; i++) { z = new Complex(x[0] + td * i, y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 2; // x=1.0 ,y=(1.0,2*pi) // x[0] = 1.0; y[0] = NextAfterNS.NextAfter.nextafter(1.0, 2.0); y[1] = NextAfterNS.NextAfter.nextafter(2.0 * Math.PI, 1.0); td = -(y[1] - y[0]) / n; for (i = 0; i < n; i++) { z = new Complex(x[0], y[1] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 3; // x=(-2.0,1.0] ,y=1.0 // x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); x[1] = 1.0; td = -(x[1] - x[0]) / n; y[0] = NextAfterNS.NextAfter.nextafter(1.0, 2.0); for (i = 0; i < n; i++) { z = new Complex(x[1] + td * i, y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 4; // x=-2.0 ,y=(1.0,2*pi) // y[0] = NextAfterNS.NextAfter.nextafter(1.0, 2.0); y[1] = NextAfterNS.NextAfter.nextafter(2.0 * Math.PI, -1.0); td = (y[1] - y[0]) / n; x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); for (i = 0; i < n; i++) { z = new Complex(x[0], y[0] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 5; // x=(-2.0,1.0] ,y=-2*pi // x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); x[1] = 1.0; y[0] = NextAfterNS.NextAfter.nextafter(-2.0 * Math.PI, 1.0); td = (x[1] - x[0]) / n; for (i = 0; i < n; i++) { z = new Complex(x[0] + td * i, y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 6; // x=1.0, y=(-2*pi,-1.0) // y[0] = NextAfterNS.NextAfter.nextafter(-2.0 * Math.PI, 1.0); y[1] = NextAfterNS.NextAfter.nextafter(-1.0, -2.0); td = (y[1] - y[0]) / n; x[0] = 1.0; for (i = 0; i < n; i++) { z = new Complex(x[0], y[0] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 7; // x=(-2.0,1.0] ,y=-1.0 // x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); x[1] = 1.0; td = (x[0] - x[1]) / n; y[0] = NextAfterNS.NextAfter.nextafter(-1.0, -2.0); for (i = 0; i < n; i++) { z = new Complex(x[1] + td * i, y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 8; // x=-2.0 ,y=(-2*pi,-1.0) // y[0] = NextAfterNS.NextAfter.nextafter(-2.0 * Math.PI, 1.0); y[1] = NextAfterNS.NextAfter.nextafter(-1.0, -2.0); td = (y[0] - y[1]) / n; x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); for (i = 0; i < n; i++) { z = new Complex(x[0], y[1] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 9; // x=-2.0 y=[-1.0,1.0] // y[0] = -1.0; y[1] = 1.0; td = (y[1] - y[0]) / n; x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); for (i = 0; i < n; i++) { z = new Complex(x[0], y[0] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 10; // x=(-2.0,1.0] y=1.0 // x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); x[1] = 1.0; td = (x[1] - x[0]) / n; y[0] = 1.0; for (i = 0; i < n; i++) { z = new Complex(x[0] + td * i, y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 11 // x=1.0 y=[1.0,pi] // y[0] = 1.0; y[1] = Math.PI; td = (y[1] - y[0]) / n; x[0] = NextAfterNS.NextAfter.nextafter(1.0, 2.0); for (i = 0; i < n; i++) { z = new Complex(x[0], y[0] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 12 // (x-0.1e1)*(x-0.1e1)+y*y=pi*pi) // (on inside) // td = Math.PI / n; x[0] = Math.PI / 2.0; for (i = 0; i < n; i++) { double a = NextAfterNS.NextAfter.nextafter(Math.PI, -1.0) * Math.Cos(x[0] - td * i) + NextAfterNS.NextAfter.nextafter(1.0, -1.0); double b = NextAfterNS.NextAfter.nextafter(Math.PI, -1.0) * Math.Sin(x[0] - td * i); z = new Complex(a, b); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 13 // x=1.0 y=[-pi,-1.0] // y[0] = -Math.PI; y[1] = -1.0; td = (y[1] - y[0]) / n; x[0] = NextAfterNS.NextAfter.nextafter(1.0, 2.0); for (i = 0; i < n; i++) { z = new Complex(x[0], y[0] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 14 // x=(-2.0,1.0] y=-1.0 // x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); x[1] = 1.0; td = (x[1] - x[0]) / n; y[0] = -1.0; for (i = 0; i < n; i++) { z = new Complex(x[0] + td * i, y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 15 // x=(-inf,-2) y=pi^+ // for (i = 0; i < n; i++) { x[0] = NextAfterNS.NextAfter.nextafter(-1.0 - Math.Exp((n - 1 - i) / exp_num), typeMethods.r8_huge()); y[0] = NextAfterNS.NextAfter.nextafter(Math.PI - 0.75 * (x[0] + 1.0), typeMethods.r8_huge()); z = new Complex(x[0], y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 16 // y[0] = 0.75 + Math.PI; y[1] = 2.0 * Math.PI; td = (y[1] - y[0]) / n; x[0] = NextAfterNS.NextAfter.nextafter(-2.0, -3.0); for (i = 0; i < n; i++) { z = new Complex(x[0], y[0] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 17 // x=(-2.0,1.0] ,y=2*pi // x[0] = NextAfterNS.NextAfter.nextafter(-2.0, 1.0); x[1] = 1.0; y[0] = 2.0 * Math.PI; td = (x[1] - x[0]) / n; for (i = 0; i < n; i++) { z = new Complex(x[0] + td * i, y[0]); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } /* * Region 18 * x=1.0 ,y=(pi,2*pi) */ y[0] = NextAfterNS.NextAfter.nextafter(Math.PI, 6.0); y[1] = NextAfterNS.NextAfter.nextafter(2.0 * Math.PI, 1.0); td = -(y[1] - y[0]) / n; x[0] = NextAfterNS.NextAfter.nextafter(1.0, 2.0); for (i = 0; i < n; i++) { z = new Complex(x[0], y[1] + td * i); WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref cond); fp.Add(z.Real + " " + z.Imaginary + " " + w.Real + " " + w.Imaginary + ""); } // // Region 19 // (x-0.1e1)*(x-0.1e1)+y*y=pi*pi) // (on outside) // td = Math.PI / (n - 1); y[0] = Math.PI / 2.0; for (i = 0; i < n; i++) { y[1] = Math.PI * Math.Sin(y[0] - td * i); x[0] = Math.Sqrt(Math.PI * Math.PI - y[1] * y[1]) + 1.0; z = y[1] switch {
private static void driver(Complex z) //****************************************************************************80 // // Purpose: // // DRIVER calls the simple and extended Wright Omega evaluators. // // Modified: // // 14 May 2016 // // Author: // // Piers Lawrence, Robert Corless, David Jeffrey // // Reference: // // Piers Lawrence, Robert Corless, David Jeffrey, // Algorithm 917: Complex Double-Precision Evaluation of the Wright Omega // Function, // ACM Transactions on Mathematical Software, // Volume 38, Number 3, Article 20, April 2012, 17 pages. // // Parameters: // // Input, Complex Z, the argument of the Wright Omega function. // { Complex condest = new(); Complex e = new(); Complex r = new(); Console.WriteLine(""); Console.WriteLine("DRIVER:"); Console.WriteLine(" Demonstrate simple and extended Wright Omega evaluators."); // // Simple evaluator. // Complex w = WrightOmega.wrightomega(z); Console.WriteLine(""); Console.WriteLine(" Calling:"); Console.WriteLine(" w = wrightomega(z);"); Console.WriteLine(" returns:"); Console.WriteLine(" w = omega(" + z.Real + ", " + z.Imaginary + ") = ( " + w.Real + ", " + w.Imaginary + ")"); // // Extended evaluator. // WrightOmega.wrightomega_ext(z, ref w, ref e, ref r, ref condest); Console.WriteLine(""); Console.WriteLine(" Calling:"); Console.WriteLine(" wrightomega_ext ( z, w, e, r, condest );"); Console.WriteLine(" returns:"); Console.WriteLine(" w = omega(" + z.Real + ", " + z.Imaginary + ") = ( " + w.Real + ", " + w.Imaginary + ")"); Console.WriteLine(" e = last update step = ( " + e.Real + ", " + e.Imaginary + ")"); Console.WriteLine(" r = penultimate residual = ( " + r.Real + ", " + r.Imaginary + ")"); Console.WriteLine(" condest = condition number estimate = ( " + condest.Real + ", " + condest.Imaginary + ")"); // // Calculate and print ultimate residual. // Complex r_ult = (2.0 * w * w - 8.0 * w - 1.0) / Complex.Pow(1.0 + w, 6.0) * r * r * r * r; Console.WriteLine(""); Console.WriteLine(" ultimate residual = ( " + r_ult.Real + ", " + r_ult.Imaginary + ")"); }