Технический форум

Технический форум (http://www.tehnari.ru/)
-   Помощь студентам (http://www.tehnari.ru/f41/)
-   -   Интерполяция функций (http://www.tehnari.ru/f41/t98840/)

oleum 12.10.2014 18:41

Интерполяция функций
 
Помоги с этим разобраться.
Интерполировать заданную таблично функцию полиномами 1-го порядка (локальная линейная интерполяция) и полиномом n-го порядка (глобальная интерполяция). Вычислить значение функции в точке x:
xi= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
yi=-1.06, -0.83, -0.68, -0.31, 0.11, 0.00, 0.12, 0.53, 0.18, 0.25, 0.38, 0.21, 0.44, 0.63, 0.86, 1.05, 1.32, 1.55, 1.82, 1.71
в точке х=11.24.
(Аппроксимация функций)
Аппроксимировать табличную функцию из предыдущей задачи полиномом 1 и 2 степени. Используя полученную аппроксимацию, вычислить значение функции в точке, указанной в предыдущей задаче. На одной координатной плоскости построить график исходной табличной функции и графики аппроксимирующих полиномов.

oleum 12.10.2014 18:44

вот что мне удалось написать по поводу интерполяции, но не факт что правильно.....а как быть с аппроксимацией? кто-нибудь может помочь?
Цитата:

Program interpol;
uses crt;

const N=20;
var x:array [1..N] of real;
y:array [1..N] of real;
a,b,c,xp,yp,deltaA,deltaB,deltaC,delta:real;
i:integer;
begin
for i:=1 to N do
begin {ввод данных через массивы}
write('x[',I,']=');
readln(x[i]);
write('y[',I,']=');
readln(y[i]);
end;
write('введите x= '); {ввод промежуточного значения}
readln(xp);
for i:=2 to N do
if (x[i-1]<=xp) and (xp<=x[i-1]) then
begin {вычисление}
delta:=x[i-1]*x[i-1]*x[i]-x[i-1]*x[i-1]*x[i+1]+x[i-1]*x[i+1]*x[i+1]-x[i-1]*x[i]*x[i]-x[i+1]*x[i+1]*x[i]+x[i+1]*x[i]*x[i];
deltaA:=x[i+1]*y[i]-x[i-1]*y[i]+y[i-1]*x[i]-x[i+1]*y[i-1]-y[i+1]*x[i]+x[i-1]*y[i+1];
deltaB:=x[i-1]*x[i-1]*y[i]-x[i+1]*x[i+1]*y[i]-y[i-1]*x[i]*x[i]+y[i+1]*x[i]*x[i]-x[i-1]*x[i-1]*y[i+1]+x[i+1]*x[i+1]*y[i-1];
deltaC:=y[i+1]*x[i-1]*x[i-1]*x[i]-y[i]*x[i-1]*x[i-1]*x[i+1]+y[i]*x[i-1]*x[i+1]*x[i+1]-y[i+1]*x[i-1]*x[i]*x[i]-y[i-1]*x[i+1]*x[i+1]*x[i]+y[i-1]*x[i+1]*x[i]*x[i];
a:=delta/deltaA;
b:=delta/deltaB;
c:=delta/deltaC;
yp:=a*xp*xp+b*xp+c;
end;
writeln('y= ',yp); {вывод искомого значения}
readln;
end.

Vladimir_S 12.10.2014 19:11

Вот это что за ахинея?
Цитата:

Сообщение от oleum (Сообщение 1069070)
if (x[i-1]<=xp) and (xp<=x[i-1])

Вероятно, имеется в виду
if (x[i-1]<=xp) and (xp<=x[i+1])?
Повнимательнее, пожалуйста.
Далее - при вычислении коэффициентов a, b и c в квадратичной интерполяции у Вас дроби (числитель и знаменатель) перевернуты.
Могу привести формализм, которым сам пользуюсь (отлаженный и проверенный). Если парабола проходит через точки с координатами (X1,Y1), (X2,Y2), (X3,Y3) и требуется определить значение Y в точке X, лежащей между X1 и X3, то
Код:

  det:=(X1-X2)*(X2-X3)*(X1-X3);
  A:=(Y1*(X2-X3)+Y2*(X3-X1)+Y3*(X1-X2))/det;
  B:=(Y1*(X3*X3-X2*X2)+Y2*(X1*X1-X3*X3)+Y3*(X2*X2-X1*X1))/det;
  C:=(Y1*X2*X3*(X2-X3)+Y2*X1*X3*(X3-X1)+Y3*X1*X2*(X1-X2))/det;
  Y:=A*X*X+B*X+C;

Линейной интерполяции я у Вас вообще не вижу.
Теперь насчет аппроксимаций, линейной и квадратичной. Формализм достаточно подробно изложен, например, здесь:
http://edu.dvgups.ru/METDOC/ENF/VMAT...GZ/frame/2.htm
Надеюсь, запрограммировать все эти суммы Вы сумеете.

oleum 13.10.2014 17:52

правильно делаю?
Код:

program Approks;
 uses crt;
label 1,2;
var
 m,i,j,n,k:integer;
 q,x,y,b,kof: array [0..30] of real;
 a: array [0..30,0..30] of real;
 s,r,c,v,e,func:real;
 BEGIN
 n:=19;
 x[0]:=1;      x[1]:=2;      x[2]:=3;      x[3]:=4;    x[4]:=5;    x[5]:=6;    x[6]:=7;    x[7]:=8;    x[8]:=9;    x[9]:=10;
 x[10]:=11;    x[11]:=12;    x[12]:=13;    x[13]:=14;  x[14]:=15;  x[15]:=16;  x[16]:=17;  x[17]:=18;  x[18]:=19;  x[19]:=20;
 y[0]:=-1.06;  y[1]:=-0.83;  y[2]:=-0.68;  y[3]:=-0.31; y[4]:=0.11;  y[5]:=0.00;  y[6]:=0.12;  y[7]:=0.53;  y[8]:=0.18;  y[9]:=0.25;
 y[10]:=0.38;  y[11]:=0.21;  y[12]:=0.44;  y[13]:=0.63; y[14]:=0.86; y[15]:=1.05; y[16]:=1.32; y[17]:=1.55; y[18]:=1.82; y[19]:=1.71;
  write('введите степень полинома N:');
  readln(m);
  for i:=0 to n do
  q[i]:=1;
  i:=0;
  repeat
            s:=0;
            r:=0;
            j:=0;
            1:
            if j>n then
              begin
              a[0,i]:=s;
              b[i]:=r;
              end
                    else
                    begin
                      s:=s+q[j];
                      r:=r+q[j]*y[j];  {Программа формирует матрицу}
                      q[j]:=q[j]*x[j];
                      j:=j+1;
                      goto 1;
                    end;
            i:=i+1;
  until i>m;
  i:=1;
  repeat
  s:=0;
  j:=0;
  2:
  if j>n then
    begin
    a[i,m]:=s;
    i:=i+1;
    end
          else
          if j<m then
            begin
            a[i,j]:=a[i-1,j+1];
            s:=s+q[j];
            q[j]:=q[j]*x[j];
            j:=j+1;
            goto 2;
            end
                  else
                    begin
                    s:=s+q[j];
                    q[j]:=q[j]*x[j];
                    j:=j+1;
                    goto 2;
                    end;
  until i>m;
 
  {решение СЛАУ методом Гаусса}
    for k:=0 to m do begin
  for i:=k+1 to m do  begin
  c:= (a[i,k])/(a[k,k]);
  a[i,k]:=0;
  for j:=k+1 to m do begin
  a[i,j]:=a[i,j]-a[k,j]*c;
  end;
  b[i]:=b[i]-b[k]*c;
  end;
  end;
  x[m]:=b[m]/a[m,m];
  for i:=m-1 downto 0 do begin
  v:=0;
  for j:=i+1 to m do begin
  v:=v+(a[i,j]*x[j]);
  end;
  x[i]:=(b[i]-v)/a[i,i];
  end;   
    for i:=m downto 0 do
      kof[i]:=x[i];                 
          for i:=m downto 0 do
    writeln('a',i,'= ',kof[i]:0:5);
    x[0]:=1;    x[1]:=2;    x[2]:=3;    x[3]:=4;    x[4]:=5;    x[5]:=6;    x[6]:=7;    x[7]:=8;    x[8]:=9;    x[9]:=10;
    x[10]:=11;  x[11]:=12;  x[12]:=13;  x[13]:=14;  x[14]:=15;  x[15]:=16;  x[16]:=17;  x[17]:=18;  x[18]:=19;  x[19]:=20;
  func:=0;
    e:=0;
      for j:= 0 to n do
      func:=0;
 begin
  for i:=m downto 0 do
  func:=func+(power(x[j],i)*kof[i]);
  e:=e+(y[j]-func)*(y[j]-func);
  end;
 writeln('Погрешность= ', e:1:5);
end.


Vladimir_S 13.10.2014 20:29

Цитата:

Сообщение от oleum (Сообщение 1069369)
правильно делаю?

Наверное. Уж извините, но делать за вас черновую работу по тестированию и отладке программы я лично не буду. Замечу только, что, во-первых, все эти goto и label - дурной тон, лучше обходиться без них, а во-вторых, я бы вместо
Код:

x[0]:= 1;    x[1]:= 2;    x[2]:= 3;    x[3]:= 4;    x[4]:= 5;    x[5]:= 6;    x[6]:= 7;    x[7]:= 8;    x[8]:= 9;    x[9]:=10;
x[10]:=11;    x[11]:=12;    x[12]:=13;    x[13]:=14;  x[14]:=15;    x[15]:=16;  x[16]:=17;  x[17]:=18;  x[18]:=19;  x[19]:=20;

написал бы просто
Код:

for i:=0 to 19 do x[i]:=i+1;


Часовой пояс GMT +4, время: 05:05.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.