Новичок
Джуниор
Регистрация: 14.04.2011
Сообщений: 1
|
ошибка float value error
вообщем, пишу курсовую на тему оптимизации функции. вот уже второй день ломаю голову, не могу понять почему на второй итерации ошибка float value error. скорее всего это из-за вычисления экспоненты, может есть возможность как-нибудь это обойти? метод мак-кормика 1, переменная метрика.
заранее благодарен
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, TeeProcs, TeEngine, Chart, Series, ArrowCha, Math;
const
num=2;
type
Matrix2 = array[1..num,1..num] of Single;
Matrix1 = array[1..num] of Single;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Chart1: TChart;
Series1: TLineSeries;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
a=12;
b=-0.3;
c=1.21;
d=0.22;
eps=0.0001;
var
Form1: TForm1;
dk,v,u: Matrix1;
g1: Matrix1;
g0: Matrix1;
n:integer;
x,y,fxy:array[0..2] of single;
Amat,Hmat,pvT:Matrix2;
Hu,p: Matrix1;
zm:single;
vTu:single;
cond:single;
implementation
{$R *.dfm}
function func(x,y:real):real;
begin
func:=a*x+b*y+exp(c*sqr(x)+d*sqr(y));
//func:=a*x+b*y+x*sqr(y)+y*sqr(x);
end;
//процедура для вычисления производных
procedure funcdx(x,y:real;var grad: Matrix1);
begin
grad[1]:=a+2*c*x*exp(c*x*x+d*y*y);
//grad[1]:=a+sqr(y);
grad[2]:=b+2*d*y*exp(c*x*x+d*y*y);
//grad[2]:=b+sqr(x);
end;
function MakeOneMatrix(hm: Matrix2): Matrix2;
var
tmp: Matrix2;
begin
tmp[1][1]:=1;
tmp[1][2]:=0;
tmp[2][1]:=0;
tmp[2][2]:=1;
result:=tmp;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.Lines.Clear;
n:=0;
with Chart1 do begin
LeftAxis.Automatic:=false;
LeftAxis.Minimum:=-5;
LeftAxis.Maximum:=5;
BottomAxis.Automatic:=false;
BottomAxis.Minimum:=-5;
BottomAxis.Maximum:=5;
SeriesList[0].Clear;
end;
x[0]:=strtofloat(Edit1.Text);//первая переменная
y[0]:=strtofloat(Edit2.Text);// вторая переменная
fxy[0]:=0;
funcdx(x[0],y[0],g0);// getting g[1] and g[2]
dk[1]:=-g0[1];
dk[2]:=-g0[2];
Hmat:=MakeOneMatrix(Hmat); // делаем матрицу H единичной
Amat:=MakeOneMatrix(Amat); // делаемем матрицу A единичной
Chart1.SeriesList[0].AddXY(x[0],y[0]);
zm:=0;
repeat
inc(n);
zm:=func(x[0]+zm*dk[1],y[0]+zm*dk[2]);
Math.RoundTo(dk[1],2);
Math.RoundTo(dk[2],2);
x[1]:=x[0]+zm*dk[1];
y[1]:=y[0]+zm*dk[2];
v[1]:=zm*dk[1];
v[2]:=zm*dk[2];
x[0]:=x[1];
y[0]:=y[1];
funcdx(x[1],y[1],g1);//вычисляем новый градиент
u[1]:=g1[1]-g0[1];
u[2]:=g1[2]-g0[2];
g0[1]:=g1[1];
g0[2]:=g1[2];
// Hu comput
Hu[1]:=Hmat[1][1]*u[1]+Hmat[1][2]*u[2];
Hu[2]:=Hmat[2][1]*u[1]+Hmat[2][2]*u[2];
// v-Hu=p
p[1]:=v[1]-Hu[1];
p[2]:=v[2]-Hu[2];
// pv^T, 2x2 матрица
pvT[1][1]:=p[1]*v[1];
pvT[1][2]:=p[1]*v[2];
pvT[2][1]:=p[2]*v[1];
pvT[2][2]:=p[2]*v[2];
// вычисление v^Tu
vTu:=v[1]*u[1]+v[2]*u[2];
//наконец, получение корректирующей матрицы
Amat[1][1]:=pvT[1][1]/vTu;
Amat[1][2]:=pvT[1][2]/vTu;
Amat[2][1]:=pvT[2][1]/vTu;
Amat[2][2]:=pvT[2][2]/vTu;
// Hmat = Hmat + Amat
Hmat[1][1]:=Hmat[1][1]+Amat[1][1];
Hmat[1][2]:=Hmat[1][2]+Amat[1][2];
Hmat[2][1]:=Hmat[2][1]+Amat[2][1];
Hmat[2][2]:=Hmat[2][2]+Amat[2][2];
// обновление напр вектора
dk[1]:=-(Hmat[1][1]*g1[1]+Hmat[1][2]*g1[2]);
dk[2]:=-(Hmat[2][1]*g1[1]+Hmat[2][2]*g1[2]);
cond:=(abs(zm)+(sqr(g1[1])+sqr(g1[2])));
fxy[n]:=func(x[n],y[n]);
Chart1.SeriesList[0].AddXY(x[n],y[n]);
cond:=sqrt(sqr(v[1])+sqr(v[2]))+sqrt(sqr(g1[1])+sqr(g1[2]));// модуль вектора v + модуль градиента g1
until cond<eps;
memo1.Lines.Add('');
memo1.Lines.Add('Минимум при x='+floattostrf(x[n],ffgeneral,3,4)+' y='+floattostrf(y[n],ffgeneral,3,4)+' f(x,y)='+floattostrf(fxy[n],ffgeneral,4,4));
memo1.Lines.Add('H = '+ floattostrf(Hmat[1][1],ffgeneral,3,4) +' '+floattostrf(Hmat[1][2],ffgeneral,3,4));
memo1.Lines.Add(' '+ floattostrf(Hmat[2][1],ffgeneral,3,4) +' '+floattostrf(Hmat[2][2],ffgeneral,3,4));
end;
end.
|