Скачиваний:
2
Добавлен:
01.05.2014
Размер:
7.14 Кб
Скачать
//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
  • #
    01.05.20144.46 Кб2ObobshNuton.dsp
  • #
    01.05.2014547 б2ObobshNuton.dsw
  • #
    01.05.201482.94 Кб2ObobshNuton.ncb
  • #
    01.05.201454.78 Кб2ObobshNuton.opt
  • #
    01.05.20141.23 Кб2ObobshNuton.plg
  • #
    01.05.20147.14 Кб2ON.CPP
  • #
    01.05.20143.97 Кб2Point1.cpp
  • #
    01.05.20141.41 Кб2Point1.h
  • #
    01.05.2014456 б2resource.h
  • #
    01.05.20142.14 Кб2Script1.rc