Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
9
Добавлен:
01.05.2014
Размер:
119.3 Кб
Скачать

Санкт-петербургский Электротехнический Университет

«ЛЭТИ»

Кафедра САПР

Отчет по лабораторным работам

4, 5

«Простые градиентные методы»

Выполнил: Гладилин Г.А.

Группа: 3372

Руководитель: Дмитриевич Г.Д.

Санкт-Петербург

2006

Цель работы:

Разработка программы многомерной минимизации целевых функций на основе применения простых градиентных методов поиска.

Целевая функция:

f(x)=8x12 + 4x1x2 + 5x22 (стартовая точка: (10,10))

Реализуемый метод:

Овражный метод

Н.Э.

О.Э.

Шаг 1.

Шаг 2. , - расчитывается любым методом

Шаг 3. , - расчитывается любым методом

КОП:

Результат работы программе на целевой функции:

OvragMethod started...

Grad started

Grad return: 4.00001 8.00000

Bolcano started...

Swann started...

Swann return: a = 0.0512, b = 0.2048, cdp = 0

Bolcano return: 0.125075

Bolcano started...

Swann started...

Swann return: a = 0.0512, b = 0.2048, cdp = 1

Bolcano return: -0.150275

Grad started

Grad return: -0.00000 -0.00540

Grad started

Grad return: -0.00000 -0.00540

Bolcano started...

Swann started...

Swann return: a = 0.0512, b = 0.2048, cdp = 0

Bolcano return: 0.100025

Bolcano started...

Swann started...

Swann return: a = 0.0512, b = 0.2048, cdp = 1

Bolcano return: -0.134975

Grad started

Grad return: 0.00000 -0.00054

OvragMethod return-0.00002 -0.00006

Lab's result = -0.00002 -0.00006

Используемые программой модули:

Vector.h – описание класса вектора

Matrix.h – описание класса матрицы

Methods.h – описание методов и операций с функциями

Приложение 1.

Листинг программы.

(labs.cpp)

#define METHODS_LOG_ON

#define METHODS_MAX_LOG_SIZE 1000

#define METHODS_MAX_CALLS 100

#include "methods.h"

#include "machines.h"

#include "machines.h"

double f(clVector& a){

return 8*pow(a[0],2)+5*pow(a[1],2)-4*a[0]*a[1];

return pow(a[0],2)+pow(a[1],2);

}

int main(void)

{

char output[300];

clVector x(2);

x[0]=0.5;

x[1]=1;

clVector p(2);

p=OvragMethod(f,x);

std::cout<<"\n Lab's result = "<<(output<<p);

return 0;

}

Приложение 2.

Листинг используемых модулей.

(vector.h)

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

//

// File: vector.h

//

// Contents:

//

// Create: 05.03.2005

// Version: 1.2

// Author: German Gering

//

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

//

// Changes:

//

// Data EV Contents Author

// ---------- ------- -------------------------- -------------------------

//

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

#ifndef _VECTORS_H_

#define _VECTORS_H_

#include "matrix.h"

#include "math.h"

#include <iostream>

class clVector{

friend class clMatrix;

private:

unsigned dimension;

double *coords;

public:

clVector(void);

clVector(clVector&);

clVector(unsigned);

clVector(double*,unsigned);

clVector& operator = (clVector&);

clVector& operator +=(clVector&);

clVector& operator -=(clVector&);

clVector& operator *=(double);

clVector& operator /=(double);

clVector operator + (clVector&);

clVector operator - (clVector&);

double operator * (clVector&);

clVector operator - (void);

clVector operator * (double a);

double & operator [](unsigned);

unsigned Length(void);

~clVector();

};

double abs(clVector);

char* operator << (char*, clVector&);

clVector& operator << (clVector&, char*);

clVector::clVector(void){

dimension=0;

coords=NULL;

}

clVector::clVector(unsigned dim){

dimension=dim;

coords=new double[dimension];

}

clVector::clVector(double *val, unsigned dim){

dimension=dim;

coords=new double[dimension];

for(unsigned i=0;i<dim;i++)

coords[i]=val[i];

}

clVector::clVector(clVector& a){

dimension=a.dimension;

coords = new double[dimension];

for(unsigned i=0;i<dimension;i++)

coords[i]=a.coords[i];

}

