Лабораторные / Лаба2
.docxМинистерство науки и высшего образования Российской Федерации
Федеральное государственное бюджетное образовательное учреждение высшего образования
Уфимский Государственный Авиационный Технический Университет
Кафедра ВМиК
Лабораторная работа №2
по дисциплине «Вычислительная математика»
ИНТЕРПОЛЯЦИЯ ФУНКЦИЙ С ПОМОЩЬЮ СПЛАЙНА
Выполнил:
ст. гр. ИВТ-
Проверила:
профессор каф. ВМиК
Шерыхалина Н.М.
Уфа 2022
1 Цель работы
Ознакомление студентов с задачей интерполяции функций, с методом прогонки для решения систем линейных алгебраических уравнений с ленточной матрицей, с понятием сплайна, получение навыков решения задач вычислительной математики на ЭВМ.
2 Выполнение работы
Алгоритм интерполяции сплайном функции y=sinx, представленный в виде программы, написанной на языке C++ представлен ниже.
#include <iostream>
#include <cmath>
#include <math.h>
#include <Windows.h>
#include <iomanip>
using namespace std;
int main()
{
double numbPI, h, maxdif;
int n, i, j, in;
double* arrn = new double[12];//массив количетва точек (n)
double* difarr = new double[12];//массив максимального оклонения
double* difeval = new double[12];//массив оценок
double* K = new double[12];//отношение погрешности предыдущей строки к данной
n = 5;//число точек
in = 0;//номер строки (от 0)
numbPI = 3.14159265; //число пи
in = 0;
do
{
h = numbPI / n;
double* x1 = new double[n + 1];
for (i = 0; i <= n; i++)
{
x1[i] = i * h;//массив со значениями точек по х
}
double* y1 = new double[n + 1];
for (i = 0; i <= n; i++)
{
y1[i] = sin(x1[i]);//массив со значениями точек по y
}
double** mat = new double* [n + 1];//матрица
for (i = 0; i < n + 1; i++)
{
mat[i] = new double[n + 1];
}
for (i = 0; i < n + 1; i++)
{
for (j = 0; j < n + 1; j++)
{
mat[i][j] = 0; //Матрица составлена
}
}
for (i = 0; i < n + 1; i++)//Заполнение матрицы
{
for (j = 0; j < n + 1; j++)
{
if (i == j)
{
if ((i == 0) || (i == n))
mat[i][j] = 1;
else mat[i][j] = 2 * h / 3;
}
if (i + 1 == j)
{
if (i != 0)
mat[i][j] = h / 6;
}
if (i == j + 1)
{
if (i != n)
mat[i][j] = h / 6;
}
}
}
double* d = new double[n + 1];
d[0] = 0;
d[n] = 0;
for (i = 1; i < n; i++)
{
d[i] = (y1[i + 1] - y1[i]) / h - (y1[i] - y1[i - 1]) / h;
}
double* lambda = new double[n + 1];
lambda[0] = -mat[0][1] / mat[0][0];
lambda[n] = 0;
for (i = 1; i < n; i++)
{
lambda[i] = -mat[i][i + 1] / (mat[i][i] + mat[i][i - 1] * lambda[i - 1]);
}
double* mu = new double[n + 1];
mu[0] = d[0] / mat[0][0];
for (i = 1; i <= n; i++)
{
mu[i] = (d[i] - mat[i][i - 1] * mu[i - 1]) / (mat[i][i] + mat[i][i - 1] * lambda[i - 1]);
}
double* m = new double[n + 1];
m[0] = 0;
m[n] = 0;
for (i = n - 1; i > 0; i--)
{
m[i] = lambda[i] * m[i + 1] + mu[i];
}
double* x2 = new double[n + 1];//массив с серединами интервалов по х
for (i = 0; i < n; i++)
{
x2[i] = (x1[i] + x1[i + 1]) / 2;
}
double* y2 = new double[n + 1];//массив с серединами интервалов по у
for (i = 0; i < n; i++)
{
y2[i] = sin(x2[i]);
}
double* spline = new double[n + 1];//массив со значениями сплайна
for (i = 0; i < n; i++)//заполнение
{
spline[i] = (pow((x1[i + 1] - x2[i]), 3) - pow(h, 2) * (x1[i + 1] - x2[i])) / 6 / h * m[i] + (pow((x2[i] - x1[i]), 3) - pow(h, 2) * (x2[i] - x1[i])) / 6 / h * m[i + 1] + (x1[i + 1] - x2[i]) / h * y1[i] + (x2[i] - x1[i]) / h * y1[i + 1];
}
double* dif = new double[n + 1];//массив с разницей между значениями sin(x) и сплайна
for (i = 0; i < n; i++)//заполнение
{
dif[i] = abs(spline[i] - y2[i]);
}
maxdif = dif[0];
for (i = 0; i < n; i++)//нахождение максимальной разницы
{
for (i = 0; i < n; i++)
{
if (dif[i] > maxdif)
maxdif = dif[i];
}
}
arrn[in] = n;
n = n * 2;
difarr[in] = maxdif;
if (in > 0)
K[in] = difarr[in - 1] / difarr[in];
if (in > 0)
difeval[in] = difarr[in - 1] / K[in];
//
in++;
//
} while (n < 10242);//Вывод данных в консоль
K[0] = 0;
difeval[0] = 0;
cout << setw(7) << "n" << " | " << setw(12) << "Max Dif" << " | " << setw(12) << "Eval Dif" << " | " << " K " << endl;
cout << "________________________________________________" << endl;
cout << "________________________________________________" << endl;
for (i = 0; i < 12; i++)
{
cout << setw(7) << arrn[i] << " | " << setw(12) << difarr[i] << " | " << setw(12) << difeval[i] << " | " << K[i] << endl;
cout << "________________________________________________" << endl;
}
return 0;
}
3 Результаты работы программы
Результат выполнения программы представлен на рисунке 1.
Рисунок 1 – Результаты работы программы.
4 Выводы
В ходе лабораторной работы была выполнена интерполяция сплайном для функции y=sinx, рассчитаны значения максимальной погрешности для разного количества точек функции, также рассчитаны значения оценочной погрешности и коэффициента уменьшение погрешности при удвоении числа рассматриваемых точек функции.