Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторные работы №4 и №5 / gera / methods
.h#include <stdio.h>
#include <iostream>
#include <cstring>
#include <conio.h>
#include <cmath>
#include "function.h"
AnsiString Minimize(myFunction F, TVector SP, TVector Dir, char* varnames);
AnsiString Swann(myFunction Fr, double &a, double &b, TVector S, TVector P, char* vars, int flag);
double SSwann(myFunction Fr, double &a, double &b, TVector S, TVector P, char* vars, int flag);
double TPS(myFunction Fr, double a, double b, TVector S, TVector P, char* vars);
double Davidon(myFunction Fr, double a, double b, TVector S, TVector P, char* vars);
AnsiString MPK(myFunction Fr, TVector P, char* varnames);
//--------------------------------------------------
AnsiString Minimize(myFunction F, TVector SP, TVector Dir, char* varnames)
{
double a=0, b=0;
TVector S, P;
AnsiString rs;
//S=SP;
//P=Dir;
/*double* ms=SP.Value();
ShowMessage("St Min: "+FloatToStr(ms[0]));
delete[] ms; */
/*double* ms1=Dir.Value();
ShowMessage("Direct Min: "+FloatToStr(ms1[0]));
delete[] ms1;
ShowMessage("Inside of Minimize");*/
F.SetDirection(1);
Swann(F, a, b, SP, Dir, varnames,0);
rs.printf("%f,%f",a,b);
return rs;
}
//--------------------------------------------------
AnsiString Swann(myFunction Fr, double &a, double &b, TVector S, TVector P, char* vars, int flag)
{
double al1, al2, r1, r2, *crd;
bool bp=true;
AnsiString rs,rs2,rs3;
TVector result;
al1=0.1;
r1=Fr.Calculate(S, P, vars, al1);
//ShowMessage("Done calc1 "+FloatToStr(r1));
r2=Fr.Calculate(S, P, vars, 0);
//ShowMessage("Done calc1 "+FloatToStr(r2));
if(r1>r2) {Fr.SetDirection(-1); /*ShowMessage("Attempt");*/ P*=-1; /*ShowMessage("Success"); */}
while(bp)
{
al2=2*al1;
r1=Fr.Calculate(S, P, vars, al1);
//ShowMessage("Done cycl calc1 "+FloatToStr(r1));
r2=Fr.Calculate(S, P, vars, al2);
//ShowMessage("Done cycl calc2 "+FloatToStr(r2));
if(r2>r1) bp=false;
else {
al1=al2;
}
}
b=al2;
a=al1/2;
rs.printf("Swann returned (alphas!): %f, %f; Method solved (coords!): ",a,b);
if (flag==1) r1=TPS(Fr,a,b,S,P,vars);
else if (flag==2) r1=Davidon(Fr,a,b,S,P,vars);
result=P;
//if(Fr.p==-1) result*=-1;
result*=r1;
result+=S;
crd=result.Value();
rs2.printf(" %f",crd[0]);
for(int lk=1; lk<vc; lk++)
{
rs3.printf(", %f",crd[lk]);
rs2+=rs3;
}
return rs+rs2;
}
//--------------------------------------------------
double TPS(myFunction Fr, double a, double b, TVector S, TVector P, char* vars)
{
double eps=0.0001, alm,al1,al2,a1,b1,resl;
bool bp=true;
a1=a;
b1=b;
alm=(a1+b1)/2;
while(bp)
{
al1=a1+fabs(b1-a1)/4;
al2=b1-fabs(b1-a1)/4;
if(Fr.Calculate(S, P, vars, al1)<Fr.Calculate(S, P, vars, alm))
{
b1=alm;
alm=al1;
}
else if( (Fr.Calculate(S, P, vars, al1)>Fr.Calculate(S, P, vars, alm))&&(Fr.Calculate(S, P, vars, al2)>Fr.Calculate(S, P, vars, alm)) )
{
a1=al1;
b1=al2;
}
else
{
a1=alm;
alm=al2;
}
if(fabs(b1-a1)<eps) bp=false;
}
resl=(b1+a1)/2;
return resl;
}
//--------------------------------------------------
double Davidon(myFunction Fr, double a, double b, TVector S, TVector P, char* vars)
{
double fi, W, z, rs, da, db, d, eps=0.000001;
bool bp=true;
TVector pointA, pointB;
//AnsiString resl;
while(bp)
{
pointA=P;
pointA*=a;
pointA+=S;
da=Fr.Derivative(P,pointA);
pointB=P;
pointB*=b;
pointB+=S;
db=Fr.Derivative(P,pointB);
z=da+db+3*(Fr.Calculate(S,P,vars,a)+Fr.Calculate(S,P,vars,b))/b;
W=pow(z*z-da*db,0.5);
fi=(z-da+W)/(db-da+2*W);
d=a+fi*(b-a);
pointA=P;
pointA*=d;
pointA+=S;
da=Fr.Derivative(P,pointA);
if (fabs(da)<eps) bp=false;
else
{
if(da<0)
a=d;
else b=d;
}
}
return d;
}
//--------------------------------------------------
double SSwann(myFunction Fr, double &a, double &b, TVector S, TVector P, char* vars, int flag)
{
double al1, al2, r1, r2, *crd;
bool bp=true;
AnsiString rs,rs2,rs3;
TVector result;
al1=0.1;
r1=Fr.Calculate(S, P, vars, al1);
r2=Fr.Calculate(S, P, vars, 0);
if(r1>r2) {Fr.SetDirection(-1); /*ShowMessage("Attempt");*/ P*=-1; /*ShowMessage("Success"); */}
while(bp)
{
al2=2*al1;
r1=Fr.Calculate(S, P, vars, al1);
r2=Fr.Calculate(S, P, vars, al2);
if(r2>r1) bp=false;
else {
al1=al2;
}
}
b=al2;
a=al1/2;
if (flag==1) r1=TPS(Fr,a,b,S,P,vars);
else if (flag==2) r1=Davidon(Fr,a,b,S,P,vars);
return r1;
}
//--------------------------------------------------
AnsiString MPK(myFunction Fr, TVector point, char* varnames)
{
TVector X1(point.Value(),point.Dimensions()), X2(point.Value(),point.Dimensions()), X3(point.Value(),point.Dimensions()), X4(point.Value(),point.Dimensions()), D(point.Value(),point.Dimensions()), P(point.Value(),point.Dimensions());
double norma, eps=0.00001,*grd,alpha, a=0, b=0;
int k=0;
bool bp=true;
AnsiString rs2, rs3;
X1=point;
grd=Fr.FormGrad(X1);
for(k=0;k<vc;k++)
P.coords[k]=-grd[k];
alpha=SSwann(Fr,a,b,X1,P,varnames,1);
//ShowMessage(FloatToStr(X1.coords[0])+" "+FloatToStr(X1.coords[1])+" "+FloatToStr(X1.coords[2]));
Fr.Reload(math);
X2=P;
X2*=alpha;
X2+=X1;
while (bp)
{
grd=Fr.FormGrad(X2);
for(k=0;k<vc;k++)
P.coords[k]=-grd[k];
alpha=SSwann(Fr,a,b,X2,P,varnames,1);
Fr.Reload(math);
X3=P;
X3*=alpha;
X3+=X2;
D=X1;
D*=-1;
D+=X3;
alpha=SSwann(Fr,a,b,X3,D,varnames,1);
Fr.Reload(math);
X4=D;
X4*=alpha;
X4+=X3;
grd=Fr.FormGrad(X4);
for(k=0;k<vc;k++)
P.coords[k]=grd[k];
norma=P.norm();
if(norma<eps) bp = false;
else
{
X1=X2;
X2=X4;
}
}
if(Fr.p==-1) X4*=-1;
rs2.printf(" %f",X4.coords[0]);
for(int lk=1; lk<vc; lk++)
{
rs3.printf(", %f",X4.coords[lk]);
rs2+=rs3;
}
return rs2;
}
//--------------------------------------------------