Log In | Get Help   
Home My Page Projects Code Snippets Project Openings Mareframe
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files
[mareframe] View of /trunk/paramin-beta/paraminhooke.cc
[mareframe] / trunk / paramin-beta / paraminhooke.cc Repository:
ViewVC logotype

View of /trunk/paramin-beta/paraminhooke.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (download) (annotate)
Mon Feb 10 17:09:07 2014 UTC (10 years, 4 months ago) by agomez
File size: 9965 byte(s)
Initial version based on Gadget 2.2.00
#include "paraminhooke.h"

// ********************************************************
// functions for class ParaminHooke
// ********************************************************
ParaminHooke::ParaminHooke(NetInterface* netInt) : ParaminSearch(netInt) {
  iters = 0;
  returnID = -1;
  lambda = 0;
  rho = 0.5;
  epsilon = 1e-4;
  maxiterations = 1000;
  type = OPTHOOKE;
  // already set in optinfo
  // converge = 0;
}

ParaminHooke::~ParaminHooke() {
}

void ParaminHooke::read(CommentStream& infile, char* text)  {
  int i = 0;

  while (!infile.eof() && strcasecmp(text, "seed") && strcasecmp(text, "[hooke]") && strcasecmp(text, "[bfgs]")) {
    infile >> ws;
    if ((strcasecmp(text, "epsilon") == 0) || (strcasecmp(text, "hookeeps") == 0)) {
      infile >> epsilon;

    } else if ((strcasecmp(text, "maxiterations") == 0) || (strcasecmp(text, "hookeiter") == 0)) {
      infile >> maxiterations;

    } else if (strcasecmp(text, "rho") == 0) {
      infile >> rho;

    } else if (strcasecmp(text, "lambda") == 0) {
      infile >> lambda;

    } else if (strcasecmp(text, "bndcheck") == 0) {
      //JMB - read and ignore bndcheck
      infile >> text;

    } else {
      cerr << "Error while reading optinfo for Hooke - unknown option " << text << endl;
      exit(EXIT_FAILURE);
    }
    infile >> text;
    i++;
  }

  if (i == 0)
    cerr << "Warning - no optinfo give for Hooke in file - using default parameters" << endl;

  //check the values specified in the optinfo file ...
  if ((rho < 0) || (rho > 1)) {
    cerr << "\nError in value of rho - setting to default value of 0.5\n";
    rho = 0.5;
  }
  if ((lambda < 0) || (lambda > 1)) {
    cerr << "\nError in value of lambda - setting to default value of " << rho << endl;
    lambda = rho;
  }
}

void ParaminHooke::OptimiseLikelihood() {
  double steplength;
  int i, keep;
  
  NumberOfHosts = net->getTotalNumProc();
  int maxnumindatagroup = numvar*10;
  // maybe not needed can do resize on the go????
  // Vector tempV(maxnumindatagroup);
  //previousf = tempV;
  previousf.Reset();
  previousf.resize(maxnumindatagroup, 0.0);
  //par = new int[maxnumindatagroup];
  par.resize(maxnumindatagroup, 0);
  xbefore = net->getInitialX();
  fbefore = net->getScore();
  bestx = xbefore;
  bestf = fbefore;
 
  cout << "in opt hooke and Jeeves best x is " << endl;
  for (i = 0; i < bestx.Size(); i++)  {
    cout << bestx[i] << " ";
  };
  cout << endl;
  cout << "in opt hooke and jeeves best f is " << bestf << endl;
 
  delta.Reset();
  delta.resize(numvar, 0.0);
  int numFromLineSeek;
  // change = new int[numvar];
  //  param = new int[numvar];
  change.Reset();
  change.resize(numvar, 0);
  param.Reset();
  param.resize(numvar,0);
  // The original definition of the delta array has not been changed, even
  // though we're sometimes working with scaled x-values.
  for (i = 0; i < numvar; i++) {
    delta[i] = fabs(bestx[i] * rho);
    if (delta[i] == 0.0)
      delta[i] = rho;
    param[i] = i;
  }

  steplength = ((lambda < verysmall) ? rho : lambda);
  
  lineS = new LineSeeker();
 
  while ((iters < maxiterations) && (steplength > epsilon)) {
    /* randomize the order of the parameters once in a while, to avoid */
    /* the order having an influence on which changes are accepted.    */
      
    randomOrder(param);

    /* find best new point, one coord at a time */
    bestNearby();

    //JMB check for too many iterations here
    
    /* if we made some improvements, pursue that direction */
    keep = 1;
    while ((bestf < fbefore) && (keep == 1) && (iters < maxiterations)) {
	// cout << "some improvement from bestNearby" << endl;
      for (i = 0; i < numvar; i++) {
        /* firstly, arrange the sign of delta[] */
        if (bestx[i] <= xbefore[i])
          delta[i] = 0.0 - fabs(delta[i]);
        else
          delta[i] = fabs(delta[i]);
      }

      numFromLineSeek = lineS->doLineseek(xbefore, bestx, bestf, net);
      iters += numFromLineSeek;
      xbefore = bestx;
      fbefore = bestf;
      bestf = lineS->getBestF();
      cout << "hooke and jeeves best f " << bestf << endl;
      bestx = lineS->getBestX();

      // if the further (optimistic) move was bad
      if (bestf >= fbefore) {
        bestf = fbefore;
        bestx = xbefore;

      } else {
        // else, look around from that point
        if (iters < maxiterations) {
          xbefore = bestx;
          fbefore = bestf;
          bestNearby();
          /* if the further (optimistic) move was bad */
          if (bestf < fbefore) {
            // bestf can only be equal or less than  fbefore
            /* make sure that the differences between the new and the old */
            /* points are due to actual displacements - beware of roundoff */
            /* errors that might cause newf < fbefore */
            keep = 0;
            for (i = 0; i < numvar; i++) {
              keep = 1;
              // AJ changing to be the same check as in gadget..
              if (fabs(bestx[i] - xbefore[i]) > rathersmall)
                break;
              else
                keep = 0;
            }
          }
        }
      }
    }

    if ((steplength >= epsilon) && (bestf >= fbefore)) {
      steplength = steplength * rho;
      for (i = 0; i < numvar; i++)
        delta[i] *= rho;
    }
  }
  // Must look into this cout..  things.. should be handle...
  cout << "\nStopping Hooke and Jeeves\n\nThe optimisation stopped after " << iters
    << " iterations (max " << maxiterations << ")\nThe steplength was reduced to "
    << steplength << " (min " << epsilon << ")\n";

  if (iters >= maxiterations)
    cout << "The optimisation stopped because the maximum number of iterations" << "\nwas reached and NOT because an optimum was found for this run\n";
  else {
    cout << "The optimisation stopped because an optimum was found for this run\n";
    converge = 1;
  }
  delete lineS;
  // delete[] change;
  // delete[] param;
  // delete[] par;
  net->setInitialScore(bestx, bestf);
  score = bestf;
}

