Skip to content

Instantly share code, notes, and snippets.

Created April 27, 2012 16:14
Show Gist options
  • Save anonymous/2510507 to your computer and use it in GitHub Desktop.
Save anonymous/2510507 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#define n 2
double sqr(double x) {return x*x;};
double absm(double x) {return (x>0)?x:-x;}
class point
{
public:
point(double a,double b) {x=a;y=b;};
point(){x=0;y=0;};
point(const point& a){x=a.x;y=a.y;};
double x,y;
point operator+(const point& a) {point tmp(this->x+a.x,this->y+a.y);return tmp;};
point operator=(const point& a) {x=a.x;y=a.y;point tmp(a.x,a.y);return tmp;};
point operator-(const point& a) {point tmp(this->x-a.x,this->y-a.y);return tmp;};
double operator*(const point& a){return this->x*a.x+this->y*a.y;};
point operator*(const double a) {point tmp(this->x*a,this->y*a);return tmp;};
point operator/(const double a) {point tmp(this->x/a,this->y/a);return tmp;};
double len() {return sqrt(sqr(x)+sqr(y));};
void print() {printf("%.4f %.4f %.4f\n",x,y,len());};
};
point xk,uk;
double func(double x,double y)
{
//return 8*x*x -4*x*y+5*y*y+8*sqrt(5)*(x+2*y)+64;
//return (4*x*x+3*y*y+4*x*y*y+x);
return ((x*x+y-11)*(x*x+y-11)+((x+y*y-7)*(x+y*y-7)));
}
double m1dfunc(double x)
{
return func(xk.x+x*uk.x,xk.y+x*uk.y);
}
double dichotomy(double a, double b,double eps,double prec)
{
double xk1,xk2;
while( (b-a)>eps )
{
xk1=(a+b)/2-prec;
xk2=(a+b)/2+prec;
if(m1dfunc(xk1)<m1dfunc(xk2))
{
if(b!=xk2) {b=xk2;}
else {break;}
}
else
{
if(a!=xk1){ a=xk1;}
else {break;}
}
}
return (a+b)/2;
}
void rosenbrouke(double eps, point fp)
{
double cappa[n],gamma;
point tmp;
point* basis[n], *a[n], *b[n];
basis[0]=new point(1,0); //сначала базис совпадает со стандартным
basis[1]=new point(0,1);
a[0]=new point(0,0);
a[1]=new point(0,0);
b[0]=new point(0,0);
b[1]=new point(0,0);
//нормальные к-ые точки (используются после исчерпывающего спуска)
point curx=fp;
//x с волной и с нижним индексом-промежуточные точки
point wavex=fp;
int k=1;
while(1)
{
for(int j=0;j<n;j++)
{
xk=wavex;
uk=*basis[j];
cappa[j]=dichotomy(-1,2,0.0001,0.0001);
// printf("cappa[%d]=%.4f\n",j,cappa[j]);
// wavex.print();
wavex=(wavex+*basis[j]*cappa[j]);
// wavex.print();
}
tmp=wavex-curx;
if(tmp.len()<eps) {break;}
else {curx=wavex;}
printf("%d: [%.4f %.4f] f=%.4f\n",k,curx.x,curx.y,func(curx.x,curx.y));
for(int j=0;j<n;j++)
{
if(absm(cappa[j])<eps*0.01) a[j]=basis[j];
else
{
a[j]->x=0;a[j]->x=0;
for(int i=j;i<n;i++)
{
(*a[j])=(*basis[i])*cappa[i]+(*a[j]);
}
}
}
b[0]=a[0];
gamma=b[0]->len();
(*basis[0])=(*b[0])/gamma;
for(int j=1;j<n;j++)
{
b[j]=a[j];
for(int i=0;i<j;i++)
{
gamma=(*a[j])*(*basis[i]);
*b[j]=*b[j]-*basis[i]*gamma;
}
gamma=b[j]->len();
*basis[j]=*b[j]/gamma;
}
k++;
wavex=curx;
}
printf("\nResult: [%.4f %.4f] f=%.4f\n",curx.x,curx.y,func(curx.x,curx.y));
getch();
}
int main()
{
point pnt(0,0);
rosenbrouke(0.00001,pnt);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment