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
// ----------------------------------------------------------------------------------------
template <typename funct>
std::pair<double,double> find_min_single_variable (
double find_min_single_variable (
const funct& f,
const double starting_point,
double& starting_point,
const double begin = -1e200,
const double end = 1e200,
const double eps = 1e-3,
......@@ -463,11 +463,9 @@ namespace dlib
double p1=0, p2=0, p3=0, f1=0, f2=0, f3=0;
long f_evals = 1;
const std::pair<double,double> p(starting_point, f(starting_point));
if (begin == end)
{
return p;
return f(starting_point);
}
using std::abs;
......@@ -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
p1 = max(p.first-1, begin);
p3 = min(p.first+1, end);
if (p1 == p.first)
f1 = p.second;
else
f1 = f(p1);
p1 = max(starting_point-1, begin);
p3 = min(starting_point+1, end);
f1 = f(p1);
f3 = f(p3);
if (p3 == p.first)
f3 = p.second;
else
f3 = f(p3);
if (p.first == p1 || p.first == p3)
if (starting_point == p1 || starting_point == p3)
{
p2 = (p1+p3)/2;
f2 = f(p2);
}
else
{
p2 = p.first;
f2 = p.second;
p2 = starting_point;
f2 = f(starting_point);
}
f_evals += 2;
......@@ -514,10 +505,20 @@ namespace dlib
// check for hitting max_iter or if the interval is now too small
if (f_evals >= max_iter || p3-p1 < eps)
{
if (f1 < min(f2,f3)) return std::make_pair(p1, f1);
if (f2 < min(f1,f3)) return std::make_pair(p2, f2);
if (f1 < min(f2,f3))
{
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
......@@ -672,22 +673,23 @@ namespace dlib
++f_evals;
}
return std::make_pair(p2, f2);
starting_point = p2;
return f2;
}
// ----------------------------------------------------------------------------------------
template <typename funct>
std::pair<double,double> find_max_single_variable (
double find_max_single_variable (
const funct& f,
const double starting_point,
double& starting_point,
const double begin = -1e200,
const double end = 1e200,
const double eps = 1e-3,
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
template <
typename funct
>
std::pair<double,double> find_min_single_variable (
double find_min_single_variable (
const funct& f,
const double starting_point,
double& starting_point,
const double begin = -1e200,
const double end = 1e200,
const double eps = 1e-3,
......@@ -198,7 +198,8 @@ namespace dlib
- Evaluates f() no more than max_iter times
- Stops searching when the window around the minimum point is smaller than eps.
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
template <
typename funct
>
std::pair<double,double> find_max_single_variable (
double find_max_single_variable (
const funct& f,
const double starting_point,
double& starting_point,
const double begin = -1e200,
const double end = 1e200,
const double eps = 1e-3,
......@@ -228,7 +229,8 @@ namespace dlib
- Evaluates f() no more than max_iter times
- Stops searching when the window around the minimum point is smaller than eps.
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
) const
{
using namespace std;
if (verbose)
{
cout << "\rChecking goodness of gamma = " << gamma << ". " << flush;
}
typedef radial_basis_kernel<sample_type> kernel_type;
// make a kcentroid and find out what the gap is at the current gamma
......@@ -346,7 +342,8 @@ namespace dlib
if (verbose)
{
cout << "Goodness = " << temp << " " << flush;
cout << "\rChecking goodness of gamma = " << gamma << ". Goodness = "
<< temp << " " << flush;
}
return temp;
}
......@@ -381,7 +378,8 @@ namespace dlib
// 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.
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;
......
......@@ -687,18 +687,65 @@ namespace
dlog << LINFO << "testing with single_variable_function and the start point: " << p;
double out, x;
total_count = 0;
double out = find_min_single_variable(&single_variable_function, p, -1e100, 1e100, eps, 1000).first;
DLIB_TEST_MSG(std::abs(out) < 1e-6, out);
x = p;
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;
total_count = 0;
out = find_max_single_variable(negate_function(&single_variable_function), p, -1e100, 1e100, eps, 1000).first;
DLIB_TEST_MSG(std::abs(out) < 1e-6, out);
x = p;
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;
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
test_single_variable_function(0);
test_single_variable_function(1);
test_single_variable_function(-10);
test_single_variable_function(-100);
test_single_variable_function(900.53);
// 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