sustaining_gazes/lib/3rdParty/dlib/include/dlib/svm/assignment_function.h
2016-04-28 15:40:36 -04:00

255 lines
7.8 KiB
C++

// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ASSIGNMENT_FuNCTION_Hh_
#define DLIB_ASSIGNMENT_FuNCTION_Hh_
#include "assignment_function_abstract.h"
#include "../matrix.h"
#include <vector>
#include "../optimization/max_cost_assignment.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor
>
class assignment_function
{
public:
typedef typename feature_extractor::lhs_element lhs_element;
typedef typename feature_extractor::rhs_element rhs_element;
typedef std::pair<std::vector<lhs_element>, std::vector<rhs_element> > sample_type;
typedef std::vector<long> label_type;
typedef label_type result_type;
assignment_function()
{
weights.set_size(fe.num_features());
weights = 0;
bias = 0;
force_assignment = false;
}
explicit assignment_function(
const matrix<double,0,1>& weights_,
double bias_
) :
weights(weights_),
bias(bias_),
force_assignment(false)
{
// make sure requires clause is not broken
DLIB_ASSERT(fe.num_features() == static_cast<unsigned long>(weights_.size()),
"\t assignment_function::assignment_function(weights_)"
<< "\n\t These sizes should match"
<< "\n\t fe.num_features(): " << fe.num_features()
<< "\n\t weights_.size(): " << weights_.size()
<< "\n\t this: " << this
);
}
assignment_function(
const matrix<double,0,1>& weights_,
double bias_,
const feature_extractor& fe_
) :
fe(fe_),
weights(weights_),
bias(bias_),
force_assignment(false)
{
// make sure requires clause is not broken
DLIB_ASSERT(fe_.num_features() == static_cast<unsigned long>(weights_.size()),
"\t assignment_function::assignment_function(weights_,fe_)"
<< "\n\t These sizes should match"
<< "\n\t fe_.num_features(): " << fe_.num_features()
<< "\n\t weights_.size(): " << weights_.size()
<< "\n\t this: " << this
);
}
assignment_function(
const matrix<double,0,1>& weights_,
double bias_,
const feature_extractor& fe_,
bool force_assignment_
) :
fe(fe_),
weights(weights_),
bias(bias_),
force_assignment(force_assignment_)
{
// make sure requires clause is not broken
DLIB_ASSERT(fe_.num_features() == static_cast<unsigned long>(weights_.size()),
"\t assignment_function::assignment_function(weights_,fe_,force_assignment_)"
<< "\n\t These sizes should match"
<< "\n\t fe_.num_features(): " << fe_.num_features()
<< "\n\t weights_.size(): " << weights_.size()
<< "\n\t this: " << this
);
}
const feature_extractor& get_feature_extractor (
) const { return fe; }
const matrix<double,0,1>& get_weights (
) const { return weights; }
double get_bias (
) const { return bias; }
bool forces_assignment (
) const { return force_assignment; }
void predict_assignments (
const std::vector<lhs_element>& lhs,
const std::vector<rhs_element>& rhs,
result_type& assignment
) const
{
assignment.clear();
matrix<double> cost;
unsigned long size;
if (force_assignment)
{
size = std::max(lhs.size(), rhs.size());
}
else
{
size = rhs.size() + lhs.size();
}
cost.set_size(size, size);
typedef typename feature_extractor::feature_vector_type feature_vector_type;
feature_vector_type feats;
// now fill out the cost assignment matrix
for (long r = 0; r < cost.nr(); ++r)
{
for (long c = 0; c < cost.nc(); ++c)
{
if (r < (long)lhs.size() && c < (long)rhs.size())
{
fe.get_features(lhs[r], rhs[c], feats);
cost(r,c) = dot(weights, feats) + bias;
}
else
{
cost(r,c) = 0;
}
}
}
if (cost.size() != 0)
{
// max_cost_assignment() only works with integer matrices, so convert from
// double to integer.
const double scale = (std::numeric_limits<dlib::int64>::max()/1000)/max(abs(cost));
matrix<dlib::int64> int_cost = matrix_cast<dlib::int64>(round(cost*scale));
assignment = max_cost_assignment(int_cost);
assignment.resize(lhs.size());
}
// adjust assignment so that non-assignments have a value of -1
for (unsigned long i = 0; i < assignment.size(); ++i)
{
if (assignment[i] >= (long)rhs.size())
assignment[i] = -1;
}
}
void predict_assignments (
const sample_type& item,
result_type& assignment
) const
{
predict_assignments(item.first, item.second, assignment);
}
result_type operator()(
const std::vector<lhs_element>& lhs,
const std::vector<rhs_element>& rhs
) const
{
result_type temp;
predict_assignments(lhs,rhs,temp);
return temp;
}
result_type operator() (
const sample_type& item
) const
{
return (*this)(item.first, item.second);
}
private:
feature_extractor fe;
matrix<double,0,1> weights;
double bias;
bool force_assignment;
};
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor
>
void serialize (
const assignment_function<feature_extractor>& item,
std::ostream& out
)
{
int version = 2;
serialize(version, out);
serialize(item.get_feature_extractor(), out);
serialize(item.get_weights(), out);
serialize(item.get_bias(), out);
serialize(item.forces_assignment(), out);
}
// ----------------------------------------------------------------------------------------
template <
typename feature_extractor
>
void deserialize (
assignment_function<feature_extractor>& item,
std::istream& in
)
{
feature_extractor fe;
matrix<double,0,1> weights;
double bias;
bool force_assignment;
int version = 0;
deserialize(version, in);
if (version != 2)
throw serialization_error("Unexpected version found while deserializing dlib::assignment_function.");
deserialize(fe, in);
deserialize(weights, in);
deserialize(bias, in);
deserialize(force_assignment, in);
item = assignment_function<feature_extractor>(weights, bias, fe, force_assignment);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ASSIGNMENT_FuNCTION_Hh_