#include "lineseeker.h"
// ********************************************************
// Functions for class lineseeker
// ********************************************************
LineSeeker::LineSeeker() {
}
LineSeeker::~LineSeeker() {
}
int LineSeeker::outstandingRequests() {
int pending = net->getNumNotAns();
return pending;
}
/* In the initial version of Hooke and Jeeves, the point xnew+d is */
/* checked after each run of bestNearby, where d=xnew-xold. That is, */
/* it's tried to go a bit further in the direction that improves the */
/* function value. Here, some more points on the line through xnew and */
/* xold are tried as most of the computers would just be waiting during */
/* this time anyway. These tries depend on the number of free computers */
/* Nr. of computers: Tries made: */
/* 1.....................xnew+d */
/* 2.....................xnew+d, xnew+2*d */
/* 3.....................xnew+d, xnew+3/2*d, xnew+2*d */
/* 4.....................xnew+1/2*d, xnew+d, xnew+3/2*d, xnew+2*d */
/* 5.....................xnew-1/2*d, xnew+1/2*d, xnew+d, xnew+3/2*d, */
/* xnew+2*d */
/* 6.....................xnew-1/2*d, xnew+1/2*d, xnew+d, xnew+3/2*d, */
/* xnew+2*d, xnew+4*d */
/* 7.....................xnew-1/2*d, xnew+1/2*d, xnew+d, xnew+3/2*d, */
/* xnew+2*d, xnew+4*d, xnew+8*d */
/* and so further. (THLTH 29.08.01) */
int LineSeeker::doLineseek(const DoubleVector& xold, const DoubleVector& xnew,
double fnew, NetInterface *netI) {
int i, j, k, l;
int numSendReceive, numDataItems;
net = netI;
int numvar = net->getNumVarsInDataGroup();
int numberOfHosts = net->getNumFreeProcesses();
if (numberOfHosts == 0)
numberOfHosts = 1;
DoubleVector d(numvar);
DoubleVector z(numvar);
for (i = 0; i < numvar; i++)
d[i] = xnew[i] - xold[i];
DoubleVector upper(netI->getUpperScaleConstant());
DoubleVector lower(netI->getLowerScaleConstant());
f = fnew;
x = xnew;
net->startNewDataGroup(numberOfHosts);
if (numberOfHosts < 5) {
l = 1;
for (i = 0; i < numvar; i++) {
z[i] = xnew[i] + d[i];
if ((z[i] < lower[i]) || (z[i] > upper[i]))
l = 0;
}
if (l)
net->setX(z);
for (j = 1; j < numberOfHosts; j++) {
for (i = 0; i < numvar; i++) {
z[i] = xnew[i] + (2 - 1 / 2 * (j - 1) - 1 / 4 * (j - 1) * (j - 2)) * d[i];
if ((z[i] < lower[i]) || (z[i] > upper[i]))
l = 0;
}
if (l)
net->setX(z);
else
break;
}
} else {
l = 1;
for (i = 0; i < numvar; i++) {
z[i] = xnew[i] - 1 / 2 * d[i];
if ((z[i] < lower[i]) || (z[i] > upper[i]))
l = 0;
}
if (l)
net->setX(z);
for (j = 1; j < 4; j++) {
for (i = 0; i < numvar; i++) {
z[i] = xnew[i] + 1 / 2 * j * d[i];
if ((z[i] < lower[i]) || (z[i] > upper[i]))
l = 0;
}
if (l)
net->setX(z);
else
break;
}
k = 2;
for (j = 4; j < numberOfHosts; j++) {
for (i = 0; i < numvar; i++) {
z[i] = xnew[i] + k * d[i];
if ((z[i] < lower[i]) || (z[i] > upper[i]))
l = 0;
}
if (l)
net->setX(z);
else
break;
k = 2 * k;
}
}
numSendReceive = net->sendAndReceiveAllData();
if (numSendReceive == net->netError()) {
cerr << "Error in lineseeker - could not receive data\n";
net->stopUsingDataGroup();
exit(EXIT_FAILURE);
} else if (numSendReceive == net->netSuccess()) {
numDataItems = net->getNumDataItemsAnswered();
for (i = 0; i < numDataItems; i++) {
if (net->getY(i) < f) {
f = net->getY(i);
x = net->getX(i);
}
}
net->stopUsingDataGroup();
} else {
cerr << "Error in lineseeker - could not receive data\n";
net->stopNetComm();
net->stopUsingDataGroup();
exit(EXIT_FAILURE);
}
return numDataItems;
}