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/netgradient.cc
[mareframe] / trunk / paramin-beta / netgradient.cc Repository:
ViewVC logotype

View of /trunk/paramin-beta/netgradient.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: 4447 byte(s)
Initial version based on Gadget 2.2.00
#include "netgradient.h"
#include "mathfunc.h"

Gradient::~Gradient() {
}

NetGradient::NetGradient(int numVars) {
  difficultgrad = 1;
  delta0 = 0.01;
  delta1 = 0.0001;
  delta2 = 0.00001;
  delta = 0.0001;
  numVar = numVars;
  normgrad = -1.0;
  // Vector tempVec(numVars);
  // grad = tempVec;
  // diagHess = tempVec;
  diagHess.resize(numVar, 0.0);
  grad.resize(numVar, 0.0);
  // deltavec = tempVec;
  deltavec.resize(numVar, delta);
}

NetGradient::~NetGradient() {
}

void NetGradient::initializeDiagonalHessian() {
    /*int i;
  for (i = 0; i < numVar; i++)
    diagHess[i]= -1.0;
    */
    diagHess.Reset();
    diagHess.resize(numVar, -1.0);
}

void NetGradient::setXVectors(const DoubleVector& x, double f, NetInterface* netInt) {
  int i;
  double deltai;
  int numberOfx = 0;

  if (difficultgrad == 0)
    numberOfx = numVar + 1;
  else if (difficultgrad == 1)
    numberOfx = numVar * 2 + 1;
  else if (difficultgrad >= 2)
    numberOfx = numVar * 4 + 1;

  // initialize new datagroup for gradient computing and set current point
  netInt->startNewDataGroup(numberOfx);
  netInt->setDataPair(x, f);
  //netInt->setX(x);

  // compute x + hi * ei for all i
  DoubleVector tempVec(x);
  for (i = 0; i < numVar; i++) {
    deltai = deltavec[i] * (1.0 + fabs(tempVec[i]));
    tempVec[i] -= deltai;
    netInt->setX(tempVec);
    if (difficultgrad == 1) {
      tempVec[i] += 2 * deltai;
      netInt->setX(tempVec);
      tempVec[i] -= deltai;
    } else if (difficultgrad >= 2) {
      tempVec[i] += 0.5 * deltai;
      netInt->setX(tempVec);
      tempVec[i] += deltai;
      netInt->setX(tempVec);
      tempVec[i] += 0.5 * deltai;
      netInt->setX(tempVec);
      tempVec[i] -= deltai;
    }
  }
}

int NetGradient::computeGradient(NetInterface* net, const DoubleVector& x, double f, int difficultgradient) {

  difficult = 0;
  difficultgrad = difficultgradient;

  int i;
  double fx1, fx2, fx3, fx4;
  int SEND_RECEIVE = 0;
  setXVectors(x, f, net);
  SEND_RECEIVE = net->sendAndReceiveAllData();
  if (SEND_RECEIVE == -1) {
    cerr << "Error in netgradient - could not send or receive data\n";
    exit(EXIT_FAILURE);
  }

  int numfx = 1;
  fx0 = f;
  double deltai;
  normgrad = 0.0;

  //Calculate f(x + hi * ei) for all i
  for (i = 0;  i < numVar; i++) {
    deltai = (1.0 + fabs(x[i])) * deltavec[i];
    fx1 = net->getY(numfx);
    numfx++;

    if (difficultgrad == 1) {
      fx4 = net->getY(numfx);
      numfx++;
      grad[i] = (fx4 - fx1) / (2.0 * deltai);
      diagHess[i] = (fx4 - 2.0 * fx0 + fx1) / (deltai * deltai);

      //Check for difficultgrad
      if ((fx4 > fx0) && (fx1 > fx0))
        difficult = 1;

      if (fabs(fx4 - fx1) / fx0 < rathersmall) {  // may be running into roundoff
        deltavec[i] = min(delta0, deltavec[i] * 5.0);
        cerr << "Warning in netgradient - possible roundoff errors in gradient\n";
      }

    } else if (difficultgrad >= 2) {
      fx2 = net->getY(numfx);
      numfx++;
      fx3 = net->getY(numfx);
      numfx++;
      fx4 = net->getY(numfx);
      numfx++;
      grad[i] = (fx1 - fx4 + 8.0 * fx3 - 8.0 * fx2) / (12.0 * deltai);
      diagHess[i] = (fx4 - 2.0 * fx0 + fx1) / (deltai * deltai);

      if (fabs(fx4 - fx1) / fx0 < rathersmall) {  // may be running into roundoff
        deltavec[i] = min(delta0, deltavec[i] * 5.0);
        cerr << "Warning in netgradient - possible roundoff errors in gradient\n";
      }

    } else {
      grad[i] = (fx0 - fx1) / deltai;
      if (fabs(fx0 - fx1) / fx0 < rathersmall) {  // may be running into roundoff
        deltavec[i] = min(delta0, deltavec[i] * 5.0);
        cerr << "Warning in netgradient - possible roundoff errors in gradient\n";
      }
    }

    if (grad[i] > verybig) { // seem to be running outside the boundary
      deltavec[i] = max(delta1, deltavec[i] / 5.0);
      cerr << "Warning in netgradient - possible boundary errors in gradient\n";
    }
    normgrad += grad[i] * grad[i];
  }

  normgrad = sqrt(normgrad);
  difficultgrad += difficult;

  // finished computing gradient do not need datagroup anymore
  net->stopUsingDataGroup();
  return 1;
}

double NetGradient::getBaseFX() {
  return fx0;
}

const DoubleVector& NetGradient::getDiagonalHessian() {
  return diagHess;
}

double NetGradient::getNormGrad() {
  return normgrad;
}

const DoubleVector& NetGradient::getGradient() {
  return grad;
}

int NetGradient::getDifficultGrad() {
  return difficultgrad;
}

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

Powered By FusionForge