Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Закрытая тема
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.03.2013, 20:10
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 10
По умолчанию Интерполяция, метод лагранжа, переменная степень

Всем привет! Решил заняться интерполяцией, да не получается. Суть задачи состоит в том, чтобы полученные точки (у меня они задаются вручную) интерполировать функцией с переменной степенью. Т.е. чтобы можно было задавать степень функции. Я попробовал реализовать метод лагранжа, но не получается. Программа запускается, но при расчетах выдает ошибку:
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  
Старый 03.03.2013, 01:23
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Наверное надо точки на запятые (в смысле десимал сепаратор) поменять.
  #3  
Старый 03.03.2013, 10:09
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 10
По умолчанию

Да не дело не в этом.
  #4  
Старый 03.03.2013, 10:52
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 10
По умолчанию

Я немного изменил код. Заметил пару глупых ошибок. Но почему-то не помогло, рисует график линией простой которая даже через точки не проходит. Помогите кто знает пожалуйста. Вот код:
Код:
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  
Старый 03.03.2013, 12:22
ART ART вне форума
Продвинутый
 
Регистрация: 13.02.2006
Адрес: Магнитогорск
Сообщения: 669
Репутация: 14745
По умолчанию

Вот тебе Лагранж на паскале

Код:
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  
Старый 03.03.2013, 12:54
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 10
По умолчанию

Блин мне нужно делфи. Хотя коды я смотрю и похожи, но мне нужно не для фиксированного количества точек. И чтобы можно было выбирать порядок полинома для разложения. Но все равно спс за полезную информацию, я посмотрю может можно изменить.
  #7  
Старый 03.03.2013, 13:25
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 10
По умолчанию

Я проверил ваш код. Попробовал его реализовать. Значение интерполяции нули во всех точках. Подумал что может просто неверно рисую график, оказалось дело не в этом. Вот немного измененный код, помогите кто может плз:
Код:
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  
Старый 03.03.2013, 19:18
ART ART вне форума
Продвинутый
 
Регистрация: 13.02.2006
Адрес: Магнитогорск
Сообщения: 669
Репутация: 14745
По умолчанию

А ничего, что в Delphi используется Object Pascal? И почему у тебя t не инициализирована ДО вычисления Лагранжа?
  #9  
Старый 03.03.2013, 21:04
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 10
По умолчанию

Да методы полностью совпадают, ошибок нет. Все дело в графиках. Как мне начертить интерполяцию? Я использую два графика, первый показывает точки вводимые вручную, второй должен показывать интерполяцию.
  #10  
Старый 03.03.2013, 21:22
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 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  
Старый 04.03.2013, 18:22
ugicedeath ugicedeath вне форума
Прохожий
 
Регистрация: 14.02.2013
Сообщения: 17
Репутация: 10
По умолчанию

Вообщем тему можно закрыть. Реализовал метод с переменной степенью на матлабе без встроенных функций.
Закрытая тема


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:31.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter