Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторные работы2 / MOLab3 / MOLab3 / FindThread
.cpp// FindThread.cpp : implementation file
//
#include "stdafx.h"
#include "MOLab3.h"
#include "FindThread.h"
// CFindThread
IMPLEMENT_DYNCREATE(CFindThread, CWinThread)
CFindThread::CFindThread()
{
m_bWorking = FALSE;
}
CFindThread::~CFindThread()
{
}
BOOL CFindThread::InitInstance()
{
return TRUE;
}
int CFindThread::ExitInstance()
{
return CWinThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(CFindThread, CWinThread)
ON_THREAD_MESSAGE(WM_CALCULATE_START, Calculate)
END_MESSAGE_MAP()
void CFindThread::Lock()
{
m_CS.Lock();
}
void CFindThread::Unlock()
{
m_CS.Unlock();
}
// CFindThread message handlers
void CFindThread::Calculate(WPARAM wParam, LPARAM lParam)
{
if (m_bWorking)
return;
m_bWorking = TRUE;
int iFindType = (int) wParam;
int iFuncType = (int) lParam;
PARAMS [0] = X_DEFAULTS[iFuncType][0];
PARAMS [1] = X_DEFAULTS[iFuncType][1];
PARAMS [2] = X_DEFAULTS[iFuncType][2];
PARAMS [3] = X_DEFAULTS[iFuncType][3];
X_START[0] = X_DEFAULTS[iFuncType][4];
X_START[1] = X_DEFAULTS[iFuncType][5];
X_EPS3 = X_DEFAULTS[iFuncType][6];
CDPoint pt;
nSteps = nStepsF = nStepsF1 = 0;
m_Path.RemoveAll();
::CreateDialog();
switch ( iFindType )
{
case 1:
pt = find1();
break;
case 2:
pt = find2();
break;
case 3:
pt = find3();
break;
case 4:
pt = find4();
break;
case 5:
pt = find5();
break;
case 6:
pt = find6();
break;
case 7:
pt = find7();
break;
case 8:
pt = find8();
break;
case 9:
pt = find9();
break;
case 10:
pt = find10();
break;
case 11:
pt = find11();
break;
case 12:
pt = find12();
break;
case 13:
pt = find13();
}
m_Result = pt;
SendMessage(m_hParentWnd, WM_CALCULATE_END, NULL, NULL);
m_bWorking = FALSE;
}
// Methods...
CDPoint CFindThread::GetResult()
{
Lock();
CDPoint pt = m_Result;
Unlock();
return pt;
}
int CFindThread::GetFSteps()
{
Lock();
int nF = nStepsF;
Unlock();
return nF;
}
int CFindThread::GetF1Steps()
{
Lock();
int nF1 = nStepsF1;
Unlock();
return nF1;
}
int CFindThread::GetF2Steps()
{
Lock();
int nF2 = nStepsF2;
Unlock();
return nF2;
}
int CFindThread::GetSteps()
{
Lock();
int nK = nSteps;
Unlock();
return nK;
}
CPtArray CFindThread::GetPath()
{
Lock();
CPtArray arr = m_Path;
Unlock();
return arr;
}
void CFindThread::Clear()
{
nSteps = nStepsF = nStepsF1 = nStepsF2 = 0;
}
double CFindThread::f (CDVector x)
{
nStepsF++;
double fRes1 = 0;
double fRes2 = 0;
for (int j = 0; j < N_ARGS; j++)
{
fRes1 += x[j] * PARAMS[j];
fRes2 += x[j] * x[j] * PARAMS[j + N_ARGS];
}
if (fRes2 > 200)
fRes2 = 200;
return fRes1 + exp(fRes2);
}
double CFindThread::f1(int i, CDVector x)
{
nStepsF1++;
double fRes = 0;
for (int j = 0; j < N_ARGS; j++)
{
fRes += x[j] * x[j] * PARAMS[j + N_ARGS];
}
if (fRes > 200)
fRes = 200;
return PARAMS[i] + 2 * PARAMS[i + N_ARGS] * x[i] * exp(fRes);
}
CDVector CFindThread::f1(CDVector x)
{
CDVector _x;
for (int i = 0; i < N_ARGS; i++)
_x[i] = f1(i, x);
return _x;
}
CMDVector CFindThread::f2(CDVector x)
{
nStepsF2++;
CMDVector buf;
double exp_part = exp(PARAMS[2] * x[0] * x[0] + PARAMS[3] * x[1] * x[1]);
buf[0][0] = (2 * PARAMS[2] + 4 * PARAMS[2] * PARAMS[2] * x[0] * x[0]) * exp_part;
buf[0][1] = 4 * PARAMS[2] * PARAMS[3] * x[0] * x[1] * exp_part;
buf[1][0] = 4 * PARAMS[2] * PARAMS[3] * x[0] * x[1] * exp_part;
buf[1][1] = (2 * PARAMS[3] + 4 * PARAMS[3] * PARAMS[3] * x[1] * x[1]) * exp_part;
return buf;
}
double CFindThread::module(CDVector x)
{
double fRes = 0;
for (int i = 0; i < N_ARGS; i++)
fRes += x[i] * x[i];
return sqrt(fRes);
}
double CFindThread::scale(CDVector x1, CDVector x2)
{
return x1[0] * x2[0] + x1[1] * x2[1];
}
CDPoint CFindThread::find1(double a)
{
Clear();
CDVector x;
CDVector x1;
x = 0.0;
x1 = 0.0;
double y = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
CDVector grad;
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x);
while (module(grad) > X_EPS3)
{
m_Path.Add(x);
nSteps++;
// =========================================== Step 2 ================================== //
x1 = x - grad * a;
// =========================================== Step 3 ================================== //
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x1);
// =========================================== Step 4 ================================== //
x = x1;
}
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
CDPoint CFindThread::find2(double a, double d)
{
Clear();
CDVector x;
CDVector x1;
x = 0.0;
x1 = 0.0;
double y = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
CDVector grad;
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x);
double md = X_EPS3 + 1;
double func = f(x), func1 = 0;
while (md > X_EPS3)
{
m_Path.Add(x);
nSteps++;
md = module(grad);
// =========================================== Step 3 ================================== //
x1 = x - grad * a;
func = func1;
while ((func1 = f(x1)) - func > -d * a * md * md)
{
a /= 5;
// =========================================== Step 3 ================================== //
x1 = x - grad * a;
}
// =========================================== Step 4 ================================== //
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x1);
// =========================================== Step 5 ================================== //
x = x1;
}
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
double CFindThread::fmin(CDVector xk, double a, CDVector f1xk)
{
CDVector x1;
x1 = xk - f1xk * a;
return f(x1);
}
double CFindThread::find_min(CDVector xk, CDVector f1xk, double left, double right)
{
double a = left;
double b = right;
double c = ( a + b ) / 2;
double ya = 0.0;
double yb = 0.0;
double yc = 0.0;
double t = 0.0;
double x = 0.0;
double y = 0.0;
ya = fmin ( xk, a, f1xk );
yb = fmin ( xk, b, f1xk );
yc = fmin ( xk, c, f1xk );
do
{
if (a > b)
swap(a, b);
if (a > c)
swap(a, c);
if (b < c)
swap(b, c);
double znam = ( b - c ) * ( ya - yc ) + ( c - a ) * ( yb - yc );
if (0 != znam)
t = c + 0.5 * ( ( b - c ) * ( b - c ) * ( ya - yc ) - ( c - a ) * ( c - a ) * ( yb - yc ) )
/ ( znam );
else
{
t = c;
}
if ( abs(t - c) < 1e-6 )
x = ( a + c ) / 2;
else x = t;
y = fmin ( xk, x, f1xk );
if ( x < c )
{
if ( abs( y - yc ) < EPS )
{
a = x;
b = c;
c = ( x + c ) / 2;
ya = y;
yb = yc;
yc = fmin ( xk, c, f1xk );
}
else if ( y < yc )
{
b = c;
c = x;
yb = yc;
yc = y;
}
else if ( y > yc)
{
a = x;
ya = y;
}
}
else if ( x > c )
{
if ( abs( y - yc ) < EPS )
{
a = c;
b = x;
c = ( x + c ) / 2;
ya = yc;
yb = y;
yc = fmin ( xk, c, f1xk );
}
else if ( y < yc )
{
a = c;
c = x;
ya = yc;
yc = y;
}
else if ( y > yc)
{
b = x;
yb = y;
}
}
else
{
ASSERT( 0 );
}
}
while ( abs( b - a ) > X_EPS3);
return x;
};
CDPoint CFindThread::find3(double a)
{
Clear();
CDVector x;
CDVector x1;
x = 0.0;
x1 = 0.0;
double y = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
CDVector grad;
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x);
double max_grad = abs(grad[0]);
for (int i = 1; i < N_ARGS; i++)
if (max_grad < abs(grad[i])) max_grad = abs(grad[i]);
a = 2.0 / max_grad;
while (module(grad) > X_EPS3)
{
m_Path.Add(x);
nSteps++;
// =========================================== Step 2 ================================== //
a = find_min(x, grad, 0, abs(2.0 / max_grad));
x1 = x - grad * a;
// =========================================== Step 3 ================================== //
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x1);
// =========================================== Step 4 ================================== //
x = x1;
}
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
CDPoint CFindThread::find4(double a)
{
Clear();
CDVector x;
x = 0.0;
double y = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
CDVector grad;
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x);
while (module(grad) > X_EPS3)
{
nSteps++;
// =========================================== Step 2 ================================== //
for (int i = 0; i < N_ARGS; i++)
{
m_Path.Add(x);
x[i] = x[i] - a * grad[i];
grad[i] = f1(i, x);
}
// =========================================== Step 3 ================================== //
}
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
CDPoint CFindThread::find5(double a)
{
Clear();
CDVector x;
x = 0.0;
double y = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
CDVector grad;
for (int i = 0; i < N_ARGS; i++)
grad[i] = f1(i, x);
double max_grad = abs(grad[0]);
for (int i = 1; i < N_ARGS; i++)
if (max_grad < abs(grad[i])) max_grad = abs(grad[i]);
a = 2.0 / max_grad;
while (module(grad) > X_EPS3)
{
m_Path.Add(x);
nSteps++;
// =========================================== Step 2 ================================== //
for (int i = 0; i < N_ARGS; i++)
{
a = find_min(x, grad, 0, abs(a));
x[i] = x[i] - a * grad[i];
grad[i] = f1(i, x);
}
// =========================================== Step 3 ================================== //
}
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
CDPoint CFindThread::find6(double d1, double d2, double a1, double a2)
{
Clear();
CDVector x = 0;
CDVector x1 = 0.0;
CDVector xk = 0.0;
double y1 = 0.0;
double y2 = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
xk[i] = x[i] = X_START[i];
m_Path.Add(x);
CDVector grad;
CDVector g;
// =========================================== Step 2 ================================== //
while ( ( module(xk) >=X_EPS1 ) || ( module(grad) > X_EPS3 ) )
{
xk = x;
for (int i = 0; i < N_ARGS; i++)
{
grad[i] = f1(i, x);
if (grad[i] <= d1)
g[i] = 0;
else g[i] = grad[i];
}
y2 = f(x);
y1 = y2 + 1;
while (y1 > y2)
{
nSteps++;
m_Path.Add(x);
y1 = y2;
x1 = x - g * a1;
for (int i = 0; i < N_ARGS; i++)
{
grad[i] = f1(i, x1);
if (abs(grad[i]) <= d1)
g[i] = 0;
else g[i] = grad[i];
}
x = x1;
y2 = f(x);
}
// =========================================== Step 3 ================================== //
for (int i = 0; i < N_ARGS; i++)
{
grad[i] = f1(i, x);
if (grad[i] >= d2)
g[i] = 0;
else g[i] = grad[i];
}
y2 = f(x);
y1 = y2 + 1;
while (y1 > y2)
{
nSteps++;
m_Path.Add(x);
y1 = y2;
x1 = x - g * a2;
for (int i = 0; i < N_ARGS; i++)
{
grad[i] = f1(i, x1);
if (abs(grad[i]) >= d2)
g[i] = 0;
else g[i] = grad[i];
}
x = x1;
y2 = f(x);
}
xk -= x;
}
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
CDPoint CFindThread::find7(double a, double l)
{
Clear();
CDVector buf = 0.0;
CDVector x = 0.0;
CDVector u = 0.0;
CDVector u1 = 0.0;
CDVector xd = 0.0;
CDVector ud = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
u[i] = x[i] = X_START[i];
CDVector grad;
grad = f1(u);
u1 = u - grad * a;
// =========================================== Step 2 ================================== //
do
{
m_Path.Add(x);
nSteps++;
xd = x;
u = u1;
for (int i = 0; i < N_ARGS; i++)
xd[i] -= (1e-9) * sign(f1(i, x));
ud = xd;
grad = f1(ud);
ud = ud - grad * a;
double mdu = module(ud - u);
double fu = f(u);
double fu1 = 0;
if (f(ud) >= fu) mdu = - mdu;
do
{
double c = l / mdu;
for (int i = 0; i < N_ARGS; i++)
u1[i] = x[i] = u[i] + c * (ud[i] - u[i]);
grad = f1(u1);
u1 = u1 - grad * a;
fu1 = f(u1);
if (fu1 > fu)
l /= 2.0;
}
while ( fu1 > fu );
}
while ( ( module(u1 - u) >= X_EPS1 ) || ( module(f1(u1)) >= X_EPS3) );
m_Path.Add(u1);
return CDPoint(u1.GetData(), f(u1));
}
CDPoint CFindThread::find8(double a, double l)
{
Clear();
CDVector buf = 0.0;
CDVector x = 0.0;
CDVector u = 0.0;
CDVector u1 = 0.0;
CDVector xd = 0.0;
CDVector ud = 0.0;
// =========================================== Step 1 ================================== //
for (int i = 0; i < N_ARGS; i++)
u[i] = x[i] = X_START[i];
m_Path.Add(x);
CDVector grad;
grad = f1(u);
u = u - grad * a;
xd = x;
for (int i = 0; i < N_ARGS; i++)
xd[i] -= (1e-9) * sign(f1(i, x));
ud = xd;
grad = f1(ud);
ud = ud - grad * a;
// =========================================== Step 2 ================================== //
do
{
m_Path.Add(u);
nSteps++;
double mdu = module(ud - u);
double fu = f(u);
double fu1 = 0;
if (f(ud) >= fu) mdu = - mdu;
do
{
double c = l / mdu;
for (int i = 0; i < N_ARGS; i++)
u1[i] = u[i] + c * (ud[i] - u[i]);
grad = f1(u1);
u1 = u1 - grad * a;
fu1 = f(u1);
if (fu1 > fu)
l /= 2.0;
}
while ( fu1 > fu );
u = ud;
ud = u1;
}
while ( ( module(u1 - u) >= X_EPS1 ) || ( module(f1(u1)) >= X_EPS3) );
m_Path.Add(u1);
return CDPoint(u1.GetData(), f(u1));
}
CDPoint CFindThread::find9(double h, double l)
{
Clear();
CDVector x = 0.0;
CDVector x1 = 0.0;
CDVector z = 0.0;
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
do
{
m_Path.Add(x);
z = x;
double fx = f(x);
bool bIsGood = false;
do
{
nSteps++;
for (int i = 0; i < N_ARGS; i++)
{
z[i] = x[i] + h;
if ( f(z) >= fx )
{
z[i] = x[i] - h;
if ( f(z) >= fx)
{
z[i] = x[i];
}
else bIsGood = true;
}
else bIsGood = true;
// x[i] = z[i];
}
if (!bIsGood)
h /= 2.0;
}
while (!bIsGood && (h > X_EPS3) );
if (bIsGood)
{
double fx1 = 0;
do
{
x1 = x + (z - x) * l;
fx1 = f(x1);
if (fx1 > fx)
l /= 2;
}
while (fx1 > fx);
x = x1;
}
}
while (h > X_EPS3);
return CDPoint(x.GetData(), f(x));
}
double CFindThread::fmin2(CDVector xk, CDVector dx, double a)
{
return f( xk - dx * a );
}
double CFindThread::find_min2(CDVector xk, CDVector dx, double left, double right)
{
double a = left;
double b = right;
double c = ( a + b ) / 2;
double ya = 0.0;
double yb = 0.0;
double yc = 0.0;
double t = 0.0;
double x = 0.0;
double y = 0.0;
ya = fmin2 ( xk, dx, a );
yb = fmin2 ( xk, dx, b );
yc = fmin2 ( xk, dx, c );
do
{
if (a > b)
swap(a, b);
if (a > c)
swap(a, c);
if (b < c)
swap(b, c);
double znam = ( b - c ) * ( ya - yc ) + ( c - a ) * ( yb - yc );
if (0 != znam)
t = c + 0.5 * ( ( b - c ) * ( b - c ) * ( ya - yc ) - ( c - a ) * ( c - a ) * ( yb - yc ) )
/ ( znam );
else
{
t = c;
}
if ( abs(t - c) < 1e-6 )
x = ( a + c ) / 2;
else x = t;
y = fmin2 ( xk, dx, x );
if ( x < c )
{
if ( abs( y - yc ) < EPS )
{
a = x;
b = c;
c = ( x + c ) / 2;
ya = y;
yb = yc;
yc = fmin2 ( xk, dx, c );
}
else if ( y < yc )
{
b = c;
c = x;
yb = yc;
yc = y;
}
else if ( y > yc)
{
a = x;
ya = y;
}
}
else if ( x > c )
{
if ( abs( y - yc ) < EPS )
{
a = c;
b = x;
c = ( x + c ) / 2;
ya = yc;
yb = y;
yc = fmin2 ( xk, dx, c );
}
else if ( y < yc )
{
a = c;
c = x;
ya = yc;
yc = y;
}
else if ( y > yc)
{
b = x;
yb = y;
}
}
else
{
ASSERT( 0 );
}
}
while ( abs( b - a ) > X_EPS3);
return x;
};
CDPoint CFindThread::find10(double h, double l)
{
Clear();
CDVector x = 0.0;
CDVector z = 0.0;
double base_l = l;
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
do
{
m_Path.Add(x);
z = x;
double fx = f(x);
bool bIsGood = false;
do
{
nSteps++;
for (int i = 0; i < N_ARGS; i++)
{
z[i] = x[i] + h;
if ( f(z) >= fx )
{
z[i] = x[i] - h;
if ( f(z) >= fx)
{
z[i] = x[i];
}
else bIsGood = true;
}
else bIsGood = true;
x[i] = z[i];
}
if (!bIsGood)
h /= 2.0;
}
while (!bIsGood && (h > X_EPS3) );
if (bIsGood)
{
l = find_min2(x, z - x, 0, base_l);
x = x + (z - x) * l;
}
}
while (h > X_EPS3);
return CDPoint(x.GetData(), f(x));
}
CDPoint CFindThread::find11(double l)
{
Clear();
CDVector x = 0.0;
CDVector x1 = 0.0;
CDVector cm = 0.0;
CPtArray simp(N_ARGS + 1, x);
CPtArray e(N_ARGS, x);
CVector<double, N_ARGS + 1> f_simp;
for (int i = 0; i < N_ARGS; i++)
{
x1 = x;
x1[i] = 1.0;
e[i] = x1;
}
for (int i = 0; i < N_ARGS; i++)
{
x[i] = X_START[i];
}
simp[0] = x;
f_simp[0] = f(x);
for (int i = 1; i < N_ARGS + 1; i++)
{
simp[i] = x + e[i - 1] * l;
f_simp[i] = f(simp[i]);
}
double simp_eps = 0;
double min = 0;
double max = 0;
int min_pos = 0;
int max_pos = 0;
do
{
nSteps++;
m_Path.Add(simp[0]);
simp_eps = 0;
min = f_simp[0];
max = f_simp[0];
min_pos = 0;
max_pos = 0;
for(int i = 1; i < N_ARGS + 1; i++)
{
if (f_simp[i] > max)
{
max = f_simp[i];
max_pos = i;
}
if (f_simp[i] < min)
{
min = f_simp[i];
min_pos = i;
}
}
cm = 0.0;
for (int i = 0; i < N_ARGS + 1; i++)
{
if (i != max_pos)
{
cm += simp[i];
}
}
cm /= N_ARGS;
x1 = cm * 2.0 - simp[max_pos];
double fx1 = f(x1);
if (fx1 < max)
{
simp[max_pos] = x1;
f_simp[max_pos] = fx1;
}
else
{
for (int i = 0; i < N_ARGS + 1; i++)
{
if (i != min_pos)
{
simp[i] = (simp[i] + simp[min_pos]) / 2.0;
f_simp[i] = f(simp[i]);
}
}
}
simp_eps = 0;
for (int i = 1; i < N_ARGS + 1; i++)
{
simp_eps += (f_simp[i] - f_simp[0]) * (f_simp[i] - f_simp[0]);
}
simp_eps = sqrt(simp_eps / (double)(N_ARGS));
}
while ( simp_eps > X_EPS3 );
min = f_simp[0];
max = f_simp[0];
min_pos = 0;
max_pos = 0;
for(int i = 1; i < N_ARGS + 1; i++)
{
if (f_simp[i] > max)
{
max = f_simp[i];
max_pos = i;
}
if (f_simp[i] < min)
{
min = f_simp[i];
min_pos = i;
}
}
m_Path.Add(simp[min_pos]);
return CDPoint(simp[min_pos].GetData(), f_simp[min_pos]);
}
CDPoint CFindThread::find12(double d)
{
Clear();
CDVector x = 0.0;
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
double a = 1;
CDVector m_f1;
CMDVector m_f2;
CDVector p;
do
{
m_Path.Add(x);
nSteps++;
m_f1 = f1(x);
m_f2 = f2(x);
double test[2][2] = {m_f2[0][0], m_f2[0][1], m_f2[1][0], m_f2[1][1]};
if (0 == m_f2[0][1])
{
p[0] = - m_f1[0] / m_f2[0][0];
p[1] = ( - m_f1[1] - m_f2[1][0] * p[0] ) / m_f2[1][1];
}
else if (0 == m_f2[1][0])
{
p[1] = - m_f1[1] / m_f2[1][1];
p[0] = ( - m_f1[0] - m_f2[0][1] * p[1] ) / m_f2[0][0];
}
else
{
p[1] = - ( m_f1[0] / m_f2[0][0] - m_f1[1] / m_f2[1][0] ) /
( m_f2[0][1] / m_f2[0][0] - m_f2[1][1] / m_f2[1][0] );
p[0] = ( - m_f1[0] - m_f2[0][1] * p[1] ) / m_f2[0][0];
};
double fk = f(x);
double _sc = p[0] * m_f1[0] + p[1] * m_f1[1];
while (f(x + p * a) - fk > d * a * _sc) a /= 2;
x = x + p * a;
}
while (module( f1(x) ) > X_EPS3);
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
double CFindThread::fmin3(CDVector xk, CDVector sk, double a)
{
return f( xk + sk * a );
}
double CFindThread::find_min3(CDVector xk, CDVector sk, double left, double right)
{
double a = left;
double b = right;
double c = ( a + b ) / 2;
double ya = 0.0;
double yb = 0.0;
double yc = 0.0;
double t = 0.0;
double x = 0.0;
double y = 0.0;
ya = fmin3 ( xk, sk, a );
yb = fmin3 ( xk, sk, b );
yc = fmin3 ( xk, sk, c );
do
{
if (a > b)
swap(a, b);
if (a > c)
swap(a, c);
if (b < c)
swap(b, c);
double znam = ( b - c ) * ( ya - yc ) + ( c - a ) * ( yb - yc );
if (0 != znam)
t = c + 0.5 * ( ( b - c ) * ( b - c ) * ( ya - yc ) - ( c - a ) * ( c - a ) * ( yb - yc ) )
/ ( znam );
else
{
t = c;
}
if ( abs(t - c) < 1e-6 )
x = ( a + c ) / 2;
else x = t;
y = fmin3 ( xk, sk, x );
if ( x < c )
{
if ( abs( y - yc ) < EPS )
{
a = x;
b = c;
c = ( x + c ) / 2;
ya = y;
yb = yc;
yc = fmin3 ( xk, sk, c );
}
else if ( y < yc )
{
b = c;
c = x;
yb = yc;
yc = y;
}
else if ( y > yc)
{
a = x;
ya = y;
}
}
else if ( x > c )
{
if ( abs( y - yc ) < EPS )
{
a = c;
b = x;
c = ( x + c ) / 2;
ya = yc;
yb = y;
yc = fmin3 ( xk, sk, c );
}
else if ( y < yc )
{
a = c;
c = x;
ya = yc;
yc = y;
}
else if ( y > yc)
{
b = x;
yb = y;
}
}
else
{
ASSERT( 0 );
}
}
while ( abs( b - a ) > X_EPS3);
return x;
};
CDPoint CFindThread::find13()
{
Clear();
CDVector x = 0.0;
CDVector x1 = 0.0;
CDVector g = 0.0;
CDVector g1 = 0.0;
CDVector s = 0.0;
for (int i = 0; i < N_ARGS; i++)
x[i] = X_START[i];
double ms = 0;
double b = 0;
g = f1(x);
double max_grad = abs(g[0]);
for (int i = 1; i < N_ARGS; i++)
if (max_grad < abs(g[i])) max_grad = abs(g[i]);
double a = 5.0 / max_grad;
s = - g;
int k = 0;
int n = 7;
do
{
nSteps++;
m_Path.Add(x);
a = find_min3(x, s, 0, abs(5.0 / max_grad));
x1 = x + s * a;
g1 = f1(x1);
ms = module(g1);
if (ms > X_EPS3)
{
if (0 != k % n)
{
b = scale( g1, g1 - g) / scale(g, g);
}
else
{
b = 0;
}
s = - g1 + s * b;
}
x = x1;
g = g1;
k++;
}
while (ms > X_EPS3);
m_Path.Add(x);
return CDPoint(x.GetData(), f(x));
}
Соседние файлы в папке MOLab3