// Copyright (C) 2011 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_FIND_MAX_FACTOR_GRAPH_VITERBi_ABSTRACT_Hh_ #ifdef DLIB_FIND_MAX_FACTOR_GRAPH_VITERBi_ABSTRACT_Hh_ #include <vector> #include "../matrix.h" namespace dlib { // ---------------------------------------------------------------------------------------- class map_problem { /*! WHAT THIS OBJECT REPRESENTS This object represents a chain-structured factor graph or graphical model. In particular, this object defines the interface a MAP problem on a factor graph must implement if it is to be solved using the find_max_factor_graph_viterbi() routine defined at the bottom of this file. Note that there is no dlib::map_problem object. What you are looking at here is simply the interface definition for a map problem. You must implement your own version of this object for the problem you wish to solve and then pass it to the find_max_factor_graph_viterbi() routine. !*/ public: unsigned long order ( ) const; /*! ensures - returns the order of this model. The order has the following interpretation: This model can represent a high order Markov chain. If order()==1 then map_problem represents a basic chain-structured graph where nodes only depend on their immediate neighbors. However, high order Markov models can also be used by setting order() > 1. !*/ unsigned long num_states ( ) const; /*! ensures - returns the number of states attainable by each variable/node in the graph. !*/ unsigned long number_of_nodes ( ) const; /*! ensures - returns the number of nodes in the factor graph. Or in other words, returns the number of variables in the MAP problem. !*/ template < typename EXP > double factor_value ( unsigned long node_id, const matrix_exp<EXP>& node_states ) const; /*! requires - EXP::type == unsigned long (i.e. node_states contains unsigned longs) - node_id < number_of_nodes() - node_states.size() == min(node_id, order()) + 1 - is_vector(node_states) == true - max(node_states) < num_states() ensures - In a chain-structured graph, each node has a potential function associated with it. The potential function operates on the variable given by the node as well as the order() previous variables. Therefore, factor_value() returns the value of the factor/potential function associated with node node_id where the following nodes take on the values defined below: - node_states(0) == the value of the node with ID node_id - node_states(i) == the value of the node with ID node_id-i - It is ok for this function to return a value of -std::numeric_limits<double>::infinity(). !*/ }; // ---------------------------------------------------------------------------------------- template < typename map_problem > void find_max_factor_graph_viterbi ( const map_problem& prob, std::vector<unsigned long>& map_assignment ); /*! requires - prob.num_states() > 0 - std::pow(prob.num_states(), prob.order()) < std::numeric_limits<unsigned long>::max() (i.e. The Viterbi algorithm is exponential in the order of the map problem. So don't make order too large.) - map_problem == an object with an interface compatible with the map_problem object defined at the top of this file. ensures - This function is a tool for exactly solving the MAP problem in a chain-structured graphical model or factor graph. That is, it attempts to solve a certain kind of optimization problem which can be defined as follows: - Let X denote a set of prob.number_of_nodes() integer valued variables, each taking a value in the range [0, prob.num_states()). - Let X(i) = the ith variable in X. - Let F(i) = factor_value_i(X(i), X(i-1), ..., X(i-prob.order())) (This is the value returned by prob.factor_value(i, node_states). Note that each factor's value function operates on at most prob.order()+1 variables. Moreover, the variables are adjacent and hence the graph is "chain-structured".) Then this function finds the assignments to the X variables which maximizes: sum over all valid i: F(i) - #map_assignment == the result of the optimization. - #map_assignment.size() == prob.number_of_nodes() - for all valid i: - #map_assignment[i] < prob.num_states() - #map_assignment[i] == The MAP assignment for node/variable i. !*/ // ---------------------------------------------------------------------------------------- } #endif // DLIB_FIND_MAX_FACTOR_GRAPH_VITERBi_ABSTRACT_Hh_