|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Интерполяция, метод лагранжа, переменная степень
Всем привет! Решил заняться интерполяцией, да не получается. Суть задачи состоит в том, чтобы полученные точки (у меня они задаются вручную) интерполировать функцией с переменной степенью. Т.е. чтобы можно было задавать степень функции. Я попробовал реализовать метод лагранжа, но не получается. Программа запускается, но при расчетах выдает ошибку:
Invalid floating point evaluation и показывает на строчку расчета произведений. Помогите пожалуйста, мне не обязательно интерполировать методом лагранжа, если есть другие варианты не скупитесь плз. Вот код: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Series, TeEngine, ExtCtrls, TeeProcs, Chart; type TForm1 = class(TForm) Edit1: TEdit; Label1: TLabel; Chart1: TChart; Series1: TLineSeries; Series2: TPointSeries; Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; x: array [1..100] of real; y: array [1..100] of real; L: array [1..100] of real; n,j,i:integer; t,q:real; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); const t='Введите значение'; begin n:=strtoint(edit1.text); for i:=1 to n do //Ввод точек через окошко begin x[i]:=StrToFloat(InputBox('Ввод Х'+IntToStr(i),t,'0')); y[i]:=StrToFloat(InputBox('Ввод Y'+IntToStr(i),t,'0')); series2.AddXY(x[i],y[i]); end; end; procedure TForm1.Button2Click(Sender: TObject); // Сами расчеты begin for i:=1 to n do begin L[i]:=1; end; FOR j:=1 TO n DO begin IF i<>j THEN begin L[i]:=L[i]*(t-x[i])/(x[j]-x[i]); //Произведения, формула лагранжа end; end; for i:=1 to n do begin q:=0; q:=q+L[i]*y[i]; // Суммирование произведений end; t:=-4; while t<4+0.1 do // График begin series1.AddXY(t,q); t:=t+0.1; end; end; end. |
#2
|
||||
|
||||
Наверное надо точки на запятые (в смысле десимал сепаратор) поменять.
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#3
|
|||
|
|||
Да не дело не в этом.
|
#4
|
|||
|
|||
Я немного изменил код. Заметил пару глупых ошибок. Но почему-то не помогло, рисует график линией простой которая даже через точки не проходит. Помогите кто знает пожалуйста. Вот код:
Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Series, TeEngine, ExtCtrls, TeeProcs, Chart; type TForm1 = class(TForm) Edit1: TEdit; Label1: TLabel; Chart1: TChart; Series1: TLineSeries; Series2: TPointSeries; Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; q: array [1..100] of real; y: array [1..100] of real; x: array [1..100] of real; n,i,j:integer; L,t:real; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); const t='Введите значение'; begin n:=strtoint(edit1.text); for i:=0 to n-1 do //Ввод данных begin x[i]:=StrToFloat(InputBox('Ввод X'+IntToStr(i),t,'0')); y[i]:=StrToFloat(InputBox(Ввод Y'+IntToStr(i),t,'0')); series2.AddXY(x[i],y[i]); end; end; procedure TForm1.Button2Click(Sender: TObject); begin for i:=0 to n-1 do begin //Задание начального значения q[i]:=1; end; if (i<j) and (i>j) then begin //Условие расчета произведения и сам полином for j:=0 to n-1 do begin q[i]:=q[i]*(t-x[j])/(x[i]-x[j]); // t - переменная для разложения end; end; L:=0; //Обнуление значения разложения для расчета суммы for i:=0 to n-1 do begin //Сумма произведений L:=L+y[i]*q[i]; end; t:=0; while t<x[n-1]+0.1 do begin //График series1.AddXY(t,L); t:=t+0.1; end; end; end. Последний раз редактировалось ugicedeath, 03.03.2013 в 10:57. |
#5
|
|||
|
|||
Вот тебе Лагранж на паскале
Код:
program Langrange; type TValues = array [0..3] of real; var vX, vY: TValues; function getF(x: real): real; begin Result := exp(x - 10); end; function getL(x: real; n: integer): real; var i, j: integer; mul: real; res: real; begin res := 0; for i := 0 to n do begin mul := 1; for j := 0 to n do if i <> j then mul := mul * (x - vX[j]) / (vX[i] - vX[j]) ; res := res + vY[i] * mul; end; Result := res; end; procedure Init; begin vx[0] := 1; vy[0] := 0.00012; vx[1] := 1.5; vy[1] := 0.000203; vx[2] := 2; vy[2] := 0.000335; vx[3] := 2.5; vy[3] := 0.00055; end; var i: integer; x0: real; f1, f2: real; begin Init; x0 := 1.6; f1 := getL(x0, 1); f2 := getF(x0); writeln('Лагранж: ', f1); writeln('Точное: ', f2); writeln('Погрешность: ', (f2 - f1):0:10); end. |
#6
|
|||
|
|||
Блин мне нужно делфи. Хотя коды я смотрю и похожи, но мне нужно не для фиксированного количества точек. И чтобы можно было выбирать порядок полинома для разложения. Но все равно спс за полезную информацию, я посмотрю может можно изменить.
|
#7
|
|||
|
|||
Я проверил ваш код. Попробовал его реализовать. Значение интерполяции нули во всех точках. Подумал что может просто неверно рисую график, оказалось дело не в этом. Вот немного измененный код, помогите кто может плз:
Код:
procedure TForm1.Button2Click(Sender: TObject); begin q:=1; L:=0; if (i<j) and (i>j) then begin //Условие for i:=0 to n-1 do begin for j:=0 to n-1 do begin q:=q*(t-x[j])/(x[i]-x[j]); // t - переменная для разложения и сам метод L:=L+q*y[i]; end; end; result:=L; end; i:=0; t:=x[i]; while t<x[n-1]+0.1 do begin //График series1.AddXY(t,result); t:=t+0.1; end; end; |
#8
|
|||
|
|||
А ничего, что в Delphi используется Object Pascal? И почему у тебя t не инициализирована ДО вычисления Лагранжа?
|
#9
|
|||
|
|||
Да методы полностью совпадают, ошибок нет. Все дело в графиках. Как мне начертить интерполяцию? Я использую два графика, первый показывает точки вводимые вручную, второй должен показывать интерполяцию.
|
#10
|
|||
|
|||
Вообщем я немного изменил код, как вы сказали заранее присвоил значения для t. Пришлось массивов сделать несколько штук. Вот код:
Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Series, TeEngine, ExtCtrls, TeeProcs, Chart; type TForm1 = class(TForm) Edit1: TEdit; Label1: TLabel; Chart1: TChart; Series1: TLineSeries; Series2: TPointSeries; Button1: TButton; Button2: TButton; Label2: TLabel; Label3: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; y: array [1..100] of real; x: array [1..100] of real; q: array [1..100] of real; L: array [1..100] of real; t: array [1..100] of real; n,i,j,g,k:integer; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); const t='Введите значение'; begin n:=strtoint(edit1.text); for i:=0 to n-1 do begin x[i]:=StrToFloat(InputBox('Ввод X'+IntToStr(i),t,'0')); y[i]:=StrToFloat(InputBox('Ввод Y'+IntToStr(i),t,'0')); series2.AddXY(x[i],y[i]); end; end; procedure TForm1.Button2Click(Sender: TObject); begin n:=strtoint(edit1.text); for k:=0 to n-1 do begin t[k]:=k/10; end; for k:=0 to n-1 do begin q[k]:=1; end; for k:=0 to n-1 do begin L[k]:=0; end; if (i<j) and (i>j) then begin / for i:=0 to n-1 do begin for j:=0 to n-1 do begin q[k]:=q[k]*(t[k]-x[j])/(x[i]-x[j]); end; L[k]:=L[k]+q[k]*y[i]; end; end; for k:=1 to n-1 do begin series1.AddXY(t[k],L[k]); end; end; end. |
#11
|
|||
|
|||
Вообщем тему можно закрыть. Реализовал метод с переменной степенью на матлабе без встроенных функций.
|