Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
23
Добавлен:
02.05.2014
Размер:
23.17 Кб
Скачать
// 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