Стася
Постоялец
Offline
|
|
« : 15-02-2009 19:09 » |
|
Определить степень интерполяционного полинома и рассчитать полином по интерполяционной формуле Ньютона. Основная часть проги написана. Я не знаю, как определять степень, по-моему это как-то связано вот с этой формулой Ньютона.
|
|
« Последнее редактирование: 24-02-2009 15:20 от Алексей1153++ »
|
Записан
|
|
|
|
Стася
Постоялец
Offline
|
|
« Ответ #1 : 22-02-2009 16:27 » |
|
Теперь уже знаю. Но встала другая проблема, как по функции построить график? Помогите, пожалуйста, исправить ошибку в коде. unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids,Math, TeEngine, Series, ExtCtrls, TeeProcs, Chart;
type TForm1 = class(TForm) StringGrid1: TStringGrid; Button1: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Edit1: TEdit; Label1: TLabel; Edit2: TEdit; Edit3: TEdit; Chart1: TChart; Series1: TLineSeries; Button2: TButton; Edit4: TEdit; Edit5: TEdit; Label2: TLabel; Label3: TLabel; procedure Button2Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1; xydata:array of array of real; pddata,cddata:array of real;
implementation
{$R *.dfm}
procedure GetArray; Var i:word; n:integer; begin n:=strtoint(form1.Edit1.text); Setlength(xydata,n,2); for i:=1 to n do begin xydata[i-1,0]:=strtofloat(form1.Stringgrid1.Cells[0,i]); xydata[i-1,1]:=strtofloat(form1.Stringgrid1.cells[1,i]); end; end;
procedure TForm1.Button1Click(Sender: TObject); Var n:integer; begin n:=strtoint(Edit1.Text); Stringgrid1.ColCount:=n+1; Stringgrid1.RowCount:=n+2; Stringgrid1.FixedCols:=0; Stringgrid1.Cells[0,0]:='x'; Stringgrid1.Cells[1,0]:='y'; end;
procedure RR(Order:byte); Var i:word; n:integer; begin n:=strtoint(form1.Edit1.text); if order>1 then begin Setlength(pddata,n-order+1); for i:=0 to n-order do pddata[i]:=cddata[i]; end; Setlength(cddata,n-order); for i:=0 to n-order-1 do //так как динамический массив начинается с нуля,то уменьшаем все на 1 if order>1 then cddata[i]:=(pddata[i+1]-pddata[i])/(xydata[i+order,0]-xydata[i,0]) else cddata[i]:=(xydata[i+1,1]-xydata[i,1])/(xydata[i+1,0]-xydata[i,0]); end;
function GetRR(Order:byte;number:byte):real; {Var i;integer} begin GetArray; {for i:=1 to order do} RR(Order); result:=cddata[number]; end;
function Getdm(Order:byte):real; Var i:integer; min,max:real; n:word; begin n:=strtoint(form1.Edit1.text); GetArray; for i:=1 to order do RR(i); min:=cddata[0]; max:=min; for i := 1 to n-order do begin if cddata[i-1]<min then min:=cddata[i]; if cddata[i-1]>max then max:=cddata[i]; end; result:=(max-min)*power(xydata[n-1,0]-xydata[0,0],order); end;
function stepen(Order:byte):byte; Var min:real; i,n: Integer; begin n:=strtoint(form1.Edit1.text); GetArray; RR(Order); min:=getdm(1); result:=1; for i := 2 to n - 1 do begin if Getdm(i)<min then begin min:=Getdm(i); result:=i; end; end; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); Var tf:textfile; n:integer; i:word; begin n:=strtoint(edit1.Text); Assignfile(tf,'data.txt'); Rewrite(tf); Writeln(tf,n); for i:=1 to n do begin Writeln(tf,Stringgrid1.Cells[0,i]); Writeln(tf,Stringgrid1.Cells[1,i]); end; Closefile(tf); end;
procedure TForm1.FormCreate(Sender: TObject); Var tf:textfile; i:word; s:string; n:integer; begin n:=strtoint(Edit1.Text); Assignfile(tf,'data.txt'); Reset(tf); Readln(tf,n); Stringgrid1.ColCount:=n+1; Stringgrid1.Rowcount:=n+2; For i:=1 to n do begin Readln(tf,s); Stringgrid1.Cells[0,i]:=s; Readln(tf,s); Stringgrid1.Cells[1,i]:=s; end; closefile(tf); end;
procedure TForm1.Button3Click(Sender: TObject); Var i,j:word; n:integer; begin n:=strtoint(Edit1.Text); GetArray; for i:=2 to n do begin RR(i-1); for j:=1 to n-i+1 do Stringgrid1.Cells[i,j]:=floattostr(cddata[j-1]); end; end;
procedure TForm1.Button4Click(Sender: TObject); Var i,n:integer; begin n:=strtoint(form1.Edit1.Text); for i:=2 to n do begin getdm(i-1); Stringgrid1.Cells[i,n+1]:=floattostr(getdm(i-1)); stepen(i-1); Edit2.Text:=floattostr(stepen(i-1)); end; end;
function PN(order:byte;x:real):real; Var i,j:word; k,m:real; begin GetArray; k:=xydata[1,0]; for i:=1 to order do begin m:=GetRR(i,1); for j:=1 to order do begin m:=m*(x-xydata[j-1,0]); end; k:=k+m; end; result:=k; end;
procedure TForm1.Button2Click(Sender: TObject); Var a,b,x:real; n:integer; i,j:word; begin n:=strtoint(Edit1.Text); a:=strtofloat(Edit4.Text); b:=strtofloat(Edit5.Text); while b<a do begin x:=PN(i,j); Chart1.SeriesList[0].AddXY(i,x,'',clblue); end; end;
end.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 22-02-2009 17:20 » |
|
Стася,
1) где ошибка ? 2) в чём проявляется ? 3) где код, который строит график ?
|
|
|
Записан
|
|
|
|
Стася
Постоялец
Offline
|
|
« Ответ #3 : 22-02-2009 18:30 » |
|
График не строится. Функция и неправильный код, по которому строится график находятся в конце.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 22-02-2009 18:38 » |
|
эти названия переменных ни о чём не говорят procedure TForm1.Button2Click(Sender: TObject); Var a,b,x:real; n:integer; i,j:word; begin n:=strtoint(Edit1.Text); a:=strtofloat(Edit4.Text); b:=strtofloat(Edit5.Text); while b<a do begin x:=PN(i,j); Chart1.SeriesList[0].AddXY(i,x,'',clblue); end; end;
а ещё - от a и b (так понимаю, минимум и максимум) ничего в цикле не зависит, i,j - тоже не меняются, значит будет нарисована прямая. А ещё цикл либо зависнет, либо ни разу не выполнится, так как (a>b) - константа
|
|
|
Записан
|
|
|
|
Стася
Постоялец
Offline
|
|
« Ответ #5 : 23-02-2009 17:13 » |
|
procedure TForm1.Button2Click(Sender: TObject); Var x:real; n:integer; i,j:longint; begin n:=strtoint(Edit1.Text); for i:=-100 to 100 do begin for j := 1 to n do begin x:=PN(i,j); Chart1.SeriesList[0].AddXY(i,x,'',clblue); end; end; end; Только все равно график не строится. Скорее всего он просто не вытаскивает данные из массива, а вообще я не знаю(((
|
|
« Последнее редактирование: 24-02-2009 13:14 от Стася »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 24-02-2009 15:19 » |
|
Стася, скажи, ты как хочешь отобразить график, каким способом:
1) отрезками 2) при помощи сканирования прямоугольной области
1. меняем x от x0 до xmax с шагом dx . для каждой точки x считаем y=F(x) и ставим очередную точку (все эти точки просто соединить отрезками)
2. сканируем обе оси (x и y) во вложенном цикле с шагом dx и dy. Для каждой точки проверяем условие |F(x)-y| <= 0.00001 (некая точность)
если условие выполнено - ставим точку, если не выполнено - не ставим.
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #7 : 24-02-2009 15:37 » |
|
Стася, в Delphi есть горячая клавиша F7, нажимая которую происходит пошаговое выполнение программы, проверяй в отладке, что у тебя в массиве и какие данные идут в Chart. Алексей1153++, тут для вывода графика используется готовый компонент TChart, он по координатным точкам строит интерполяционную кривую.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 24-02-2009 15:41 » |
|
ну тогда метод 1) подойдёт
|
|
|
Записан
|
|
|
|
Стася
Постоялец
Offline
|
|
« Ответ #9 : 24-02-2009 17:10 » |
|
procedure TForm1.Button2Click(Sender: TObject); Var x,dx:real; n:integer; i,j:longint; begin n:=strtoint(Edit1.Text); dx:=strtofloat(Edit4.Text); for i:=-100 to 100 do begin for j := 1 to n do begin x:=PN(i,j); Chart1.SeriesList[0].AddXY(i,x,'',clblue); x:=x+dx; end; end; end; Ошибка вот такая:"Access violation at address 00465324 in module 'Project1.exe'.Read of address 00000000".Видимо все-таки входные данные, в одном месте исправила (нашла при помощи F7), а сейчас не пойму в чем дело и в чем там ошибка, а ошибка вот в какой функции: procedure RR(Order:byte); Var i:word; n:integer; begin n:=strtoint(form1.Edit1.text); if order>1 then begin Setlength(pddata,n-order+1); for i:=0 to n-order do pddata[i]:=cddata[i]; end; Setlength(cddata,n-order); for i:=0 to n-order-1 do //так как динамический массив начинается с нуля,то уменьшаем все на 1 if order>1 then cddata[i]:=(pddata[i+1]-pddata[i])/(xydata[i+order,0]-xydata[i,0]) else cddata[i]:=(xydata[i+1,1]-xydata[i,1])/(xydata[i+1,0]-xydata[i,0]); end;
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #10 : 24-02-2009 17:27 » |
|
Setlength(pddata,n-order+1); for i:=0 to n-order do pddata[i]:=cddata[i]; end; Setlength(cddata,n-order);
Смотри, ты сначала создаешь массив pddata, затем ты его инициализируешь элементами массива cddata, который еще не создан.
|
|
|
Записан
|
|
|
|
Стася
Постоялец
Offline
|
|
« Ответ #11 : 24-02-2009 17:33 » |
|
А как исправить? Это тут тогда всю прогу переписывать надо.
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #12 : 24-02-2009 18:08 » |
|
Стася, если честно, то на месте препода я бы 2 бала поставил, даже не разбираясь в коде. Так все криво, что ужас. Может и преподу надо 2 ставить, что так учит.
|
|
|
Записан
|
|
|
|
Стася
Постоялец
Offline
|
|
« Ответ #13 : 24-02-2009 18:13 » |
|
Стыдно признаваться, но мы ее писали под руководством препода. Сами написали для подсчета dm и степени интерполяционного полинома. Осталось вот график по функции. Препод на нас забил, разбирайтесь мол сами. Вот мы и разбираемся.
|
|
|
Записан
|
|
|
|
|