logo
C#, 320 стр

Вычисление интеграла

Давайте более подробно рассмотрим ситуацию с функциями высшего порядка на примере задачи вычисления определенного интеграла с заданной точностью. С этой целью создадим класс, в котором будет описан делегат, определяющий контракт, коему должны удовлетворять подынтегральные функции. В этом же классе определим метод, вычисляющий интеграл. По сути самой задачи этот метод представляет собой функцию высшего порядка. Приведу программный код, описывающий класс:

public class HighOrderIntegral

{

//delegate

public delegate double SubIntegralFun(double x);

public double EvalIntegral(double a, double b,

double eps,SubIntegralFun sif)

{

int n=4;

double I0=0, I1 = I( a, b, n,sif);

for( n=8; n < Math.Pow(2.0,15.0); n*=2)

{

I0 =I1; I1=I(a,b,n,sif);

if(Math.Abs(I1-I0)<eps) break;

}

if(Math.Abs(I1-I0)< eps)

Console.WriteLine("Требуемая точность достигнута! "+

" eps = {0}, достигнутая точность ={1}, n= {2}",

eps,Math.Abs(I1-I0),n);

else

Console.WriteLine("Требуемая точность не достигнута! "+

" eps = {0}, достигнутая точность ={1}, n= {2}",

eps,Math.Abs(I1-I0),n);

return(I1);

}

private double I(double a, double b, int n,

SubIntegralFun sif)

{

//Вычисляет частную сумму по методу трапеций

double x = a, sum = sif(x)/2, dx = (b-a)/n;

for (int i= 2; i <= n; i++)

{

x += dx; sum += sif(x);

}

x = b; sum += sif(x)/2;

return(sum*dx);

}

}//class HighOrderIntegral

Прокомментирую этот текст:

Чтобы продемонстрировать работу с классом HighOrderIntegral, приведу еще класс Functions, где описано несколько функций, удовлетворяющих контракту, который задан классом SubIntegralFun:

class functions

{

//подынтегральные функции

static public double sif1(double x)

{

int k = 1; int b = 2;

return (double)(k*x +b);

}

static public double sif2(double x)

{

double a = 1.0; double b = 2.0; double c= 3.0;

return (double)(a*x*x +b*x +c);

}

}//class functions

А теперь рассмотрим метод класса клиента, выполняющий создание нужных объектов и тестирующий их работу:

public void TestEvalIntegrals()

{

double myint1=0.0;

HighOrderIntegral.SubIntegralFun hoisif1 =

new HighOrderIntegral.SubIntegralFun(functions.sif1);

HighOrderIntegral hoi = new HighOrderIntegral();

myint1 = hoi.EvalIntegral(2,3,0.1e-5,hoisif1);

Console.WriteLine("myintegral1 = {0}",myint1);

HighOrderIntegral.SubIntegralFun hoisif2 =

new HighOrderIntegral.SubIntegralFun(functions.sif2);

myint1= hoi.EvalIntegral(2,3,0.1e-5,hoisif2);

Console.WriteLine("myintegral2 = {0}",myint1);

}//EvalIntegrals

Здесь создаются два экземпляра делегата и объект класса HighOrderIntegral, вызывающий метод вычисления интеграла. Результаты работы показаны на 20.2.

Рис. 20.2.  Вычисление интеграла с использованием функций высших порядков