source/numeric/cycliccoordinate.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/cycliccoordinate.hxx"
00029 #include "numeric/exception.hxx"
00030 #include "numeric/nlpmodel.hxx"
00031 #include "numeric/funcobj.hxx"
00032 #include "numeric/quadfitlinesearch.hxx"
00033 #include "numeric/type.hxx"
00034 
00035 #include <cmath>
00036 #include <stdio.h>
00037 
00038 using namespace ::scsolver::numeric;
00039 using ::std::vector;
00040 
00041 namespace scsolver { namespace numeric { namespace nlp {
00042 
00043 CyclicCoordinate::CyclicCoordinate() :
00044     BaseAlgorithm(),
00045     m_maxIteration(2000),
00046     m_debug(false)
00047 {
00048 }
00049 
00050 CyclicCoordinate::~CyclicCoordinate()
00051 {
00052 }
00053 
00054 void CyclicCoordinate::debugPrint(const vector<double>& vars, const char* msg) const
00055 {
00056     if (!m_debug)
00057         return;
00058 
00059     FILE* fs = stdout;
00060     fprintf(fs, "%s: (", msg);
00061     size_t n = vars.size();
00062     for (size_t i = 0; i < n; ++i)
00063     {
00064         if (i > 0)
00065             fprintf(fs, ", ");
00066         fprintf(fs, "%g", vars[i]);
00067     }
00068     fprintf(fs, ")\n");
00069 }
00070 
00071 static double calcDeltaDistance(const vector<double>& dists)
00072 {
00073     double dist = 0.0;
00074     vector<double>::const_iterator itr = dists.begin(), itrEnd = dists.end();
00075     for (; itr != itrEnd; ++itr)
00076         dist += (*itr) * (*itr);
00077 
00078     dist = ::std::pow(dist, 1.0/static_cast<double>(dists.size()));
00079     return dist;
00080 }
00081 
00082 void CyclicCoordinate::solve()
00083 {
00084     const double eps = 1.0e-5;
00085 
00086     Model& model = *getModel();
00087     model.print();
00088     BaseFuncObj& F = *model.getFuncObject();
00089 
00090     vector<double> vars;
00091     model.getVars(vars);
00092     double fval = F(vars);
00093     if (m_debug)
00094     {
00095         debugPrint(vars, "initial vars");
00096         printf("F(x) = %g\n", fval);
00097     }
00098 
00099     // Iterate cyclically.
00100     size_t varCount = vars.size();
00101     double dist = 0.0;
00102     vector<double> deltas(varCount);
00103     for (size_t i = 0; i < m_maxIteration; ++i)
00104     {
00105         if (m_debug)
00106             printf("ITERATION %d\n", i);
00107 
00108         for (size_t varIndex = 0; varIndex < varCount; ++varIndex)
00109         {
00110             SingleVarFuncObj& rSingleFuncObj = F.getSingleVarFuncObj(varIndex);
00111             QuadFitLineSearch qfit(&rSingleFuncObj);
00112             qfit.setGoal(GOAL_MINIMIZE);
00113             qfit.setDebug(false);
00114             double res = qfit.solve();
00115             F.setVar(varIndex, res);
00116             deltas[varIndex] = res - deltas[varIndex];
00117         }
00118         const vector<double>& tmpVars = F.getVars();
00119         dist = calcDeltaDistance(deltas);
00120         debugPrint(tmpVars, "  after the iteration"); 
00121         debugPrint(deltas, "  deltas");
00122         if (m_debug)
00123         {
00124             printf("  dist = %g\n", dist);
00125             printf("  F(x) = %g\n", F.eval());
00126         }
00127         if (dist < eps)
00128             return;
00129 
00130         deltas = tmpVars;
00131     }
00132 
00133     throw ModelInfeasible();
00134 }
00135 
00136 }}}

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