PARP Research Group University of Murcia, Spain


src/qvmath/qvmultidimensionalminimizer.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <QVMultidimensionalMinimizer>
00026 
00027 double QVMultidimensionalMinimizer::static_function (const gsl_vector *v, void *multidimensionalMinimizerPtr)
00028         {
00029         QVMultidimensionalMinimizer *multidimensionalMinimizer =
00030                 (QVMultidimensionalMinimizer *) multidimensionalMinimizerPtr;
00031 
00033         for (int i = 0; i < v->size; i++)
00034                 multidimensionalMinimizer->actual[i] = gsl_vector_get(v, i);
00035 
00036         return multidimensionalMinimizer->function(multidimensionalMinimizer->actual);
00037         }
00038 
00039 bool QVMultidimensionalMinimizer::iterate(const int maxIterations, const double maxError)
00040         {
00041         // 1. Get first point and step direction
00043         gsl_vector *x = gsl_vector_alloc (actual.size());
00044         for(int i=0; i < actual.size(); i++)
00045                 gsl_vector_set (x, i, actual[i]);
00046         
00048         gsl_vector *step_direction = gsl_vector_alloc (step.size());
00049         for(int i=0; i < step.size(); i++)
00050                 gsl_vector_set (step_direction, i, step[i]);
00051 
00052         // 2. Create GSL minimization structures.
00053         gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (gsl_multimin_fminimizer_nmsimplex, vectorSize);
00054         gsl_multimin_function multimin_function = { &static_function, vectorSize, this };
00055         gsl_multimin_fminimizer_set (s, &multimin_function, x, step_direction);
00056 
00057         // 3. Proceed to iterate.
00058         iterations = 0;
00059         int status = GSL_CONTINUE;
00060         while (status == GSL_CONTINUE && iterations++ <= maxIterations)
00061                 if (status = gsl_multimin_fminimizer_iterate (s))
00062                         break;
00063                 else
00064                         status = gsl_multimin_test_size (gsl_multimin_fminimizer_size (s), maxError);
00065 
00066         minimumValue = gsl_multimin_fminimizer_minimum(s);
00067 
00068         // 4. Release GSL minimization structures.
00069         gsl_multimin_fminimizer_free (s);
00070         gsl_vector_free (x);
00071         gsl_vector_free (step_direction);
00072 
00073         // 5. Return optimization status.
00074         return (status == GSL_SUCCESS);
00075         }
00076 
00077 #include <qvmath/qvtensorindexator.h>
00078 const QList<QVVector> QVMultidimensionalMinimizer::gridIterate(const QVVector &firstGridPoint, const QVVector &secondGridPoint, const int divisions, const int maxIterations, const double maxError)
00079         {
00080         Q_ASSERT(vectorSize == secondGridPoint.size());
00081         Q_ASSERT(firstGridPoint.size() == secondGridPoint.size());
00082 
00083         const QVVector step = (secondGridPoint - firstGridPoint)/(divisions-1);
00084         QVTensorIterator iterator(QVector<int>(vectorSize ,divisions));
00085 
00086         QList<QVVector> solutions;
00087         QVVector minVector;
00088         double  minValue = std::numeric_limits<double>::max();
00089         do      {
00090                 QVVector startingVector(vectorSize);
00091                 for (int i = 0; i < vectorSize; i++)
00092                         startingVector[i] = firstGridPoint[i] + step[i] * iterator.getIndex(i);
00093                 setStartingVector(startingVector);
00094                 if (!iterate(maxIterations, maxError))
00095                         continue;
00096 
00097                 solutions.append(getMinimum());
00098 
00099                 //std::cout << startingVector << "\tf("<< getMinimum() << ") = " << getMinimumValue() << std::endl;
00100 
00101                 if (getMinimumValue() < minValue)
00102                         {
00103                         minValue = getMinimumValue();
00104                         minVector = getMinimum(); 
00105                         }
00106 
00107                 } while(iterator.nextVector());
00108 
00109         //std::cout << "Minimum: f(" << minVector << ") = " << minValue << std::endl;
00110 
00111         setMinimum(minVector);
00112         setMinimumValue(minValue);
00113         //actual = minVector;
00114         //minimumValue = minValue;
00115 
00116         //std::cout << "Minimum: f(" << getMinimum() << ") = " << getMinimumValue() << std::endl;
00117         return solutions;
00118         }



QVision framework. PARP research group, copyright 2007, 2008.