"tests/vscode:/vscode.git/clone" did not exist on "11fb217a76e03886d27d26a081ea4ed52cb8c214"
Commit c49e76ad authored by Davis King's avatar Davis King
Browse files

Changed the load() function's signature so that it works with

any type at all so long as it is convertible to a matrix via vector_to_matrix().

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403426
parent 125f6eb8
......@@ -62,92 +62,13 @@ namespace dlib
empirical_kernel_map().swap(*this);
}
template <typename T>
void load(
const kernel_type& kernel_,
const std::vector<sample_type>& basis_samples
const T& basis_samples
)
{
load(kernel_, vector_to_matrix(basis_samples));
}
template <typename EXP>
void load(
const kernel_type& kernel_,
const matrix_exp<EXP>& basis_samples
)
{
// make sure requires clause is not broken
DLIB_ASSERT(basis_samples.size() > 0 && is_vector(basis_samples),
"\tvoid empirical_kernel_map::load(kernel,basis_samples)"
<< "\n\t You have to give a non-empty set of basis_samples and it must be a vector"
<< "\n\t basis_samples.size(): " << basis_samples.size()
<< "\n\t is_vector(basis_samples): " << is_vector(basis_samples)
<< "\n\t this: " << this
);
// clear out the weights before we begin. This way if an exception throws
// this object will already be in the right state.
weights.set_size(0,0);
kernel = kernel_;
basis.clear();
basis.reserve(basis_samples.size());
// find out the value of the largest norm of the elements in basis_samples.
const scalar_type max_norm = max(diag(kernel_matrix(kernel, basis_samples)));
// we will consider anything less than or equal to this number to be 0
const scalar_type eps = max_norm*100*std::numeric_limits<scalar_type>::epsilon();
// Copy all the basis_samples into basis but make sure we don't copy any samples
// that have length 0
for (long i = 0; i < basis_samples.size(); ++i)
{
const scalar_type norm = kernel(basis_samples(i), basis_samples(i));
if (norm > eps)
{
basis.push_back(basis_samples(i));
}
}
if (basis.size() == 0)
{
clear();
throw empirical_kernel_map_error("All basis_samples given to empirical_kernel_map::load() were zero vectors");
}
matrix<scalar_type,0,0,mem_manager_type> K(kernel_matrix(kernel, basis)), U,W,V;
if (svd2(false,true,K,U,W,V))
{
clear();
throw empirical_kernel_map_error("While loading empirical_kernel_map with data, SVD failed to converge.");
}
// now count how many elements of W are non-zero
const long num_not_zero = static_cast<long>(sum(W>eps));
// Really, this should never happen. But I'm checking for good measure.
if (num_not_zero == 0)
{
clear();
throw empirical_kernel_map_error("While loading empirical_kernel_map with data, SVD failed");
}
weights.set_size(num_not_zero, basis.size());
// now fill the weights matrix with the output of the SVD
long counter = 0;
for (long i =0; i < W.size(); ++i)
{
double val = W(i);
if (val > eps)
{
val = std::sqrt(val);
set_rowm(weights,counter) = rowm(trans(V),i)/val;
++counter;
}
}
load_impl(kernel_, vector_to_matrix(basis_samples));
}
const kernel_type get_kernel (
......@@ -310,6 +231,87 @@ namespace dlib
private:
template <typename T>
void load_impl(
const kernel_type& kernel_,
const T& basis_samples
)
{
// make sure requires clause is not broken
DLIB_ASSERT(basis_samples.size() > 0 && is_vector(basis_samples),
"\tvoid empirical_kernel_map::load(kernel,basis_samples)"
<< "\n\t You have to give a non-empty set of basis_samples and it must be a vector"
<< "\n\t basis_samples.size(): " << basis_samples.size()
<< "\n\t is_vector(basis_samples): " << is_vector(basis_samples)
<< "\n\t this: " << this
);
// clear out the weights before we begin. This way if an exception throws
// this object will already be in the right state.
weights.set_size(0,0);
kernel = kernel_;
basis.clear();
basis.reserve(basis_samples.size());
// find out the value of the largest norm of the elements in basis_samples.
const scalar_type max_norm = max(diag(kernel_matrix(kernel, basis_samples)));
// we will consider anything less than or equal to this number to be 0
const scalar_type eps = max_norm*100*std::numeric_limits<scalar_type>::epsilon();
// Copy all the basis_samples into basis but make sure we don't copy any samples
// that have length 0
for (long i = 0; i < basis_samples.size(); ++i)
{
const scalar_type norm = kernel(basis_samples(i), basis_samples(i));
if (norm > eps)
{
basis.push_back(basis_samples(i));
}
}
if (basis.size() == 0)
{
clear();
throw empirical_kernel_map_error("All basis_samples given to empirical_kernel_map::load() were zero vectors");
}
matrix<scalar_type,0,0,mem_manager_type> K(kernel_matrix(kernel, basis)), U,W,V;
if (svd2(false,true,K,U,W,V))
{
clear();
throw empirical_kernel_map_error("While loading empirical_kernel_map with data, SVD failed to converge.");
}
// now count how many elements of W are non-zero
const long num_not_zero = static_cast<long>(sum(W>eps));
// Really, this should never happen. But I'm checking for good measure.
if (num_not_zero == 0)
{
clear();
throw empirical_kernel_map_error("While loading empirical_kernel_map with data, SVD failed");
}
weights.set_size(num_not_zero, basis.size());
// now fill the weights matrix with the output of the SVD
long counter = 0;
for (long i =0; i < W.size(); ++i)
{
double val = W(i);
if (val > eps)
{
val = std::sqrt(val);
set_rowm(weights,counter) = rowm(trans(V),i)/val;
++counter;
}
}
}
std::vector<sample_type> basis;
matrix<scalar_type,0,0,mem_manager_type> weights;
kernel_type kernel;
......
......@@ -115,13 +115,15 @@ namespace dlib
- this object has its initial value
!*/
template <typename EXP>
template <typename T>
void load(
const kernel_type& kernel,
const matrix_exp<EXP>& basis_samples
const T& basis_samples
);
/*!
requires
- T must be a dlib::matrix type or something convertable to a matrix via vector_to_matrix()
(e.g. a std::vector)
- is_vector(basis_samples) == true
- basis_samples.size() > 0
- kernel must be capable of operating on the elements of basis_samples. That is,
......@@ -140,19 +142,6 @@ namespace dlib
If this happens then this object will revert back to its initial value.
!*/
void load(
const kernel_type& kernel,
const std::vector<sample_type>& basis_samples
);
/*!
requires
- basis_samples.size() > 0
ensures
- performs load(kernel,vector_to_matrix(basis_samples)). I.e. This function
does the exact same thing as the above load() function but lets you use
a std::vector of basis samples instead of a row/column matrix of basis samples.
!*/
const kernel_type get_kernel (
) const;
/*!
......
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