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 < ((int)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
00084 const QVVector step = (secondGridPoint - firstGridPoint)/(divisions-1);
00085 QVTensorIterator iterator(QVector<int>(vectorSize ,divisions));
00086 QList<QVVector> startingVectors;
00087 do {
00088 QVVector startingVector(vectorSize);
00089 for (int i = 0; i < vectorSize; i++)
00090 startingVector[i] = firstGridPoint[i] + step[i] * iterator.getIndex(i);
00091 if (!startingVectors.contains(startingVector))
00092 startingVectors.append(startingVector);
00093 } while(iterator.nextVector());
00094
00096
00097 QList<QVVector> solutions;
00098 QVVector minVector;
00099 double minValue = std::numeric_limits<double>::max();
00100 foreach(QVVector startingVector, startingVectors)
00101 {
00102
00103
00104
00105
00106 setStartingVector(startingVector);
00107 if (!iterate(maxIterations, maxError))
00108 continue;
00109
00110 solutions.append(getMinimum());
00111
00112
00113
00114 if (getMinimumValue() < minValue)
00115 {
00116 minValue = getMinimumValue();
00117 minVector = getMinimum();
00118 }
00119
00120 }
00121
00122
00123
00124 setMinimum(minVector);
00125 setMinimumValue(minValue);
00126
00127
00128
00129
00130 return solutions;
00131 }