clVector& clVector::operator =(clVector &a){

if(coords!=a.coords){

if(dimension!=a.dimension){

if(coords)

delete [] coords;

dimension=a.dimension;

coords=new double[dimension];

}

for(unsigned i=0;i<dimension;i++)

coords[i]=a.coords[i];

}

return *this;

}

clVector& clVector::operator +=(clVector &a){

for(unsigned i=0;i<dimension;i++)

coords[i]+=a.coords[i];

return *this;

}

clVector& clVector::operator -=(clVector &a){

for(unsigned i=0;i<dimension;i++)

coords[i]-=a.coords[i];

return *this;

}

clVector& clVector::operator /=(double a){

for(unsigned i=0;i<dimension;i++)

coords[i]/=a;

return *this;

}

clVector& clVector::operator *=(double a){

for(unsigned i=0;i<dimension;i++)

coords[i]*=a;

return *this;

}

clVector clVector::operator +(clVector &a){

clVector nv=*this;

for(unsigned i=0;i<dimension;i++)

nv.coords[i]+=a.coords[i];

return nv;

}

clVector clVector::operator -(clVector &a){

clVector nv=*this;

for(unsigned i=0;i<dimension;i++)

nv.coords[i]-=a.coords[i];

return nv;

}

clVector clVector::operator -(void){

clVector nv=*this;

for(unsigned i=0;i<=dimension;i++)

nv.coords[i]=-coords[i];

return nv;

}

clVector clVector::operator *(double a){

clVector nv=*this;

for(unsigned i=0;i<this->dimension;i++)

nv.coords[i]*=a;

return nv;

}

double clVector::operator * (clVector& a){

if(a.dimension!=dimension)

return -1;

double _t=0;

for(unsigned i=0;i<dimension;i++)

_t+=coords[i]*a.coords[i];

return _t;

}

inline unsigned clVector::Length(void){

return dimension;

}

inline double& clVector::operator [](unsigned index){

return coords[index];

}

clVector::~clVector(){

dimension=0;

delete [] coords;

coords=NULL;

}

inline double abs(clVector a){

double p=0;

for(unsigned i=0;i<a.Length();i++)

p+=pow(a[i],2);

return sqrt(p);

}

char * operator << (char* buf,clVector& a){

sprintf(buf,"");

unsigned N=a.Length();

for(unsigned i=0;i<N;i++)

sprintf(buf,"%s%5.5lf ",buf,a[i]);

return buf;

}

clVector& operator << (clVector& a,char *buf){

char *p=strdup(buf);

char *t;

unsigned n=a.Length();

t=strtok(p," ,\0");

for(unsigned i=0;i<n;i++){

a[i]=atof(t);

t=strtok(NULL," ,");

}

free(p);

return a;

}

#endif

(matrix.h)

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

//

// File: matrix.h

//

// Contents:

//

// Create: 05.03.2005

// Version: 1.1

// Author: German Gering

//

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

//

// Changes:

//

// Data EV Contents Author

// ---------- ------- -------------------------- -------------------------

//

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

#ifndef _MATRIX_H_

#define _MATRIX_H_

#include "vector.h"

class clMatrix{

private:

clVector *Lines;

unsigned N,M;

public:

clMatrix(void);

clMatrix(unsigned);

clMatrix(unsigned,unsigned);

clMatrix(double **,unsigned,unsigned);

clMatrix(clMatrix&);

clMatrix&operator = (clMatrix&);

clMatrix&operator +=(clMatrix&);

clMatrix&operator -=(clMatrix&);

clMatrix&operator *=(clMatrix&);

clMatrix&operator /=(clMatrix&);

clMatrix operator + (clMatrix&);

clMatrix operator - (clMatrix&);

clMatrix operator * (clMatrix&);

clMatrix operator / (clMatrix&);

clMatrix operator - (void);

clVector& operator [](unsigned);

void GetSize(unsigned&, unsigned&);

unsigned GetN(void);

unsigned GetM(void);

~clMatrix(void);

};

clMatrix div(clMatrix &);

double det(clMatrix &);

double gausdet(clMatrix &);

char * operator << (char *, clMatrix&);

clMatrix& operator << (clMatrix&, char *);

clMatrix::clMatrix(void){

N=0;

Lines=NULL;

}

clMatrix::clMatrix(unsigned N_, unsigned M_){

clVector ex(M_);

N=N_;

M=M_;

Lines=new clVector[N];

for(unsigned i=0;i<N;i++)

Lines[i]=ex;

}

