Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CubicLS.cpp

Go to the documentation of this file.
00001 //============================================================
00002 // COOOL           version 1.1           ---     Nov,  1995
00003 //   Center for Wave Phenomena, Colorado School of Mines
00004 //============================================================
00005 //
00006 //   This code is part of a preliminary release of COOOL (CWP
00007 // Object-Oriented Optimization Library) and associated class 
00008 // libraries. 
00009 //
00010 // The COOOL library is a free software. You can do anything you want
00011 // with it including make a fortune.  However, neither the authors,
00012 // the Center for Wave Phenomena, nor anyone else you can think of
00013 // makes any guarantees about anything in this package or any aspect
00014 // of its functionality.
00015 //
00016 // Since you've got the source code you can also modify the
00017 // library to suit your own purposes. We would appreciate it 
00018 // if the headers that identify the authors are kept in the 
00019 // source code.
00020 //
00021 //======================================================================
00022 // Definition of the cubic line search class
00023 // Armijo and Goldstein's line search algorithm
00024 // author:  Doug Hart, Adapted to the COOOL library by Wenceslau Gouveia
00025 // Modified to fit into new classes.  H. Lydia Deng, 02/21/94, 03/15/94
00026 //========================================================================
00027 
00028 
00029 #include <limits.h>
00030 #include <float.h>
00031 #include "CubicLS.hh"
00032 
00033 #define VERBOSE
00034 
00035 CubicLineSearch::CubicLineSearch(ObjectiveFunction* f, int it) 
00036 : LineSearch(f)
00037 {       iterMax =       it;
00038 }
00039 
00040 CubicLineSearch::CubicLineSearch(ObjectiveFunction* f, int it, Vector<double>* interval)
00041 : LineSearch(f,interval)
00042 {       iterMax =       it;
00043 }
00044 
00045 CubicLineSearch::~CubicLineSearch()     { if (fp != NULL) fp = NULL;}
00046 
00047 // Code for the Cubic Line Search
00048 Model<double> CubicLineSearch::search(Model<double>& current_solution, Vector<double>& p, double slope, double lambda)
00049 {
00050         int tst = 0;                                    // useful vars
00051         double alpha2=0, alpha_tmp=0, alpha_prev=0;
00052         double alpha_prev2=0, alpha=0;
00053         double f1=0, f2=0, fprev=0;
00054         double a=0, b=0;
00055         double c=0, cm11=0, cm12=0, cm21=0, cm22=0;
00056         double disc=0;
00057         double new_m=0, old_m=0;
00058         Model<double> new_solution(current_solution);
00059 
00060         
00061         old_m = fp->performance(current_solution);      // Evaluation at the  
00062                                                         // current solution
00063         iterNum = 0; iterNum++;                         // iteration counter
00064         alpha = 1.;                                     // updating step
00065 
00066         new_solution = current_solution.update(1,alpha,p);      // updating
00067         new_m = fp->performance(new_solution);          // Evaluation at the 
00068                                                         // new solution
00069         iterNum++;
00070 
00071         // Implementing Goldstein's test for alpha too small
00072         while (new_m < old_m + (1. - lambda)*alpha*slope && iterNum< iterMax)
00073         {
00074                 alpha *= 3;
00075                 new_solution = current_solution.update(1, alpha, p);
00076                 new_m = fp->performance(new_solution);
00077                 iterNum++;
00078         }
00079         if (iterNum == iterMax)
00080                 cerr << "Alpha over flowed! \n";
00081 
00082         // Armijo's test for alpha too large
00083         alpha_prev = alpha; // H.L. Deng, 6/13/95
00084         while (new_m > old_m + lambda*alpha*slope && iterNum < iterMax)
00085         {
00086                 alpha2 = alpha * alpha;
00087                 f1 = new_m - old_m - slope * alpha;
00088 
00089                 if (tst == 0)
00090                 {
00091                         alpha_tmp = -slope * alpha2 / (f1 * 2.);
00092                                                 // tentative alpha
00093 
00094                         tst = 1;
00095                 }
00096                 else
00097                 {
00098                         alpha_prev2 = alpha_prev * alpha_prev;
00099                         f2 = fprev - old_m - alpha_prev * slope;
00100 
00101                         c = 1. / (alpha - alpha_prev);
00102                         cm11 = 1. / alpha2;
00103                         cm12 = -1. / alpha_prev2;
00104                         cm21 = -alpha_prev / alpha2;
00105                         cm22 = alpha / alpha_prev2;
00106 
00107                         a = c * (cm11 * f1 + cm12 * f2);
00108                         b = c * (cm21 * f1 + cm22 * f2);
00109                         disc = b * b - 3. * a * slope;
00110 
00111                         if ((Abs(a) > FLT_MIN) && (disc > FLT_MIN))
00112                                 alpha_tmp = (-b + sqrt(disc)) / (3. * a);
00113                         else
00114                                 alpha_tmp = slope * alpha2 / (2. * f1);
00115 
00116                         if (alpha_tmp >= .5 * alpha)
00117                                 alpha_tmp = .5 * alpha;
00118                 }
00119                 alpha_prev = alpha;
00120                 fprev = new_m;
00121 
00122                 if (alpha_tmp < .1 * alpha)
00123                         alpha *= .1;
00124                 else
00125                         alpha = alpha_tmp;
00126 
00127                 new_solution = current_solution.update(1, alpha, p);
00128                 new_m = fp->performance(new_solution);
00129                 iterNum++;
00130         }
00131 #ifdef COOOL_VERBOSE
00132         if (iterNum == iterMax)
00133                 cerr << "Alpha under flowed! \n";
00134 #endif
00135         value = new_m;
00136         appendSearchNumber();
00137         return (new_solution);                          // # of iterations
00138 }
00139 
00140 Model<long> CubicLineSearch::search(Model<long>& current_solution, Vector<double>& p, double slope, double lambda)
00141 {
00142     Model<double> temp(current_solution);
00143     temp = search(temp, p, slope, lambda);
00144     Model<long> optm(temp);
00145     return optm;
00146 }

Generated on Wed Dec 15 21:20:28 2004 for vuVolume by  doxygen 1.3.9.1