Міністерство освіти і науки України
Національний університет “Львівська політехніка”
/
ЛАБОРАТОРНА РОБОТА № 7
з дисципліни:
"Чисельні методи"
на тему:
«Наближене обчислення визначених інтегралів»
ЛАБОРАТОРНА РОБОТА № 7
Тема роботи:
Наближене обчислення визначених інтегралів.
Мета роботи:
Вивчити методи наближеного обчислення визначених інтегралів.
Варіант 24:
Обчислити визначений інтеграл методом прямокутників, трапецій, парабол, трьох восьмих, Монте-Карло та оцінити абсолютну та відносну похибку обчислення. Проміжок інтегрування вибрати [N;N+2], де N- номер студента у списку.
1) заданий інтеграл обчислити наближено та точно. Похибку знайти як різницю точного та обчисленого значення. Дослідити як кількість ітерацій впливає на точність обчислень.
2) заданий подвійний інтеграл обчислити наближено на області [N;N+2]х[N;N+2]. Оцінити похибку обчислення.
3) заданий невластивий інтеграл обчислити наближено. Застосувати спеціальні методи обчислення невластивих інтегралів. Оцінити похибку обчислення.
1.
2.
3.
Код програми:
#include <Windows.h>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <random>
#include <ctime>
using namespace std;
double Function1(double x) {return pow(x, 1 / 3.0);}
double Function2(double x, double y) {return pow(x + y, 1 / 3.0);}
double Function3(double x, int n) {return log(1 + sin(n)*cos(x)) / cos(x);}
double Integral_Rect(double a, double b, int n) {
double result = 0;
double h = (b - a) / n;
for (int i = 0; i < n; i++)
result += Function1(a + (i + 0.5)*h);
return result*h;
}
double Integral2_Rect(double a, double b, double c, double d, int nx, int ny) {
double result = 0, xi, yj;
double hx = (b - a) / nx;
double hy = (d - c) / ny;
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
xi = a + hx / 2 + i*hx;
yj = c + hy / 2 + j*hy;
result += Function2(xi, yj);
}
}
return hx*hy*result;
}
double Integral3_Rect(double a, double b, int n) {
double result = 0;
double h = (b - a) / n;
for (int i = 0; i < n; i++)
result += Function3(a + (i + 0.5)*h, 12);
return result*h;
}
double Integral_Trapeze(double a, double b, int n) {
double result = 0;
double h = (b - a) / n;
for (int i = 1; i < (n - 1); i++)
result += (2 * Function1(a + i*h));
result += Function1(a) + Function1(b);
return result*h / 2;
}
double Integral2_Trapeze(double a, double b, double c, double d, int nx, int ny) {
double result = 0 , xi, yj, q;
double hx = (b - a) / nx;
double hy = (d - c) / ny;
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
xi = a + hx / 2 + i*hx;
yj = c + hy / 2 + j*hy;
if ((i == 0 && j == 0) || (i == 0 && j == ny) || (i == nx && j == 0) || (i == nx && j == ny))
q = 1 / 4.0;
else{
if (((i == 0 || i == nx) && (j%ny != 0))||((j == 0 || j == ny) && (i%nx != 0)))
q = 1 / 2.0;
else{
if (i&nx != 0 || j%ny != 0)
q = 1.0;
}
}
result += q* Function2(xi, yj);
}
}
return hx*hy*result;
}
double Integral_Simpson(double a, double b, int n) {
double result = 0;
double h = (b - a) / n;
for (int i = 1; i < n; i++) {
if (i % 2 == 1)
result += (2 * Function1(a + i*h));
else
result += (4 * Function1(a + i*h));
}
result += Function1(a) + Function1(b);
return result*h / 3;
}
double Integral_38(double a, double b) {
double result = 0;
result = Function1(a) / 8 + 3 * Function1((2 * a + b)/3) / 8 + 3 * Function1((a + 2 * b)/3) / 8 + Function1(b) / 8;
return (b - a)*result;
}
double Integral_MonteCarlo(double a, double b, int N) {
srand(time(NULL));
double result = 0;
double u;
for (int i = 0; i < N; i++) {
u = rand() % (int)b + (int)a;
result += Function1(u);
}
return (b - a)*result / N;
}
double Integral2_MonteCarlo(double a, double b, double c, double d, int N) {
double result = 0;
double u, v;
for (int i = 0; i < N; i++) {
u = rand() % (int)b + (int)a;
v = rand() % (int)d + (int)c;
result += Function2(u, v);
}
return (b - a)*(d - c)*result / N;
}
int main() {
SetConsoleOutputCP(1251);
int N, var;
double abs_value_I;
cout << "Введіть номер: ";
cin >> var;
cout << "ЗАВДАННЯ 1:" << endl << endl;
abs_value_I = 4.7016374079;
for (N = 100; N <= 1000; N += 100) {
double I = Integral_Rect(var, var + 2, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод прямокутників: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
for (N = 100; N <= 1000; N += 100) {
double I = Integral_Trapeze(var, var + 2, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод трапецій: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
for (N = 100; N <= 1000; N += 100) {
double I = Integral_Simpson(var, var + 2, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод Сімпсона: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
for (N = 100; N <= 1000; N += 100) {
double I = Integral_38(var, var + 2);
cout <<"К-сть точок розбиття: "<< N << "\nМетод 3/8: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
for (N = 100; N <= 1000; N += 100) {
double I = Integral_MonteCarlo(var, var + 2, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод Монте-Карло: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
cout << endl << "ЗАВДАННЯ 2: " << endl << endl;
abs_value_I = 11.8486846472;
for (N = 100; N <= 1000; N += 100) {
double I = Integral2_Rect(var, var + 2, var, var + 2, N, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод прямокутників: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
for (N = 100; N <= 1000; N += 100) {
double I = Integral2_Trapeze(var, var + 2, var, var + 2, N, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод трапецій: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<< endl;
}
for (N = 100; N <= 1000; N += 100) {
double I = Integral2_MonteCarlo(var, var + 2, var, var + 2, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод Монте-Карло: " << setprecision(10) << I << "\nІстинне значення: " << abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
cout << endl << "ЗАВДАННЯ 3: " << endl << endl;
abs_value_I = -1.7793057937;
for (N = 100; N <= 1000; N += 100) {
double I = Integral3_Rect(0, 3.142, N);
cout <<"К-сть точок розбиття: "<< N << "\nМетод прямокутників: " << setprecision(10) << I << "\nІстинне значення: "<< abs_value_I << "\nАбсолютна похибка: " << fabs(abs_value_I - I) << endl<<endl;
}
system("pause>>void");
return 0;
}
Результат:
//////////////
Графік:
/
/
//
/
Висновок:
В результаті виконання лабораторної роботи було вивчено методи для наближеного обчислення визначених інтегралів. Також приведено графіки залежності точності обчислень від кількості точок розбиття. З графіків видно, що найкраще показали себе метод прямокутників та метод 3/8 (для одномірних інтегралів).
Також було обчислено 3 визначених інтеграли на проміжку [12,14]:
1. = 4,701;
2. = 11,848;
3. = -1,779.