
Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №62 / ON
.CPP//Obobshenniy Method Nutona Class Edition ver.2.0
#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include "point1.h"
Point fabs(const Point&); //fabs: x[]=fabs(x[])
double f(const Point&); //prototype function f(x1,x2)
double dfdp(const Point&,const Point&); //derivative in the direction #2
Point df(const Point&); //derivative of f(x[])
double dfitd(const Point&,const Point&); //derivative in the direction
double min(double,double); //prototype of function min(x,y)
double Length(const Point&,const Point&); //length of segment x0(x0[0],x0[1]),x1(x1[0],x1[1])
void Svenn4(double,const Point&,const Point&,double,Point&,Point&); //Method Svenn-4
double FindStep(const Point&,const Point&,double); //find alpha of Davidon's method
bool EndOfSearch(const Point&,double); //End of search for method of Koshi
Point ON(double[],double); //method оf Newton
const int k=3;
main()
{
cout << "Laboratory work 6\nThe generalized method of Newton\n\n";
cout << endl;
double xk[3]={4,-1,2}; //start point xk
//double xk[2]={1.5,2};
double x_min[3]={1,3,-5}; //really minimum of f(x)
//double x_min[2]={1,1};
double e=0.001; //accuracy
Point answer(k);
answer=ON(xk,e);
cout << "Minimum is:\n";
answer.printPointEx("CoordinatbI");
answer.Inaccuracy(x_min);
cout << "\nPress any key" << endl;
getchar();
return 0;
}
/////////////////////////////fabs/////////////////////////////////
Point fabs (const Point &A)
{
Point At=A;
Point result(k);
int i=0;
while (i<k)
{
result[i]=fabs(At[i]);
i++;
}
return result;
}
////////////////////////////f(x)//////////////////////////////
double f(const Point &p)
{
Point pt=p;
return //100*(pt[1]-pt[0]*pt[0])*(pt[1]-pt[0]*pt[0])+(1-pt[0])*(1-pt[0]);
(pt[0]-1)*(pt[0]-1)+(pt[1]-3)*(pt[1]-3)+4*(pt[2]+5)*(pt[2]+5);
}
///////////////derivative in the direction#2//////////////////////
double dfdp(const Point &x, const Point &p)
{
double a=0.000001;
Point x1=x;
Point p1=p;
x1=x1+p1*a;
Point x2=x;
x2=x2+p1*(-a);
return (f(x1)-f(x2))/(2*a);
}
/////////////////////derivative of f(x[])////////////////////////
Point df(const Point &x)
{
Point result(k);
double a=0.000001;
Point x1(k);
Point x2(k);
double tmp_ans = 0;
int i=0;
while (i<k)
{
x1=x;
x2=x;
x1[i]=x1[i]+a;
x2[i]=x2[i]-a;
result[i]=(f(x1)-f(x2))/(2*a);
i++;
}
return result;
}
///////////////////////derivative in the direction////////////////////////////
double dfitd(const Point &x, const Point &p)
{
Point dy=df(x);
Point pt=p;
double result=0;
int i=0;
while (i<k)
{
result=result+dy[i]*pt[i];
i++;
}
return result;
}
///////////////////////////function min(x,y)//////////////////////////////////
double min(double x, double y)
{
if (x < y)
return x;
else
return y;
}
/////////////////////////////SegmentLength////////////////////////////////////
double Length(const Point &x,const Point &y)
{
Point xt=x;
Point yt=y;
double result=0;
int i=0;
while (i<k)
{
result=result+pow(xt[i]-yt[i],2);
i++;
}
if ((yt[0]-xt[0])>0)
return sqrt(result);
else
return -sqrt(result);
}
////////////////////////////////////Svenn-4//////////////////////////////////////////////
void Svenn4(double dy1,const Point &pk1,const Point &xk1,double ak,Point &xa,Point &xb)
{
//Svenn-4:
Point xk=xk1;
Point pk=pk1;
Point x_prev=xk;
//Part 1:
if (dy1 > 0)
{
pk = -pk;
};
//Part 2:
while (dfitd(x_prev,pk)*dfitd(xk,pk) > 0)
{
x_prev = xk;
xk = xk + pk*ak;
ak = ak*2;
}
//Part 3:
Point x_a(k);
Point x_b(k);
if (dy1 > 0)
{
x_a = xk;
x_b = x_prev;
}
else
{
x_a = x_prev;
x_b = xk;
};
// x_a.printPoint();
// x_b.printPoint();
xa = x_a;
xb = x_b;
}
/////////////////////////Davidon's method//////////////////////////////
double FindStep(const Point &pk1,const Point &xk1,double e)
{
//Davidon method:
//Initial Stage:
int count=0;
Point xk=xk1;
Point pk=pk1;
pk.Norming();
double dy1=dfdp(xk,pk);
double nju=1;
double ak=min(nju,fabs(2*(f(xk)-dy1)/dy1));
Point xa(k);
Point xb(k);
Svenn4(dy1,pk,xk,ak,xb,xa);
//Basic Stage:
//Part I:
double dya=dfdp(xa,pk);
double dyb=dfdp(xb,pk);
double z=dya+dyb+3*(f(xb)-f(xa))/Length(xb,xa);
double W=sqrt(z*z-dya*dyb);
double al_r=ak*((W-dyb+z)/(2*W-dyb+dya)); //approximation step
double sum_al_r=al_r;
Point r(k); //approximation minimum:
r = xk;
r = r + pk*al_r;
//Part II:
while ((fabs(dfdp(r,pk))>e) && (fabs(Length(xa,r))>e) && (fabs(Length(r,xb))>e))
{
if (dfdp(r,pk)>0)
{
xa = r;
ak = al_r;
}
else
{
xb = r;
ak = ak-al_r;
}
dya=dfdp(xa,pk);
dyb=dfdp(xb,pk);
z=dya+dyb+3*(f(xb)-f(xa))/Length(xb,xa);
W=sqrt(z*z-dya*dyb);
al_r=ak*((W-dyb+z)/(2*W-dyb+dya)); //approximation step
//approximation minimum:
r = xb;
r = r + pk*al_r;
count++;
}
cout << "kol-vo iteracii davidona: "<<count;
return al_r;
}
////////////////////////////End of search/////////////////////////////////////
bool EndOfSearch(const Point &x,double e)
{
bool stop=false;
Point temp(k);
temp=df(x);
if (temp.norma()<e)
{
stop=true;
}
return stop;
}
/////////////////////////OM Newtona///////////////////////////////////
Point ON(double *xk1,double e)
{
Point xk(k);
xk.setPoint(xk1);
int count=0;
int M=100;
//Basic Stage:
//Part I:
double H[3][3] = {{0.5, 0,0},{0,0.5,0},{0,0,0.125}}; //obratnaya = Gesse^(-1)//
//double H[2][2] = {{0.0098, 0.0294},{0.0294,0.0932}};
Point dy = df(xk);
Point pk(k);
pk[0]=-(H[0][0]*dy[0]+H[0][1]*dy[1]+H[0][2]*dy[2]);
pk[1]=-(H[1][0]*dy[0]+H[1][1]*dy[1]+H[1][2]*dy[2]);
pk[2]=-(H[2][0]*dy[0]+H[2][1]*dy[1]+H[2][2]*dy[2]);
//pk[0]=-(H[0][0]*dy[0]+H[0][1]*dy[1]);
//pk[1]=-(H[1][0]*dy[0]+H[1][1]*dy[1]);
//pk.printPoint();
//getchar();
//Part II:
double a;
cout << "Please input alpha: " << endl;
cin >> a;
xk = xk + pk*a;
count++;
while ((EndOfSearch(xk,e)==false) && (count < M))
{
dy = df(xk);
pk[0]=-(H[0][0]*dy[0]+H[0][1]*dy[1]+H[0][2]*dy[2]);
pk[1]=-(H[1][0]*dy[0]+H[1][1]*dy[1]+H[1][2]*dy[2]);
pk[2]=-(H[2][0]*dy[0]+H[2][1]*dy[1]+H[2][2]*dy[2]);
//pk[0]=-(H[0][0]*dy[0]+H[0][1]*dy[1]);
//pk[1]=-(H[1][0]*dy[0]+H[1][1]*dy[1]);
a = FindStep(pk,xk,0.0001);
xk = xk + pk*a;
xk.printPointEx("TmpCoordinates");
count++;
}
cout << "iteration counts: "<< count <<endl;
return xk;
}
/////////////////////////////////////////////////////////////////////
Соседние файлы в папке Лабораторная работа №62