1개의 텍스트 형식
시스템 사용;
네임스페이스 Legalsoft.Truffer
{ /// <summary> /// 확장된 사다리꼴 규칙을 구현하는 루틴입니다. /// </summary> public class Trapzd : Quadrature { /// <summary> /// 적분의 한계와 적분의 현재 값입니다. /// </summary> private double a { get; 세트; } = 0.0; 개인 더블 b { 가져오기; 세트; } = 0.0; 개인 이중 s { get; 세트; } = 0.0;
개인 UniVarRealValueFun funx;
공개 Trapzd()
{ }
/// <summary>
/// 생성자는 입력 func, /// 제한 a와 b 사이에 통합될 함수 또는 functor
, 입력을 사용합니다.
/// </summary>
/// <param name="funcc"></param>
/// <param name="aa"></param>
/// <param name="bb"></ param>
public Trapzd(UniVarRealValueFun funcc, double aa, double bb)
{ this.funx = funcc; this.a = aa; this.b = bb; n = 0; }
/// <summary>
/// 확장된 사다리꼴 규칙의 개선의 n번째 단계를 반환합니다
. /// 첫 번째 호출(n= 1)에서 루틴은 S(a, b)f(x)의 가장 대략적인 추정값을 반환합니다. )dx. /// 후속 호출은 n=2,3,...을 설정하고 2n-2 /// 추가 내부 점을
추가하여 정확도를 향상시킵니다 . /// </summary> /// <returns></returns> public override double next() { n++; if (n == 1) { return (s = 0.5 * (b - a) * (funx.funk(a) + funx.funk(b))); } else { int = 1;
for (int j = 1; j < n - 1; j++)
{ it <<= 1; } 더블 tnm = 그것; 이중 del = (b - a) / tnm; 더블 x = a + 0.5 * 델; 이중 합계 = 0.0; for (int j = 0; j < it; j++, x += del) { sum += funx.funk(x); } s = 0.5 * (s + (b - a) * 합계 / tnm); 반환 s; } }
/// <summary>
/// a에서 b까지 함수 또는 펑터 func의 적분을 반환합니다.
/// 상수 EPS는 원하는 분수 정확도와 JMAX로 설정될 수 있으므로
/// 2의 JMAX-제곱이 됩니다. 1은 허용되는 최대 단계 수입니다.
/// 적분은 사다리꼴 규칙에 따라 수행됩니다.
/// </summary>
/// <param name="funcc"></param>
/// <param name="a"></param>
/// <param name="b"></ param>
/// <param name="eps"></param>
/// <returns></returns>
/// <Exception cref="Exception"></Exception>
공용 정적 이중 qtrap(UniVarRealValueFun funcc, 이중 a, 이중 b, 이중 EPS = 1.0e-10)
{ const int JMAX = 20; 이중 s; 이중 노인 = 0.0;
Trapzd t = new Trapzd(funcc, a, b);
for (int j = 0; j < JMAX; j++)
{ s = t.next(); if (j > 5) { //if (Math.Abs(s - olds) < eps * Math.Abs(olds) || (s == 0.0 && olds == 0.0)) if (Math.Abs(s - olds) < eps * Math.Abs(olds) || (Math.Abs(s) <= float.Epsilon && Math.Abs(olds) <= float.Epsilon) ) { return s; } } olds = s; }
throw new Exception("루틴 qtrap에 단계가 너무 많습니다.");
}
/// <summary>
/// a에서 b까지 함수 또는 펑터 func의 적분을 반환합니다.
/// 상수 EPS는 원하는 분수 정확도와 JMAX로 설정될 수 있으므로
/// 2의 JMAX-제곱이 됩니다. 1은 허용되는 최대 단계 수입니다.
/// 적분은 심슨의 법칙에 따라 수행됩니다.
{ const int JMAX = 20;
이중 ost = 0.0;
이중 OS = 0.0;
Trapzd t = new Trapzd(funcc, a, b);
for (int j = 0; j < JMAX; j++)
{ double st = t.next(); 더블 s = (4.0 * st - ost) / 3.0; if (j > 5) { //if (Math.Abs(s - os) < eps * Math.Abs(os) || (s == 0.0 && os == 0.0)) if (Math.Abs(s - os) < eps * Math.Abs(os) || (Math.Abs(s) <= float.Epsilon && Math.Abs(os) <= float. 엡실론)) { return s; } } os = s;
ost = st;
}
throw new Exception("루틴 qsimp에 단계가 너무 많습니다.");
}
public static double qromb(UniVarRealValueFun func, double a, double b)
{ return qromb(func, a, b, 1.0e-10); }
/// <summary>
/// a에서 b까지 함수 또는 functor func의 적분을 반환합니다.
/// 통합은 Romberg의 2K 차 방법에 의해 수행됩니다. 여기서, 예를 들어
/// K=2는 Simpson의 규칙입니다.
/// </summary>
/// <param name="funcc"></param>
/// <param name="a"></param>
/// <param name="b"></ param>
/// <param name="eps"></param>
/// <returns></returns>
/// <Exception cref="Exception"></Exception>
public static double qromb(UniVarRealValueFun funcc, 더블에이, 더블비,
이중 EPS) { int JMAX = 20; int JMAXP = JMAX + 1;
정수 K = 5;
double[] s = 새로운 double[JMAX];
double[] h = 새로운 double[JMAXP];
Poly_interp polint = new Poly_interp(h, s, K);
h[0] = 1.0;
Trapzd t = new Trapzd(funcc, a, b);
for (int j = 1; j <= JMAX; j++)
{ s[j - 1] = t.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] = 0.25 * h[j - 1]; } throw new Exception("루틴 qromb에 단계가 너무 많습니다.");
} }
}
2 코드 형식
using System;
namespace Legalsoft.Truffer
{
/// <summary>
/// Routine implementing the extended trapezoidal rule.
/// </summary>
public class Trapzd : Quadrature
{
/// <summary>
/// Limits of integration and current value of integral.
/// </summary>
private double a { get; set; } = 0.0;
private double b { get; set; } = 0.0;
private double s { get; set; } = 0.0;
private UniVarRealValueFun funx;
public Trapzd()
{
}
/// <summary>
/// The constructor takes as inputs func, the function or functor to be
/// integrated between limits a and b, also input.
/// </summary>
/// <param name="funcc"></param>
/// <param name="aa"></param>
/// <param name="bb"></param>
public Trapzd(UniVarRealValueFun funcc, double aa, double bb)
{
this.funx = funcc;
this.a = aa;
this.b = bb;
n = 0;
}
/// <summary>
/// Returns the nth stage of refinement of the extended trapezoidal 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 2n-2
/// additional interior points.
/// </summary>
/// <returns></returns>
public override double next()
{
n++;
if (n == 1)
{
return (s = 0.5 * (b - a) * (funx.funk(a) + funx.funk(b)));
}
else
{
int it = 1;
for (int j = 1; j < n - 1; j++)
{
it <<= 1;
}
double tnm = it;
double del = (b - a) / tnm;
double x = a + 0.5 * del;
double sum = 0.0;
for (int j = 0; j < it; j++, x += del)
{
sum += funx.funk(x);
}
s = 0.5 * (s + (b - a) * sum / tnm);
return s;
}
}
/// <summary>
/// Returns the integral of the function or functor func from a to b.The
/// constants EPS can be set to the desired fractional accuracy and JMAX so
/// that 2 to the power JMAX-1 is the maximum allowed number of steps.
/// Integration is performed by the trapezoidal rule.
/// </summary>
/// <param name="funcc"></param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="eps"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static double qtrap(UniVarRealValueFun funcc, double a, double b, double eps = 1.0e-10)
{
const int JMAX = 20;
double s;
double olds = 0.0;
Trapzd t = new Trapzd(funcc, a, b);
for (int j = 0; j < JMAX; j++)
{
s = t.next();
if (j > 5)
{
//if (Math.Abs(s - olds) < eps * Math.Abs(olds) || (s == 0.0 && olds == 0.0))
if (Math.Abs(s - olds) < eps * Math.Abs(olds) ||
(Math.Abs(s) <= float.Epsilon && Math.Abs(olds) <= float.Epsilon)
)
{
return s;
}
}
olds = s;
}
throw new Exception("Too many steps in routine qtrap");
}
/// <summary>
/// Returns the integral of the function or functor func from a to b.The
/// constants EPS can be set to the desired fractional accuracy and JMAX so
/// that 2 to the power JMAX-1 is the maximum allowed number of steps.
/// Integration is performed by Simpson's rule.
/// </summary>
/// <param name="funcc"></param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="eps"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static double qsimp(UniVarRealValueFun funcc, double a, double b, double eps = 1.0e-10)
{
const int JMAX = 20;
double ost = 0.0;
double os = 0.0;
Trapzd t = new Trapzd(funcc, a, b);
for (int j = 0; j < JMAX; j++)
{
double st = t.next();
double s = (4.0 * st - ost) / 3.0;
if (j > 5)
{
//if (Math.Abs(s - os) < eps * Math.Abs(os) || (s == 0.0 && os == 0.0))
if (Math.Abs(s - os) < eps * Math.Abs(os) || (Math.Abs(s) <= float.Epsilon && Math.Abs(os) <= float.Epsilon))
{
return s;
}
}
os = s;
ost = st;
}
throw new Exception("Too many steps in routine qsimp");
}
public static double qromb(UniVarRealValueFun func, double a, double b)
{
return qromb(func, a, b, 1.0e-10);
}
/// <summary>
/// Returns the integral of the function or functor func from a to b.
/// Integration is performed by Romberg's method of order 2K, where, e.g.,
/// K=2 is Simpson's rule.
/// </summary>
/// <param name="funcc"></param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="eps"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static double qromb(UniVarRealValueFun funcc, double a, double b, double eps)
{
int JMAX = 20;
int JMAXP = JMAX + 1;
int K = 5;
double[] s = new double[JMAX];
double[] h = new double[JMAXP];
Poly_interp polint = new Poly_interp(h, s, K);
h[0] = 1.0;
Trapzd t = new Trapzd(funcc, a, b);
for (int j = 1; j <= JMAX; j++)
{
s[j - 1] = t.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] = 0.25 * h[j - 1];
}
throw new Exception("Too many steps in routine qromb");
}
}
}