00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
00069 gsl_multimin_fminimizer_free (s);
00070 gsl_vector_free (x);
00071 gsl_vector_free (step_direction);
00072
00073
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
00100
00101 if (getMinimumValue() < minValue)
00102 {
00103 minValue = getMinimumValue();
00104 minVector = getMinimum();
00105 }
00106
00107 } while(iterator.nextVector());
00108
00109
00110
00111 setMinimum(minVector);
00112 setMinimumValue(minValue);
00113
00114
00115
00116
00117 return solutions;
00118 }