source/numeric/hookejeeves.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  The Contents of this file are made available subject to
00004  *  the terms of GNU Lesser General Public License Version 2.1.
00005  *
00006  *
00007  *    GNU Lesser General Public License Version 2.1
00008  *    =============================================
00009  *    Copyright 2008 by Kohei Yoshida.
00010  *    1039 Kingsway Dr., Apex, NC 27502, USA
00011  *
00012  *    This library is free software; you can redistribute it and/or
00013  *    modify it under the terms of the GNU Lesser General Public
00014  *    License version 2.1, as published by the Free Software Foundation.
00015  *
00016  *    This library is distributed in the hope that it will be useful,
00017  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *    Lesser General Public License for more details.
00020  *
00021  *    You should have received a copy of the GNU Lesser General Public
00022  *    License along with this library; if not, write to the Free Software
00023  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00024  *    MA  02111-1307  USA
00025  *
00026  ************************************************************************/
00027 
00028 #include "numeric/hookejeeves.hxx"
00029 #include "numeric/exception.hxx"
00030 #include "numeric/nlpmodel.hxx"
00031 #include "numeric/funcobj.hxx"
00032 #include "numeric/quadfitlinesearch.hxx"
00033 
00034 #include <cmath>
00035 #include <stdio.h>
00036 
00037 using namespace ::scsolver::numeric;
00038 using ::std::vector;
00039 
00040 namespace scsolver { namespace numeric { namespace nlp {
00041 
00042 HookeJeeves::HookeJeeves() :
00043     BaseAlgorithm(),
00044     m_maxIteration(10000)
00045 {
00046 }
00047 
00048 HookeJeeves::~HookeJeeves()
00049 {
00050 }
00051 
00052 static void debugPrint(const vector<double>& vars, const char* msg, bool debug)
00053 {
00054     if (!debug)
00055         return;
00056 
00057     FILE* fs = stdout;
00058     fprintf(fs, "%s: (", msg);
00059     size_t n = vars.size();
00060     for (size_t i = 0; i < n; ++i)
00061     {
00062         if (i > 0)
00063             fprintf(fs, ", ");
00064         fprintf(fs, "%g", vars[i]);
00065     }
00066     fprintf(fs, ")\n");
00067 }
00068 
00069 static double calcDeltaDistance(const vector<double>& pt1, const vector<double>& pt2)
00070 {
00071     size_t n = pt1.size();
00072     if (n != pt2.size())
00073         throw Exception("size of the current point differs from the size of the previous point.");
00074 
00075     double dist = 0.0;
00076     for (size_t i = 0; i < n; ++i)
00077     {
00078         double one = pt2[i] - pt1[i];
00079         one *= one;
00080         dist += one;
00081     }
00082 
00083     dist = ::std::pow(dist, 1.0/static_cast<double>(n));
00084     return dist;
00085 }
00086 
00087 static void getPatternSearchVector(const vector<double>& pt1, const vector<double>& pt2, 
00088                                    vector<double>& vec)
00089 {
00090     using ::scsolver::numeric::Exception;
00091 
00092     size_t n = pt1.size();
00093     if (n != pt2.size())
00094         throw Exception("size of the current point differs from the size of the previous point.");
00095 
00096     vector<double> tmp(n);
00097     for (size_t i = 0; i < n; ++i)
00098         tmp[i] = pt2[i] - pt1[i];
00099     vec.swap(tmp);
00100 }
00101 
00102 void HookeJeeves::solve()
00103 {
00104     const double eps = 1.0e-6;
00105     bool debug = isDebug();
00106     Model& model = *getModel();
00107     model.print();
00108     BaseFuncObj& F = *model.getFuncObject();
00109 
00110     vector<double> vars;
00111     model.getVars(vars);
00112     double fval = F(vars);
00113     if (debug)
00114     {
00115         debugPrint(vars, "initial vars", debug);
00116         printf("F(x) = %g\n", fval);
00117     }
00118 
00119     // Iterate cyclically along the axes.
00120     size_t varCount = vars.size();
00121     vector<double> prevVars(vars);
00122     for (size_t i = 0; i < m_maxIteration; ++i)
00123     {
00124         if (debug)
00125             printf("ITERATION %d\n", i);
00126 
00127         for (size_t varIndex = 0; varIndex < varCount; ++varIndex)
00128         {
00129             SingleVarFuncObj& rSingleFuncObj = F.getSingleVarFuncObj(varIndex);
00130             QuadFitLineSearch qfit(&rSingleFuncObj);
00131             qfit.setGoal(GOAL_MINIMIZE);
00132             qfit.setDebug(false);
00133             double res = qfit.solve();
00134             F.setVar(varIndex, res);
00135         }
00136         const vector<double>& tmpVars = F.getVars();
00137         debugPrint(tmpVars, "  after the iteration", debug); 
00138         if (debug)
00139         {
00140             printf("  F(x) = %g\n", F.eval());
00141         }
00142 
00143         double dist = calcDeltaDistance(prevVars, tmpVars);
00144         if (debug)
00145             printf("  distance = %g\n", dist);
00146 
00147         if (dist < eps)
00148             return;
00149         
00150         vector<double> vec;
00151         getPatternSearchVector(prevVars, tmpVars, vec);
00152         debugPrint(vec, "pattern search vector", debug);
00153         SingleVarFuncObj& rSingleFuncObj = F.getSingleVarFuncObjByRatio(vec);
00154         QuadFitLineSearch qfit(&rSingleFuncObj);
00155         qfit.setGoal(GOAL_MINIMIZE);
00156         qfit.setDebug(false);
00157         qfit.solve();
00158         const vector<double>& tmpVars2 = F.getVars();
00159         debugPrint(tmpVars2, "end of pattern search", debug);
00160         
00161         prevVars = tmpVars2;
00162     }
00163 
00164     throw ModelInfeasible();
00165 }
00166 
00167 }}}

Generated on Mon Jul 28 09:13:20 2008 for scsolver by  doxygen 1.5.3