Commit a5b2454c authored by Davis King's avatar Davis King

Removed the dlib::sparse_vector namespace. I put everything from this

namespace into the normal dlib:: namespace so that code which works
with both sparse and dense vectors is more cohesive.
...@@ -298,7 +298,7 @@ namespace dlib ...@@ -298,7 +298,7 @@ namespace dlib
// figure out how many elements we need in our dense vectors. // figure out how many elements we need in our dense vectors.
const unsigned long max_dim = sparse_vector::max_index_plus_one(samples); const unsigned long max_dim = max_index_plus_one(samples);
// now turn all the samples into dense samples // now turn all the samples into dense samples
......
...@@ -415,7 +415,8 @@ namespace dlib ...@@ -415,7 +415,8 @@ namespace dlib
template < template <
typename vector_type typename vector_type
> >
unsigned long max_index_plus_one ( typename enable_if<is_same_type<sample_pair, typename vector_type::value_type>,unsigned long>::type
max_index_plus_one (
const vector_type& pairs const vector_type& pairs
) )
{ {
......
...@@ -201,7 +201,7 @@ namespace dlib ...@@ -201,7 +201,7 @@ namespace dlib
// add an element into the stored data sequence // add an element into the stored data sequence
dh_temp.s = x - prev_x; dh_temp.s = x - prev_x;
dh_temp.y = funct_derivative - prev_derivative; dh_temp.y = funct_derivative - prev_derivative;
double temp = dlib::dot(dh_temp.s, dh_temp.y); double temp = dot(dh_temp.s, dh_temp.y);
// only accept this bit of data if temp isn't zero // only accept this bit of data if temp isn't zero
if (std::abs(temp) > std::numeric_limits<double>::epsilon()) if (std::abs(temp) > std::numeric_limits<double>::epsilon())
{ {
......
...@@ -105,9 +105,6 @@ namespace dlib ...@@ -105,9 +105,6 @@ namespace dlib
result_type& assignment result_type& assignment
) const ) const
{ {
using dlib::sparse_vector::dot;
using dlib::dot;
assignment.clear(); assignment.clear();
matrix<double> cost; matrix<double> cost;
......
...@@ -779,8 +779,6 @@ namespace dlib ...@@ -779,8 +779,6 @@ namespace dlib
// Rather than doing something like, best_idx = index_of_max(weights*x-b) // Rather than doing something like, best_idx = index_of_max(weights*x-b)
// we do the following somewhat more complex thing because this supports // we do the following somewhat more complex thing because this supports
// both sparse and dense samples. // both sparse and dense samples.
using dlib::sparse_vector::dot;
using dlib::dot;
scalar_type best_val = dot(rowm(weights,0),x) - b(0); scalar_type best_val = dot(rowm(weights,0),x) - b(0);
unsigned long best_idx = 0; unsigned long best_idx = 0;
......
...@@ -57,8 +57,6 @@ namespace dlib ...@@ -57,8 +57,6 @@ namespace dlib
result_type& labels result_type& labels
) const ) const
{ {
using dlib::sparse_vector::dot;
using dlib::dot;
labels.clear(); labels.clear();
......
...@@ -744,14 +744,14 @@ namespace dlib ...@@ -744,14 +744,14 @@ namespace dlib
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return sparse_vector::distance(alpha,w , x.alpha,x.w); return distance(alpha,w , x.alpha,x.w);
} }
scalar_type inner_product ( scalar_type inner_product (
const sample_type& x const sample_type& x
) const ) const
{ {
return alpha*sparse_vector::dot(w,x); return alpha*dot(w,x);
} }
scalar_type inner_product ( scalar_type inner_product (
...@@ -765,20 +765,20 @@ namespace dlib ...@@ -765,20 +765,20 @@ namespace dlib
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
return alpha*x.alpha*sparse_vector::dot(w,x.w); return alpha*x.alpha*dot(w,x.w);
} }
scalar_type squared_norm ( scalar_type squared_norm (
) const ) const
{ {
return alpha*alpha* sparse_vector::length_squared(w); return alpha*alpha*length_squared(w);
} }
scalar_type operator() ( scalar_type operator() (
const sample_type& x const sample_type& x
) const ) const
{ {
return sparse_vector::distance(static_cast<scalar_type>(1), x, alpha, w); return distance(static_cast<scalar_type>(1), x, alpha, w);
} }
scalar_type test_and_train ( scalar_type test_and_train (
...@@ -1032,7 +1032,7 @@ namespace dlib ...@@ -1032,7 +1032,7 @@ namespace dlib
if (samples_seen > 0) if (samples_seen > 0)
{ {
scalar_type temp1 = sparse_vector::distance_squared(alpha,w , x.alpha,x.w); scalar_type temp1 = distance_squared(alpha,w , x.alpha,x.w);
scalar_type temp2 = alpha*w_extra - x.alpha*x.w_extra; scalar_type temp2 = alpha*w_extra - x.alpha*x.w_extra;
return std::sqrt(temp1 + temp2*temp2); return std::sqrt(temp1 + temp2*temp2);
} }
...@@ -1047,7 +1047,7 @@ namespace dlib ...@@ -1047,7 +1047,7 @@ namespace dlib
) const ) const
{ {
if (samples_seen > 0) if (samples_seen > 0)
return alpha*(sparse_vector::dot(w,x) + w_extra*x_extra); return alpha*(dot(w,x) + w_extra*x_extra);
else else
return 0; return 0;
} }
...@@ -1064,7 +1064,7 @@ namespace dlib ...@@ -1064,7 +1064,7 @@ namespace dlib
); );
if (samples_seen > 0 && x.samples_seen > 0) if (samples_seen > 0 && x.samples_seen > 0)
return alpha*x.alpha*(sparse_vector::dot(w,x.w) + w_extra*x.w_extra); return alpha*x.alpha*(dot(w,x.w) + w_extra*x.w_extra);
else else
return 0; return 0;
} }
...@@ -1073,7 +1073,7 @@ namespace dlib ...@@ -1073,7 +1073,7 @@ namespace dlib
) const ) const
{ {
if (samples_seen > 0) if (samples_seen > 0)
return alpha*alpha*(sparse_vector::length_squared(w) + w_extra*w_extra); return alpha*alpha*(length_squared(w) + w_extra*w_extra);
else else
return 0; return 0;
} }
...@@ -1084,13 +1084,13 @@ namespace dlib ...@@ -1084,13 +1084,13 @@ namespace dlib
{ {
if (samples_seen > 0) if (samples_seen > 0)
{ {
scalar_type temp1 = sparse_vector::distance_squared(1,x,alpha,w); scalar_type temp1 = distance_squared(1,x,alpha,w);
scalar_type temp2 = x_extra - alpha*w_extra; scalar_type temp2 = x_extra - alpha*w_extra;
return std::sqrt(temp1 + temp2*temp2); return std::sqrt(temp1 + temp2*temp2);
} }
else else
{ {
return std::sqrt(sparse_vector::length_squared(x) + x_extra*x_extra); return std::sqrt(length_squared(x) + x_extra*x_extra);
} }
} }
...@@ -1229,7 +1229,7 @@ namespace dlib ...@@ -1229,7 +1229,7 @@ namespace dlib
temp_basis_vectors.set_size(1); temp_basis_vectors.set_size(1);
temp_alpha.set_size(1); temp_alpha.set_size(1);
temp_basis_vectors(0) = sample_type(w.begin(), w.end()); temp_basis_vectors(0) = sample_type(w.begin(), w.end());
sparse_vector::scale_by(temp_basis_vectors(0), scale); dlib::scale_by(temp_basis_vectors(0), scale);
temp_alpha(0) = alpha/scale; temp_alpha(0) = alpha/scale;
} }
else else
...@@ -1239,7 +1239,7 @@ namespace dlib ...@@ -1239,7 +1239,7 @@ namespace dlib
temp_basis_vectors.set_size(2); temp_basis_vectors.set_size(2);
temp_alpha.set_size(2); temp_alpha.set_size(2);
temp_basis_vectors(0) = sample_type(w.begin(), w.end()); temp_basis_vectors(0) = sample_type(w.begin(), w.end());
sparse_vector::scale_by(temp_basis_vectors(0), 2); dlib::scale_by(temp_basis_vectors(0), 2);
temp_alpha(0) = alpha; temp_alpha(0) = alpha;
temp_basis_vectors(1) = sample_type(w.begin(), w.end()); temp_basis_vectors(1) = sample_type(w.begin(), w.end());
temp_alpha(1) = -alpha; temp_alpha(1) = -alpha;
......
...@@ -39,7 +39,7 @@ namespace dlib ...@@ -39,7 +39,7 @@ namespace dlib
const sample_type& b const sample_type& b
) const ) const
{ {
const scalar_type d = sparse_vector::distance_squared(a,b); const scalar_type d = distance_squared(a,b);
return std::exp(-gamma*d); return std::exp(-gamma*d);
} }
...@@ -123,7 +123,7 @@ namespace dlib ...@@ -123,7 +123,7 @@ namespace dlib
const sample_type& b const sample_type& b
) const ) const
{ {
return std::pow(gamma*(sparse_vector::dot(a,b)) + coef, degree); return std::pow(gamma*(dot(a,b)) + coef, degree);
} }
sparse_polynomial_kernel& operator= ( sparse_polynomial_kernel& operator= (
...@@ -211,7 +211,7 @@ namespace dlib ...@@ -211,7 +211,7 @@ namespace dlib
const sample_type& b const sample_type& b
) const ) const
{ {
return std::tanh(gamma*(sparse_vector::dot(a,b)) + coef); return std::tanh(gamma*(dot(a,b)) + coef);
} }
sparse_sigmoid_kernel& operator= ( sparse_sigmoid_kernel& operator= (
...@@ -284,7 +284,7 @@ namespace dlib ...@@ -284,7 +284,7 @@ namespace dlib
const sample_type& b const sample_type& b
) const ) const
{ {
return sparse_vector::dot(a,b); return dot(a,b);
} }
bool operator== ( bool operator== (
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "../algs.h" #include "../algs.h"
#include <vector> #include <vector>
#include <map> #include <map>
// This is included just so we can do some disable_if stuff on it in the max_index_plus_one routine().
#include "../manifold_regularization/sample_pair.h"
namespace dlib namespace dlib
...@@ -16,624 +18,619 @@ namespace dlib ...@@ -16,624 +18,619 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
namespace sparse_vector template <typename T, typename U>
typename T::value_type::second_type distance_squared (
const T& a,
const U& b
)
{ {
typedef typename T::value_type::second_type scalar_type;
typedef typename U::value_type::second_type scalar_typeU;
// Both T and U must contain the same kinds of elements
COMPILE_TIME_ASSERT((is_same_type<scalar_type, scalar_typeU>::value));
template <typename T, typename U> typename T::const_iterator ai = a.begin();
typename T::value_type::second_type distance_squared ( typename U::const_iterator bi = b.begin();
const T& a,
const U& b
)
{
typedef typename T::value_type::second_type scalar_type;
typedef typename U::value_type::second_type scalar_typeU;
// Both T and U must contain the same kinds of elements
COMPILE_TIME_ASSERT((is_same_type<scalar_type, scalar_typeU>::value));
typename T::const_iterator ai = a.begin(); scalar_type sum = 0, temp = 0;
typename U::const_iterator bi = b.begin(); while (ai != a.end() && bi != b.end())
{
scalar_type sum = 0, temp = 0; if (ai->first == bi->first)
while (ai != a.end() && bi != b.end())
{ {
if (ai->first == bi->first) temp = ai->second - bi->second;
{ ++ai;
temp = ai->second - bi->second; ++bi;
++ai;
++bi;
}
else if (ai->first < bi->first)
{
temp = ai->second;
++ai;
}
else
{
temp = bi->second;
++bi;
}
sum += temp*temp;
} }
else if (ai->first < bi->first)
while (ai != a.end())
{ {
sum += ai->second*ai->second; temp = ai->second;
++ai; ++ai;
} }
while (bi != b.end()) else
{ {
sum += bi->second*bi->second; temp = bi->second;
++bi; ++bi;
} }
return sum; sum += temp*temp;
} }
// ------------------------------------------------------------------------------------ while (ai != a.end())
template <typename T, typename U, typename V, typename W>
typename T::value_type::second_type distance_squared (
const V& a_scale,
const T& a,
const W& b_scale,
const U& b
)
{ {
typedef typename T::value_type::second_type scalar_type; sum += ai->second*ai->second;
typedef typename U::value_type::second_type scalar_typeU; ++ai;
// Both T and U must contain the same kinds of elements }
COMPILE_TIME_ASSERT((is_same_type<scalar_type, scalar_typeU>::value)); while (bi != b.end())
{
sum += bi->second*bi->second;
++bi;
}
typename T::const_iterator ai = a.begin(); return sum;
typename U::const_iterator bi = b.begin(); }
scalar_type sum = 0, temp = 0; // ------------------------------------------------------------------------------------
while (ai != a.end() && bi != b.end())
{
if (ai->first == bi->first)
{
temp = a_scale*ai->second - b_scale*bi->second;
++ai;
++bi;
}
else if (ai->first < bi->first)
{
temp = a_scale*ai->second;
++ai;
}
else
{
temp = b_scale*bi->second;
++bi;
}
sum += temp*temp; template <typename T, typename U, typename V, typename W>
} typename T::value_type::second_type distance_squared (
const V& a_scale,
const T& a,
const W& b_scale,
const U& b
)
{
typedef typename T::value_type::second_type scalar_type;
typedef typename U::value_type::second_type scalar_typeU;
// Both T and U must contain the same kinds of elements
COMPILE_TIME_ASSERT((is_same_type<scalar_type, scalar_typeU>::value));
while (ai != a.end()) typename T::const_iterator ai = a.begin();
typename U::const_iterator bi = b.begin();
scalar_type sum = 0, temp = 0;
while (ai != a.end() && bi != b.end())
{
if (ai->first == bi->first)
{ {
sum += a_scale*a_scale*ai->second*ai->second; temp = a_scale*ai->second - b_scale*bi->second;
++ai; ++ai;
++bi;
} }
while (bi != b.end()) else if (ai->first < bi->first)
{ {
sum += b_scale*b_scale*bi->second*bi->second; temp = a_scale*ai->second;
++ai;
}
else
{
temp = b_scale*bi->second;
++bi; ++bi;
} }
return sum; sum += temp*temp;
} }
// ------------------------------------------------------------------------------------ while (ai != a.end())
template <typename T, typename U>
typename T::value_type::second_type distance (
const T& a,
const U& b
)
{ {
return std::sqrt(distance_squared(a,b)); sum += a_scale*a_scale*ai->second*ai->second;
++ai;
} }
while (bi != b.end())
// ------------------------------------------------------------------------------------
template <typename T, typename U, typename V, typename W>
typename T::value_type::second_type distance (
const V& a_scale,
const T& a,
const W& b_scale,
const U& b
)
{ {
return std::sqrt(distance_squared(a_scale,a,b_scale,b)); sum += b_scale*b_scale*bi->second*bi->second;
++bi;
} }
// ------------------------------------------------------------------------------------ return sum;
// ------------------------------------------------------------------------------------ }
template <typename T, typename EXP>
typename enable_if<is_matrix<T> >::type assign (
T& dest,
const matrix_exp<EXP>& src
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(src),
"\t void assign(dest,src)"
<< "\n\t the src matrix must be a row or column vector"
);
dest = src;
}
template <typename T, typename EXP>
typename disable_if<is_matrix<T> >::type assign (
T& dest,
const matrix_exp<EXP>& src
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(src),
"\t void assign(dest,src)"
<< "\n\t the src matrix must be a row or column vector"
);
dest.clear();
typedef typename T::value_type item_type;
for (long i = 0; i < src.size(); ++i)
{
if (src(i) != 0)
dest.insert(dest.end(),item_type(i, src(i)));
}
}
template <typename T, typename U> // ------------------------------------------------------------------------------------
typename disable_if_c<is_matrix<T>::value || is_matrix<U>::value>::type assign (
T& dest, // sparse
const U& src // sparse
)
{
dest.assign(src.begin(), src.end());
}
template <typename T, typename U, typename Comp, typename Alloc, typename S> template <typename T, typename U>
typename disable_if<is_matrix<S> >::type assign ( typename T::value_type::second_type distance (
std::map<T,U,Comp,Alloc>& dest, // sparse const T& a,
const S& src // sparse const U& b
) )
{ {
dest.clear(); return std::sqrt(distance_squared(a,b));
dest.insert(src.begin(), src.end()); }
}
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
template <typename T> template <typename T, typename U, typename V, typename W>
struct has_unsigned_keys typename T::value_type::second_type distance (
{ const V& a_scale,
static const bool value = is_unsigned_type<typename T::value_type::first_type>::value; const T& a,
}; const W& b_scale,
const U& b
)
{
return std::sqrt(distance_squared(a_scale,a,b_scale,b));
}
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
namespace impl template <typename T, typename EXP>
{ typename enable_if<is_matrix<T> >::type assign (
template <typename T, typename U> T& dest,
typename T::value_type::second_type dot ( const matrix_exp<EXP>& src
const T& a, )
const U& b {
) // make sure requires clause is not broken
{ DLIB_ASSERT(is_vector(src),
typedef typename T::value_type::second_type scalar_type; "\t void assign(dest,src)"
<< "\n\t the src matrix must be a row or column vector"
typename T::const_iterator ai = a.begin(); );
typename U::const_iterator bi = b.begin();
scalar_type sum = 0;
while (ai != a.end() && bi != b.end())
{
if (ai->first == bi->first)
{
sum += ai->second * bi->second;
++ai;
++bi;
}
else if (ai->first < bi->first)
{
++ai;
}
else
{
++bi;
}
}
return sum; dest = src;
} }
}
template <typename T> template <typename T, typename EXP>
inline typename T::value_type::second_type dot ( typename disable_if<is_matrix<T> >::type assign (
const T& a, T& dest,
const T& b const matrix_exp<EXP>& src
) )
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(src),
"\t void assign(dest,src)"
<< "\n\t the src matrix must be a row or column vector"
);
dest.clear();
typedef typename T::value_type item_type;
for (long i = 0; i < src.size(); ++i)
{ {
return dlib::sparse_vector::impl::dot(a,b); if (src(i) != 0)
dest.insert(dest.end(),item_type(i, src(i)));
} }
}
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> template <typename T, typename U>
inline T4 dot ( typename disable_if_c<is_matrix<T>::value || is_matrix<U>::value>::type assign (
const std::vector<T1,T2>& a, T& dest, // sparse
const std::map<T3,T4,T5,T6>& b const U& src // sparse
) )
{ {
return dlib::sparse_vector::impl::dot(a,b); dest.assign(src.begin(), src.end());
} }
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> template <typename T, typename U, typename Comp, typename Alloc, typename S>
inline T4 dot ( typename disable_if<is_matrix<S> >::type assign (
const std::map<T3,T4,T5,T6>& a, std::map<T,U,Comp,Alloc>& dest, // sparse
const std::vector<T1,T2>& b const S& src // sparse
) )
{ {
return dlib::sparse_vector::impl::dot(a,b); dest.clear();
} dest.insert(src.begin(), src.end());
}
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
template <typename T, typename EXP> template <typename T>
struct has_unsigned_keys
{
static const bool value = is_unsigned_type<typename T::value_type::first_type>::value;
};
// ------------------------------------------------------------------------------------
namespace impl
{
template <typename T, typename U>
typename T::value_type::second_type dot ( typename T::value_type::second_type dot (
const T& a, const T& a,
const matrix_exp<EXP>& b const U& b
) )
{ {
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(b),
"\t scalar_type dot(sparse_vector a, dense_vector b)"
<< "\n\t 'b' must be a vector to be used in a dot product."
);
typedef typename T::value_type::second_type scalar_type; typedef typename T::value_type::second_type scalar_type;
typedef typename T::value_type::first_type first_type;
typename T::const_iterator ai = a.begin();
typename U::const_iterator bi = b.begin();
scalar_type sum = 0; scalar_type sum = 0;
for (typename T::const_iterator ai = a.begin(); while (ai != a.end() && bi != b.end())
(ai != a.end()) && (ai->first < static_cast<first_type>(b.size()));
++ai)
{ {
sum += ai->second * b(ai->first); if (ai->first == bi->first)
{
sum += ai->second * bi->second;
++ai;
++bi;
}
else if (ai->first < bi->first)
{
++ai;
}
else
{
++bi;
}
} }
return sum; return sum;
} }
}
// ------------------------------------------------------------------------------------ template <typename T>
inline typename T::value_type::second_type dot (
const T& a,
const T& b
)
{
return impl::dot(a,b);
}
template <typename T, typename EXP> template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
typename T::value_type::second_type dot ( inline T4 dot (
const matrix_exp<EXP>& b, const std::vector<T1,T2>& a,
const T& a const std::map<T3,T4,T5,T6>& b
) )
{ {
return dot(a,b); return impl::dot(a,b);
} }
// ------------------------------------------------------------------------------------ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
inline T4 dot (
const std::map<T3,T4,T5,T6>& a,
const std::vector<T1,T2>& b
)
{
return impl::dot(a,b);
}
template <typename T> // ------------------------------------------------------------------------------------
typename T::value_type::second_type length_squared (
const T& a template <typename T, typename EXP>
) typename T::value_type::second_type dot (
const T& a,
const matrix_exp<EXP>& b
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(b),
"\t scalar_type dot(sparse_vector a, dense_vector b)"
<< "\n\t 'b' must be a vector to be used in a dot product."
);
typedef typename T::value_type::second_type scalar_type;
typedef typename T::value_type::first_type first_type;
scalar_type sum = 0;
for (typename T::const_iterator ai = a.begin();
(ai != a.end()) && (ai->first < static_cast<first_type>(b.size()));
++ai)
{ {
typedef typename T::value_type::second_type scalar_type; sum += ai->second * b(ai->first);
}
typename T::const_iterator i; return sum;
}
scalar_type sum = 0; // ------------------------------------------------------------------------------------
for (i = a.begin(); i != a.end(); ++i) template <typename T, typename EXP>
{ typename T::value_type::second_type dot (
sum += i->second * i->second; const matrix_exp<EXP>& b,
} const T& a
)
{
return dot(a,b);
}
return sum; // ------------------------------------------------------------------------------------
}
// ------------------------------------------------------------------------------------ template <typename T>
typename T::value_type::second_type length_squared (
const T& a
)
{
typedef typename T::value_type::second_type scalar_type;
template <typename T> typename T::const_iterator i;
typename T::value_type::second_type length (
const T& a
)
{
return std::sqrt(length_squared(a));
}
// ------------------------------------------------------------------------------------ scalar_type sum = 0;
template <typename T, typename U> for (i = a.begin(); i != a.end(); ++i)
void scale_by (
T& a,
const U& value
)
{ {
for (typename T::iterator i = a.begin(); i != a.end(); ++i) sum += i->second * i->second;
{
i->second *= value;
}
} }
// ------------------------------------------------------------------------------------ return sum;
// ------------------------------------------------------------------------------------ }
namespace impl // ------------------------------------------------------------------------------------
{
template <typename T>
typename enable_if<is_matrix<typename T::type>,unsigned long>::type max_index_plus_one (
const T& samples
)
{
if (samples.size() > 0)
return samples(0).size();
else
return 0;
}
template <typename T> template <typename T>
typename enable_if<is_built_in_scalar_type<typename T::type>,unsigned long>::type max_index_plus_one ( typename T::value_type::second_type length (
const T& sample const T& a
) )
{ {
return sample.size(); return std::sqrt(length_squared(a));
} }
// This !is_built_in_scalar_type<typename T::type>::value is here to avoid an inexplicable bug in Vistual Studio 2005 // ------------------------------------------------------------------------------------
template <typename T>
typename enable_if_c<(!is_built_in_scalar_type<typename T::type>::value) && (is_pair<typename T::type::value_type>::value) ,unsigned long>::type
max_index_plus_one (
const T& samples
)
{
typedef typename T::type sample_type;
// You are getting this error because you are attempting to use sparse sample vectors
// but you aren't using an unsigned integer as your key type in the sparse vectors.
COMPILE_TIME_ASSERT(sparse_vector::has_unsigned_keys<sample_type>::value);
template <typename T, typename U>
void scale_by (
T& a,
const U& value
)
{
for (typename T::iterator i = a.begin(); i != a.end(); ++i)
{
i->second *= value;
}
}
// these should be sparse samples so look over all them to find the max index. // ------------------------------------------------------------------------------------
unsigned long max_dim = 0; // ------------------------------------------------------------------------------------
for (long i = 0; i < samples.size(); ++i)
{
if (samples(i).size() > 0)
max_dim = std::max<unsigned long>(max_dim, (--samples(i).end())->first + 1);
}
return max_dim; namespace impl
} {
template <typename T>
typename enable_if<is_matrix<typename T::type>,unsigned long>::type max_index_plus_one (
const T& samples
)
{
if (samples.size() > 0)
return samples(0).size();
else
return 0;
} }
template <typename T> template <typename T>
typename enable_if<is_pair<typename T::value_type>,unsigned long>::type max_index_plus_one ( typename enable_if<is_built_in_scalar_type<typename T::type>,unsigned long>::type max_index_plus_one (
const T& sample const T& sample
) )
{ {
if (sample.size() > 0) return sample.size();
return (--sample.end())->first + 1;
return 0;
} }
// This !is_built_in_scalar_type<typename T::type>::value is here to avoid an inexplicable bug in Vistual Studio 2005
template <typename T> template <typename T>
typename disable_if<is_pair<typename T::value_type>,unsigned long>::type max_index_plus_one ( typename enable_if_c<(!is_built_in_scalar_type<typename T::type>::value) && (is_pair<typename T::type::value_type>::value) ,unsigned long>::type
max_index_plus_one (
const T& samples const T& samples
) )
{ {
return impl::max_index_plus_one(vector_to_matrix(samples)); typedef typename T::type sample_type;
} // You are getting this error because you are attempting to use sparse sample vectors
// but you aren't using an unsigned integer as your key type in the sparse vectors.
COMPILE_TIME_ASSERT(has_unsigned_keys<sample_type>::value);
// ------------------------------------------------------------------------------------
template <typename T, long NR, long NC, typename MM, typename L, typename EXP> // these should be sparse samples so look over all them to find the max index.
inline void add_to ( unsigned long max_dim = 0;
matrix<T,NR,NC,MM,L>& dest, for (long i = 0; i < samples.size(); ++i)
const matrix_exp<EXP>& src {
) if (samples(i).size() > 0)
{ max_dim = std::max<unsigned long>(max_dim, (--samples(i).end())->first + 1);
// make sure requires clause is not broken }
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (long r = 0; r < src.size(); ++r)
dest(r) += src(r);
}
template <typename T, long NR, long NC, typename MM, typename L, typename EXP> return max_dim;
inline typename disable_if<is_matrix<EXP> >::type add_to (
matrix<T,NR,NC,MM,L>& dest,
const EXP& src
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(i->first) += i->second;
} }
}
// ------------------------------------------------------------------------------------ template <typename T>
typename enable_if<is_pair<typename T::value_type>,unsigned long>::type max_index_plus_one (
const T& sample
)
{
if (sample.size() > 0)
return (--sample.end())->first + 1;
return 0;
}
template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U> template <typename T>
inline void add_to ( typename disable_if_c<is_pair<typename T::value_type>::value ||
matrix<T,NR,NC,MM,L>& dest, is_same_type<typename T::value_type,sample_pair>::value,unsigned long>::type
const matrix_exp<EXP>& src, max_index_plus_one (
const U& C const T& samples
) )
{ {
// make sure requires clause is not broken return impl::max_index_plus_one(vector_to_matrix(samples));
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()), }
"\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (long r = 0; r < src.size(); ++r)
dest(r) += C*src(r);
}
template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U> // ------------------------------------------------------------------------------------
inline typename disable_if<is_matrix<EXP> >::type add_to (
matrix<T,NR,NC,MM,L>& dest,
const EXP& src,
const U& C
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(i->first) += C*i->second;
}
// ------------------------------------------------------------------------------------ template <typename T, long NR, long NC, typename MM, typename L, typename EXP>
inline void add_to (
matrix<T,NR,NC,MM,L>& dest,
const matrix_exp<EXP>& src
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (long r = 0; r < src.size(); ++r)
dest(r) += src(r);
}
template <typename T, long NR, long NC, typename MM, typename L, typename EXP> template <typename T, long NR, long NC, typename MM, typename L, typename EXP>
inline void subtract_from ( inline typename disable_if<is_matrix<EXP> >::type add_to (
matrix<T,NR,NC,MM,L>& dest, matrix<T,NR,NC,MM,L>& dest,
const matrix_exp<EXP>& src const EXP& src
) )
{ {
// make sure requires clause is not broken // make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()), DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)" "\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector." << "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest) << "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src) << "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size() << "\n\t dest.size(): " << dest.size()
); );
for (long r = 0; r < src.size(); ++r) for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(r) -= src(r); dest(i->first) += i->second;
} }
template <typename T, long NR, long NC, typename MM, typename L, typename EXP> // ------------------------------------------------------------------------------------
inline typename disable_if<is_matrix<EXP> >::type subtract_from (
matrix<T,NR,NC,MM,L>& dest,
const EXP& src
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(i->first) -= i->second;
}
// ------------------------------------------------------------------------------------ template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U>
inline void add_to (
matrix<T,NR,NC,MM,L>& dest,
const matrix_exp<EXP>& src,
const U& C
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (long r = 0; r < src.size(); ++r)
dest(r) += C*src(r);
}
template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U> template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U>
inline void subtract_from ( inline typename disable_if<is_matrix<EXP> >::type add_to (
matrix<T,NR,NC,MM,L>& dest, matrix<T,NR,NC,MM,L>& dest,
const matrix_exp<EXP>& src, const EXP& src,
const U& C const U& C
) )
{ {
// make sure requires clause is not broken // make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()), DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)" "\t void add_to(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector." << "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest) << "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src) << "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size() << "\n\t dest.size(): " << dest.size()
); );
for (long r = 0; r < src.size(); ++r) for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(r) -= C*src(r); dest(i->first) += C*i->second;
} }
template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U> // ------------------------------------------------------------------------------------
inline typename disable_if<is_matrix<EXP> >::type subtract_from (
matrix<T,NR,NC,MM,L>& dest,
const EXP& src,
const U& C
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(i->first) -= C*i->second;
}
// ------------------------------------------------------------------------------------ template <typename T, long NR, long NC, typename MM, typename L, typename EXP>
inline void subtract_from (
matrix<T,NR,NC,MM,L>& dest,
const matrix_exp<EXP>& src
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (long r = 0; r < src.size(); ++r)
dest(r) -= src(r);
}
template <typename T> template <typename T, long NR, long NC, typename MM, typename L, typename EXP>
typename T::value_type::second_type min ( inline typename disable_if<is_matrix<EXP> >::type subtract_from (
const T& a matrix<T,NR,NC,MM,L>& dest,
) const EXP& src
{ )
typedef typename T::value_type::second_type type; {
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(i->first) -= i->second;
}
type temp = 0; // ------------------------------------------------------------------------------------
for (typename T::const_iterator i = a.begin(); i != a.end(); ++i)
{
if (temp > i->second)
temp = i->second;
}
return temp;
}
// ------------------------------------------------------------------------------------ template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U>
inline void subtract_from (
matrix<T,NR,NC,MM,L>& dest,
const matrix_exp<EXP>& src,
const U& C
)
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (long r = 0; r < src.size(); ++r)
dest(r) -= C*src(r);
}
template <typename T> template <typename T, long NR, long NC, typename MM, typename L, typename EXP, typename U>
typename T::value_type::second_type max ( inline typename disable_if<is_matrix<EXP> >::type subtract_from (
const T& a matrix<T,NR,NC,MM,L>& dest,
) const EXP& src,
{ const U& C
typedef typename T::value_type::second_type type; )
{
// make sure requires clause is not broken
DLIB_ASSERT(is_vector(dest) && max_index_plus_one(src) <= static_cast<unsigned long>(dest.size()),
"\t void subtract_from(dest,src)"
<< "\n\t dest must be a vector large enough to hold the src vector."
<< "\n\t is_vector(dest): " << is_vector(dest)
<< "\n\t max_index_plus_one(src): " << max_index_plus_one(src)
<< "\n\t dest.size(): " << dest.size()
);
for (typename EXP::const_iterator i = src.begin(); i != src.end(); ++i)
dest(i->first) -= C*i->second;
}
type temp = 0; // ------------------------------------------------------------------------------------
for (typename T::const_iterator i = a.begin(); i != a.end(); ++i)
{ template <typename T>
if (temp < i->second) typename T::value_type::second_type min (
temp = i->second; const T& a
} )
return temp; {
typedef typename T::value_type::second_type type;
type temp = 0;
for (typename T::const_iterator i = a.begin(); i != a.end(); ++i)
{
if (temp > i->second)
temp = i->second;
} }
return temp;
}
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
template <typename T>
typename T::value_type::second_type max (
const T& a
)
{
typedef typename T::value_type::second_type type;
type temp = 0;
for (typename T::const_iterator i = a.begin(); i != a.end(); ++i)
{
if (temp < i->second)
temp = i->second;
}
return temp;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -67,302 +67,298 @@ namespace dlib ...@@ -67,302 +67,298 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
namespace sparse_vector template <typename T, typename U>
{ typename T::value_type::second_type distance_squared (
template <typename T, typename U> const T& a,
typename T::value_type::second_type distance_squared ( const U& b
const T& a, );
const U& b /*!
); requires
/*! - a and b are sparse vectors
requires ensures
- a and b are sparse vectors - returns the squared distance between the vectors
ensures a and b
- returns the squared distance between the vectors !*/
a and b
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, typename U, typename V, typename W>
typename T::value_type::second_type distance_squared (
template <typename T, typename U, typename V, typename W> const V& a_scale,
typename T::value_type::second_type distance_squared ( const T& a,
const V& a_scale, const W& b_scale,
const T& a, const U& b
const W& b_scale, );
const U& b /*!
); requires
/*! - a and b are sparse vectors
requires ensures
- a and b are sparse vectors - returns the squared distance between the vectors
ensures a_scale*a and b_scale*b
- returns the squared distance between the vectors !*/
a_scale*a and b_scale*b
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, typename U>
typename T::value_type::second_type distance (
template <typename T, typename U> const T& a,
typename T::value_type::second_type distance ( const U& b
const T& a, );
const U& b /*!
); requires
/*! - a and b are sparse vectors
requires ensures
- a and b are sparse vectors - returns the distance between the vectors
ensures a and b. (i.e. std::sqrt(distance_squared(a,b)))
- returns the distance between the vectors !*/
a and b. (i.e. std::sqrt(distance_squared(a,b)))
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, typename U, typename V, typename W>
typename T::value_type::second_type distance (
template <typename T, typename U, typename V, typename W> const V& a_scale,
typename T::value_type::second_type distance ( const T& a,
const V& a_scale, const W& b_scale,
const T& a, const U& b
const W& b_scale, );
const U& b /*!
); requires
/*! - a and b are sparse vectors
requires ensures
- a and b are sparse vectors - returns the distance between the vectors
ensures a_scale*a and b_scale*b. (i.e. std::sqrt(distance_squared(a_scale,a,b_scale,b)))
- returns the distance between the vectors !*/
a_scale*a and b_scale*b. (i.e. std::sqrt(distance_squared(a_scale,a,b_scale,b)))
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, typename U>
void assign (
template <typename T, typename U> T& dest,
void assign ( const U& src
T& dest, );
const U& src /*!
); requires
/*! - dest == a sparse vector or a dense vector
requires - src == a sparse vector or a dense vector
- dest == a sparse vector or a dense vector - dest is not dense when src is sparse
- src == a sparse vector or a dense vector (i.e. you can't assign a sparse vector to a dense vector. This is
- dest is not dense when src is sparse because we don't know what the proper dimensionality should be for the
(i.e. you can't assign a sparse vector to a dense vector. This is dense vector)
because we don't know what the proper dimensionality should be for the ensures
dense vector) - #src represents the same vector as dest.
ensures (conversion between sparse/dense formats is done automatically)
- #src represents the same vector as dest. !*/
(conversion between sparse/dense formats is done automatically)
!*/
// ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T>
typename T::value_type::second_type dot (
template <typename T> const T& a,
typename T::value_type::second_type dot ( const T& b
const T& a, );
const T& b /*!
); requires
/*! - a and b are sparse vectors
requires ensures
- a and b are sparse vectors - returns the dot product between the vectors a and b
ensures !*/
- returns the dot product between the vectors a and b
!*/ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
T4 dot (
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> const std::vector<T1,T2>& a,
T4 dot ( const std::map<T3,T4,T5,T6>& b
const std::vector<T1,T2>& a, );
const std::map<T3,T4,T5,T6>& b /*!
); requires
/*! - a and b are sparse vectors
requires ensures
- a and b are sparse vectors - returns the dot product between the vectors a and b
ensures !*/
- returns the dot product between the vectors a and b
!*/ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
T4 dot (
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> const std::map<T3,T4,T5,T6>& a,
T4 dot ( const std::vector<T1,T2>& b
const std::map<T3,T4,T5,T6>& a, );
const std::vector<T1,T2>& b /*!
); requires
/*! - a and b are sparse vectors
requires ensures
- a and b are sparse vectors - returns the dot product between the vectors a and b
ensures !*/
- returns the dot product between the vectors a and b
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, typename EXP>
typename T::value_type::second_type dot (
template <typename T, typename EXP> const T& a,
typename T::value_type::second_type dot ( const matrix_exp<EXP>& b
const T& a, );
const matrix_exp<EXP>& b /*!
); requires
/*! - a is an unsorted sparse vector
requires - is_vector(b) == true
- a is an unsorted sparse vector ensures
- is_vector(b) == true - returns the dot product between the vectors a and b
ensures !*/
- returns the dot product between the vectors a and b
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, typename EXP>
typename T::value_type::second_type dot (
template <typename T, typename EXP> const matrix_exp<EXP>& a,
typename T::value_type::second_type dot ( const T& b
const matrix_exp<EXP>& a, );
const T& b /*!
); requires
/*! - b is an unsorted sparse vector
requires - is_vector(a) == true
- b is an unsorted sparse vector ensures
- is_vector(a) == true - returns the dot product between the vectors a and b
ensures !*/
- returns the dot product between the vectors a and b
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T>
typename T::value_type::second_type length_squared (
template <typename T> const T& a
typename T::value_type::second_type length_squared ( );
const T& a /*!
); requires
/*! - a is a sparse vector
requires ensures
- a is a sparse vector - returns dot(a,a)
ensures !*/
- returns dot(a,a)
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T>
typename T::value_type::second_type length (
template <typename T> const T& a
typename T::value_type::second_type length ( );
const T& a /*!
); requires
/*! - a is a sparse vector
requires ensures
- a is a sparse vector - returns std::sqrt(length_squared(a,a))
ensures !*/
- returns std::sqrt(length_squared(a,a))
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, typename U>
void scale_by (
template <typename T, typename U> T& a,
void scale_by ( const U& value
T& a, );
const U& value /*!
); requires
/*! - a is an unsorted sparse vector
requires ensures
- a is an unsorted sparse vector - #a == a*value
ensures (i.e. multiplies every element of the vector a by value)
- #a == a*value !*/
(i.e. multiplies every element of the vector a by value)
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T>
unsigned long max_index_plus_one (
template <typename T> const T& samples
unsigned long max_index_plus_one ( );
const T& samples /*!
); requires
/*! - samples == a single vector (either sparse or dense), or a container
requires of vectors which is either a dlib::matrix of vectors or something
- samples == a single vector (either sparse or dense), or a container convertible to a dlib::matrix via vector_to_matrix() (e.g. a std::vector)
of vectors which is either a dlib::matrix of vectors or something Valid types of samples include (but are not limited to):
convertible to a dlib::matrix via vector_to_matrix() (e.g. a std::vector) - dlib::matrix<double,0,1> // A single dense vector
Value types of samples include (but are not limited to): - std::map<unsigned int, double> // A single sparse vector
- dlib::matrix<double,0,1> // A single dense vector - std::vector<dlib::matrix<double,0,1> > // An array of dense vectors
- std::map<unsigned int, double> // A single sparse vector - std::vector<std::map<unsigned int, double> > // An array of sparse vectors
- std::vector<dlib::matrix<double,0,1> > // An array of dense vectors ensures
- std::vector<std::map<unsigned int, double> > // An array of sparse vectors - This function tells you the dimensionality of a set of vectors. The vectors
ensures can be either sparse or dense.
- This function tells you the dimensionality of a set of vectors. The vectors - if (samples.size() == 0) then
can be either sparse or dense. - returns 0
- if (samples.size() == 0) then - else if (samples contains dense vectors or is a dense vector) then
- returns 0 - returns the number of elements in the first sample vector. This means
- else if (samples contains dense vectors or is a dense vector) then we implicitly assume all dense vectors have the same length)
- returns the number of elements in the first sample vector. This means - else
we implicitly assume all dense vectors have the same length) - In this case samples contains sparse vectors or is a sparse vector.
- else - returns the largest element index in any sample + 1. Note that the element index values
- In this case samples contains sparse vectors or is a sparse vector. are the values stored in std::pair::first. So this number tells you the dimensionality
- returns the largest element index in any sample + 1. Note that the element index values of a set of sparse vectors.
are the values stored in std::pair::first. So this number tells you the dimensionality !*/
of a set of sparse vectors.
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, long NR, long NC, typename MM, typename L, typename SRC, typename U>
inline void add_to (
template <typename T, long NR, long NC, typename MM, typename L, typename SRC, typename U> matrix<T,NR,NC,MM,L>& dest,
inline void add_to ( const SRC& src,
matrix<T,NR,NC,MM,L>& dest, const U& C = 1
const SRC& src, );
const U& C = 1 /*!
); requires
/*! - SRC == a matrix expression or an unsorted sparse vector
requires - is_vector(dest) == true
- SRC == a matrix expression or an unsorted sparse vector - Let MAX denote the largest element index in src.
- is_vector(dest) == true Then we require that:
- Let MAX denote the largest element index in src. - MAX < dest.size()
Then we require that: - (i.e. dest needs to be big enough to contain all the elements of src)
- MAX < dest.size() ensures
- (i.e. dest needs to be big enough to contain all the elements of src) - #dest == dest + C*src
ensures !*/
- #dest == dest + C*src
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T, long NR, long NC, typename MM, typename L, typename SRC, typename U>
inline void subtract_from (
template <typename T, long NR, long NC, typename MM, typename L, typename SRC, typename U> matrix<T,NR,NC,MM,L>& dest,
inline void subtract_from ( const SRC& src,
matrix<T,NR,NC,MM,L>& dest, const U& C = 1
const SRC& src, );
const U& C = 1 /*!
); requires
/*! - SRC == a matrix expression or an unsorted sparse vector
requires - is_vector(dest) == true
- SRC == a matrix expression or an unsorted sparse vector - Let MAX denote the largest element index in src.
- is_vector(dest) == true Then we require that:
- Let MAX denote the largest element index in src. - MAX < dest.size()
Then we require that: - (i.e. dest needs to be big enough to contain all the elements of src)
- MAX < dest.size() ensures
- (i.e. dest needs to be big enough to contain all the elements of src) - #dest == dest - C*src
ensures !*/
- #dest == dest - C*src
!*/ // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- template <typename T>
typename T::value_type::second_type min (
template <typename T> const T& vect
typename T::value_type::second_type min ( );
const T& vect /*!
); requires
/*! - T == an unsorted sparse vector
requires ensures
- T == an unsorted sparse vector - returns the minimum value in the sparse vector vect. Note that
ensures this value is always <= 0 since a sparse vector has an unlimited number
- returns the minimum value in the sparse vector vect. Note that of 0 elements.
this value is always <= 0 since a sparse vector has an unlimited number !*/
of 0 elements.
!*/ // ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------ template <typename T>
typename T::value_type::second_type max (
template <typename T> const T& vect
typename T::value_type::second_type max ( );
const T& vect /*!
); requires
/*! - T == an unsorted sparse vector
requires ensures
- T == an unsorted sparse vector - returns the maximum value in the sparse vector vect. Note that
ensures this value is always >= 0 since a sparse vector has an unlimited number
- returns the maximum value in the sparse vector vect. Note that of 0 elements.
this value is always >= 0 since a sparse vector has an unlimited number !*/
of 0 elements.
!*/
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -149,9 +149,6 @@ namespace dlib ...@@ -149,9 +149,6 @@ namespace dlib
feature_vector_type& psi feature_vector_type& psi
) const ) const
{ {
using dlib::sparse_vector::dot;
using dlib::dot;
matrix<double> cost; matrix<double> cost;
unsigned long size; unsigned long size;
if (force_assignment) if (force_assignment)
......
...@@ -184,7 +184,7 @@ namespace dlib ...@@ -184,7 +184,7 @@ namespace dlib
{ {
cache[i].get_truth_joint_feature_vector_cached(ftemp); cache[i].get_truth_joint_feature_vector_cached(ftemp);
sparse_vector::subtract_from(psi_true, ftemp); subtract_from(psi_true, ftemp);
} }
} }
...@@ -249,7 +249,7 @@ namespace dlib ...@@ -249,7 +249,7 @@ namespace dlib
auto_mutex lock(self.accum_mutex); auto_mutex lock(self.accum_mutex);
data.loss += loss; data.loss += loss;
sparse_vector::add_to(data.subgradient, ftemp); add_to(data.subgradient, ftemp);
} }
else else
{ {
...@@ -268,12 +268,12 @@ namespace dlib ...@@ -268,12 +268,12 @@ namespace dlib
loss_temp, loss_temp,
ftemp); ftemp);
loss += loss_temp; loss += loss_temp;
sparse_vector::add_to(faccum, ftemp); add_to(faccum, ftemp);
} }
auto_mutex lock(self.accum_mutex); auto_mutex lock(self.accum_mutex);
data.loss += loss; data.loss += loss;
sparse_vector::add_to(data.subgradient, faccum); add_to(data.subgradient, faccum);
} }
} }
......
...@@ -59,9 +59,6 @@ namespace dlib ...@@ -59,9 +59,6 @@ namespace dlib
- All vectors have non-zero size. That is, they have more than 0 dimensions. - All vectors have non-zero size. That is, they have more than 0 dimensions.
!*/ !*/
{ {
using namespace dlib::sparse_vector;
using namespace dlib;
if (!is_learning_problem(samples, labels)) if (!is_learning_problem(samples, labels))
return false; return false;
...@@ -171,8 +168,6 @@ namespace dlib ...@@ -171,8 +168,6 @@ namespace dlib
"\t structural_svm_graph_labeling_problem::structural_svm_graph_labeling_problem()" "\t structural_svm_graph_labeling_problem::structural_svm_graph_labeling_problem()"
<< "\n\t invalid inputs were given to this function"); << "\n\t invalid inputs were given to this function");
using namespace dlib::sparse_vector;
// figure out how many dimensions are in the node and edge vectors. // figure out how many dimensions are in the node and edge vectors.
node_dims = 0; node_dims = 0;
...@@ -321,9 +316,6 @@ namespace dlib ...@@ -321,9 +316,6 @@ namespace dlib
feature_vector_type& psi feature_vector_type& psi
) const ) const
{ {
using dlib::sparse_vector::dot;
using dlib::dot;
const sample_type& samp = samples[idx]; const sample_type& samp = samples[idx];
// setup the potts graph based on samples[idx] and current_solution. // setup the potts graph based on samples[idx] and current_solution.
......
...@@ -75,9 +75,6 @@ namespace dlib ...@@ -75,9 +75,6 @@ namespace dlib
unsigned long best_idx = 0; unsigned long best_idx = 0;
using sparse_vector::dot;
using dlib::dot;
const scalar_type dot_true_psi = dot(true_psi, current_solution); const scalar_type dot_true_psi = dot(true_psi, current_solution);
// figure out which element in the cache is the best (i.e. has the biggest risk) // figure out which element in the cache is the best (i.e. has the biggest risk)
...@@ -338,7 +335,7 @@ namespace dlib ...@@ -338,7 +335,7 @@ namespace dlib
{ {
cache[i].get_truth_joint_feature_vector_cached(ftemp); cache[i].get_truth_joint_feature_vector_cached(ftemp);
sparse_vector::subtract_from(psi_true, ftemp); subtract_from(psi_true, ftemp);
} }
} }
...@@ -364,7 +361,7 @@ namespace dlib ...@@ -364,7 +361,7 @@ namespace dlib
scalar_type loss; scalar_type loss;
separation_oracle_cached(i, w, loss, ftemp); separation_oracle_cached(i, w, loss, ftemp);
total_loss += loss; total_loss += loss;
sparse_vector::add_to(subgradient, ftemp); add_to(subgradient, ftemp);
} }
} }
......
...@@ -64,7 +64,7 @@ namespace dlib ...@@ -64,7 +64,7 @@ namespace dlib
auto_mutex lock(self.accum_mutex); auto_mutex lock(self.accum_mutex);
total_loss += loss; total_loss += loss;
sparse_vector::add_to(subgradient, ftemp); add_to(subgradient, ftemp);
} }
else else
{ {
...@@ -79,12 +79,12 @@ namespace dlib ...@@ -79,12 +79,12 @@ namespace dlib
scalar_type loss_temp; scalar_type loss_temp;
self.separation_oracle_cached(i, w, loss_temp, ftemp); self.separation_oracle_cached(i, w, loss_temp, ftemp);
loss += loss_temp; loss += loss_temp;
sparse_vector::add_to(faccum, ftemp); add_to(faccum, ftemp);
} }
auto_mutex lock(self.accum_mutex); auto_mutex lock(self.accum_mutex);
total_loss += loss; total_loss += loss;
sparse_vector::add_to(subgradient, faccum); add_to(subgradient, faccum);
} }
} }
......
...@@ -68,7 +68,7 @@ namespace dlib ...@@ -68,7 +68,7 @@ namespace dlib
) const ) const
{ {
// plus 1 for the bias term // plus 1 for the bias term
return sparse_vector::max_index_plus_one(samples) + 1; return max_index_plus_one(samples) + 1;
} }
virtual bool optimization_status ( virtual bool optimization_status (
...@@ -138,13 +138,13 @@ namespace dlib ...@@ -138,13 +138,13 @@ namespace dlib
{ {
if (labels(i) > 0) if (labels(i) > 0)
{ {
sparse_vector::subtract_from(subgradient, samples(i), Cpos); subtract_from(subgradient, samples(i), Cpos);
subgradient(subgradient.size()-1) += Cpos; subgradient(subgradient.size()-1) += Cpos;
} }
else else
{ {
sparse_vector::add_to(subgradient, samples(i), Cneg); add_to(subgradient, samples(i), Cneg);
subgradient(subgradient.size()-1) -= Cneg; subgradient(subgradient.size()-1) -= Cneg;
} }
...@@ -171,8 +171,6 @@ namespace dlib ...@@ -171,8 +171,6 @@ namespace dlib
- for all i: #dot_prods[i] == dot(colm(#w,0,w.size()-1), samples(i)) - #w(w.size()-1) - for all i: #dot_prods[i] == dot(colm(#w,0,w.size()-1), samples(i)) - #w(w.size()-1)
!*/ !*/
{ {
using dlib::sparse_vector::dot;
using dlib::dot;
// The reason for using w_size_m1 and not just w.size()-1 is because // The reason for using w_size_m1 and not just w.size()-1 is because
// doing it this way avoids an inane warning from gcc that can occur in some cases. // doing it this way avoids an inane warning from gcc that can occur in some cases.
const long w_size_m1 = w.size()-1; const long w_size_m1 = w.size()-1;
...@@ -558,8 +556,8 @@ namespace dlib ...@@ -558,8 +556,8 @@ namespace dlib
// sparse vector container so we need to use this special kind of copy to handle that case. // sparse vector container so we need to use this special kind of copy to handle that case.
// As an aside, the reason for using max_index_plus_one() and not just w.size()-1 is because // As an aside, the reason for using max_index_plus_one() and not just w.size()-1 is because
// doing it this way avoids an inane warning from gcc that can occur in some cases. // doing it this way avoids an inane warning from gcc that can occur in some cases.
const long out_size = sparse_vector::max_index_plus_one(x); const long out_size = max_index_plus_one(x);
sparse_vector::assign(df.basis_vectors(0), matrix_cast<scalar_type>(colm(w, 0, out_size))); assign(df.basis_vectors(0), matrix_cast<scalar_type>(colm(w, 0, out_size)));
df.alpha.set_size(1); df.alpha.set_size(1);
df.alpha(0) = 1; df.alpha(0) = 1;
......
...@@ -50,7 +50,7 @@ namespace dlib ...@@ -50,7 +50,7 @@ namespace dlib
samples(samples_), samples(samples_),
labels(labels_), labels(labels_),
distinct_labels(select_all_distinct_labels(labels_)), distinct_labels(select_all_distinct_labels(labels_)),
dims(sparse_vector::max_index_plus_one(samples_)+1) // +1 for the bias dims(max_index_plus_one(samples_)+1) // +1 for the bias
{} {}
virtual long get_num_dimensions ( virtual long get_num_dimensions (
...@@ -70,7 +70,7 @@ namespace dlib ...@@ -70,7 +70,7 @@ namespace dlib
feature_vector_type& psi feature_vector_type& psi
) const ) const
{ {
sparse_vector::assign(psi, samples[idx]); assign(psi, samples[idx]);
// Add a constant -1 to account for the bias term. // Add a constant -1 to account for the bias term.
psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1))); psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1)));
...@@ -94,8 +94,6 @@ namespace dlib ...@@ -94,8 +94,6 @@ namespace dlib
// LOSS(idx,y) + F(x,y). Note that y in this case is given by distinct_labels[i]. // LOSS(idx,y) + F(x,y). Note that y in this case is given by distinct_labels[i].
for (unsigned long i = 0; i < distinct_labels.size(); ++i) for (unsigned long i = 0; i < distinct_labels.size(); ++i)
{ {
using dlib::sparse_vector::dot;
using dlib::dot;
// Compute the F(x,y) part: // Compute the F(x,y) part:
// perform: temp == dot(relevant part of current solution, samples[idx]) - current_bias // perform: temp == dot(relevant part of current solution, samples[idx]) - current_bias
scalar_type temp = dot(rowm(current_solution, range(i*dims, (i+1)*dims-2)), samples[idx]) - current_solution((i+1)*dims-1); scalar_type temp = dot(rowm(current_solution, range(i*dims, (i+1)*dims-2)), samples[idx]) - current_solution((i+1)*dims-1);
...@@ -112,7 +110,7 @@ namespace dlib ...@@ -112,7 +110,7 @@ namespace dlib
} }
} }
sparse_vector::assign(psi, samples[idx]); assign(psi, samples[idx]);
// add a constant -1 to account for the bias term // add a constant -1 to account for the bias term
psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1))); psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1)));
...@@ -287,7 +285,7 @@ namespace dlib ...@@ -287,7 +285,7 @@ namespace dlib
trained_function_type df; trained_function_type df;
const long dims = sparse_vector::max_index_plus_one(all_samples); const long dims = max_index_plus_one(all_samples);
df.labels = select_all_distinct_labels(all_labels); df.labels = select_all_distinct_labels(all_labels);
df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1)); df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1));
df.b = colm(reshape(weights, df.labels.size(), dims+1), dims); df.b = colm(reshape(weights, df.labels.size(), dims+1), dims);
......
...@@ -50,18 +50,18 @@ namespace ...@@ -50,18 +50,18 @@ namespace
DLIB_TEST(samples.size() == 150); DLIB_TEST(samples.size() == 150);
DLIB_TEST(labels.size() == 150); DLIB_TEST(labels.size() == 150);
DLIB_TEST(sparse_vector::max_index_plus_one(samples) == 5); DLIB_TEST(max_index_plus_one(samples) == 5);
fix_nonzero_indexing(samples); fix_nonzero_indexing(samples);
DLIB_TEST(sparse_vector::max_index_plus_one(samples) == 4); DLIB_TEST(max_index_plus_one(samples) == 4);
load_libsvm_formatted_data("iris.scale2",samples, labels); load_libsvm_formatted_data("iris.scale2",samples, labels);
DLIB_TEST(samples.size() == 150); DLIB_TEST(samples.size() == 150);
DLIB_TEST(labels.size() == 150); DLIB_TEST(labels.size() == 150);
DLIB_TEST(sparse_vector::max_index_plus_one(samples) == 5); DLIB_TEST(max_index_plus_one(samples) == 5);
fix_nonzero_indexing(samples); fix_nonzero_indexing(samples);
DLIB_TEST(sparse_vector::max_index_plus_one(samples) == 4); DLIB_TEST(max_index_plus_one(samples) == 4);
one_vs_one_trainer<any_trainer<sample_type,scalar_type>,scalar_type> trainer; one_vs_one_trainer<any_trainer<sample_type,scalar_type>,scalar_type> trainer;
...@@ -85,7 +85,7 @@ namespace ...@@ -85,7 +85,7 @@ namespace
std::vector<dsample_type> dsamples = sparse_to_dense(samples); std::vector<dsample_type> dsamples = sparse_to_dense(samples);
DLIB_TEST(dsamples.size() == 150); DLIB_TEST(dsamples.size() == 150);
DLIB_TEST(dsamples[0].size() == 4); DLIB_TEST(dsamples[0].size() == 4);
DLIB_TEST(sparse_vector::max_index_plus_one(dsamples) == 4); DLIB_TEST(max_index_plus_one(dsamples) == 4);
one_vs_one_trainer<any_trainer<dsample_type,scalar_type>,scalar_type> trainer; one_vs_one_trainer<any_trainer<dsample_type,scalar_type>,scalar_type> trainer;
......
...@@ -42,7 +42,6 @@ namespace ...@@ -42,7 +42,6 @@ namespace
const sample_type& b const sample_type& b
) const ) const
{ {
using namespace sparse_vector;
return dot(a,b); return dot(a,b);
} }
...@@ -365,7 +364,6 @@ namespace ...@@ -365,7 +364,6 @@ namespace
- tests the kcentroid object with the given kernel - tests the kcentroid object with the given kernel
!*/ !*/
{ {
using namespace dlib::sparse_vector;
// Here we declare that our samples will be 2 dimensional column vectors. // Here we declare that our samples will be 2 dimensional column vectors.
typedef typename kernel_type::sample_type sample_type; typedef typename kernel_type::sample_type sample_type;
...@@ -439,7 +437,7 @@ namespace ...@@ -439,7 +437,7 @@ namespace
temp[3] = 4; temp[3] = 4;
temp[4] = 5; temp[4] = 5;
dlog << LDEBUG << "AAAA 3.4" ; dlog << LDEBUG << "AAAA 3.4" ;
double junk = sparse_vector::distance(temp2,temp); double junk = dlib::distance(temp2,temp);
dlog << LDEBUG << "AAAA 3.5" ; dlog << LDEBUG << "AAAA 3.5" ;
DLIB_TEST(approx_equal(test(temp), junk) ); DLIB_TEST(approx_equal(test(temp), junk) );
...@@ -462,7 +460,7 @@ namespace ...@@ -462,7 +460,7 @@ namespace
temp[2] = 3; temp[2] = 3;
temp[3] = 4; temp[3] = 4;
temp[4] = 5; temp[4] = 5;
DLIB_TEST(approx_equal(test(temp), sparse_vector::distance(temp2,temp))); DLIB_TEST(approx_equal(test(temp), dlib::distance(temp2,temp)));
// make test store the -1*point(0,1,0,3,-1) // make test store the -1*point(0,1,0,3,-1)
...@@ -483,7 +481,7 @@ namespace ...@@ -483,7 +481,7 @@ namespace
temp[2] = -3; temp[2] = -3;
temp[3] = 4; temp[3] = 4;
temp[4] = 5; temp[4] = 5;
DLIB_TEST(approx_equal(test(temp), sparse_vector::distance(temp2,temp))); DLIB_TEST(approx_equal(test(temp), dlib::distance(temp2,temp)));
...@@ -500,8 +498,8 @@ namespace ...@@ -500,8 +498,8 @@ namespace
temp[2] = -3; temp[2] = -3;
temp[3] = 4; temp[3] = 4;
temp[4] = 5; temp[4] = 5;
DLIB_TEST(approx_equal(test(temp), sparse_vector::distance(temp2,temp))); DLIB_TEST(approx_equal(test(temp), dlib::distance(temp2,temp)));
DLIB_TEST(approx_equal(test.get_distance_function()(temp), sparse_vector::distance(temp2,temp))); DLIB_TEST(approx_equal(test.get_distance_function()(temp), dlib::distance(temp2,temp)));
dlog << LDEBUG << "AAAA 6" ; dlog << LDEBUG << "AAAA 6" ;
...@@ -522,8 +520,8 @@ namespace ...@@ -522,8 +520,8 @@ namespace
temp[2] = -3; temp[2] = -3;
temp[3] = 4; temp[3] = 4;
temp[4] = 5; temp[4] = 5;
DLIB_TEST(approx_equal(test(temp), sparse_vector::distance(temp2,temp))); DLIB_TEST(approx_equal(test(temp), dlib::distance(temp2,temp)));
DLIB_TEST(approx_equal(test.get_distance_function()(temp), sparse_vector::distance(temp2,temp))); DLIB_TEST(approx_equal(test.get_distance_function()(temp), dlib::distance(temp2,temp)));
DLIB_TEST(approx_equal(test(test), 0)); DLIB_TEST(approx_equal(test(test), 0));
DLIB_TEST(approx_equal(test.get_distance_function()(test.get_distance_function()), 0)); DLIB_TEST(approx_equal(test.get_distance_function()(test.get_distance_function()), 0));
...@@ -545,7 +543,6 @@ namespace ...@@ -545,7 +543,6 @@ namespace
- tests the kcentroid object with the given kernel - tests the kcentroid object with the given kernel
!*/ !*/
{ {
using namespace sparse_vector;
// Here we declare that our samples will be 2 dimensional column vectors. // Here we declare that our samples will be 2 dimensional column vectors.
typedef typename kernel_type::sample_type sample_type; typedef typename kernel_type::sample_type sample_type;
......
...@@ -14,7 +14,6 @@ namespace ...@@ -14,7 +14,6 @@ namespace
using namespace test; using namespace test;
using namespace dlib; using namespace dlib;
using namespace std; using namespace std;
using namespace dlib::sparse_vector;
dlib::logger dlog("test.sparse_vector"); dlib::logger dlog("test.sparse_vector");
......
...@@ -135,30 +135,30 @@ namespace ...@@ -135,30 +135,30 @@ namespace
// Now test some of the sparse helper functions // Now test some of the sparse helper functions
DLIB_TEST(sparse_vector::max_index_plus_one(samples) == 2); DLIB_TEST(max_index_plus_one(samples) == 2);
DLIB_TEST(sparse_vector::max_index_plus_one(samples[0]) == 2); DLIB_TEST(max_index_plus_one(samples[0]) == 2);
matrix<double,3,1> m; matrix<double,3,1> m;
m = 1; m = 1;
sparse_vector::add_to(m, samples[3]); add_to(m, samples[3]);
DLIB_TEST(m(0) == 1 + samples[3][0].second); DLIB_TEST(m(0) == 1 + samples[3][0].second);
DLIB_TEST(m(1) == 1 + samples[3][1].second); DLIB_TEST(m(1) == 1 + samples[3][1].second);
DLIB_TEST(m(2) == 1); DLIB_TEST(m(2) == 1);
m = 1; m = 1;
sparse_vector::subtract_from(m, samples[3]); subtract_from(m, samples[3]);
DLIB_TEST(m(0) == 1 - samples[3][0].second); DLIB_TEST(m(0) == 1 - samples[3][0].second);
DLIB_TEST(m(1) == 1 - samples[3][1].second); DLIB_TEST(m(1) == 1 - samples[3][1].second);
DLIB_TEST(m(2) == 1); DLIB_TEST(m(2) == 1);
m = 1; m = 1;
sparse_vector::add_to(m, samples[3], 2); add_to(m, samples[3], 2);
DLIB_TEST(m(0) == 1 + 2*samples[3][0].second); DLIB_TEST(m(0) == 1 + 2*samples[3][0].second);
DLIB_TEST(m(1) == 1 + 2*samples[3][1].second); DLIB_TEST(m(1) == 1 + 2*samples[3][1].second);
DLIB_TEST(m(2) == 1); DLIB_TEST(m(2) == 1);
m = 1; m = 1;
sparse_vector::subtract_from(m, samples[3], 2); subtract_from(m, samples[3], 2);
DLIB_TEST(m(0) == 1 - 2*samples[3][0].second); DLIB_TEST(m(0) == 1 - 2*samples[3][0].second);
DLIB_TEST(m(1) == 1 - 2*samples[3][1].second); DLIB_TEST(m(1) == 1 - 2*samples[3][1].second);
DLIB_TEST(m(2) == 1); DLIB_TEST(m(2) == 1);
...@@ -227,7 +227,6 @@ namespace ...@@ -227,7 +227,6 @@ namespace
sv[0] = 1; sv[0] = 1;
sv[3] = 1; sv[3] = 1;
using namespace sparse_vector;
DLIB_TEST(dot(sv,dv) == 5); DLIB_TEST(dot(sv,dv) == 5);
DLIB_TEST(dot(dv,sv) == 5); DLIB_TEST(dot(dv,sv) == 5);
...@@ -249,7 +248,6 @@ namespace ...@@ -249,7 +248,6 @@ namespace
sv[0] = 1; sv[0] = 1;
sv[3] = 1; sv[3] = 1;
using namespace sparse_vector;
assign(dv2, dv); assign(dv2, dv);
......
...@@ -64,7 +64,7 @@ namespace ...@@ -64,7 +64,7 @@ namespace
feature_vector_type& psi feature_vector_type& psi
) const ) const
{ {
sparse_vector::assign(psi, samples[idx]); assign(psi, samples[idx]);
// Add a constant -1 to account for the bias term. // Add a constant -1 to account for the bias term.
psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1))); psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1)));
...@@ -88,8 +88,6 @@ namespace ...@@ -88,8 +88,6 @@ namespace
// LOSS(idx,y) + F(x,y). Note that y in this case is given by distinct_labels[i]. // LOSS(idx,y) + F(x,y). Note that y in this case is given by distinct_labels[i].
for (unsigned long i = 0; i < distinct_labels.size(); ++i) for (unsigned long i = 0; i < distinct_labels.size(); ++i)
{ {
using dlib::sparse_vector::dot;
using dlib::dot;
// Compute the F(x,y) part: // Compute the F(x,y) part:
// perform: temp == dot(relevant part of current solution, samples[idx]) - current_bias // perform: temp == dot(relevant part of current solution, samples[idx]) - current_bias
scalar_type temp = dot(rowm(current_solution, range(i*dims, (i+1)*dims-2)), samples[idx]) - current_solution((i+1)*dims-1); scalar_type temp = dot(rowm(current_solution, range(i*dims, (i+1)*dims-2)), samples[idx]) - current_solution((i+1)*dims-1);
...@@ -106,7 +104,7 @@ namespace ...@@ -106,7 +104,7 @@ namespace
} }
} }
sparse_vector::assign(psi, samples[idx]); assign(psi, samples[idx]);
// add a constant -1 to account for the bias term // add a constant -1 to account for the bias term
psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1))); psi.push_back(std::make_pair(dims-1,static_cast<scalar_type>(-1)));
...@@ -221,7 +219,7 @@ namespace ...@@ -221,7 +219,7 @@ namespace
trained_function_type df; trained_function_type df;
const long dims = sparse_vector::max_index_plus_one(all_samples); const long dims = max_index_plus_one(all_samples);
df.labels = select_all_distinct_labels(all_labels); df.labels = select_all_distinct_labels(all_labels);
df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1)); df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1));
df.b = colm(reshape(weights, df.labels.size(), dims+1), dims); df.b = colm(reshape(weights, df.labels.size(), dims+1), dims);
...@@ -302,7 +300,7 @@ namespace ...@@ -302,7 +300,7 @@ namespace
trained_function_type df; trained_function_type df;
const long dims = sparse_vector::max_index_plus_one(all_samples); const long dims = max_index_plus_one(all_samples);
df.labels = select_all_distinct_labels(all_labels); df.labels = select_all_distinct_labels(all_labels);
df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1)); df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1));
df.b = colm(reshape(weights, df.labels.size(), dims+1), dims); df.b = colm(reshape(weights, df.labels.size(), dims+1), dims);
...@@ -383,7 +381,7 @@ namespace ...@@ -383,7 +381,7 @@ namespace
trained_function_type df; trained_function_type df;
const long dims = sparse_vector::max_index_plus_one(all_samples); const long dims = max_index_plus_one(all_samples);
df.labels = select_all_distinct_labels(all_labels); df.labels = select_all_distinct_labels(all_labels);
df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1)); df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1));
df.b = colm(reshape(weights, df.labels.size(), dims+1), dims); df.b = colm(reshape(weights, df.labels.size(), dims+1), dims);
...@@ -464,7 +462,7 @@ namespace ...@@ -464,7 +462,7 @@ namespace
trained_function_type df; trained_function_type df;
const long dims = sparse_vector::max_index_plus_one(all_samples); const long dims = max_index_plus_one(all_samples);
df.labels = select_all_distinct_labels(all_labels); df.labels = select_all_distinct_labels(all_labels);
df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1)); df.weights = colm(reshape(weights, df.labels.size(), dims+1), range(0,dims-1));
df.b = colm(reshape(weights, df.labels.size(), dims+1), dims); df.b = colm(reshape(weights, df.labels.size(), dims+1), dims);
......
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