Pers.narod.ru. Алгоритмы. Реализация основных методов интерполяции функции одной переменной |
Задана исходная функция ln((x2-3x+2)/(x2+1)) и интервал [0,1]. Построить узлы интерполяции xi =a+h*i, i=0,1,...,N, h=(b-a)/N, (N - параметр задачи), и вычислить в этих узлах значения fi= g(xi). Вычисленные значения xi, fi занести в массивы.
Написать программу для нахождения значения F(z) в некоторой произвольной точке z принадлежит [a,b], не совпадающей ни с одним из узлов xi с помощью кусочно-постоянной интерполяции. Значение z вводить с клавиатуры. Найти погрешность метода |g(z)-F(z)|, вывести на печать. Составить таблицу поведения погрешности в зависимости от N=10, 20, 40, 80.
Написать программу для нахождения значения F(z) в некоторой произвольной точке z принадлежит [a,b] с помощью кусочно-линейной интерполяции. Значение z вводить с клавиатуры. Найти погрешность метода |g(z)-F(z)|, вывести на печать. Составить таблицу поведения погрешности в зависимости от N=10, 20, 40, 80.
Написать программу для вычисления значения полинома Лагранжа LN(z), где z - произвольная точка из отрезка [a,b], не совпадающая ни с одним из узлов xi. Попробовать различные точки z: близко к левому концу отрезка [a,b], в средней части, близко к правому концу. Найти погрешность метода |g(z)-F(z)|, вывести на печать. Составить таблицу поведения погрешности в зависимости от N=10, 20, 40, 80.
Кусочно-постоянная интерполяция. Пусть z принадлежит [xi-1, xi], i=1,2,..,N. Искомая функция является постоянной и равна левому: Fi(z)=fi или правому: Fi(z)=fi значению. Условия интерполяция выполняются, однако найденная функция является разрывной.
Кусочно-линейная интерполяция. На каждом интервале функция является линейной Fi(z)=kiz+ci; значения коэффициентов находятся из выполнения условий интерполяции и непрерывности интерполирующей функции: Fi(xi-1)= fi-1, Fi(xi)= fi. Итоговая функция будет непрерывной, но производная будет разрывной в каждом узле интерполяции.
Полином Лагранжа ,
где и т.д.
В общем случае , i=0,1,2,...,N.
Формирование таблиц исходных данных (файл 10.dat, 20.dat, 40.dat, 80.dat для N=10,20,40,80 соответственно).
program Tabl; {01.pas} const n:array [1..4] of integer=(10,20,40,80); var h,a,b,x,y:real; i,r:integer; f1:text; name:string; function f(x:real):real; begin f:=ln( (sqr(x)-3*x+2)/(sqr(x)+1) ); end; begin writeln ('a,b? '); readln (a,b); for r:=1 to 4 do begin h:=(b-a)/n[r]; str(n[r]:2,name); name:=Concat (name,'.dat'); assign (f1,name); rewrite (f1); for i:=0 to n[r] do begin x:=a+i*h; y:=f(x); writeln(f1,x,' ',y); end; writeln ('file ',name,' OK for N=',n[r]); close (f1); end; end.
Кусочно-постоянная интерполяция
program Post; {02.pas} const n:array [1..4] of integer=(10,20,40,80); var a,b,z,fx:real; x,y:array[0..100] of real; i,r,n1,num:integer; f1:text; name:string; function f(x:real):real; begin f:=ln( (sqr(x)-3*x+2)/(sqr(x)+1) ); end; begin writeln ('Z? '); readln (z); writeln ('n':5,'g(z)':15,'f(z)':15,'|g(z)-f(z)|':15); for r:=1 to 4 do begin str(n[r]:2,name); name:=Concat (name,'.dat'); assign (f1,name); reset (f1); i:=0; while not eof(f1) do begin readln (f1,x[i],y[i]); i:=i+1; end; close (f1); n1:=i-1; a:=x[0]; b:=x[n1]; if z<a then fx:=y[0] else if z>b then fx:=y[n1] else begin num:=Trunc((z-a)*n1/(b-a)); fx:=y[num]; end; writeln (n1:5,fx:15:10,f(z):15:10,abs(fx-f(z)):15:10); end; end.
program Linear; {03.pas} const n:array [1..4] of integer=(10,20,40,80); var a,b,z,fx,a1,b1:real; x,y:array[0..100] of real; i,r,n1,num:integer; f1:text; name:string; function f(x:real):real; begin f:=ln( (sqr(x)-3*x+2)/(sqr(x)+1) ); end; begin writeln ('Z? '); readln (z); writeln ('n':5,'g(z)':15,'f(z)':15,'|g(z)-f(z)|':15); for r:=1 to 4 do begin str(n[r]:2,name); name:=Concat (name,'.dat'); assign (f1,name); reset (f1); i:=0; while not eof(f1) do begin readln (f1,x[i],y[i]); i:=i+1; end; close (f1); n1:=i-1; a:=x[0]; b:=x[n1]; if z<=a then fx:=y[0] else if z>=b then fx:=y[n1] else begin num:=Trunc((z-a)*n1/(b-a)); {коэффициенты прямой от точки (x[i],y[i]) до (x[i+1],y[i+1])} a1:=(y[num]-y[num+1])/(x[num]-x[num+1]); b1:=y[num]-a1*x[num]; fx:=a1*x[num]+b1; end; writeln (n1:5,fx:15:10,f(z):15:10,abs(fx-f(z)):15:10); end; end.
program Lagr; {04.pas} type vector=array[0..100] of real; const n:array [1..4] of integer=(10,20,40,80); var a,b,z,fx,a1,b1:real; x,y:vector; i,r,n1,num:integer; f1:text; name:string; function f(x:real):real; begin f:=ln( (sqr(x)-3*x+2)/(sqr(x)+1) ); end; function Lagrange (n:integer; var x,f:vector; x0:real):real; var i,j:integer; p,s:real; begin s:=0; for i:=0 to n do begin p:=1; for j:=0 to n do begin if i<>j then p:=p*((x0-x[j])/(x[i]-x[j])); end; s:=s+f[i]*p; end; Lagrange:=s; end; begin writeln ('Z? '); readln (z); writeln ('n':5,'g(z)':15,'f(z)':15,'|g(z)-f(z)|':15); for r:=1 to 4 do begin str(n[r]:2,name); name:=Concat (name,'.dat'); assign (f1,name); reset (f1); i:=0; while not eof(f1) do begin readln (f1,x[i],y[i]); i:=i+1; end; close (f1); n1:=i-1; a:=x[0]; b:=x[n1]; if z<=a then fx:=y[0] else if z>=b then fx:=y[n1] else begin fx:=Lagrange (n1,x,y,z); end; writeln (n1:5,fx:15:10,f(z):15:10,abs(fx-f(z)):15:10); end; end.
Формирование файлов данных
a,b? 0 0.99 file 10.dat OK for N=10 file 20.dat OK for N=20 file 40.dat OK for N=40 file 80.dat OK for N=80
Не вводим интервал [0,1], т.к. именно у этой функции в x=1 особенность :)
Кусочно-постоянная интерполяция
Z? 0.47 n g(z) f(z) |g(z)-f(z)| 10 -0.1773519752 -0.4091988287 0.2318468535 20 -0.3295804736 -0.4091988287 0.0796183552 40 -0.3295804736 -0.4091988287 0.0796183552 80 -0.3694280026 -0.4091988287 0.0397708262
Кусочно-линейная интерполяция
Z? 0.47 n g(z) f(z) |g(z)-f(z)| 10 -0.1773519752 -0.4091988287 0.2318468535 20 -0.3295804736 -0.4091988287 0.0796183552 40 -0.3295804736 -0.4091988287 0.0796183552 80 -0.3694280026 -0.4091988287 0.0397708262
Полином Лагранжа
Точка в левой части отрезка
Z? 0.07 n g(z) f(z) |g(z)-f(z)| 10 0.5847133934 0.5800612760 0.0046521174 20 0.5799415750 0.5800612760 0.0001197010 40 0.5800624092 0.5800612760 0.0000011332 80 -47.3439597970 0.5800612760 47.9240210730
Точка в середине отрезка
Z? 0.47 n g(z) f(z) |g(z)-f(z)| 10 -0.4090353367 -0.4091988287 0.0001634920 20 -0.4091988939 -0.4091988287 0.0000000651 40 -0.4091988287 -0.4091988287 0.0000000000 80 -0.4091988287 -0.4091988287 0.0000000000
Точка в правой части отрезка
Z? 0.92 n g(z) f(z) |g(z)-f(z)| 10 -3.1078544062 -3.0620054005 0.0458490056 20 -3.0607425377 -3.0620054005 0.0012628628 40 -3.0620056491 -3.0620054005 0.0000002486 80-109.2519895900 -3.0620054005 106.1899841900
Как видно из таблиц анализа погрешности, наиболее точным является метод интерполяции с помощью полинома Лагранжа. Однако, погрешность полинома Лагранжа может существенно увеличиться на концах отрезка при слишком большом числе отрезков интерполяции.
Скачать файлы с программами и данными из этой статьи: pas_interp.zip (5 Кб)
гостевая; E-mail |