Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Готовые отчеты / ЛиФП. Лабораторная работа 2

.pdf
Скачиваний:
93
Добавлен:
29.01.2021
Размер:
176.38 Кб
Скачать

Федеральное агентство связи ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ

ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М. А. БОНЧ-БРУЕВИЧА» (СПбГУТ)

Факультет инфокоммуникационных сетей и систем Кафедра программной инженерии и вычислительной техники

ЛАБОРАТОРНАЯ РАБОТА №2 по дисциплине «Логическое и функциональное программирование»

Выполнил: студент 3-го курса дневного отделения группы ИКПИ-85

Коваленко Леонид Александрович Преподаватель:

доцент кафедры ПИиВТ Ерофеев Сергей Анатольевич

Санкт-Петербург

2020

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

Написать программу на языке Turbo Prolog 2.0 для построения натурального кубического сплайна.

Схема решения Приведем пример построения кубического сплайна на основе трех

точек (x1 , y1) , (x2 , y2) , (x3 , y3) .

1. Определим число отрезков.

Очевидна зависимость: Число отрезков = Число точек – 1. Число отрезков для трех точек — 2 (от x1 до x2 и от x2 до x3 ). 2. Определим число сплайнов.

Так как отрезков 2, то:

1)

a1 x3 +b1 x2 +c1 x +d1

для

x [ x1 , x2 ) ;

2)

a2 x3 +b2 x2 +c2 x +d2

для

x [ x2 , x3 ] .

Нам предстоит найти коэффициенты a1 ,b1 ,c1 ,d1 ,a2 , b2 ,c2 , d2 .

3. Формируем систему уравнений, которая имеет следующие строки:

1) Строки кубических полиномов (по абсциссам), приравненных значениям соответствующих ординат.

a1 x31 +b1 x21+c1 x1 +d1= y1

a1 x32 +b1 x22+c1 x2 +d1= y2 a2 x32 +b2 x22+c2 x2 +d2= y2 a2 x33 +b2 x23 +c2 x3 +d2= y3

2) Строки с приравненными значениями первых производных двух полиномов в общей точке.

3a1 x22+2b1 x2+c1=3 a2 x22 +2 b2 x2+c2

3)Строки с приравненными значениями вторых производных двух

полиномов в общей точке.

6a1 x2 +2b1=6 a2 x2 +2 b2

4)Строки с приравненными нулю вторыми производными в граничных

точках. (В нашем случае — граничные точки (x1 , y1) , (x3 , y3) ).

6a1 x1 +2 b1=0

6a2 x3 +2 b2=0

Данные граничные условия нужны именно для натурального сплайна. 2

По итогу получим следующее:

a

1

x3+b

1

x2+c

1

x +d

1

= y

1

 

a

1

x3

+b

1

x2

+c

1

x

+d

+0+0+0+0= y

1

 

1

1

1

 

 

 

 

1

 

1

 

1

 

1

 

 

 

 

 

a

1

x3+b

1

x2+c

1

x +d

1

= y

2

 

a

1

x3

+b

1

x2

+c

1

x

+d

+0+0+0+0= y

2

 

2

2

2

 

 

 

 

2

 

2

 

2

 

1

 

 

 

 

 

a

2

x3+b

2

x2+c

2

x

+d

2

= y

2

 

0+0+0+0+a

2

x3+b

2

x2+c

2

x +d

= y

2

 

2

2

2

 

 

 

 

 

 

 

 

 

 

2

 

2

2

2

 

a2 x33+b2 x32+c2 x3 +d2= y3

 

0+0+0+0+a2 x33 +b2 x32+c2 x3 +d2= y3

3 a1 x22+2b1 x2+c1=3 a2 x22 +2 b2 x2+c2

 

3 a1 x22 +2b1 x2+c1 +0−3 a2 x22−2b2 x2c2−0=0

6 a1 x2+2 b1=6 a2 x2+2 b2

 

6 a1 x2 +2 b1 +0+0−6 a2 x2−2 b2−0−0=0

 

 

6 a1 x1 +2 b1=0

 

 

 

 

 

 

6 a1 x1 +2 b1+0+0+0+0+0+0=0

 

 

 

6 a2 x3 +2 b2=0

 

 

 

 

 

 

0+0+0+0+6 a2 x3 +2b2+0+0=0

 

 

(

x3

 

x2

 

x

1

0

 

0

 

0

0

a1

 

y1

 

1

 

1

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

x23

 

x22

 

x2

1

0

 

0

 

0

0

b1

 

y2

 

0

 

0

 

0

0

x23

 

x22

 

x2

1

c1

 

y2

 

0

 

0

 

0

0

x33

 

x32

 

x3

1

d1

=

y

3

3 x2

2 x

 

1

0

−3 x

2

−2 x

 

−1 −0 a2

 

 

2

2

 

0

 

 

2

 

 

 

 

2

 

 

 

b2

 

0

 

6 x

2

2

 

0

0

−6 x

2

−2 −0 −0

 

 

6 x

2

 

0

0

0

0

 

0

0

c2

 

0

 

 

 

 

 

 

 

0

1

0

 

0

0

6 x3

 

2

 

0

0

)(d2)(

0 )

Зависимость числа строк R в системе уравнений от числа точек P :

R=4 P−4

4. Решаем систему уравнений методом Гаусса.

Метод Гаусса — классический метод решения системы линейных алгебраических уравнений (СЛАУ). Онлайн калькулятор метода Гаусса.

Код программы Входные данные поступают с клавиатуры либо файла, пример

содержимого которого приведен в табл. 1. Таблица 1 — Пример входных данных в файле

point(2,2)

point(1,1)

point(3,3)

Последовательность ввода точек (и с клавиатуры, и с файла) не имеет значения, они будут отсортированы по возрастанию координаты X . Точки с повторяющимися значениями X после сортировки будут удалены (кроме первой).

Код программы построения кубического сплайна приведен в табл. 2.

3

Таблица 2 — Код программы построения кубического сплайна

NOWARNINGS

%Раздел описания доменов

DOMAINS

file = datafile % Файл datafile

point = point(real, real) % Структура, описывающая точку points = point* % Список точек

list_of_real = real* % Список вещественных чисел

matrix = list_of_real* % Список списков вещественных чисел

%Раздел описания предикатов

PREDICATES

length(points, integer) input(points) input_action(points, integer) read_points_from_console(points) read_points_from_file(points) quicksort(points, points)

partition(points, real, points, points) merge(points, points, points) merge(list_of_real, list_of_real, list_of_real) merge(matrix, matrix, matrix)

distinct(points, points) form_system(points, matrix) create_list(real, integer, list_of_real)

create_equation(list_of_real, real, integer, integer, list_of_real) create_equation_1(point, integer, integer, list_of_real) create_equation_2(point, integer, integer, list_of_real) create_equation_3(point, integer, integer, list_of_real) create_equation_4(point, integer, integer, list_of_real) get_last(points, point)

stage_1(integer, points, matrix) stage_1_1(integer, point, list_of_real) stage_1_2(integer, points, matrix) stage_1_2(integer, points, matrix, integer) stage_1_3(integer, point, list_of_real) stage_2(integer, points, matrix) stage_2(integer, points, matrix, integer) stage_3(integer, points, matrix) stage_3(integer, points, matrix, integer) stage_4(integer, points, matrix)

gaussian_elimination_with_backsubstitution(matrix, list_of_real) gaussian_elimination(matrix, matrix, matrix) backsubstitution(matrix, list_of_real, list_of_real) backsubstitution_auxillary(list_of_real, list_of_real, real, real) pivot_row(matrix, list_of_real, matrix) normalized_pivot_row(list_of_real, list_of_real) normalized_pivot_row_auxillary(list_of_real, real, list_of_real) normalized_other_rows(matrix, list_of_real, matrix) normalized_other_row(list_of_real, real, list_of_real, list_of_real) output(points, list_of_real)

output_action(points, list_of_real, integer) write_coefficients(points, list_of_real)

%Раздел описания внутренней цели

GOAL

input(Points), % Ввод точек

quicksort(Points, SortedPoints), % Быстрая сортировка списка точек [O(N log N)] distinct(SortedPoints, SortedPointsWithoutDuplicates), % Удаление точек с повторяющимися X

[O(N)]

form_system(SortedPointsWithoutDuplicates, EquationSystem), % Формирование системы уравнений [O(N^2)]

gaussian_elimination_with_backsubstitution(EquationSystem, Result), % Решение системы

уравнений [O(N^3)]

output(SortedPointsWithoutDuplicates, Result), % Вывод результата readchar(_). % Завершение программы после нажатия клавиши клавиатуры

%Раздел описания предложений

CLAUSES

%Вспомогательные общие предикаты

%Длина списка

length([], 0). length([_|Xs], N) :-

length(Xs, P), N = P + 1.

% Ввод точек input(Points) :-

write("-== MENU ==-"), nl, write("1. Read from console;"), nl,

4

write("2. Read from file."), nl, write("Another button to exit"), nl, readint(C), % Считывание целого числа input_action(Points, C), % Ввод списка точек length(Points, Length), Length >= 3;

write("There must be at least three points!"), fail. % Если меньше 4 точек

%Ввод из диалогового окна input_action(Points, 1) :-

read_points_from_console(Points).

%Ввод из файла

input_action(Points, 2) :- write("File name: "),

readln(FileName), % Ввод названия файла existfile(FileName), % Существует ли файл openread(datafile, FileName), % Открытие файла для чтения readdevice(datafile), % Перенаправление ввода на файл read_points_from_file(Points), % Чтение точек из файла closefile(datafile), !; % Закрытие файла

write("Error reading file!"), nl, fail.

% Чтение точек с консоли read_points_from_console([point(X, Y)|Tail]) :-

write("X: "), readreal(X), % Чтение X write("Y: "), readreal(Y), % Чтение Y read_points_from_console(Tail).

read_points_from_console([]).

% Чтение точек с файла read_points_from_file([Point|Tail]) :-

readterm(point, Point), % Чтение терма point(X, Y) read_points_from_file(Tail).

read_points_from_file([]).

%Пример содержимого файла:

%point(2, 2)

%point(1, 1)

%point(3, 3)

%Быстрая сортировка

quicksort([point(X, Y)|Xs], Zs) :- partition(Xs, X, Left, Right), % Разбиение quicksort(Left, Ls), % Обработка левой части

quicksort(Right, Rs), % Обработка правой части merge(Ls, [point(X, Y)|Rs], Zs). % Объединение списков

quicksort([], []).

%Пример (для integer):

%quicksort([5, 3, 1, 2, 4], X)

%-> X = [1, 2, 3, 4, 5]

%Разбиение списка

partition([point(X, Y)|Xs], Z, Ls, [point(X, Y)|Rs]) :- X > Z,

partition(Xs, Z, Ls, Rs).

partition([point(X, Y)|Xs], Z, [point(X, Y)|Ls], Rs) :- X <= Z,

partition(Xs, Z, Ls, Rs). partition([], _, [], []).

%Примеры (для integer):

%partition([1, 2, 3, 4, 5], 2, L, X)

%-> L = [1, 2], X = [3, 4, 5]

%partition([1, 2, 3, 4, 5], 4, L, X)

%-> L = [1, 2, 3, 4], X = [5]

%Объединение двух списков

merge([H|Xs], Zs, [H|Ts]) :- merge(Xs, Zs, Ts). merge([], Zs, Zs).

%Пример (для integer):

%merge([1, 2, 3], [4, 5, 6], X)

%-> X = [1, 2, 3, 4, 5, 6]

%Удаление дубликатов точек по X [O(N) - нужна предварительная сортировка] distinct([], []). % В пустом списке нет дубликатов

distinct([Point], [Point]). % В списке из одной точки нет дубликатов distinct([point(X, Y1), point(X, _)|Tail], Result) :- % Если точки одинаковы по X

distinct([point(X, Y1)|Tail], Result).

distinct([Point1, Point2|Tail], [Point1|Result]) :- % Если точки разные по X distinct([Point2|Tail], Result).

%Пример (для integer):

%distinct([1, 1, 2, 2, 2, 3, 3, 4], X)

%-> X = [1, 2, 3, 4]

%Комментарий: без предварительной сортировки потребуется алгоритм со сложностью O(N^2)

5

% Формирование системы уравнений form_system(Points, Equations) :-

length(Points, Length),

% Строки кубических полиномов (по абсциссам), приравненных значениям соответствующих

ординат

stage_1(Length, Points, Equations1),

%Строки с приравненными значениями первых производных двух полиномов в общей точке stage_2(Length, Points, Equations2),

%Строки с приравненными значениями вторых производных двух полиномов в общей точке stage_3(Length, Points, Equations3),

%Строки с приравненными нулю вторыми производными в граничных точках

stage_4(Length, Points, Equations4),

% Объединение четырех систем уравнений merge(Equations1, Equations2, Equations12), merge(Equations3, Equations4, Equations34), merge(Equations12, Equations34, Equations).

%Создание списка длины N, заполненного значением X create_list(X, N, [X|L]) :-

N > 0, % Выполняем, пока N > 0, записывая в голову значение Х Next = N - 1, % Получаем следующее значение N

create_list(X, Next, L).

create_list(_, N, []) :- N <= 0. % Рекурсия останавливается, когда/если N меньше 1

%Создание уравнения

create_equation(List, Y, ZerosBeforeCount, ZerosAfterCount, Equation) :- create_list(0, ZerosBeforeCount, ZerosBefore), % Создание левой части уравнения create_list(0, ZerosAfterCount, ZerosAfter), % Создание правой части уравнения merge(ZerosBefore, List, EqPart1), % Слияние левой части с заполненной merge(EqPart1, ZerosAfter, EqPart2), % Последующее слияние с правой частью merge(EqPart2, [Y], Equation). % Добавление Y в конец

% Создание уравнения первого этапа

create_equation_1(point(X, Y), ZerosBeforeCount, ZerosAfterCount, Equation) :- AX = X * X * X, BX = X * X,

List = [AX, BX, X, 1], % List = [X^3, X^2, X, 1] create_equation(List, Y, ZerosBeforeCount, ZerosAfterCount, Equation).

% Создание уравнения второго этапа

create_equation_2(point(X, _), ZerosBeforeCount, ZerosAfterCount, Equation) :- AX = 3 * X * X, BX = 2 * X, NAX = -AX, NBX = -BX,

List = [AX, BX, 1, 0, NAX, NBX, -1, 0], % List = [3*X^2, 2*X, 1, 0, -3*X^2, -2*X, -1, 0] create_equation(List, 0, ZerosBeforeCount, ZerosAfterCount, Equation).

% Создание уравнения третьего этапа

create_equation_3(point(X, _), ZerosBeforeCount, ZerosAfterCount, Equation) :- AX = 6 * X, BX = 2, NAX = -AX, NBX = -BX,

List = [AX, BX, 0, 0, NAX, NBX, 0, 0], % List = [6*X, 2, 0, 0, -6*X, -2, 0, 0] create_equation(List, 0, ZerosBeforeCount, ZerosAfterCount, Equation).

% Создание уравнения четвертого этапа

create_equation_4(point(X, _), ZerosBeforeCount, ZerosAfterCount, Equation) :- AX = 6 * X, BX = 2,

List = [AX, BX, 0, 0], % List = [6*X, 2, 0, 0]

create_equation(List, 0, ZerosBeforeCount, ZerosAfterCount, Equation).

% Получение последней точки списка get_last([Head], LastPoint) :- Head = LastPoint.

get_last([_|Tail], LastPoint) :- get_last(Tail, LastPoint).

%Строки кубических полиномов (по абсциссам), приравненных значениям соответствующих ординат stage_1(Length, [Point|Tail], Equations) :-

get_last(Tail, LastPoint),

stage_1_1(Length, Point, Equation1), % Уравнение для первой точки

stage_1_2(Length, Tail, Equations2), % Уравнения для точек между первой и последней stage_1_3(Length, LastPoint, Equation3), % Уравнение для последней точки merge([Equation1], Equations2, Eq12), % Слияние уравнений

merge(Eq12, [Equation3], Equations).

%Уравнение для первой точки

stage_1_1(Length, Point, Equation) :- ZerosAfterCount = 4 * (Length - 2),

create_equation_1(Point, 0, ZerosAfterCount, Equation).

% Уравнения для точек между первой и последней

stage_1_2(Length, Tail, Equations) :- stage_1_2(Length, Tail, Equations, 1). stage_1_2(_, [_], [], _).

stage_1_2(Length, [Point|Tail], [Equation1, Equation2|Equations], CurrentIndex) :- ZerosBeforeCount1 = 4 * (CurrentIndex - 1),

ZerosAfterCount1 = 4 * (Length - CurrentIndex - 1), ZerosBeforeCount2 = 4 * CurrentIndex,

6

ZerosAfterCount2 = 4 * (Length - CurrentIndex - 2), create_equation_1(Point, ZerosBeforeCount1, ZerosAfterCount1, Equation1), create_equation_1(Point, ZerosBeforeCount2, ZerosAfterCount2, Equation2), NewCurrentIndex = CurrentIndex + 1,

stage_1_2(Length, Tail, Equations, NewCurrentIndex).

%Уравнение для последней точки stage_1_3(Length, Point, Equation) :-

ZerosBeforeCount = 4 * (Length - 2), create_equation_1(Point, ZerosBeforeCount, 0, Equation).

%Строки с приравненными значениями первых производных двух полиномов в общей точке stage_2(Length, Points, Equations) :- stage_2(Length, Points, Equations, 0). stage_2(Length, [_|Tail], Equations, 0) :- stage_2(Length, Tail, Equations, 1). stage_2(_, [_], [], N) :- not(N = 0).

stage_2(Length, [Point|Tail], [Equation|Equations], CurrentIndex) :-

ZerosBeforeCount = 4 * (CurrentIndex - 1), ZerosAfterCount = 4 * (Length - CurrentIndex - 2),

create_equation_2(Point, ZerosBeforeCount, ZerosAfterCount, Equation), NewCurrentIndex = CurrentIndex + 1,

stage_2(Length, Tail, Equations, NewCurrentIndex).

%Строки с приравненными значениями вторых производных двух полиномов в общей точке stage_3(Length, Points, Equations) :- stage_3(Length, Points, Equations, 0). stage_3(Length, [_|Tail], Equations, 0) :- stage_3(Length, Tail, Equations, 1). stage_3(_, [_], [], N) :- not(N = 0).

stage_3(Length, [Point|Tail], [Equation|Equations], CurrentIndex) :- ZerosBeforeCount = 4 * (CurrentIndex - 1),

ZerosAfterCount = 4 * (Length - CurrentIndex - 2), create_equation_3(Point, ZerosBeforeCount, ZerosAfterCount, Equation),

NewCurrentIndex = CurrentIndex + 1, stage_3(Length, Tail, Equations, NewCurrentIndex).

%Строки с приравненными нулю вторыми производными в граничных точках

stage_4(Length, [Point|Tail], [Equation1, Equation2]) :- First_ZerosAfterCount = 4 * (Length - 2), create_equation_4(Point, 0, First_ZerosAfterCount, Equation1), get_last(Tail, Last),

Last_ZerosBeforeCount = 4 * (Length - 2), create_equation_4(Last, Last_ZerosBeforeCount, 0, Equation2).

% Решение системы уравнений методом Гаусса gaussian_elimination_with_backsubstitution(Ass, Xs) :-

gaussian_elimination(Ass, [], ReversedReducedAss), % Прямой ход метода Гаусса backsubstitution(ReversedReducedAss, [], Xs). % Обратный ход метода Гаусса

%Пример:

%gaussian_elimination_with_backsubstitution([[1, 2, 3], [2, 2, 3]], X)

%-> X = [0, 1.5]

%Прямой ход метода Гаусса

gaussian_elimination([], Xss, Xss). gaussian_elimination(Lower, Upper, Xss) :-

pivot_row(Lower, PivotRow, OtherRows), % Получаем строку с опорным элементом normalized_pivot_row(PivotRow, NormalizedPivotRow), % Приводим строку с опорным

элементом к нормальному виду

normalized_other_rows(OtherRows, NormalizedPivotRow, NewLower), % Приводим другие строки

к нормальному виду

gaussian_elimination(NewLower, [NormalizedPivotRow|Upper], Xss). % Повтор

%Пример:

%gaussian_elimination([[1, 2, 3], [2, 2, 3]], [], X)

%-> X = [[(3-1*(3/2))/(2-1*(2/2))], [2/2, 3/2]] = [[1.5], [1, 1.5]]

%Получение опорного элемента

pivot_row([PivotRow], PivotRow, []). pivot_row([[X1|Row1],[X2|Row2]|Rows], PivotRow, [[X2|Row2]|Rest]) :-

abs(X1) > abs(X2), !, % Ищем максимальный по модулю элемент pivot_row([[X1|Row1]|Rows], PivotRow, Rest). % Ищем опорный элемент в первом столбце

матрицы

pivot_row([Row1,Row2|Rows], PivotRow, [Row1|Rest]) :- % Перебираем все строки pivot_row([Row2|Rows], PivotRow, Rest). % Для нахождения опорного элемента

%Приведение строки к нормальному виду normalized_pivot_row([Pivot|As], Bs) :-

not(Pivot = 0.0), % Недопускаем деления на нуль normalized_pivot_row_auxillary(As, Pivot, Bs).

%Приведение остальных строк к нормальному виду normalized_other_rows([], _, []). normalized_other_rows([[A|As]|Ass], PivotRow, [Bs|Bss]) :-

normalized_other_row(As, A, PivotRow, Bs), normalized_other_rows(Ass, PivotRow, Bss).

7

%Вспомогательный предикат для приведения строки к нормальному виду normalized_pivot_row_auxillary([], _, []). normalized_pivot_row_auxillary([A|As], Pivot, [B|Bs]) :-

B = A / Pivot, % Делим значение головы списка на значение опорного элемента normalized_pivot_row_auxillary(As, Pivot, Bs).

%Приведение строки к нормальному виду

normalized_other_row([], _, [], []). normalized_other_row([A|As], X, [P|Ps], [B|Bs]) :-

B = A - X * P, % Вычитаем строки из строки с опорным элементом normalized_other_row(As, X, Ps, Bs). % Берем следующие числа в списках

%Обратный ход метода Гаусса backsubstitution([], Xs, Xs).

backsubstitution([As|Ass], Ys, Xs) :- % Обратная подстановка backsubstitution_auxillary(Ys, As, 0, Y),

backsubstitution(Ass, [Y|Ys], Xs). % Обратная подстановка для оставшейся части

%Пример:

%backsubstitution([[1.5], [1, 1.5]], [], X)

%-> X = [1.5-(0+(1.5-0)*1), 1.5-0] = [0, 1.5]

%Вспомогательный предикат для обратного хода метода Гаусса

backsubstitution_auxillary([], [B], Acc0, Acc) :- % Ищем один неизвестный свободный член в строке

Acc = B - Acc0. % Вычитаем правую часть backsubstitution_auxillary([X|Xs], [A|As], Acc0, Acc) :-

Acc1 = Acc0 + X * A, % Подставляем предыдущие значения backsubstitution_auxillary(Xs, As, Acc1, Acc).

%Вывод результата output(Points, Result) :-