clMatrix::clMatrix(double **array_, unsigned N_, unsigned M_){

clMatrix(N_,M_);

for(unsigned i=0;i<N_;i++)

for(unsigned j=0;j<M_;j++)

Lines[i].coords[j]=array_[i][j];

}

clMatrix::clMatrix(clMatrix &a){

N=a.N;

M=a.M;

Lines=new clVector[N];

for(unsigned i=0;i<N;i++)

Lines[i]=a.Lines[i];

}

clMatrix& clMatrix::operator = (clMatrix& a){

unsigned aN,aM;

a.GetSize(aN,aM);

if(a.Lines!=Lines){

if(N!=a.N){

delete [] Lines;

N=a.N;

Lines=new clVector[N];

}

for(unsigned i=0;i<N;i++)

Lines[i]=a.Lines[i];

}

return *this;

}

clMatrix& clMatrix::operator +=(clMatrix& a){

for(unsigned i=0;i<N;i++)

Lines[i]+=a.Lines[i];

return *this;

}

clMatrix& clMatrix::operator -=(clMatrix& a){

for(unsigned i=0;i<N;i++)

Lines[i]-=Lines[i];

return *this;

}

clMatrix& clMatrix::operator *=(clMatrix& a){

for(unsigned i=0;i<N;i++)

for(unsigned k=0;k<a.M;k++){

Lines[i].coords[k]=0;

for(unsigned j=0;j<M;j++)

Lines[i].coords[k]+=Lines[i].coords[j]*a.Lines[j].coords[k];

}

return *this;

}

clMatrix& clMatrix::operator /=(clMatrix& a){

*this*=div(a);

return *this;

}

clMatrix clMatrix::operator + (clMatrix& a){

clMatrix nm(N,M);

for(unsigned i=0;i<N;i++)

nm.Lines[i]=this->Lines[i]-a.Lines[i];

return nm;

}

clMatrix clMatrix::operator - (clMatrix& a){

clMatrix nm(N,M);

for(unsigned i=0;i<N;i++)

nm.Lines[i]=Lines[i]-a.Lines[i];

return nm;

}

clMatrix clMatrix::operator * (clMatrix& a){

clMatrix nm(N,a.M);

for(unsigned i=0;i<N;i++)

for(unsigned k=0;k<a.M;k++){

nm.Lines[i].coords[k]=0;

for(unsigned j=0;j<M;j++)

nm.Lines[i].coords[k]+=Lines[i].coords[j]*a.Lines[j].coords[k];

}

return nm;

}

clMatrix clMatrix::operator / (clMatrix& a){

clMatrix nm=div(a);

nm*=*this;

return nm;

}

clMatrix clMatrix::operator -(void){

clMatrix nm(N,M);

for(unsigned i=0;i<N;i++)

nm.Lines[i]=-this->Lines[i];

return nm;

}

clVector& clMatrix::operator [](unsigned index){

return Lines[index];

}

void clMatrix::GetSize(unsigned &N_,unsigned &M_){

N_=N;

M_=M;

}

unsigned clMatrix::GetN(void){

return N;

}

unsigned clMatrix::GetM(void){

return M;

}

clMatrix::~clMatrix(void){

N=0;

M=0;

delete [] Lines;

}

clMatrix div(clMatrix &a_){

unsigned n,i,k;

a_.GetSize(n,n);

clMatrix a(n,n);

for(i=0;i<n;i++)

for(k=0;k<n;k++)

a[i][k]=(i==k);

double t;

for(i=0;i<n;i++){

if(a[i][i]!=0){

t=a_[i][i];

a[i]/=t;

a_[i]/=t;

if(i>0)

for(k=0;k<i;k++){

a[k]=a[k]+a[i]*(-a_[k][i]);

a_[k]=a_[k]+a_[i]*(-a_[k][i]);

}

for(k=i+1;k<n;k++){

a[k]=a[k]+a[i]*(-a_[k][i]);

a_[k]=a_[k]+a_[i]*(-a_[k][i]);

}

}

}

return a;

}

double det(clMatrix &a_){

unsigned n,k,i;

double res=1;

clMatrix a=a_;

a.GetSize(n,n);

double t;

for(i=0;i<n;i++){

if(a[i][i]!=0){

t=-1/a[i][i];

if(i>0)

for(k=0;k<i;k++)

a[k]=a[k]+a[i]*(a[k][i]*t);

for(k=i+1;k<n;k++)

a[k]=a[k]+a[i]*(a[k][i]*t);

}

}

for(i=0;i<n;i++)

res*=a[i][i];

return res;

}

double gausdet(clMatrix &matrix){

double res=0,sign=-1;

unsigned i,k,j,n;

matrix.GetSize(n,n);

if(n==1)

res=matrix[0][0];

else

if(n<=2)

res=matrix[0][0]*matrix[1][1]-matrix[0][1]*matrix[1][0];

else{

clMatrix m(n-1,n-1);

for(i=0;i<n;i++){

for(j=0;j<n;j++)

for(k=1;k<n;k++){

if(j<i)

m[k-1][j]=matrix[k][j];

if(j>i)

m[k-1][j-1]=matrix[k][j];

}

sign*=-1;

res=res+matrix[0][i]*sign*det(m);

}

}

return res;

}

char * operator << (char* buf,clMatrix& a){

sprintf(buf,"");

unsigned N,M;

a.GetSize(N,M);

for(unsigned i=0;i<N;i++){

for(unsigned k=0;k<M;k++){

sprintf(buf,"%s%5.5lf ",buf,a[i][k]);

}

sprintf(buf,"%s%c",buf,'\n');

}

return buf;

}

clMatrix& operator << (clMatrix& a,char *buf){

char *p=strdup(buf);

char *t;

unsigned m=a.GetM(),n=a.GetN();

t=strtok(p," ,");

for(unsigned i=0;i<n;i++)

for(unsigned k=0;k<m;k++){

a[i][k]=atof(t);

t=strtok(NULL," ,");

}

free(p);

return a;

}

#endif

(methods.h)

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

//

// File: methods.h

//

// Contents:

//

// Create: 14.03.2006

// Version: 1.3

// Author: German Gering

//

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

//

// Changes:

// ==========+=======+======================================+================

// Data |EV > FV|Contents | Author

// ==========+=======+======================================+================

// 16.03.2006|1.2>1.3| 1)В методы добавлена возможность | German Gering

// | | логирования результатов, для чего |

// | | перед подключением файла выполнить |

// | | #define METHODS_LOG_ON и |

// | | #define METHODS_MAX_LOG_SIZE <size> |

// ----------+-------+--------------------------------------+----------------

// 14.03.2006|1.1>1.2| 1)Swann4 переделан в универльный | German Gering

// | | метод Swann. Добавлен метод SwannD |

// | | 2)Введено понятие базис простраства |

// | | и функции его инициализации |

// | | 3)Добавлены градиентные методы: |

// | | [Овражный метод], [Метод Коши] |

// ----------+-------+--------------------------------------+----------------

// 05.03.2006|1.0>1.1| 1)Реорганизация функций | German Gering

// ==========+=======+======================================+================

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

//

//

// double min(double, double) -- inline

// Возвращает минимум из двух чисел.

//

// double max(double, double) -- inline

// Возвращает максимум из двух чисел.

//

// clVector Grad( double (*f)(clVector&),

// clVector &x,

// double STEP=1e-6)

// Расчитывает градиент функции f в точке х. STEP -- "точность".

//

// void initND(unsigned N)

// Инициализирует базис (N+1)-мерного пространства, запролняя его по-умолчаниею:

// ,------N------,

// e[i]={0,..,0,1,0,..,0}. Необходимо для удобства работы с многомерными

// ^i позиция

// в 2х мерном пространстве: производится вызов с параметром 1 и фукции D,

// Swann, SwannD и т.п. используются с параметром по-умолчанию.

//

// void closeND(void)

// Удаляет базис (N+1)-мерного пространства.

//

// double D( double (*f)(clVector &),

// clVector &x,

// clVector &p=basis[0],

// double STEP=1e-6)

// Расчитывает производную функции f в точке x по направлению p. Направление

// по умолчанию -- первый орт простанства. Чтобы использовать направление по

// умолчанию необходимо инициализировать базис простанства. STEP -- "точность".

//

// int Swann( double &a,

// double &b,

// double(*f)(clVector &),

// clVector &x,

// clVector &p_=basis[0],

// double ALPHA=1e-4)

// Расчитывает отрезок [a,b], на котором далее будет производится поиск,

