Московский государственный технический
Факультет «Информатика и управление»
Кафедра ИУ5. Курс «Основы информатики»
Отчет по лабораторной работе №7
«Численное интегрирование функции »
Выполнил: | Проверил: | |
студент группы ИУ5-11 | преподаватель каф. ИУ5 | |
Лукьянченко Александр | ||
Подпись и дата: | Подпись и дата: |
Москва, 2012 г.
Постановка задачи
1. Численное интегрирование функции с заданной точностью методом прямоугольников.
Вычислить определённый интеграл в пределах от a до b для четырех функций f1 = x, f2 = sin(22 * x), f3 = x4 и f4 = arctg(x).
Вычисление интеграла оформить в виде функции IntRect.
Вычисления выполнить для пяти значений точности: 0.01, 0.001, 0.0001, 0.00001 и 0.000001.
Исследовать быстродействие алгоритма в зависимости от подынтегральной функции и требуемой точности (быстродействие алгоритма можно оценить числом элементарных прямоугольников n).
Результаты представить в виде 5 таблиц, по одной таблице для каждого значения точности. В каждой таблице выводить данные для всех четырех функций.
Для печати таблицы результатов использовать функцию
void PrintTabl(I_print i_prn[],int k), приведенную в приложении 2.
Здесь i_prn[] – массив структур типа I_print размерностью k.
Вид таблицы приведен в Приложении 1.
2. Выполнить п.1, используя для интегрирования метод трапеций. Вычисление интеграла оформить в виде функции IntTrap.
Для печати таблиц результатов использовать ту же функцию, что и в методе прямоугольников.
Разработка алгоритма
Используемые переменные:
double a,b – интервал
I_print pr[] – массив структур для вывода
double eps – погрешность
int n – количество прямоугольников/трапеций
Вычисление определенных интегралов производится двумя способами:
- Метод прямоугольников – площадь под графиком разбивается на сумму прямоугольников, площадь которых вычисляется как произведение Dx на значение функции в середине этого отрезка.
- Метод трапеций – разбитие на трапеции, площадь которых – полусумма значений функции на краях Dx на Dx.
Текст программы
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
typedef double (*TPF)(double);
double IntRect(TPF f,double a,double b,double eps,int& n);
double IntTrap(TPF f,double a,double b,double eps,int& n);
struct I_print{ //данные для печати результатов интегрирования
char* name;//название функции
double i_sum; //значение интегральной суммы
double i_toch; //точное значение интеграла
int n; //число разбиений области интегрирования
//при котором достигнута требуемая точность
};
void PrintTabl(I_print i_prn[],int k)
{
const int m=4;//число столбцов таблицы
int wn[m]={12,18,18,10};//ширина столбцов таблицы
char *title[m]={"Function","Integral","IntSum","N "};
int size[m];
for(int i=0;i<m;i++)
size[i]=strlen(title[i]);
//шапка таблицы
cout<<char(218)<<setfill(char(196));
for(int j=0;j<m-1;j++)
cout<<setw(wn[j])<<char(194);
cout<<setw(wn[m-1])<<char(191)<<endl;
cout<<char(179);
for(int j=0;j<m;j++)
cout<<setw((wn[j]-size[j])/2)<<setfill(' ')<<' '<<title[j]
<<setw((wn[j]-size[j])/2)<<char(179);
cout<<endl;
for(int i=0;i<k;i++)
{//заполнение таблицы
cout<<char(195)<<fixed;
for(int j=0;j<m-1;j++)
cout<<setfill(char(196))<<setw(wn[j])<<char(197);
cout<<setw(wn[m-1])<<char(180)<<setfill(' ')<<endl;
cout<<char(179)<<setw((wn[0]-strlen(i_prn[i].name))/2)<<' '<<i_prn[i].name
<<setw((wn[0]-strlen(i_prn[i].name))/2)<<char(179);
cout<<setw(wn[1]-1)<<setprecision(10)<<i_prn[i].i_toch<<char(179)
<<setw(wn[2]-1)<<i_prn[i].i_sum<<setprecision(6)<<char(179)
<<setw(wn[3]-1)<<i_prn[i].n<<char(179)<<endl;
}
//низ таблицы
cout<<char(192)<<setfill(char(196));
for(int j=0;j<m-1;j++)
cout<<setw(wn[j])<<char(193);
cout<<setw(wn[m-1])<<char(217)<<setfill(' ')<<endl;
}
double f1(double x) {return x;}
double f2(double x) {return sin(22*x);}
double f3(double x) {return pow(x, 4);}
double f4(double x) {return atan(x);}
int main()
{
cout<<"Enter a and b: ";
double a,b;
cin>>a>>b;
cout<<endl<<endl;
int n=0;
I_print pr[4];
for(int p=0; p<2; p++)
{
double eps=0.01;
switch(p){
case 0: cout<<"Method pramougolnik:"<<endl; break;
case 1: cout<<"Method trpecii:"<<endl; break;
}
do{
cout<<"Tochnost: "<<eps<<endl;
for(int i=0; i<5; i++)
{
switch(i){
case 0:
pr[i].name=" y=x";
if(p==0)
pr[i].i_sum=IntRect(f1, a, b, eps, n);
else
pr[i].i_sum=IntTrap(f1, a, b, eps, n);
pr[i].i_toch=(b*b - a*a)/2.0;
pr[i].n=n;
break;
case 1:
pr[i].name="y=sin(22x)";
if(p==0)
pr[i].i_sum=IntRect(f2, a, b, eps, n);
else
pr[i].i_sum=IntTrap(f2, a, b, eps, n);
pr[i].i_toch=(cos(a*22.0) - cos(b*22.0))/22.0;
pr[i].n=n;
break;
case 2:
pr[i].name=" y=x^4";
if(p==0)
pr[i].i_sum=IntRect(f3, a, b, eps, n);
else
pr[i].i_sum=IntTrap(f3, a, b, eps, n);
pr[i].i_toch=(b*b*b*b*b - a*a*a*a*a)/5.0;
pr[i].n=n;
break;
case 3:
pr[i].name="y=arctg(x)";
if(p==0)
pr[i].i_sum=IntRect(f4, a, b, eps, n);
else
pr[i].i_sum=IntTrap(f4, a, b, eps, n);
pr[i].i_toch=b*atan(b) - a*atan(a) - (log(b*b+1) - log(a*a+1))/2.0;
pr[i].n=n;
break;
}
}
PrintTabl(pr,4);
cout<<endl;
eps/=10;
} while(eps>0.000001);
}
system("PAUSE");
return 0;
}
double IntRect(TPF f,double a,double b,double eps,int& n){
n=4;
int i, j;
double result, h, result1;
h = (b-a)/n;
do{
result=0.0;
result1=0.0;
for(i=1; i <= n; i++){
result += f(a + h * (i - 0.5));
}
result*=h;
n*=2;
h = (b-a)/n;
for(j=1; j <= n; j++){
result1 += f(a + h * (j - 0.5));
}
result1*=h;
} while(abs(result-result1)>eps);
return result1;
}
double IntTrap(TPF f,double a,double b,double eps,int& n){
int i, j;
n=4;
double result, h, result1;
h = (b-a)/n;
do{
result=0.0;
result1=0.0;
for(i=1; i<=n; i++)
{
result+=(f(a+(i-1)*h)+f((a+i*h)))*0.5*h;
}
n*=2;
h = (b-a)/n;
for(j=1; j<=n; j++)
{
result1+=(f(a+(j-1)*h)+f((a+j*h)))*0.5*h;
}
} while(abs(result-result1)>eps);
return result;
}
Анализ результатов
Скриншоты: