public:
virtual ~Function() {}
//! ndim - dimensionality
- virtual double calc(const double* x) const = 0;
+ virtual double calc(const double* x) const = 0;
};
virtual Ptr<Function> getFunction() const = 0;
optim::DownhillSolver::getFunction
--------------------------------------------
-Getter for the optimized function. The optimized function is represented by ``Solver::Function`` interface, which requires
+Getter for the optimized function. The optimized function is represented by ``Solver::Function`` interface, which requires
derivatives to implement the sole method ``calc(double*)`` to evaluate the function.
.. ocv:function:: Ptr<Solver::Function> optim::DownhillSolver::getFunction()
optim::DownhillSolver::minimize
-----------------------------------
-The main method of the ``DownhillSolver``. It actually runs the algorithm and performs the minimization. The sole input parameter determines the
+The main method of the ``DownhillSolver``. It actually runs the algorithm and performs the minimization. The sole input parameter determines the
centroid of the starting simplex (roughly, it tells where to start), all the others (terminal criteria, initial step, function to be minimized)
are supposed to be set via the setters before the call to this method or the default values (not always sensible) will be used.
};
double DownhillSolverImpl::try_new_point(
- Mat_<double>& p,
+ Mat_<double>& p,
Mat_<double>& y,
- Mat_<double>& coord_sum,
+ Mat_<double>& coord_sum,
const Ptr<Solver::Function>& f,
- int ihi,
+ int ihi,
double fac,
Mat_<double>& ptry
)
int ndim=p.cols;
int j;
double fac1,fac2,ytry;
-
+
fac1=(1.0-fac)/ndim;
fac2=fac1-fac;
- for (j=0;j<ndim;j++)
+ for (j=0;j<ndim;j++)
{
ptry(j)=coord_sum(j)*fac1-p(ihi,j)*fac2;
}
ytry=f->calc((double*)ptry.data);
- if (ytry < y(ihi))
+ if (ytry < y(ihi))
{
y(ihi)=ytry;
- for (j=0;j<ndim;j++)
+ for (j=0;j<ndim;j++)
{
coord_sum(j) += ptry(j)-p(ihi,j);
p(ihi,j)=ptry(j);
}
}
-
+
return ytry;
}
form a simplex - each row is an ndim vector.
On output, nfunk gives the number of function evaluations taken.
*/
- double DownhillSolverImpl::inner_downhill_simplex(
- cv::Mat_<double>& p,
+ double DownhillSolverImpl::inner_downhill_simplex(
+ cv::Mat_<double>& p,
double MinRange,
double MinError,
int& nfunk,
Mat_<double> coord_sum(1,ndim,0.0),buf(1,ndim,0.0),y(1,ndim,0.0);
nfunk = 0;
-
+
for(i=0;i<ndim+1;++i)
{
y(i) = f->calc(p[i]);
}
nfunk = ndim+1;
-
+
compute_coord_sum(p,coord_sum);
-
- for (;;)
+
+ for (;;)
{
ilo=0;
/* find highest (worst), next-to-worst, and lowest
(best) points by going through all of them. */
ihi = y(0)>y(1) ? (inhi=1,0) : (inhi=0,1);
- for (i=0;i<mpts;i++)
+ for (i=0;i<mpts;i++)
{
- if (y(i) <= y(ilo))
+ if (y(i) <= y(ilo))
ilo=i;
- if (y(i) > y(ihi))
+ if (y(i) > y(ihi))
{
inhi=ihi;
ihi=i;
- }
- else if (y(i) > y(inhi) && i != ihi)
+ }
+ else if (y(i) > y(inhi) && i != ihi)
inhi=i;
}
if(range < d) range = d;
}
- if(range <= MinRange || error <= MinError)
+ if(range <= MinRange || error <= MinError)
{ /* Put best point and value in first slot. */
std::swap(y(0),y(ilo));
- for (i=0;i<ndim;i++)
+ for (i=0;i<ndim;i++)
{
std::swap(p(0,i),p(ilo,i));
}
{ /*If that's better than the best point, go twice as far in that direction*/
ytry = try_new_point(p,y,coord_sum,f,ihi,2.0,buf);
}
- else if (ytry >= y(inhi))
+ else if (ytry >= y(inhi))
{ /* The new point is worse than the second-highest, but better
than the worst so do not go so far in that direction */
ysave = y(ihi);
ytry = try_new_point(p,y,coord_sum,f,ihi,0.5,buf);
- if (ytry >= ysave)
+ if (ytry >= ysave)
{ /* Can't seem to improve things. Contract the simplex to good point
in hope to find a simplex landscape. */
- for (i=0;i<mpts;i++)
+ for (i=0;i<mpts;i++)
{
- if (i != ilo)
+ if (i != ilo)
{
for (j=0;j<ndim;j++)
{
#include <cmath>
#include <algorithm>
-static void mytest(cv::Ptr<cv::optim::DownhillSolver> solver,cv::Ptr<cv::optim::Solver::Function> ptr_F,cv::Mat& x,cv::Mat& step,
+static void mytest(cv::Ptr<cv::optim::DownhillSolver> solver,cv::Ptr<cv::optim::Solver::Function> ptr_F,cv::Mat& x,cv::Mat& step,
cv::Mat& etalon_x,double etalon_res){
solver->setFunction(ptr_F);
int ndim=MAX(step.cols,step.rows);