Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Помогите исправить код


Автор: MrAlex 3.5.2010, 16:18
Уважаемые программисты, помогите разобраться что не так.
Надо решить систему нелинейных уравнений методом простой итерации и методом Ньютона. Метод итерации вроде получился, а метод Ньютона никак не получается, что делать? Пишет, что "Invalid floating point operation"


Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    StringGrid1: TStringGrid;
    StringGrid2: TStringGrid;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
   // procedure FormCreate(Sender: TObject);
    procedure newton();
    procedure prost_iter();
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  i:integer;

implementation

{$R *.dfm}

 procedure TForm1.prost_iter();
var
x,y:array[0..100] of real;

begin
x[0]:=1;
y[0]:=1;
for i:=1 to 100 do
begin
x[i]:=0.85+cos(y[i-1]);
y[i]:=1.32+sin(x[i-1]);
if ((x[i]-x[i-1])<0.1) and ((y[i]-y[i-1])<0.1) then
begin
form1.StringGrid1.Cells[0,1]:=floattostr(x[i]);
form1.StringGrid1.Cells[1,1]:=floattostr(y[i]);
end;
end;
end;

procedure TForm1.newton();
var
i:integer;
dx1, dx2:array[0..100] of real;
x,y:array[0..100] of real;
f1, f2:array[0..100] of real;

begin
x[1]:=1.5;
y[1]:=0.5;
f1[1]:=0.85+cos(y[i]);
f2[1]:=-1.32+sin(x[i-1]);
for i:=2 to 100 do
begin
f1[i]:=0.85+cos(y[i]);
f2[i]:=-1.32+sin(x[i]);
dx1[i]:=(f1[i]*(-1)*sin(y[i-1])-1*f2[i])/(cos(x[i-1])*sin(y[i-1]));
dx2[i]:=(cos(x[i-1])*f2[i]-f1[i]*2)/(cos(x[i-1])*sin(y[i-1]));
x[i]:=x[i-1]+dx1[i];
y[i]:=y[i-1]+dx2[i];
if(abs(dx1[i])<0.1) and (abs(dx2[i])<0.1) then
begin
form1.StringGrid2.Cells[0,1]:=floattostr(x[i]);
form1.StringGrid2.Cells[0,2]:=floattostr(y[i]);
end;

end;

end;


procedure TForm1.Button1Click(Sender: TObject);
begin
//prost_iter();
newton();

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
close();
end;

end.
 

Заранее благодарен!

Автор: superVad 3.5.2010, 17:51
Ерунда какая то.
f1[1]:=0.85+cos(y[i]);
f2[1]:=-1.32+sin(x[i-1]);
Как ты тут обращаешся к i а оно у тебя еще не инициализировано. Вот чему тут i равно?

for i:=2 to 100 do
begin
f1[i]:=0.85+cos(y[i]);
f2[i]:=-1.32+sin(x[i]);
Ты обращаешься к элементам массива (y[2] например) которые еще ничем не заполнены...

Да и отформатируй код - самому же легче будет.

Автор: MrAlex 3.5.2010, 18:10
Вот так вот правильнее будет?

Код

begin
x[1]:=1.5;
y[1]:=0.5;
for i:=1 to 100 do
begin
f1[i]:=0.85+cos(y[i]);
f2[i]:=-1.32+sin(x[i]);
dx1[i]:=(f1[i]*(-1)*sin(y[i-1])-1*f2[i])/(cos(x[i-1])*sin(y[i-1]));
dx2[i]:=(cos(x[i-1])*f2[i]-f1[i]*2)/(cos(x[i-1])*sin(y[i-1]));
x[i]:=x[i-1]+dx1[i];
y[i]:=y[i-1]+dx2[i];


Автор: superVad 3.5.2010, 18:35
MrAlex, ну я же не знаю, чего ты хочешь
Но все равно не правильно. smile

может так....
Код

begin
  x[0]:=1.5;
  y[0]:=0.5;
  for i:=1 to 100 do
  begin
    f1[i]:=0.85+cos(y[i-1]);
    f2[i]:=-1.32+sin(x[i-1]);
    dx1[i]:=(f1[i]*(-1)*sin(y[i-1])-1*f2[i])/(cos(x[i-1])*sin(y[i-1]));
    ...


Да и вроде как значения f1, f2, dx1, dx2 ты дальше уже нигде не используешь. Т.е. это могут быть не массивы а просто переменные типа real.

Добавлено через 6 минут и 26 секунд
т.е.
Код

procedure TForm1.newton();
var
  i:integer;
  dx1, dx2, f1, f2: real;
  x,y:array[0..100] of real;
begin
  x[0]:=1.5;
  y[0]:=0.5;
  for i:=1 to 100 do
  begin
    f1:=0.85+cos(y[i-1]);
    f2:=-1.32+sin(x[i-1]);
    dx1:=(f1*(-1)*sin(y[i-1])-1*f2)/(cos(x[i-1])*sin(y[i-1]));
    dx2:=(cos(x[i-1])*f2-f1*2)/(cos(x[i-1])*sin(y[i-1]));
    x[i]:=x[i-1]+dx1;
    y[i]:=y[i-1]+dx2;
    if(abs(dx1)<0.1) and (abs(dx2)<0.1) then
    begin
      form1.StringGrid2.Cells[0,1]:=floattostr(x[i]);
      form1.StringGrid2.Cells[0,2]:=floattostr(y[i]);
    end;
  end;
end;

Автор: MrAlex 3.5.2010, 19:01
Спасибо! Ошибку больше не выдает, но и результат не выводит, почему?

Автор: superVad 3.5.2010, 20:06
Не получает ни одного результата удовлетворяющего условие:
if(abs(dx1)<0.1) and (abs(dx2)<0.1) then

Автор: MrAlex 3.5.2010, 20:46
Что делать? Как исправить?

Автор: profesiachuvak 3.5.2010, 22:02
Цитата(MrAlex @  3.5.2010,  20:46 Найти цитируемый пост)
Что делать? Как исправить? 

Искать алгоритм методов, и искать ошибку в его реализации. Тут нужно теорию проверять.

Автор: MrAlex 4.5.2010, 00:38
Ребята, ну кто в этом разберается помогите, пожалуйста

Автор: superVad 4.5.2010, 09:41
В чем - в этом? В решении системы нелинейных уравнений методом Ньютона?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)