// с начальной точки x по направлению p. Направление по-молчанию -- первый

// орт пространства. Чтобы использовать направление по умолчанию необходимо

// инициализировать базис пространства. ALPHA -- "точность". Возвращает 0 или

// 1, если для нахождения [a,b] направление было изменено на противоположное.

//

// double Davidon( double(*f)(clVector &),

// clVector &x,

// clVector &p_=basis[0],

// double EPS=1e-4)

// Расчитывает доставляющий в минимум шаг для функции f из точки x по

// направлению p_. Направление по-умолчанию -- первый орт пространства. Чтобы

// использовать направление по умолчанию необходимо инициализировать базис

// пространства.

//

// clVector OvragMethod( double(*f)(clVector &),

// clVector &x,

// double EPS1=1e-3,

// double EPS2=1e-3)

// Расчитывает минимум функции со стартовой точки x с момощью [Овражный метод]

// с точностями EPS1 и EPS2 соответственно.

//

// clVector Koshi( double(*f)(clVector &),

// clVector &x,

// unsigned MaxIterationNumber=100,

// double EPS=1e-3)

// Расчитывает минимум функции со стартовой точки x с помощью [Метод Коши]

// с придельным колличеством итерация MaxIterationNumber и точность EPS.

#ifndef _METHODS_H_

#define _METHODS_H_

#include "matrix.h"

clMatrix basis;

#ifdef METHODS_LOG_ON

char output[METHODS_MAX_LOG_SIZE];

unsigned long LOG_COUNTER=0;

char spaces[METHODS_MAX_CALLS]={0};

char *putspaces(unsigned N){

strcpy(spaces,"");

for(unsigned i=0;i<N;i++)

sprintf(spaces,"%s ",spaces);

return spaces;

}

#endif

double min(double, double);

double max(double, double);

void initND(unsigned);

void closeND(void);

clVector Grad(double (*)(clVector&), clVector &, double);

double D(double (*)(clVector &), clVector &, clVector &, double);

int Swann(double &, double &, double(*)(clVector &),clVector &, clVector &, double);

double Davidon(double(*)(clVector &),clVector &, clVector &, double);

double Bolcano(double(*)(clVector &),clVector &, clVector &, double);

clVector OvragMethod(double(*)(clVector &),clVector &, double, double);

void initND(unsigned N){

basis.clMatrix::clMatrix(N,N);

for(unsigned i=0;i<N;i++)

for(unsigned k=0;k<N;k++)

if(i==k)

basis[i][k]=1;

else

basis[i][k]=0;

}

void closeND(void){

basis.clMatrix::~clMatrix();

}

inline double min(double a, double b){

return a>b?b:a;

}

inline double max(double a, double b){

return a>b?a:b;

}

clVector Grad(double (*f)(clVector&), clVector &x, double STEP = 1e-6){

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(LOG_COUNTER++)<<"Grad started";

#endif

clVector g(x.Length());

clVector y(x);

for(unsigned i=0;i<x.Length();i++){

if(i>0)

y[i-1]-=STEP;

y[i]+=STEP;

g[i]=(f(y)-f(x))/STEP;

}

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"Grad return: "<<(output<<g);

#endif

return g;

}

double D(double (*f)(clVector &),clVector &x,clVector &p=basis[0], double STEP = 1e-6){

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(LOG_COUNTER++)<<"D started";

#endif

double res=(Grad(f,x,STEP))*p;

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"D return: "<<res;

#endif

return res;

}

int Swann(double &a, double &b, double(*f)(clVector &),clVector &x, clVector &p_=basis[0], double ALPHA=1e-4){

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(LOG_COUNTER++)<<"Swann started... ";

#endif

int cdp=0;

double ga=ALPHA;

clVector p(p_);

if(f(x+p*ga)<f(x+p*(ga*2))){

p*=-1;

cdp=1;

}

while(f(x+p*ga)>f(x+p*(ga*2)))

ga*=2;

a=min(ga/2,ga*2);

b=max(ga/2,ga*2);

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"Swann return: a = "<<a<<", b = "<<b<<", cdp = "<<cdp;

#endif

return cdp;

}