write("1. Write to console;"), nl, write("2. Write to file."), nl, write("Another button to exit"), nl, readint(C), % Считывание числа output_action(Points, Result, C); % Вывод write("The program is complete.").

%Вывод в диалоговое окно

output_action(Points, Result, 1) :- write_coefficients(Points, Result).

% Вывод в файл output_action(Points, Result, 2) :-

write("File name: "), readln(FileName), % Ввод названия файла

openwrite(datafile, FileName), % Открытие файла для записи writedevice(datafile), % Перенаправление вывода на файл write_coefficients(Points, Result), % Запись данных closefile(datafile). % Закрытие файла

% Вывод коэффициентов для каждого отрезка write_coefficients([_], []).

write_coefficients([point(X1, _), point(X2, Y2)|PointTail], [A, B, C, D|CoefTail]) :- write("From X=", X1, " To X=", X2), nl,

write("A: ", A), nl, write("B: ", B), nl, write("C: ", C), nl, write("D: ", D), nl, nl,

write_coefficients([point(X2, Y2)|PointTail], CoefTail).

Тестирование Для точек (1, 1) , (2 ,2) , (3 ,3) получим следующий результат:

a1=0 , b1=0 , c1=1 ,d1=0 , a2=0, b2 =0 ,c2=1 , d2 =0

Для точек (1, 1) , (2 ,8) , (3 ,27) получим следующий результат:

a1=3 , b1=−9 , c1=13 ,d1=−6 ,a2 =−3 ,b2=27 ,c2=−59 ,d2 =42

Для точек (−1, 0.5) , (0 , 0) , (3 ,3) получим следующий результат:

a1=0.1875 ,b1=0.5625,c1=−0.125 ,d1=0 , a2=−0.0625, b2=0.5625 ,c2=−0.125 ,d2 =0

Данные результаты совпадают с результатами онлайн сервиса.

8

Феномен Рунге — эффект нежелательных осцилляций (колебаний), возникающий при интерполяции полиномами высоких степеней.

В качестве примера феномена Рунге обычно приводится функция:

f(x)=1+1x2

Если интерполировать её между −5 и 5 чисто полиномиально, то полученный интерполянт будет осциллировать ближе к концам интервала (с возрастанием степени полинома погрешность такой интерполяции стремится к бесконечности). Интерполяция кубическим сплайном в этом случае справляется гораздо лучше (рис. 1).

Рисунок 1 — Интерполяция кубическим сплайном и полиномиальным многочленом функции типа Рунге

Полиномиальная интерполяция была выполнена онлайн сервисом. Интерполяция кубическим сплайном выполнялась при помощи

разработанной программы и сверялась с онлайн сервисом. Входные данные приведены в табл. 3.

Таблица 3 — Входные данные с точками функции 1/(1+x2)

point(-5, 0.038461538) point(-3, 0.1) point(-1, 0.5) point(0, 1)

point(1, 0.5) point(3, 0.1) point(5, 0.038461538)

9

Результат работы программы был записан в файл (табл. 4). Таблица 4 — Файл с результатом построения кубического сплайна

From X=-5 To X=-3

A:-0.0021153846312

B:-0.031730769469

C:-0.11942307782

D:-0.029807693281

From X=-3 To X=-1

A:0.052884615406

B:0.46326923087

C:1.3655769232

D:1.4551923077

From X=-1 To X=0

A:-0.40230769232

B:-0.90230769232

C:0

D:1

From X=0 To X=1

A:0.40230769232

B:-0.90230769232

C:0

D:1

From X=1 To X=3

A:-0.052884615406

B:0.46326923087

C:-1.3655769232

D:1.4551923077

From X=3 To X=5

A:0.0021153846312

B:-0.031730769469

C:0.11942307782

D:-0.029807693281

Выводы В результате выполнения лабораторной работы мы разработали

программу на языке Turbo Prolog 2.0 для построения кубического сплайна. Было проведено тестирование отдельных предикатов и всей программы в целом. Программа полностью удовлетворяет заданным требованиям.

10