mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
extended MinProblemSolver::Function to 1) report the space dimensionality, 2) compute gradient if needed
This commit is contained in:
parent
5b9182ba43
commit
63a63e3eaa
@ -63,9 +63,11 @@ public:
|
|||||||
class CV_EXPORTS Function
|
class CV_EXPORTS Function
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Function() {}
|
virtual ~Function() {}
|
||||||
virtual double calc(const double* x) const = 0;
|
virtual int getDims() const = 0;
|
||||||
virtual void getGradient(const double* /*x*/,double* /*grad*/) {}
|
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.
|
/** @brief Getter for the optimized function.
|
||||||
|
@ -46,6 +46,25 @@
|
|||||||
|
|
||||||
namespace cv
|
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 SEC_METHOD_ITERATIONS 4
|
||||||
#define INITIAL_SEC_METHOD_SIGMA 0.1
|
#define INITIAL_SEC_METHOD_SIGMA 0.1
|
||||||
|
@ -235,6 +235,7 @@ protected:
|
|||||||
inline void createInitialSimplex( const Mat& x0, Mat& simplex, Mat& step )
|
inline void createInitialSimplex( const Mat& x0, Mat& simplex, Mat& step )
|
||||||
{
|
{
|
||||||
int i, j, ndim = step.cols;
|
int i, j, ndim = step.cols;
|
||||||
|
CV_Assert( _Function->getDims() == ndim );
|
||||||
Mat x = x0;
|
Mat x = x0;
|
||||||
if( x0.empty() )
|
if( x0.empty() )
|
||||||
x = Mat::zeros(1, ndim, CV_64F);
|
x = Mat::zeros(1, ndim, CV_64F);
|
||||||
|
@ -60,16 +60,19 @@ static void mytest(cv::Ptr<cv::ConjGradSolver> solver,cv::Ptr<cv::MinProblemSolv
|
|||||||
|
|
||||||
class SphereF_CG:public cv::MinProblemSolver::Function{
|
class SphereF_CG:public cv::MinProblemSolver::Function{
|
||||||
public:
|
public:
|
||||||
|
int getDims() const { return 4; }
|
||||||
double calc(const double* x)const{
|
double calc(const double* x)const{
|
||||||
return x[0]*x[0]+x[1]*x[1]+x[2]*x[2]+x[3]*x[3];
|
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++){
|
for(int i=0;i<4;i++){
|
||||||
grad[i]=2*x[i];
|
grad[i]=2*x[i];
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
};
|
};
|
||||||
class RosenbrockF_CG:public cv::MinProblemSolver::Function{
|
class RosenbrockF_CG:public cv::MinProblemSolver::Function{
|
||||||
|
int getDims() const { return 2; }
|
||||||
double calc(const double* x)const{
|
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]);
|
return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+(1-x[0])*(1-x[0]);
|
||||||
}
|
}
|
||||||
|
@ -68,11 +68,13 @@ static void mytest(cv::Ptr<cv::DownhillSolver> solver,cv::Ptr<cv::MinProblemSolv
|
|||||||
|
|
||||||
class SphereF:public cv::MinProblemSolver::Function{
|
class SphereF:public cv::MinProblemSolver::Function{
|
||||||
public:
|
public:
|
||||||
|
int getDims() const { return 2; }
|
||||||
double calc(const double* x)const{
|
double calc(const double* x)const{
|
||||||
return x[0]*x[0]+x[1]*x[1];
|
return x[0]*x[0]+x[1]*x[1];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class RosenbrockF:public cv::MinProblemSolver::Function{
|
class RosenbrockF:public cv::MinProblemSolver::Function{
|
||||||
|
int getDims() const { return 2; }
|
||||||
double calc(const double* x)const{
|
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]);
|
return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+(1-x[0])*(1-x[0]);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user