Routine implementing the extended midpoint rule.
The constructor takes as inputs func, the function or functor to be integrated between limits a and b, also input.
Returns the nth stage of refinement of the extended midpoint rule.On the first call(n= 1), the routine returns the crudest estimate of S(a, b)f(x)dx. Subsequent calls set n=2,3,... and improve the accuracy by adding (2/3)x3^(n-1) additional interior points.
using System;
namespace Legalsoft.Truffer
{
///
/// Routine implementing the extended midpoint rule.
///
public class Midpnt : Quadrature
{
//public delegateFunc funk { get; set; } = null;
public double a;
public double b;
public double s;
//public T funk;
public UniVarRealValueFun funk;
///
/// The constructor takes as inputs func, the function or functor to be
/// integrated between limits a and b, also input.
///
///
///
public Midpnt(UniVarRealValueFun funcc, double aa, double bb)
{
this.funk = funcc;
this.a = aa;
this.b = bb;
n = 0;
}
///
/// Returns the nth stage of refinement of the extended midpoint rule.On the
/// first call(n= 1), the routine returns the crudest estimate of S(a, b)f(x)dx.
/// Subsequent calls set n=2,3,... and improve the accuracy by adding
/// (2/3)x3^(n-1) additional interior points.
///
///
public override double next()
{
n++;
if (n == 1)
{
return (s = (b - a) * func(0.5 * (a + b)));
}
else
{
int it = 1;
for (int j = 1; j < n - 1; j++)
{
it *= 3;
}
double tnm = it;
double del = (b - a) / (3.0 * tnm);
double ddel = del + del;
double x = a + 0.5 * del;
double sum = 0.0;
for (int j = 0; j < it; j++)
{
sum += func(x);
x += ddel;
sum += func(x);
x += del;
}
s = (s + (b - a) * sum / tnm) / 3.0;
return s;
}
}
public new double func(double x)
{
return funk.funk(x);
}
public static double qromo(Midpnt q)
{
return qromo(q, 3.0e-9);
}
///
/// Romberg integration on an open interval. Returns the integral of a function
/// using any specified elementary quadrature algorithm q and Romberg's method.
/// Normally q will be an open formula, not evaluating the function at the
/// endpoints. It is assumed that q triples the number of steps on each call,
/// and that its error series contains only even powers of the number of steps.
/// The routines midpnt, midinf, midsql, midsqu, midexp are possible choices
/// for q. The constants below have the same meanings as in qromb.
///
///
///
///
///
public static double qromo(Midpnt q, double eps)
{
int JMAX = 14, JMAXP = JMAX + 1, K = 5;
double[] h = new double[JMAXP];
double[] s = new double[JMAX];
Poly_interp polint = new Poly_interp(h, s, K);
h[0] = 1.0;
for (int j = 1; j <= JMAX; j++)
{
s[j - 1] = q.next();
if (j >= K)
{
double ss = polint.rawinterp(j - K, 0.0);
if (Math.Abs(polint.dy) <= eps * Math.Abs(ss)) return ss;
}
h[j] = h[j - 1] / 9.0;
}
throw new Exception("Too many steps in routine qromo");
}
}
}
using System;
namespace Legalsoft.Truffer
{
///
/// Routine implementing the extended midpoint rule.
///
public class Midpnt : Quadrature
{
//public delegateFunc funk { get; set; } = null;
public double a;
public double b;
public double s;
//public T funk;
public UniVarRealValueFun funk;
///
/// The constructor takes as inputs func, the function or functor to be
/// integrated between limits a and b, also input.
///
///
///
public Midpnt(UniVarRealValueFun funcc, double aa, double bb)
{
this.funk = funcc;
this.a = aa;
this.b = bb;
n = 0;
}
///
/// Returns the nth stage of refinement of the extended midpoint rule.On the
/// first call(n= 1), the routine returns the crudest estimate of S(a, b)f(x)dx.
/// Subsequent calls set n=2,3,... and improve the accuracy by adding
/// (2/3)x3^(n-1) additional interior points.
///
///
public override double next()
{
n++;
if (n == 1)
{
return (s = (b - a) * func(0.5 * (a + b)));
}
else
{
int it = 1;
for (int j = 1; j < n - 1; j++)
{
it *= 3;
}
double tnm = it;
double del = (b - a) / (3.0 * tnm);
double ddel = del + del;
double x = a + 0.5 * del;
double sum = 0.0;
for (int j = 0; j < it; j++)
{
sum += func(x);
x += ddel;
sum += func(x);
x += del;
}
s = (s + (b - a) * sum / tnm) / 3.0;
return s;
}
}
public new double func(double x)
{
return funk.funk(x);
}
public static double qromo(Midpnt q)
{
return qromo(q, 3.0e-9);
}
///
/// Romberg integration on an open interval. Returns the integral of a function
/// using any specified elementary quadrature algorithm q and Romberg's method.
/// Normally q will be an open formula, not evaluating the function at the
/// endpoints. It is assumed that q triples the number of steps on each call,
/// and that its error series contains only even powers of the number of steps.
/// The routines midpnt, midinf, midsql, midsqu, midexp are possible choices
/// for q. The constants below have the same meanings as in qromb.
///
///
///
///
///
public static double qromo(Midpnt q, double eps)
{
int JMAX = 14, JMAXP = JMAX + 1, K = 5;
double[] h = new double[JMAXP];
double[] s = new double[JMAX];
Poly_interp polint = new Poly_interp(h, s, K);
h[0] = 1.0;
for (int j = 1; j <= JMAX; j++)
{
s[j - 1] = q.next();
if (j >= K)
{
double ss = polint.rawinterp(j - K, 0.0);
if (Math.Abs(polint.dy) <= eps * Math.Abs(ss)) return ss;
}
h[j] = h[j - 1] / 9.0;
}
throw new Exception("Too many steps in routine qromo");
}
}
}