extended MinProblemSolver::Function to 1) report the space dimensionality, 2) compute gradient if needed

This commit is contained in:
Vadim Pisarevsky 2015-05-05 15:56:06 +03:00
parent 5b9182ba43
commit 63a63e3eaa
5 changed files with 32 additions and 5 deletions

View File

@ -63,9 +63,11 @@ public:
class CV_EXPORTS Function
{
public:
virtual ~Function() {}
virtual double calc(const double* x) const = 0;
virtual void getGradient(const double* /*x*/,double* /*grad*/) {}
virtual ~Function() {}
virtual int getDims() const = 0;
virtual double getGradientEps() const;
virtual double calc(const double* x) const = 0;
virtual void getGradient(const double* x,double* grad);
};
/** @brief Getter for the optimized function.

View File

@ -46,6 +46,25 @@
namespace cv
{
double MinProblemSolver::Function::getGradientEps() const { return 1e-3; }
void MinProblemSolver::Function::getGradient(const double* x, double* grad)
{
double eps = getGradientEps();
int i, n = getDims();
AutoBuffer<double> x_buf(n);
double* x_ = x_buf;
for( i = 0; i < n; i++ )
x_[i] = x[i];
for( i = 0; i < n; i++ )
{
x_[i] = x[i] + eps;
double y1 = calc(x_);
x_[i] = x[i] - eps;
double y0 = calc(x_);
grad[i] = (y1 - y0)/(2*eps);
x_[i] = x[i];
}
}
#define SEC_METHOD_ITERATIONS 4
#define INITIAL_SEC_METHOD_SIGMA 0.1

View File

@ -235,6 +235,7 @@ protected:
inline void createInitialSimplex( const Mat& x0, Mat& simplex, Mat& step )
{
int i, j, ndim = step.cols;
CV_Assert( _Function->getDims() == ndim );
Mat x = x0;
if( x0.empty() )
x = Mat::zeros(1, ndim, CV_64F);

View File

@ -60,16 +60,19 @@ static void mytest(cv::Ptr<cv::ConjGradSolver> solver,cv::Ptr<cv::MinProblemSolv
class SphereF_CG:public cv::MinProblemSolver::Function{
public:
int getDims() const { return 4; }
double calc(const double* x)const{
return x[0]*x[0]+x[1]*x[1]+x[2]*x[2]+x[3]*x[3];
}
void getGradient(const double* x,double* grad){
// use automatically computed gradient
/*void getGradient(const double* x,double* grad){
for(int i=0;i<4;i++){
grad[i]=2*x[i];
}
}
}*/
};
class RosenbrockF_CG:public cv::MinProblemSolver::Function{
int getDims() const { return 2; }
double calc(const double* x)const{
return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+(1-x[0])*(1-x[0]);
}

View File

@ -68,11 +68,13 @@ static void mytest(cv::Ptr<cv::DownhillSolver> solver,cv::Ptr<cv::MinProblemSolv
class SphereF:public cv::MinProblemSolver::Function{
public:
int getDims() const { return 2; }
double calc(const double* x)const{
return x[0]*x[0]+x[1]*x[1];
}
};
class RosenbrockF:public cv::MinProblemSolver::Function{
int getDims() const { return 2; }
double calc(const double* x)const{
return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+(1-x[0])*(1-x[0]);
}