//Нам не обойтись без класса векторов
#include "vector.h"
/*Параметризованный класс для вычисления интегральных сумм */
template <class YourOwnFloatType>
class Integrate
{
vector<YourOwnFloatType> x, y; /*Узлы и значения в узлах*/
public:
/*Конструктор, в качестве параметра принимающий два вектора, содержащих соответственно узлы и значения в них */
Integrate(vector<YourOwnFloatType> _x, vector <YourOwnFloatType> _y): x(_x), y(_y)
{
/*Проверяем входные данные на корректность */
if(x.getm()!=y.getm())
throw xmsg("Количество узлов не совпадает с количеством значений в них");
if(x.getm()<2)
throw xmsg("Слишком мало точек");
}
Integrate(Integrate &_): x(_.x), y(_.y) {} /*Конструктор копирования */
//Прототипы методов численного интегрирования
//Метод прямоугольников
YourOwnFloatType rectangle_method(),
//Метод трапеций
trapecion_method(),
/*Метод Симпсона - желательно четное число интервалов*/
simpson_method();
};
//Определения методов численного интегрирования
//Метод прямоугольников
template <class YourOwnFloatType>
YourOwnFloatType Integrate<YourOwnFloatType>::rectangle_method()
{
YourOwnFloatType sum=0;/* Интегральная сумма */
/*В связи с возможностью наличия во входных данных неравноотстоящих узлов шаг интегрирования в этом и последующих методах будем вычислять как разность между текущим узлом и ближайшим к нему */
for(int i=0;i<x.getm()-1;i++)
sum+=(x[i+1]-x[i])*y[i];
return sum;/* Возвращаем результат */
}
//Метод трапеций
template <class YourOwnFloatType>
YourOwnFloatType Integrate<YourOwnFloatType>::trapecion_method()
{
YourOwnFloatType sum=0;
/*Суммируем предполагаемые значения функции в междоузлиях */
for(int i=0;i<x.getm()-1;i++)
sum+=(x[i+1]-x[i])*(y[i]+y[i+1])/2;
return sum;
}
//Метод Симпсона
template <class YourOwnFloatType>
YourOwnFloatType Integrate<YourOwnFloatType>::simpson_method()
{
YourOwnFloatType sum=0;
/*В этом методе на каждом шаге интегрирования интегральная сумма вычисляется на двух интервалах (по трём точкам)*/
for(int i=0;i<x.getm()-2;i+=2)
sum+=(x[i+1]-x[i])*(y[i]+4*y[i+1]+y[i+2])/3;
return sum;
}
/*Подставляя в шаблон конкретный тип, получаем действительный вектор */
typedef vector<double> dvector;
#include <conio.h>
/*Тестирующая функция */
void main()
{
double limits[2]={.7,1.3};/*Пределы интегрирования */
/*Количество интервалов */
#define POINTCOUNT 20
/*Вектора, содержащие узлы и значения в них */
dvector x=POINTCOUNT+1,y=POINTCOUNT+1;
/*Шаг интегрирования */
double step=(limits[1]-limits[0])/POINTCOUNT;
for(int i=0;i<=POINTCOUNT;i++)
x[i]=limits[0]+i*step,
y[i]=1/sqrt(2*x[i]*x[i]+.3);
/*Создаём объект, в качестве параметров используя только что заполненные векторы */
Integrate<double> test(x,y);
/*Выводим на экран результаты интегрирования различными методами для сравнения и анализа */
cout<<test.rectangle_method()<<endl
<<test.trapecion_method()<<endl
<<test.simpson_method()<<endl;
getch();
}