拡張された中間点ルールを実装するルーチン。
コンストラクターは、入力として関数 func を受け取ります。これは、制限 a と b の間で積分される関数またはファンクターでもあります。
拡張中点ルールの n 番目の改良段階を返します。最初の呼び出し (n= 1) で、ルーチンは S(a, b)f(x)dx の最も粗い推定値を返します。後続の呼び出しでは n=2,3,... が設定され、(2/3)x3^(n-1) 個の追加の内部点を追加することで精度が向上します。
1 テキスト形式
システムを使用する;
namespace Legalsoft.Truffer
{ /// <summary> /// 拡張中間点ルールを実装するルーチン。 /// </summary> public class Midpnt : Quadrature { //public delegateFunc funk { get; セット; } = null;
パブリックダブルa;
パブリックダブルb;
パブリックダブル s;
//パブリック T ファンク;
public UniVarRealValueFun ファンク;
/// <summary>
/// コンストラクターは入力として func を受け取ります。これは、 /// 制限 a と b の間で統合される関数またはファンクターであり
、これも入力です。
/// </summary>
/// <param name="aa"></param>
/// <param name="bb"></param>
public Midpnt(UniVarRealValueFun funcc, double aa, double bb)
{ this.funk = funcc; this.a = aa; これ.b = bb; n = 0; }
/// <summary>
/// 拡張中点ルールの n 番目の改良段階を返します
。 /// 最初の呼び出し (n= 1) で、ルーチンは S(a, b)f(x) の最も粗い推定値を返します。 )dx。
/// 後続の呼び出しでは n=2,3,... が設定され、 /// (2/3)x3^(n-1) 個の追加の内部点を追加することで精度が向上します
。
/// </summary>
/// <returns></returns>
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; ダブル tnm = それ; ダブルデル = (b - a) / (3.0 * tnm); ダブル ddel = デル + デル; ダブル x = a + 0.5 * デル; 二重和 = 0.0; for (int j = 0; j < it; j++) { sum += func(x); x += ddel; 合計 += 関数(x); x += デル; s = (s + (b - a) * 合計/ tnm) / 3.0; 戻り値;
public
new
double func(double x)
{ return funk.funk(x); }
public static double qromo(Midpnt q)
{ return qromo(q, 3.0e-9); }
/// <summary>
/// オープンインターバルでの Romberg 統合。
/// 指定された基本求積アルゴリズム q とロンバーグ法を使用して、関数の積分を返します。
/// 通常、q は開いた式となり、 /// エンドポイントで関数は評価されません
。q は各呼び出しのステップ数を 3 倍にし、
/// 、その誤差系列にはステップ数の偶数乗のみが含まれると仮定します。
/// ルーチン Midpnt、midinf、midsql、midsqu、midexp は、
/// q の選択肢として考えられます。以下の定数は、qromb の場合と同じ意味を持ちます。
/// <returns></returns>
/// <例外 cref="Exception"></例外>
public static double qromo(Midpnt q, double eps)
{ int JMAX = 14, JMAXP = JMAX + 1, K = 5; double[] h = 新しい double[JMAXP]; double[] s = 新しい 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)) ss を返します。
h[j] = h[j -
1] / 9.0;
throw
new Exception("ルーチン qromo のステップが多すぎます");
} }
}
2コード形式
using System;
namespace Legalsoft.Truffer
{
/// <summary>
/// Routine implementing the extended midpoint rule.
/// </summary>
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;
/// <summary>
/// The constructor takes as inputs func, the function or functor to be
/// integrated between limits a and b, also input.
/// </summary>
/// <param name="aa"></param>
/// <param name="bb"></param>
public Midpnt(UniVarRealValueFun funcc, double aa, double bb)
{
this.funk = funcc;
this.a = aa;
this.b = bb;
n = 0;
}
/// <summary>
/// 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.
/// </summary>
/// <returns></returns>
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);
}
/// <summary>
/// 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.
/// </summary>
/// <param name="q"></param>
/// <param name="eps"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
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");
}
}
}