testLineMinimizer.C 2.46 KB
Newer Older
1 2 3 4 5 6 7
////////////////////////////////////////////////////////////////////////////////
//
// testLineMinimizer.C
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
8 9
#include <cassert>
#include <cstdlib>
10 11 12 13
#include "LineMinimizer.h"
using namespace std;

const double fac = 0.1;
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
void ff(int ifun, double x, double *f, double *g)
{
  const double s = 0.45;
  switch (ifun)
  {
    case 1:
      *f = fac*(x*x*x*x -100*x*x - 100*x);
      *g = fac*(4*x*x*x - 200*x - 100);
      break;

    case 2:
      *f = fac*(x*x*x*x);
      *g = fac*(4*x*x*x);
      break;

    case 3:
      // function (3.1) of More and Thuente
      if ( x <= 1.0 )
      {
        double s = 0.3;
        *f = 0.5*(1.0-s)*x*x - x;
        *g = (1.0-s)*x - 1.0;
      }
      else
      {
        *f = 0.5*(s-1.0) - s*x;
        *g = -s;
      }
      break;

    case 4:
      // function (3.3) of More and Thuente
      *f = -3*x/(x*x+2.0) - 0.03*x;
      *g = (-3*(x*x+2.0) + 6*x*x)/((x*x+2)*(x*x+2)) - 0.03;
      break;

    default:
      cout << "incorrect ifun value" << endl;
      assert(false);
  }
}

56 57 58
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
59 60
  // use: testLineMinimizer ifun niter xstart sigma1 sigma2 alpha_start
  if ( argc != 7 )
61
  {
62
    cout << "use:testLineMinimizer ifun, niter xstart sigma1 sigma2 alpha_start"
63 64 65 66
         << endl;
    return 1;
  }

67 68 69 70 71 72 73 74
  const int ifun = atoi(argv[1]);
  const int n = atoi(argv[2]);
  double x = atof(argv[3]);
  const double sigma1 = atof(argv[4]);
  const double sigma2 = atof(argv[5]);
  const double alpha_start = atof(argv[6]);
  double x0 = x;
  double f,g;
75 76 77 78 79
  double alpha = 0;
  LineMinimizer linmin;
  linmin.set_sigma1(sigma1);
  linmin.set_sigma2(sigma2);
  linmin.set_alpha_start(alpha_start);
80
  linmin.set_debug_print();
81 82

  // descent direction p
83 84
  ff(ifun,x0,&f,&g);
  double p = -g;
85 86 87 88 89

  bool done = false;
  int i = 0;
  while ( !done && i < n )
  {
90
    cout << "========================================================" << endl;
91
    i++;
92
    ff(ifun,x,&f,&g);
93 94 95 96 97 98 99 100 101 102 103
    // fp = derivative in the descent direction p
    double fp = g * p;
    done = linmin.done();
    cout << "i=" << i << " x=" << x << " f=" << f << " fp=" << fp << endl;
    if ( !done )
    {
      alpha = linmin.next_alpha(alpha,f,fp);
      cout << "alpha=" << alpha << endl;
      x = x0 + alpha * p;
    }
  }
104
  cout << "========================================================" << endl;
105
}