Вы находитесь на странице: 1из 6

Министерство науки и высшего образования Российской Федерации

ФГБОУ ВО
«Уфимский государственный авиационный технический университет»

Кафедра ТОЭ

Лабораторная работа
по дисциплине «Вычислительная математика»

«Лабораторная работа №2»

Выполнил:
студент гр.
Сергеев Д.С.

Проверил:
преподаватель
Шерыхалина Н. М.

Уфа 2021
Содержание
1 МЕТОД ГРАДИЕНТНОГО СПУСКА...........................................................................................3
1.1 Постановка задачи....................................................................................................................3
1.2 Решение задачи.........................................................................................................................3
1.3 Программный код.....................................................................................................................4
1.4 Тестирование............................................................................................................................6

Изм. Лист № докум. Подп. Дата

Разраб. Сергеев Д.С. Лит. Лист Листов

Пров. Шерыхалина Н.М. 2 3


У
Рецен. ФИО Лабораторная работа №1
Н.контр. ФИО УГАТУ СТС-209
Утв.. ФИО
1 МЕТОД ГРАДИЕНТНОГО СПУСКА

1.1 Постановка задачи


Интерполировать функцию f (x)=sin ⁡(x ) при равномерном разбиении с
удвоением числа отрезков. Границы: a=0, b= π
Вывести максимальную погрешность, отношение погрешности предыдущей
строки к данной и оценку погрешности.

1.2 Решение задачи


Для интерполирования использую сплайны третьей степени:

S3(x)=аi0 +аi1(x - xi)+аi2(x - xi)2 +аi3(x - xi)3, x[xi, xi+1],


Задамся следующими краевыми условиями:

S '3' ( a ) =f ' ' ( a ), S '3' ( b ) =f ' ' ( b ) ;

Значения S3(x) вычислю по формуле:


3 2 3 2
( xi −x ) −hi ( xi −x ) ( x−x i −1 ) −hi ( x −xi −1 )
S 3 ( x )= m i−1 + mi +
6 hi 6 hi
xi −x x−x i−1
+ y i−1 + yi
hi hi
Для нахождения mi потребуется система уравнений в матричном виде:

a0 b0 0 0 ⋯ 0 0 0 m0 d0

( )( ) ( )
c1 a 1 b 1 0 ⋯ 0 0 0 m1 d1
0 c2 a 2 b 2 ⋯ 0 0 0 m2 d2
⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋮ = ⋮
0 0 0 ⋯ c n−2 an−2 b n−2 0 mn−2 d n−2
0 0 0 ⋯ 0 c n−1 an−1 bn−1 mn−1 d n−1
0 0 0 ⋯ 0 0 cn an mn dn
.
Для нахождения коэффициента mi:

mi = i mi+1 + i, i=0,...,n-1,


Коэффициенты I, i найду с помощью прямой прогонки:

3
Изм. № докум. Подп. Дата
b0 d0 −bi d i −c i μ i−1
λ0 =− , μ0 = , λi = , μi= , i=1, . .. , n
a0 a0 ai +c i λi −1 ai + c i λi−1 .
Так как у нас заданы краевые условия второй производной, коэффициенты
a, b, c, d найду по следующим формулам:

a0 =1 , b0 =0 , d 0 =f ' ' ( a ) ,
''
c n =0 , an =1 , d n=f ( b ) .

hi h i +hi +1 hi +1 y i +1 − y i y i − y i−1
c i= , ai = , bi = , d i= −
6 3 6 hi +1 hi , i=1,...,n−1 ,
Hi находиться по следующей формуле:

hi=xi-xi-1, xi=a+ih.
1.3 Программный код
С помощью вышеописанных теоретических данных напишу программу для
нахождения погрешности:

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
double f(double x)
{
return sin(x); // radian
}
double log(double a, double b)
{
return log(b) / log(a);
}
int main()
{

double hg, ag = 0, bg = 3.141592653589793;


const int N = 10241;
double x[N];
double h[N];
double a[N];
double b[N];
double c[N];
double d[N];
double lyambda[N];
double mu[N];
double m[N];
double x1[N];
double S3[N];
double max, max1 = 0, K;
cout << "n max deltaoc K" << endl;
for (int n = 5; n <= 10240; n *= 2)
{

3
Изм. № докум. Подп. Дата
hg = (bg - ag) / n;
for (int i = 0; i <= n; i++) // x(i)
{
x[i] = ag + i * hg;
}
for (int i = 1; i <= n; i++) // h
{
h[i] = x[i] - x[i - 1];
}
a[0] = 1;
a[n] = 1;
b[0] = 0;
c[n] = 0;
d[0] = (-1) * f(ag);
d[n] = (-1) * f(bg);
for (int i = 1; i < n; i++) // a, b, c, d
{
a[i] = (h[i] + h[i + 1]) / 3;
b[i] = h[i + 1] / 6;
c[i] = h[i] / 6;
d[i] = (f(x[i + 1]) - f(x[i])) / h[i + 1] - ((f(x[i]) - f(x[i - 1])) / h[i]);
}
lyambda[0] = (-1) * b[0] / a[0];
mu[0] = d[0] / a[0];
for (int i = 1; i <= n; i++) // lyambda, mu, x1
{
lyambda[i] = (-1) * b[i] / (a[i] + (c[i] * lyambda[i - 1]));
mu[i] = (d[i] - (c[i] * mu[i - 1]))/(a[i]+(c[i]*lyambda[i-1]));
x1[i] = x[i - 1] + hg / 2;
}
m[n] = mu[n];
for (int i = n-1; i >=0; i--) //m
{
m[i] = lyambda[i] * m[i + 1] + mu[i];
}
for (int i = 1; i <= n; i++) //S3
{
S3[i] = ((pow(x[i] - x1[i], 3)-(pow(h[i], 2)*(x[i]-x1[i])))*m[i-1]/(6*h[i]))+
((pow(x1[i] - x[i], 3) - (pow(h[i], 2) * (x1[i] - x[i-1]))) * m[i] / (6 * h[i]))+((x[i]-
x1[i])*f(x[i-1])/h[i])+ ((x1[i] - x[i-1]) * f(x[i]) / h[i]);
}
// max
max = S3[1]-f(x1[1]);
for (int i = 1; i <= n; i++)
{
if (S3[i] - f(x1[i]) > max)
{
max = S3[i] - f(x1[i]);
}
}
//k
if (n > 5)
{
K = max1 / max;
}
else
{
K = 0;
}
// vivod
cout << setprecision(16) << n << " " << abs(max) << " " << max1/4<< " "<< K<< endl;
max1 = max;
}
}

3
Изм. № докум. Подп. Дата
Внешний цикл программы пересчитывает количество разбиений. Далее
подсчитывается шаг, значения xi, hi в зависимости от номера отрезка. Далее с
помощью формул из теоретической части подсчитываются коэффициенты a, b, c,
d. С помощью них находятся прогоночные коэффициенты , . Далее находится
S3 и погрешности вычислений. С помощью последнего цикла находится
максимальная погрешность с последующим выводом.
В программном коде использовались следующие функции:
1) f() - подсчет и вывод значения функции.

1.4 Тестирование
Результаты тестирования (Рисунок 1):

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

3
Изм. № докум. Подп. Дата

Вам также может понравиться