source/numeric/bisectionsearch.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/bisectionsearch.hxx"
00029 #include "numeric/exception.hxx"
00030 #include "numeric/funcobj.hxx"
00031 #include "numeric/diff.hxx"
00032 
00033 namespace scsolver { namespace numeric {
00034 
00035 BisectionSearch::BisectionSearch(double lower, double upper) :
00036     BaseLineSearch(),
00037     m_lowerBound(lower),
00038     m_upperBound(upper),
00039     m_maxIteration(100)
00040 {
00041 }
00042 
00043 BisectionSearch::~BisectionSearch()
00044 {
00045 }
00046 
00047 double BisectionSearch::solve()
00048 {
00049     SingleVarFuncObj* pFuncObj = getFuncObj();
00050     bool debug = isDebug();
00051     if (!pFuncObj)
00052         throw Exception("BisectionSearch::solve: no function object set");
00053 
00054     if (debug)
00055         fprintf(stdout, "BisectionSearch::solve:   function = %s\n", pFuncObj->getFuncString().c_str());
00056 
00057     SingleVarFuncObj& F = *pFuncObj;
00058     NumericalDiffer diff;
00059     diff.setFuncObject(pFuncObj);
00060     double oldInterval = 0.0;
00061 
00062     for (size_t i = 0; i < m_maxIteration; ++i)
00063     {
00064         if (debug)
00065             fprintf(stdout, "BisectionSearch::solve: ITERATION %d\n", i);
00066 
00067         double interval = m_upperBound - m_lowerBound;
00068         if (interval < 3.89e-15 || oldInterval == interval)
00069         {
00070             if (i == 0)
00071                 throw Exception("BisectionSearch::solve: interval is already too small in the first iteration");
00072 
00073             // range has become significantly small, or the interval has not 
00074             // shrunk since the previous interation.
00075             return m_lowerBound;
00076         }
00077 
00078         double x = m_lowerBound + interval/2.0;
00079         diff.setVariable(x);
00080         double ff = diff.run();
00081         if (debug)
00082         {
00083             fprintf(stdout, "BisectionSearch::solve:   f(%g) = %g; f'(%g) = %g\n", 
00084                     x, F(x), x, ff);
00085             fprintf(stdout, "BisectionSearch::solve:   range: %g - %g (interval = %g)\n",
00086                     m_lowerBound, m_upperBound, interval);
00087         }
00088 
00089         if ((ff > 0 ? ff : -ff) < 3.89e-15)
00090             // f'(x) is close enough to zero to be zero-equivalent.
00091             return x;
00092 
00093         if (ff > 0)
00094             // minimum occurs to the left of current position.
00095             m_upperBound = x;
00096         else
00097             // minimum occurs to the right of current position.
00098             m_lowerBound = x;
00099 
00100         oldInterval = interval;
00101     }
00102 
00103     throw MaxIterationReached();
00104     return 0.0;
00105 }
00106 
00107 }}

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