- •2005 Г Содержание:
- •1. Цель работы и требования задания :
- •2. Спецификация программы, раскрывающая смысл входных и выходных данных, основных переменных, функций и классов.
- •2.1. Входные данные :
- •2.2. Выходные данные :
- •2.4. Класс Cvector:
- •3.Текст программы с детальными комментариями ведущих операторов программы.
- •4. Описание интерфейса пользователя программы.
- •5. Результаты сравнения двух способов вычисления производных – численного и аналитического.
- •8.Ответы на контрольные вопросы.
- •9.Вывод
2.4. Класс Cvector:
class Cvector
{
public:
doublex[100]; // текущая переменная
doublex0[100];// предыдущее значение
doublep[100];//направление
double a;
intn,c;//число переменных
double otv0[100];// в Дэвидоне
double otv[100] ; // в Дэвидоне
double d[100] ; //задаем вектор апроксимирующего минимума
doublez,w,r; // в Дэвидоне
voiddf(double*tochka,double*otvet)//численная производная
{
double* tochka2 = new double[n];
for (int i=0; i<n; i++)
tochka2[i]=tochka[i];
double h=0.000001; // приращение
for(i=0; i<n; i++)
{
tochka[i]=tochka[i]+h;
tochka2[i]=tochka2[i]-h;
otvet[i]=(f(tochka,c) - f(tochka2,c))/(2*h);//вычисляем производную
tochka[i]= tochka[i] - h;
tochka2[i]=tochka2[i] + h;
}
}
double diffp(double *tochka, double *p)//производная по направлению
{
double* res = new double[n], otv=0;
df(tochka, res);
for(int i=0;i<n; i++)
otv=otv+res[i]*p[i];
return otv;
}
double gra(double y[], double z[])//Аналитическая производная
{
double ar[2] = {0,0};
double sum = 0;
ar[0] = 400*y[0]*y[0]*y[0] - 400*y[1]*y[0] + 2*y[0] - 2 ;
ar[1] = 200*y[1] - 200*y[0]*y[0] ;
for (int i=0; i<n; i++)
sum = sum + ar[i]*z[i];
return sum;
}
double norma(double u[])//Норма вектора
{
double su = 0;
for (int i=0; i<n; i++)
{
su = su + u[i]*u[i];
}
return fabs(sqrt(su));
}
double OtrLength(double *St, double *Fin)//Длина отрезка
{
double res=0;
for (int i=0; i<2; i++)
res = res + (Fin[i]-St[i])*(Fin[i]-St[i]);
if((Fin[0]-St[0])>0)
return sqrt(res);
else
return -sqrt(res);
}
double f(double x[],int t)//значение функции
{
double otv;
switch (t)
{
case 0:
{
return pow((x[0] - 1),2) + pow((x[1] - 3),2) + 4*pow((x[2] + 5),2);break;
}
case 1:
{
return 100*(x[1] - x[0]*x[0])*(x[1] - x[0]*x[0]) + (1 - x[0])*(1 - x[0]);break;
}
case 2:{
return 4*pow((x[0] - 5),2) + pow((x[1] - 6),2);break;
}
case 3:
{
return 8*pow(x[0],2) + 4*x[0]*x[1] + 5*pow(x[1],2);break;
}
case 4:
{
return x[0]*x[0];break;
}
}
}
};
3.Текст программы с детальными комментариями ведущих операторов программы.
bool boo2 = false;
Cvector v;
v.c = m_com.GetCurSel();
CString sn[10];
char s3[100];
m_ed3.GetWindowText(s3,100);
int j2,j3 =0;
for(j2 = 0;j2<strlen(s3);j2++)
{
while ((s3[j2] != ',')&&(j2 <= strlen(s3)))
{
sn[j3] = sn[j3]+s3[j2];
j2++;
}
j3++;
}
for(j2 = 0;j2<j3;j2++)
v.x[j2] = atof(sn[j2]);
// INPUT N
v.n = 3;
v.df(v.x,v.p);
for(int i=0;i<v.n; i++)
v.p[i] = -v.p[i];
double norg;
char s7[100];
m_ed2.GetWindowText(s7,100);
norg = atof(s7);
if (norg == 0)
{
AfxMessageBox("You are input illegal charcters in 'Norma gradienta'",MB_ICONSTOP);
boo2 = true;
}
float cou,ogr;
char s1[100];
m_ed1.GetWindowText(s1,100);
cou = atoi(s1);
if (cou == 0)
{
AfxMessageBox("You are input illegal charcters in 'Count of Iteration'",MB_ICONSTOP);
boo2 = true;
}
ogr = 0;
while (boo2 == false)
{
ogr = ogr+1;
if (ogr>=cou)
{
boo2 = true;
}
v.a = 0.1;
for (int i= 0; i<v.n; i++)
{
v.x0[i] = v.x[i];
}
while (v.diffp(v.x0,v.p)*v.diffp(v.x,v.p)>0)
{
for(i=0; i<v.n; i++)
{
v.x0[i] = v.x[i];
}
for(int i=0; i<v.n; i++)
{
v.x[i] = v.x[i]+v.a*v.p[i];
}
v.a=2*v.a;
}
CString sr;
char s4[100];
for(i=0; i<v.n; i++)
{
gcvt(v.x[i],12, s4);
sr = sr+s4+';';
}
m_ed4.SetWindowText(sr);
// находим переменные в соответстви с методом
v.z=v.diffp(v.x0,v.p) + v.diffp(v.x,v.p) +3*(v.f(v.x0,v.c)-v.f(v.x,v.c))/v.OtrLength(v.x0,v.x);
v.w=sqrt(v.z*v.z-v.diffp(v.x0,v.p) * v.diffp(v.x,v.p));
v.r=v.a * (v.z - v.diffp(v.x0,v.p) + v.w) / (v.diffp(v.x,v.p) - v.diffp(v.x0,v.p) + 2*v.w);
for( i=0; i<v.n; i++)//находим точку апроксимирующего минимума
v.d[i]=v.x0[i]+v.r*v.p[i];
// сокращаем ТИЛ до соответствующего условия
while (fabs(v.diffp(v.d,v.p))>0.01)
{
if(v.diffp(v.d,v.p)<0) //минимум справа от апр. минимума
{
for(i=0;i<v.n;i++)
v.x0[i]=v.d[i];
v.a = v.a - v.r;
}
else //минимум слева от апр. минимума
{
v.a= v.r;
for(i=0;i<v.n;i++)
v.x[i]=v.d[i];
}
// находим переменные в соответстви с методом
v.z=v.diffp(v.x0,v.p) + v.diffp(v.x,v.p) +3*(v.f(v.x0,v.c)-v.f(v.x,v.c))/v.OtrLength(v.x0,v.x);
v.w=sqrt(v.z*v.z-v.diffp(v.x0,v.p) * v.diffp(v.x,v.p));
v.r=v.a * (v.z - v.diffp(v.x0,v.p) + v.w) / (v.diffp(v.x,v.p) - v.diffp(v.x0,v.p) + 2*v.w);
for( i=0; i<v.n; i++)//находим точку апроксимирующего минимума
v.d[i] = v.x0[i]+ v.r*v.p[i];
}
for(i=0;i<v.n;i++) //получаем конечный результат
v.x0[i]=v.d[i];
for(i=0; i<v.n; i++)
{
v.otv0[i] = v.otv[i];
}
for(i=0; i<v.n; i++)
{
v.otv[i] = v.x0[i];
}
double ak;
v.df(v.otv,v.p);
for(i=0;i<v.n; i++)
v.p[i] = -v.p[i];
for(i=0; i<v.n; i++)
{
v.x[i] = v.otv[i];
v.x0[i] = v.otv0[i];
}
if (v.norma(v.p) < norg)
boo2 = true;
}
if ((cou!= 0)&&(norg!=0))
{
CString sr2;
char s8[100];
for(i=0; i<v.n; i++)
{
gcvt(v.x[i],12, s8);
sr2 = sr2+s8+';';
}
m_ed5.SetWindowText(sr2);
}
}