void ParaminHooke::bestNearby() {
  double ftmp;
  int i, j;
  int withinbounds;
  int newopt;
  net->startNewDataGroup(10 * numvar);
 
  for (i = 0; i < numvar; i++)
    change[i] = 0;
  numparamset = 0;
  i = 0;
  // sending as many points as there are processors in total.
  // ************
  // AJ if never within bound then will set numvar points!!!!
  // 

  while ((i < NumberOfHosts) && (numparamset < numvar)) {
    withinbounds = SetPoint(param[numparamset]);
    if (withinbounds == 1) {
      change[param[numparamset]]++;
      i++;
    }
    numparamset++;
  }
  // send all available data to all free hosts and then receive them
  // back one at a time, sending new points when possible. If point I was
  // trying to set was not within bound then nothing has been set and
  // nothing will be sent. This could lead to poor use of available hosts.
  net->sendToAllIdleHosts();
  while (net->getNumNotAns() > 0) {
    ReceiveValue();
    if (iters % 1000 == 0) {
	cout << "\nAfter " << iters << " function evaluations, f(x) = " << bestf << " at\n"; 
	  for (j = 0; j < bestx.Size(); j++) 
	      cout << bestx[j] << sep;
      cout << endl;
    }
    if (iters < maxiterations) {
      if (MyDataGroup()) {
        // Update the optimum if received a better value
        newopt = UpdateOpt();
        if (!newopt) {
          SetPointNearby();
	};
      }
      if (net->allSent())
        SetPointNextCoord();
      if (!net->allSent())
        net->sendToIdleHosts();

    } else {
      net->receiveAll();
      // This takes time, ?? need to do this
      // since I am receiving all, maybe should check if any
      // of the return values are optimum.
    }
  }
  net->stopUsingDataGroup();
}

int ParaminHooke::SetPoint(int n) {
  // return 0 and do nothing if the changes goes out of bounds.
  DoubleVector z(bestx);
  double next = bestx[n] + delta[n];
  int numset;
 
  if (next < lowerbound[n]) {
      
      return 0;
  }
  else if (next > upperbound[n]) {
      
      return 0;
  }
  else {
      
    numset = net->getNumDataItemsSet();
    z[n] = next;
    net->setX(z);
    par[numset] = n;
    previousf[numset] = bestf;
    return 1;
  }
}

int ParaminHooke::MyDataGroup() {
  return (returnID >= 0);
}

void ParaminHooke::ReceiveValue() {
  int receive = net->receiveOne();
  if (receive == net->netError()) {
    cerr << "Error in Hooke - failed to receive data in linesearch\n";
    net->stopUsingDataGroup();
    exit(EXIT_FAILURE);
  }
  returnID = net->getReceiveID();
  if (MyDataGroup()) {
    iters++;
    freceive = net->getY(returnID);
  }
}

int ParaminHooke::UpdateOpt() {
  int newopt = 0;
  if (freceive < bestf) {
    bestf = freceive;
    bestx = net->getX(returnID);
    newopt = 1;
  }
  return newopt;
}

void ParaminHooke::SetPointNearby()  {
  int withinbounds = 0;
  int returnparam;
  returnparam = par[returnID];
  if (change[returnparam] == 1) {
    if (freceive < previousf[returnID])
      withinbounds = SetPoint(returnparam);
    else {
      delta[returnparam] = 0.0 - delta[returnparam];
      withinbounds = SetPoint(returnparam);
      if (withinbounds)
        change[returnparam]++;
    }
  }
}

void ParaminHooke::SetPointNextCoord()  {
  int withinbounds = 0;
  while ((numparamset < numvar) && withinbounds == 0) {
    withinbounds = SetPoint(param[numparamset]);
    if (withinbounds)
      change[param[numparamset]]++;
    numparamset++;
  }
}
void ParaminHooke::Print(ofstream& outfile, int prec) {
 outfile << "; Hooke & Jeeves algorithm ran for " << iters
    << " function evaluations\n; and stopped when the likelihood value was "
    << setprecision(prec) << score;
  if (converge == -1)
    outfile << "\n; because an error occured during the optimisation\n";
  else if (converge == 1)
    outfile << "\n; because the convergence criteria were met\n";
  else
    outfile << "\n; because the maximum number of function evaluations was reached\n";
}

root@forge.cesga.es
ViewVC Help
Powered by ViewVC 1.0.0  

Powered By FusionForge