Commit b655d51e authored by Davis King's avatar Davis King

- Fixed a bug in find_max_single_variable(). It was missing a - sign on the return.

- changed the find_*_single_variable() functions so that their interfaces are like
  the other find_* functions.
- Made the verbose printout from feature ranking more reasonable.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403238
parent 3fb3b86c
...@@ -441,9 +441,9 @@ namespace dlib ...@@ -441,9 +441,9 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename funct> template <typename funct>
std::pair<double,double> find_min_single_variable ( double find_min_single_variable (
const funct& f, const funct& f,
const double starting_point, double& starting_point,
const double begin = -1e200, const double begin = -1e200,
const double end = 1e200, const double end = 1e200,
const double eps = 1e-3, const double eps = 1e-3,
...@@ -463,11 +463,9 @@ namespace dlib ...@@ -463,11 +463,9 @@ namespace dlib
double p1=0, p2=0, p3=0, f1=0, f2=0, f3=0; double p1=0, p2=0, p3=0, f1=0, f2=0, f3=0;
long f_evals = 1; long f_evals = 1;
const std::pair<double,double> p(starting_point, f(starting_point));
if (begin == end) if (begin == end)
{ {
return p; return f(starting_point);
} }
using std::abs; using std::abs;
...@@ -481,27 +479,20 @@ namespace dlib ...@@ -481,27 +479,20 @@ namespace dlib
// The first thing we do is get a starting set of 3 points that are inside the [begin,end] bounds // The first thing we do is get a starting set of 3 points that are inside the [begin,end] bounds
p1 = max(p.first-1, begin); p1 = max(starting_point-1, begin);
p3 = min(p.first+1, end); p3 = min(starting_point+1, end);
if (p1 == p.first) f1 = f(p1);
f1 = p.second; f3 = f(p3);
else
f1 = f(p1);
if (p3 == p.first) if (starting_point == p1 || starting_point == p3)
f3 = p.second;
else
f3 = f(p3);
if (p.first == p1 || p.first == p3)
{ {
p2 = (p1+p3)/2; p2 = (p1+p3)/2;
f2 = f(p2); f2 = f(p2);
} }
else else
{ {
p2 = p.first; p2 = starting_point;
f2 = p.second; f2 = f(starting_point);
} }
f_evals += 2; f_evals += 2;
...@@ -514,10 +505,20 @@ namespace dlib ...@@ -514,10 +505,20 @@ namespace dlib
// check for hitting max_iter or if the interval is now too small // check for hitting max_iter or if the interval is now too small
if (f_evals >= max_iter || p3-p1 < eps) if (f_evals >= max_iter || p3-p1 < eps)
{ {
if (f1 < min(f2,f3)) return std::make_pair(p1, f1); if (f1 < min(f2,f3))
if (f2 < min(f1,f3)) return std::make_pair(p2, f2); {
starting_point = p1;
return f1;
}
if (f2 < min(f1,f3))
{
starting_point = p2;
return f2;
}
return std::make_pair(p3, f3); starting_point = p3;
return f3;
} }
// if f1 is small then take a step to the left // if f1 is small then take a step to the left
...@@ -672,22 +673,23 @@ namespace dlib ...@@ -672,22 +673,23 @@ namespace dlib
++f_evals; ++f_evals;
} }
return std::make_pair(p2, f2); starting_point = p2;
return f2;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename funct> template <typename funct>
std::pair<double,double> find_max_single_variable ( double find_max_single_variable (
const funct& f, const funct& f,
const double starting_point, double& starting_point,
const double begin = -1e200, const double begin = -1e200,
const double end = 1e200, const double end = 1e200,
const double eps = 1e-3, const double eps = 1e-3,
const long max_iter = 100 const long max_iter = 100
) )
{ {
return find_min_single_variable(negate_function(f), starting_point, begin, end, eps, max_iter); return -find_min_single_variable(negate_function(f), starting_point, begin, end, eps, max_iter);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -176,9 +176,9 @@ namespace dlib ...@@ -176,9 +176,9 @@ namespace dlib
template < template <
typename funct typename funct
> >
std::pair<double,double> find_min_single_variable ( double find_min_single_variable (
const funct& f, const funct& f,
const double starting_point, double& starting_point,
const double begin = -1e200, const double begin = -1e200,
const double end = 1e200, const double end = 1e200,
const double eps = 1e-3, const double eps = 1e-3,
...@@ -198,7 +198,8 @@ namespace dlib ...@@ -198,7 +198,8 @@ namespace dlib
- Evaluates f() no more than max_iter times - Evaluates f() no more than max_iter times
- Stops searching when the window around the minimum point is smaller than eps. - Stops searching when the window around the minimum point is smaller than eps.
The search will begin with the given starting_point. The search will begin with the given starting_point.
- returns std::make_pair(P, f(P)) - #starting_point == P
- returns f(P)
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -206,9 +207,9 @@ namespace dlib ...@@ -206,9 +207,9 @@ namespace dlib
template < template <
typename funct typename funct
> >
std::pair<double,double> find_max_single_variable ( double find_max_single_variable (
const funct& f, const funct& f,
const double starting_point, double& starting_point,
const double begin = -1e200, const double begin = -1e200,
const double end = 1e200, const double end = 1e200,
const double eps = 1e-3, const double eps = 1e-3,
...@@ -228,7 +229,8 @@ namespace dlib ...@@ -228,7 +229,8 @@ namespace dlib
- Evaluates f() no more than max_iter times - Evaluates f() no more than max_iter times
- Stops searching when the window around the minimum point is smaller than eps. - Stops searching when the window around the minimum point is smaller than eps.
The search will begin with the given starting_point. The search will begin with the given starting_point.
- returns std::make_pair(P, f(P)) - #starting_point == P
- returns f(P)
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -334,10 +334,6 @@ namespace dlib ...@@ -334,10 +334,6 @@ namespace dlib
) const ) const
{ {
using namespace std; using namespace std;
if (verbose)
{
cout << "\rChecking goodness of gamma = " << gamma << ". " << flush;
}
typedef radial_basis_kernel<sample_type> kernel_type; typedef radial_basis_kernel<sample_type> kernel_type;
// make a kcentroid and find out what the gap is at the current gamma // make a kcentroid and find out what the gap is at the current gamma
...@@ -346,7 +342,8 @@ namespace dlib ...@@ -346,7 +342,8 @@ namespace dlib
if (verbose) if (verbose)
{ {
cout << "Goodness = " << temp << " " << flush; cout << "\rChecking goodness of gamma = " << gamma << ". Goodness = "
<< temp << " " << flush;
} }
return temp; return temp;
} }
...@@ -381,7 +378,8 @@ namespace dlib ...@@ -381,7 +378,8 @@ namespace dlib
// works by ranking features by how much they separate the centroids of the two classes // works by ranking features by how much they separate the centroids of the two classes
// we will pick the gamma to use by finding the one that best separates the two classes. // we will pick the gamma to use by finding the one that best separates the two classes.
test<sample_matrix_type, label_matrix_type> funct(samples, labels, num_sv, verbose); test<sample_matrix_type, label_matrix_type> funct(samples, labels, num_sv, verbose);
double best_gamma = find_max_single_variable(funct, 1.0, 1e-8, 1000, 1e-3, 50).first; double best_gamma = 1.0;
find_max_single_variable(funct, best_gamma, 1e-8, 1000, 1e-3, 50);
typedef radial_basis_kernel<sample_type> kernel_type; typedef radial_basis_kernel<sample_type> kernel_type;
......
...@@ -687,18 +687,65 @@ namespace ...@@ -687,18 +687,65 @@ namespace
dlog << LINFO << "testing with single_variable_function and the start point: " << p; dlog << LINFO << "testing with single_variable_function and the start point: " << p;
double out, x;
total_count = 0; total_count = 0;
double out = find_min_single_variable(&single_variable_function, p, -1e100, 1e100, eps, 1000).first; x = p;
DLIB_TEST_MSG(std::abs(out) < 1e-6, out); out = find_min_single_variable(&single_variable_function, x, -1e100, 1e100, eps, 1000);
DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5);
DLIB_TEST_MSG(std::abs(x) < 1e-6, x);
dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count; dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count;
total_count = 0; total_count = 0;
out = find_max_single_variable(negate_function(&single_variable_function), p, -1e100, 1e100, eps, 1000).first; x = p;
DLIB_TEST_MSG(std::abs(out) < 1e-6, out); out = -find_max_single_variable(negate_function(&single_variable_function), x, -1e100, 1e100, eps, 1000);
DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5);
DLIB_TEST_MSG(std::abs(x) < 1e-6, x);
dlog << LINFO << "find_max_single_variable(): got single_variable_function in " << total_count; dlog << LINFO << "find_max_single_variable(): got single_variable_function in " << total_count;
if (p > 0)
{
total_count = 0;
x = p;
out = find_min_single_variable(&single_variable_function, x, -1e-4, 1e100, eps, 1000);
DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5);
DLIB_TEST_MSG(std::abs(x) < 1e-6, x);
dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count;
if (p > 3)
{
total_count = 0;
x = p;
out = -find_max_single_variable(negate_function(&single_variable_function), x, 3, 1e100, eps, 1000);
DLIB_TEST_MSG(std::abs(out - (3*3*3+5)) < 1e-6, out-(3*3*3+5));
DLIB_TEST_MSG(std::abs(x-3) < 1e-6, x);
dlog << LINFO << "find_max_single_variable(): got single_variable_function in " << total_count;
}
}
if (p < 0)
{
total_count = 0;
x = p;
out = find_min_single_variable(&single_variable_function, x, -1e100, 1e-4, eps, 1000);
DLIB_TEST_MSG(std::abs(out-5) < 1e-6, out-5);
DLIB_TEST_MSG(std::abs(x) < 1e-6, x);
dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count;
if (p < -3)
{
total_count = 0;
x = p;
out = find_min_single_variable(&single_variable_function, x, -1e100, -3, eps, 1000);
DLIB_TEST_MSG(std::abs(out - (3*3*3+5)) < 1e-6, out-(3*3*3+5));
DLIB_TEST_MSG(std::abs(x+3) < 1e-6, x);
dlog << LINFO << "find_min_single_variable(): got single_variable_function in " << total_count;
}
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -720,6 +767,7 @@ namespace ...@@ -720,6 +767,7 @@ namespace
test_single_variable_function(0); test_single_variable_function(0);
test_single_variable_function(1); test_single_variable_function(1);
test_single_variable_function(-10); test_single_variable_function(-10);
test_single_variable_function(-100);
test_single_variable_function(900.53); test_single_variable_function(900.53);
// test with the rosen function // test with the rosen function
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment