00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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 }}}