Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №6.doc
Скачиваний:
5
Добавлен:
01.05.2014
Размер:
125.95 Кб
Скачать

5) Текст программы

//Obobshenniy Method Nutona

#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 SegmentLength(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 FindAlpha(const Point&,const Point&,double); //find alpha of Davidon's method

bool KOP(const Point&,double); //KOP for Koshi method

Point ON(double[],double); //Coshi method

const int k=3;

main()

{

cout << "Laboratory work #6\nVariant 1\nObobshennii metod N'utona\n\n";

cout << endl;

double xk[3]={4,-1,-2}; //start point xk

double x_min[3]={1,3,-5}; //really minimum of f(x1,x2)

double eps=0.0001; //accuracy (epsilon)

Point answer(k);

answer=ON(xk,eps);

cout << "Minimum finded ON method:\n";

answer.printPointEx("Coordinates");

answer.Inaccuracy(x_min);

cout << "\nPress any key for exit..." << 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(x1,x2)//////////////////////////////

double f(const Point &p)

{

Point pt=p;

return (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 alpha=0.000001;

Point x1=x;

Point p1=p;

x1=x1+p1*alpha;

Point x2=x;

x2=x2+p1*(-alpha);

return (f(x1)-f(x2))/(2*alpha);

}

/////////////////////derivative of f(x[])////////////////////////

Point df(const Point &x)

{

Point ans(k);

double alpha=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]+alpha; //ans.x1=(f(x[0]+alpha,x[1])-f(x[0]-alpha,x[1]))/(2*alpha);

x2[i]=x2[i]-alpha; //ans.x2=(f(x[0],x[1]+alpha)-f(x[0],x[1]-alpha))/(2*alpha);

ans[i]=(f(x1)-f(x2))/(2*alpha);

i++;

}

return ans;

}

///////////////////////derivative in the direction////////////////////////////

double dfitd(const Point &x, const Point &p)

{

Point dy=df(x);

Point pt=p;

double ans=0;

int i=0;

while (i<k)

{

ans=ans+dy[i]*pt[i];

i++;

}

return ans;

}

///////////////////////////function min(x,y)//////////////////////////////////

double min(double x, double y)

{

if (x < y)

return x;

else

return y;

}

/////////////////////////////SegmentLength////////////////////////////////////

double SegmentLength(const Point &x,const Point &y)

{

Point xt=x;

Point yt=y;

double ans=0;

int i=0;

while (i<k)

{

ans=ans+pow(xt[i]-yt[i],2);

i++;

}

if ((yt[0]-xt[0])>0)

return sqrt(ans);

else

return -sqrt(ans);

}

////////////////////////////////////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;

//Step 1:

if (dy1 > 0)

{

pk = -pk;

};

//Step 2:

while (dfitd(x_prev,pk)*dfitd(xk,pk) > 0)

{

x_prev = xk;

xk = xk + pk*ak;

ak = ak*2;

}

//Step 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;

};

//cout << "Intervals finded of Svenn-4 method:" << endl;

// x_a.printPoint();

// x_b.printPoint();

//end of Svenn-4;

xa = x_a;

xb = x_b;

}

/////////////////////////Davidon's method//////////////////////////////

double FindAlpha(const Point &pk1,const Point &xk1,double eps)

{

//Davidon method:

//Initial Stage:

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));

//cout << ak <<endl;

Point xa(k);

Point xb(k);

Svenn4(dy1,pk,xk,ak,xb,xa);

//Basic Stage:

//Step I:

double dya=dfdp(xa,pk);

double dyb=dfdp(xb,pk);

double z=dya+dyb+3*(f(xb)-f(xa))/SegmentLength(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;

//Step II:

while ((fabs(dfdp(r,pk))>eps) && (fabs(SegmentLength(xa,r))>eps) && (fabs(SegmentLength(r,xb))>eps))

{

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))/SegmentLength(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;

}

return al_r;

}

////////////////////////////KOP////////////////////////////////////////

bool KOP(const Point &x,double epsilon)

{

bool stop=false;

Point temp(k);

temp=df(x);

if (temp.norma()<epsilon)

{

stop=true;

}

return stop;

}

/////////////////////////ON_method///////////////////////////////////

Point ON(double *xk1,double eps)

{

//Initial Stage:

Point xk(k);

xk.setPoint(xk1);

int count=1;

int M=100;

//Basic Stage:

//Step I:

double H1[3][3] = {{0.5, 0,0},{0,0.5,0},{0,0,0.125}}; //obratnaya = Gesse^(-1)

Point dy = df(xk);

Point pk(k);

pk[0]=-(H1[0][0]*dy[0]+H1[0][1]*dy[1]+H1[0][2]*dy[2]);

pk[1]=-(H1[1][0]*dy[0]+H1[1][1]*dy[1]+H1[1][2]*dy[2]);

pk[2]=-(H1[2][0]*dy[0]+H1[2][1]*dy[1]+H1[2][2]*dy[2]);

//pk.printPoint();

//getchar();

//Step II:

double alpha;

cout << "Please input alpha: " << endl;

cin >> alpha;

xk = xk + pk*alpha;

count++;

while ((KOP(xk,eps)==false) && (count < M))

{

dy = df(xk);

pk[0]=-(H1[0][0]*dy[0]+H1[0][1]*dy[1]+H1[0][2]*dy[2]);

pk[1]=-(H1[1][0]*dy[0]+H1[1][1]*dy[1]+H1[1][2]*dy[2]);

pk[2]=-(H1[2][0]*dy[0]+H1[2][1]*dy[1]+H1[2][2]*dy[2]);

alpha = FindAlpha(pk,xk,0.001);

xk = xk + pk*alpha;

xk.printPointEx("TmpCoordinates");

count++;

}

cout << "ON iteration counts: "<< count <<endl;

return xk;

}

/////////////////////////////////////////////////////////////////////