Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №9 / itog1
.cpp#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <cmath>
#include<iostream>
#include "math.h"
#define min(a,b) (((a)>(b))?(b):(a))
#define max(a,b) (((a)<(b))?(b):(a))
double error=-9999;
unsigned int vusov=0;
#define adr unsigned long
#define right(p) (((adr )p!=NULL))
// структура для вектора
class vect {
public:
unsigned short n; //длина вектора
double * x;
vect() {n=0; x=0;} //конструктор по умолчанию
vect(unsigned short dlin) {n=dlin;if(n!=0) x=new double [n];else x=0;} //создание вектора длины n без инициализации
vect (vect &a) //конструктор копирования
{
n=a.n;
if(n)
{
x=new double [n];
memcpy(x,a.x,n*sizeof(double));
}
else x=0;
}
vect operator = (vect &a)
{
n=a.n;
if(n) x=new double [n]; else x=0;
if(n) memcpy(x,a.x,n*sizeof(double));
return *this;
}
vect mult(double c) //метод класса, для умножения вектора на число
{
vect itog(n) ;
for(int i=0;i<n;i++)
{
itog.x[i]=x[i]*c;
}
return itog;
}
vect sum(vect a) //метод класса, для подсчета суммы векторов
{
if(a.n!=n)
{
printf("Error in sum");
return vect(0);
}
vect itog(n) ;
for(int i=0;i<n;i++)
{
itog.x[i]=x[i]+a.x[i];
}
return itog;
}
vect razn(vect a) //метод класса, для подсчета разности векторов
{
if(a.n!=n)
{
printf("Dif vectors with diff. dimensions");
return vect(0);
}
vect itog(n) ;
for(int i=0;i<n;i++)
{
itog.x[i]=x[i]-a.x[i];
}
return itog;
}
double pr_ch(vect b)// метод для перемножения векторов
{
if(n!=b.n)
{
printf("Dif vectors with diff. dimensions");
return 0;
}
double itog=0;
for(int i=0;i<n;i++)
{
itog=itog+x[i]*b.x[i];
}
return itog;
}
double norm()//подсчет нормы вектора
{
double res=0;
for(int i=0; i<n;i++)
res+=x[i]*x[i];
res=sqrt(res);
return res;
}
};
class matr
{
public:
unsigned short n;
double * x;
matr(unsigned short dlin=0) {n=dlin; if(n) x=new double[n*n];else x=0;}
matr (matr &a) // метод для копирования матриц
{
n=a.n;
if(n) x=new double [n*n]; else x=0;
if(n) memcpy(x,a.x,n*n*sizeof(double));
}
matr operator = (matr &a)// метод для копирования матриц
{
n=a.n;
if(n) x=new double [n*n]; else x=0;
if(n) memcpy(x,a.x,n*n*sizeof(double));
return *this;
}
double & e(unsigned short i,unsigned short j )// метод для определения элемента матрицы
{
if(i>n || j>n )
{printf("Error in e"); return error; }
return x[i*n+j];
}
~matr() {if(right(x)) delete [] x;n=0;x=0;}
matr multm(matr &a, matr &res)// метод для перемножения матриц
{
if(a.n!=n){printf("Error - Mult matrix - different dimensions"); return matr(0);}
memset(res.x,0,n*n*sizeof(double));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0; k<n; k++)
res.e(i,j)+=e(i,k)*a.e(k,j);
}
}
return res;
}
matr sum(matr a, matr b)// метод для сложения матриц
{
if(a.n!=b.n)
{
printf("Error - Sum matrix - different dimensions");
return matr(0);
}
matr itog(n);
for(int i=0;i<n*n;i++)
{
itog.x[i]=a.x[i]+b.x[i];
printf("i=%d x[i]=%f",i,x[i]);
}
return itog;
}
matr mult(double c)// метод для перемножения матрицы на число
{
int ind=0;
matr itog(n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
itog.x[ind]=x[ind]*c;
ind++;
}
}
return itog;
}
vect mult(vect &a)// метод для перемножения матрицы на столбец
{
if(a.n!=n){printf("Error in mult matrix"); return vect(0);}
vect res(n);
memset(res.x,0,sizeof(double)*n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
res.x[i]+=e(i,j)*a.x[j];
}
}
return res;
}
matr pr_m(vect a,vect b)// метод для перемножения векторов
{
if(a.n!=b.n)
{
printf("Dif vectors with diff. dimensions");
return matr(0);
}
matr itog(a.n);
int ind=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
itog.x[ind]=a.x[i]*b.x[j];
ind++;
}
}
return itog;
}
};
int z=0;//выбор функции
int dlin;//число переменных
double y(vect &v)//заданные функции
{
vusov++;
if(z==1)return v.x[0]*v.x[0]*v.x[0]+v.x[1]*v.x[1]-3*v.x[0]-2*v.x[1]+2;
if(z==2)return (v.x[1]-v.x[0]*v.x[0])*(v.x[1]-v.x[0]*v.x[0])+(1-v.x[0])*(1-v.x[0]);
}
//функция для прехода в новую точку вдоль линии
double next(double a, vect &x0, vect &p)
{
return y(x0.sum(p.mult(a)));//y(x+p*a)
}
//функция для расчёта производной
double dy(double a, vect &x0, vect & p)
{
double e=0.000000000001;
return (next(a+e/2,x0,p)-next(a-e/2,x0,p))/e;
}
//функция для расчёта градиента
inline vect grad(vect & point)
{
double e=0.000000000001;
vect res(point.n);
vect temp(point.n);
for(int i=0; i<point.n;i++)
{
memcpy(temp.x,point.x,point.n*sizeof(double));
temp.x[i]+=e;
res.x[i]=(y(temp)-y(point))/e;
}
return res;
}
// метод Свенна 4
void Swann4(double a0,vect &x0, vect & p, double &x1, double &x2)
{
double x=0,y1,y2;
if(dy(a0,x0,p)>0) a0=-a0;
y1=dy(a0,x0,p);
do
{
a0*=2;
y2=dy(a0,x0,p);
}while(y1*y2>0);
x1=min(a0,a0/2);
x2=max(a0,a0/2);
/*printf("\n x1= %f",x1);
printf("\n x2= %f",x2);*/
}
// метод Дэвидона
vect Davidon(vect &x0, vect & p, double *al)
{
vect res(x0.n);
double e=0.0000001;
double a,b;
Swann4(0.00000001, x0, p,a,b);
double x1=0,x12=0, z=0, w=0,delta=0;
do{
z =dy(a,x0,p)+dy(b,x0,p)+3*(next(a,x0,p)-next(b,x0,p))/(b-a);
w =sqrt(z*z-dy(a,x0,p)*dy(b,x0,p));
delta =(z-dy(a,x0,p)+w)/(dy(b,x0,p)-dy(a,x0,p)+2*w);
x12=x1;
x1=a+delta*(b-a);
if(dy(x1,x0,p)>0)
b=x1;
else
a=x1;
}while(fabs(dy(x1,x0,p))>e);
*al=x1;
res=x0.sum(p.mult(x1));
return res;
}
//шаг метода Коши
vect step(vect &x0)
{
double al;
vect p=grad(x0);
p=p.mult(-1);
vect x=Davidon(x0,p, &al);
return x;
}
void Paul1(vect &x0)
{
int i,j, iter=0,blin=1;
double e=0.0001,al,kop,znam,b,m[10][10],kop1;
vect x2(x0.n),x1(x0.n),d(x0.n),p(x0.n),xn(x0.n);
x1=x0;
do
{
x2=x1;
if(iter==0)
{
for (i=0;i<x0.n;i++)
{
for(j=0;j<x0.n;j++)
{
if(i==j)
m[i][j]=1;
else
m[i][j]=0;
}
}
}
else
{
for (i=0;i<x0.n;i++)
{
if(i==((x0.n)-1))
{
for(j=0;j<x0.n;j++)
m[i][j]=d.x[j];
}
else
{
for(j=0;j<x0.n;j++)
m[i][j]=m[i+1][j];
}
}
}
for(i=0;i<x0.n;i++)
{
for(j=0;j<x0.n;j++)
p.x[j]=m[i][j];
x2=Davidon(x2,p, &al);
kop1=grad(x2).norm();
if(kop1<=e)
{
i=x0.n+5;
blin=0;
}
}
printf("\nx2=[%f,%f] ",x2.x[0],x2.x[1]);
getch();
if(i<(x0.n+3))
{
d=x2.razn(x1);
xn=Davidon(x2,d, &al);
kop=grad(xn).norm();
x1=xn;
}
iter++;
}while((kop>e)&&blin);
printf("\n\n\nITER=%d, ",iter);
if(blin)
x0=xn;
else
x0=x2;
}
void main(void)
{
vect x1;
do
{
system("cls");
printf("\nFunction minimum search \n\n\n\n");
printf("\nMenu:\n\n\n");
printf(" 1. x1^3 + x2^2 - 3x1 - 2x2 + 2 Min: (1,1)\n\n");
printf(" 2.(x2 - x1^2)^2 + (1 - x1)^2 Min : (1,1)\n\n");
printf(" 3.Exit\n\n");
printf("Please select punkt menu(from 1 to 3): ");
scanf( "%d",&z );
if(z<0||z>3)
{
printf("\n Please from 1 to 3 ");
getch();
}
switch(z)
{
case 1:{
dlin=2;
vusov=0;
vect x0(dlin);
x0.x[0]=1.5;
x0.x[1]=2;
Paul1(x0);
printf("Min:");
for(int i=0;i<x0.n;i++)
printf("%f, ",x0.x[i]);
getch();
getch();
break;
}
case 2:{dlin=2;
vusov=0;
vect x0(dlin);
x0.x[0]=-1;
x0.x[1]=-1;
Paul1(x0);
printf("Min:");
for(int i=0;i<x0.n;i++)
printf("%f, ",x0.x[i]);
getch();
getch();
break;
}
}
}while(z!=3);
}
Соседние файлы в папке Лабораторная работа №9