1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 // The Adams-Moulton Predictor Corrector Method adapted from Conte and de Boor
6 // original source: adams_d.c
9 using System.Runtime.CompilerServices;
10 using System.Diagnostics;
13 using Microsoft.Xunit.Performance;
17 [assembly: OptimizeForBenchmarks]
20 namespace Benchstone.BenchF
22 public static class Adams
25 public static int Iterations = 1;
27 public static int Iterations = 200000;
30 static double g_xn, g_yn, g_dn, g_en;
31 const double g_xn_base = 0.09999999E+01;
32 const double g_yn_base = 0.71828180E+00;
33 const double g_dn_base = 0.21287372E-08;
34 const double g_en_base = 0.74505806E-08;
36 [MethodImpl(MethodImplOptions.NoInlining)]
37 private static void Bench()
39 double[] f = new double[5];
40 double xn, yn, dn, en, yxn, h, fnp, ynp, y0, x0, nz;
44 Console.WriteLine(" ADAMS-MOULTON METHOD ");
60 Console.WriteLine("{0}, {1}, {2}, {3}, {4}", nz, x0, y0, dn, en);
63 for (i = 2; i <= 4; i++)
70 Console.WriteLine("{0}, {1}, {2}, {3}, {4}", k, xn, yn, dn, en);
74 for (k = 4; k <= nstep; k++)
76 ynp = yn + (h / 24) * (55 * f[n] - 59 * f[n - 1] + 37 * f[n - 2] - 9 * f[n - 3]);
79 yn = yn + (h / 24) * (9 * fnp + 19 * f[n] - 5 * f[n - 1] + f[n - 2]);
88 Console.WriteLine("{0}, {1}, {2}, {3}, {4}", k, xn, yn, dn, en);
92 // Escape calculated values:
99 private static double Soln(double x)
101 return (System.Math.Exp(x) - 1.0 - (x));
104 [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
105 private static void TestBench()
107 for (int l = 1; l <= Iterations; l++)
115 public static void Test()
117 foreach (var iteration in Benchmark.Iterations)
119 using (iteration.StartMeasurement())
127 [MethodImpl(MethodImplOptions.NoOptimization)]
128 public static int Main(string[] argv)
132 Iterations = Int32.Parse(argv[0]);
135 Stopwatch sw = Stopwatch.StartNew();
140 // Note: we can't check xn or yn better because of the precision
141 // with which original results are given
142 result &= System.Math.Abs(g_xn_base - g_xn) <= 1.5e-7;
143 result &= System.Math.Abs(g_yn_base - g_yn) <= 1.5e-7;
144 result &= System.Math.Abs(g_dn) <= 2.5e-9;
145 // Actual error is much bigger than base error;
146 // this is likely due to the fact that the original program was written in Fortran
147 // and was running on a mainframe with a non-IEEE floating point arithmetic
148 // (it's still beyond the published precision of yn)
149 result &= System.Math.Abs(g_en) <= 5.5e-8;
150 Console.WriteLine(result ? "Passed" : "Failed");
152 Console.WriteLine(" BASE.....P1 1/4 (ADAMS-MOULTON), XN = {0}", g_xn_base);
153 Console.WriteLine(" VERIFY...P1 1/4 (ADAMS-MOULTON), XN = {0}\n", g_xn);
154 Console.WriteLine(" BASE.....P1 2/4 (ADAMS-MOULTON), YN = {0}", g_yn_base);
155 Console.WriteLine(" VERIFY...P1 2/4 (ADAMS-MOULTON), YN = {0}\n", g_yn);
156 Console.WriteLine(" BASE.....P1 3/4 (ADAMS-MOULTON), DN = {0}", g_dn_base);
157 Console.WriteLine(" VERIFY...P1 3/4 (ADAMS-MOULTON), DN = {0}\n", g_dn);
158 Console.WriteLine(" BASE.....P1 4/4 (ADAMS-MOULTON), EN = {0}", g_en_base);
159 Console.WriteLine(" VERIFY...P1 4/4 (ADAMS-MOULTON), EN = {0}\n", g_en);
161 Console.WriteLine("Test iterations: {0}; Total time: {1} sec", Iterations, sw.Elapsed.TotalSeconds);
162 return (result ? 100 : -1);