int SwannD(double &a, double &b, double(*f)(clVector &),clVector &x, clVector &p_=basis[0], double ALPHA=1e-4){

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(LOG_COUNTER++)<<"SwannD started... ";

#endif

int cdp=0;

double ga=ALPHA;

clVector p(p_);

if(D(f,x,p)>0){

p*=-1;

cdp=1;

}

while(D(f,x+p*ga,p)*D(f,x+p*(ga*2),p)>0)

ga*=2;

a=min(ga-cdp*2*ga,(ga-cdp*2*ga)*2);

b=max(ga-cdp*2*ga,(ga-cdp*2*ga)*2);

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"SwannD return: a = "<<a<<", b = "<<b<<", cdp = "<<cdp;

#endif

return cdp;

}

double Davidon(double(*f)(clVector &),clVector &x, clVector &p_=basis[0], double EPS=1e-4){

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<(putspaces(LOG_COUNTER++))<<"Davidon started...";

#endif

double z, w, g, m;

double a, b, a_,b_;

short int done=0;

clVector p(p_);

if(Swann(a_,b_,f,x,p)){

a=-b_;

b=-a_;

} else {

a=a_;

b=b_;

}

while(!done){

z=D(f,x+p*a,p)+D(f,x+p*b,p)+3*((f(x+p*a)+f(x+p*b))/b);

w=sqrt(pow(z,2) - D(f,x+p*a,p)*D(f,x+p*b,p));

g=(z-D(f,x+p*a,p)+w)/(D(f,x+p*b,p)-D(f,x+p*a,p)+2*w);

m=a+g*(b-a);

done=((fabs(D(f,x+p*m,p))< EPS)||(m==a)||(m==b));

if(!done)

if(D(f,x+p*m,p)>0) {

b=m;

} else {

a=m;

}

}

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"Davidon return: "<<m;

#endif

return m;

}

double Bolcano(double(*f)(clVector &),clVector &x, clVector &p_=basis[0], double EPS=1e-4){

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(LOG_COUNTER++)<<"Bolcano started...";

#endif

double a,b,z,a_,b_;

clVector p(p_);

if(Swann(a_,b_,f,x,p)){

a=-b_;

b=-a_;

} else {

a=a_;

b=b_;

}

while(fabs(b-a)>EPS){

z=(a+b)/2;

if(D(f,x+p*z,p)>0)

b=z;

else

a=z;

}

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"Bolcano return: "<<z;

#endif

return z;

}

clVector OvragMethod(double(*f)(clVector &),clVector &x, double EPS1=1e-3, double EPS2=1e-3){

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(LOG_COUNTER++)<<"OvragMethod started...";

#endif

clVector x1m(x.Length()),x1r(x.Length()),x3(x);

clVector d(x.Length()),stop(x.Length()),x2r(x.Length()),x2m(x.Length());

clVector dir(x.Length());

double ga;

do{

x1r=x3;

x1m=x3; x1m[0]+=EPS1;

dir=-Grad(f,x1r);

//ga=Davidon(f,x1r,dir);

ga=Bolcano(f,x1r,dir);

x2r=x1r+dir*ga;

//if(abs(Grad(f,x2r))>EPS2){ //личная модификация

x2m=x1m+dir*ga;

d=x2r-x2m;

//ga=Davidon(f,x2r,d);

ga=Bolcano(f,x2r,d);

x3=x2r+d*ga;

//}

stop=Grad(f,x3);

}while(abs(stop)>EPS2);

#ifdef METHODS_LOG_ON

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"OvragMethod return"<<(output<<x3);

#endif

return x3;

}

clVector Koshi(double(*f)(clVector &),clVector &x, unsigned MaxIterationNumber=100, double EPS=1e-3){

#ifdef METHODS_LOG_ON

unsigned long CUR_COUNTER;

std::cout<<"\n"<<(CUR_COUNTER=LOG_COUNTER++)<<"Koshi started";

#endif

clVector res(x),p(x.Length());

double ga;

unsigned IterationCounter=0;

while(abs(Grad(f,res))>EPS){

p=Grad(f,res); p*=-1;

ga=Bolcano(f,res,p);

res+=(p*ga);

IterationCounter++;

if(IterationCounter>=MaxIterationNumber){

#ifdef METHODS_LOG_ON

char output[1000];

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"Koshi faild. Last res = "<<(output<<res);

#endif

return res;

}

}

#ifdef METHODS_LOG_ON

char output[1000];

std::cout<<"\n"<<putspaces(--LOG_COUNTER)<<"Koshi return"<<(output<<res);

#endif

return res;

}

#endif