Лабораторные работы №4 и №5 / Л.р.4-5
.docСанкт-петербургский Электротехнический Университет
«ЛЭТИ»
Кафедра САПР
Отчет по лабораторным работам
№ 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