Minor Improvements
parent
f3b9bccfd5
commit
9fdb28f9bf
|
@ -13,7 +13,7 @@
|
||||||
* @file small.cpp
|
* @file small.cpp
|
||||||
* @brief UGM (undirected graphical model) examples: chain
|
* @brief UGM (undirected graphical model) examples: chain
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
* @author Abhijit
|
* @author Abhijit Kundu
|
||||||
*
|
*
|
||||||
* See http://www.di.ens.fr/~mschmidt/Software/UGM/chain.html
|
* See http://www.di.ens.fr/~mschmidt/Software/UGM/chain.html
|
||||||
* for more explanation. This code demos the same example using GTSAM.
|
* for more explanation. This code demos the same example using GTSAM.
|
||||||
|
|
|
@ -49,21 +49,17 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
// Print the UGM distribution
|
// Print the UGM distribution
|
||||||
cout << "\nUGM distribution:" << endl;
|
cout << "\nUGM distribution:" << endl;
|
||||||
for (size_t a = 0; a < nrStates; a++)
|
vector<DiscreteFactor::Values> allPosbValues = cartesianProduct(
|
||||||
for (size_t m = 0; m < nrStates; m++)
|
Cathy & Heather & Mark & Allison);
|
||||||
for (size_t h = 0; h < nrStates; h++)
|
for (size_t i = 0; i < allPosbValues.size(); ++i) {
|
||||||
for (size_t c = 0; c < nrStates; c++) {
|
DiscreteFactor::Values values = allPosbValues[i];
|
||||||
DiscreteFactor::Values values;
|
|
||||||
values[1] = c;
|
|
||||||
values[2] = h;
|
|
||||||
values[3] = m;
|
|
||||||
values[4] = a;
|
|
||||||
double prodPot = graph(values);
|
double prodPot = graph(values);
|
||||||
cout << c << " " << h << " " << m << " " << a << " :\t"
|
cout << values[Cathy.first] << " " << values[Heather.first] << " "
|
||||||
<< prodPot << "\t" << prodPot/3790 << endl;
|
<< values[Mark.first] << " " << values[Allison.first] << " :\t"
|
||||||
|
<< prodPot << "\t" << prodPot / 3790 << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Decoding", i.e., configuration with largest value
|
// "Decoding", i.e., configuration with largest value (MPE)
|
||||||
// We use sequential variable elimination
|
// We use sequential variable elimination
|
||||||
DiscreteSequentialSolver solver(graph);
|
DiscreteSequentialSolver solver(graph);
|
||||||
DiscreteFactor::sharedValues optimalDecoding = solver.optimize();
|
DiscreteFactor::sharedValues optimalDecoding = solver.optimize();
|
||||||
|
|
|
@ -20,8 +20,10 @@
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,4 +46,42 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
}; //Assignment
|
}; //Assignment
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get Cartesian product consisting all possible configurations
|
||||||
|
* @param vector list of keys (label,cardinality) pairs.
|
||||||
|
* @return vector list of all possible value assignments
|
||||||
|
*
|
||||||
|
* This function returns a vector of Assignment values for all possible
|
||||||
|
* (Cartesian product) configurations of set of Keys which are nothing
|
||||||
|
* but (Label,cardinality) pairs. This function should NOT be called for
|
||||||
|
* more than a small number of variables and cardinalities. E.g. For 6
|
||||||
|
* variables with each having cardinalities 4, we get 4096 possible
|
||||||
|
* configurations!!
|
||||||
|
*/
|
||||||
|
template<typename L>
|
||||||
|
std::vector<Assignment<L> > cartesianProduct(
|
||||||
|
const std::vector<std::pair<L, size_t> >& keys) {
|
||||||
|
std::vector<Assignment<L> > allPossValues;
|
||||||
|
Assignment<L> values;
|
||||||
|
typedef std::pair<L, size_t> DiscreteKey;
|
||||||
|
BOOST_FOREACH(const DiscreteKey& key, keys)
|
||||||
|
values[key.first] = 0; //Initialize from 0
|
||||||
|
while (1) {
|
||||||
|
allPossValues.push_back(values);
|
||||||
|
size_t j = 0;
|
||||||
|
for (j = 0; j < keys.size(); j++) {
|
||||||
|
L idx = keys[j].first;
|
||||||
|
values[idx]++;
|
||||||
|
if (values[idx] < keys[j].second)
|
||||||
|
break;
|
||||||
|
//Wrap condition
|
||||||
|
values[idx] = 0;
|
||||||
|
}
|
||||||
|
if (j == keys.size())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return allPossValues;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gtsam
|
} // namespace gtsam
|
||||||
|
|
|
@ -127,9 +127,16 @@ namespace gtsam {
|
||||||
*/
|
*/
|
||||||
shared_ptr combine(size_t nrFrontals, ADT::Binary op) const;
|
shared_ptr combine(size_t nrFrontals, ADT::Binary op) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Permutes the keys in Potentials and DiscreteFactor
|
||||||
|
*
|
||||||
|
* This re-implements the permuteWithInverse() in both Potentials
|
||||||
|
* and DiscreteFactor by doing both of them together.
|
||||||
|
*/
|
||||||
|
|
||||||
void permuteWithInverse(const Permutation& inversePermutation){
|
void permuteWithInverse(const Permutation& inversePermutation){
|
||||||
DiscreteFactor::permuteWithInverse(inversePermutation);
|
DiscreteFactor::permuteWithInverse(inversePermutation);
|
||||||
Potentials::permute(inversePermutation);
|
Potentials::permuteWithInverse(inversePermutation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -75,41 +75,38 @@ namespace gtsam {
|
||||||
|
|
||||||
/* ******************************************************************************** */
|
/* ******************************************************************************** */
|
||||||
void DiscreteConditional::solveInPlace(Values& values) const {
|
void DiscreteConditional::solveInPlace(Values& values) const {
|
||||||
|
// OLD
|
||||||
// assert(nrFrontals() == 1);
|
// assert(nrFrontals() == 1);
|
||||||
// Index j = (firstFrontalKey());
|
// Index j = (firstFrontalKey());
|
||||||
// size_t mpe = solve(values); // Solve for variable
|
// size_t mpe = solve(values); // Solve for variable
|
||||||
// values[j] = mpe; // store result in partial solution
|
// values[j] = mpe; // store result in partial solution
|
||||||
|
// OLD
|
||||||
|
|
||||||
// TODO: is this really the fastest way? I think it is.
|
// TODO: is this really the fastest way? I think it is.
|
||||||
|
|
||||||
|
//The following is to make make adjustment for nFrontals \neq 1
|
||||||
ADT pFS = choose(values); // P(F|S=parentsValues)
|
ADT pFS = choose(values); // P(F|S=parentsValues)
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
Values mpe;
|
Values mpe;
|
||||||
Values frontalVals;
|
|
||||||
BOOST_FOREACH(Index j, frontals()) {
|
|
||||||
frontalVals[j] = 0;
|
|
||||||
}
|
|
||||||
double maxP = 0;
|
double maxP = 0;
|
||||||
|
|
||||||
while (1) {
|
DiscreteKeys keys;
|
||||||
|
BOOST_FOREACH(Index idx, frontals()) {
|
||||||
|
DiscreteKey dk(idx,cardinality(idx));
|
||||||
|
keys & dk;
|
||||||
|
}
|
||||||
|
// Get all Possible Configurations
|
||||||
|
vector<Values> allPosbValues = cartesianProduct(keys);
|
||||||
|
|
||||||
|
// Find the MPE
|
||||||
|
BOOST_FOREACH(Values& frontalVals, allPosbValues) {
|
||||||
double pValueS = pFS(frontalVals); // P(F=value|S=parentsValues)
|
double pValueS = pFS(frontalVals); // P(F=value|S=parentsValues)
|
||||||
// Update MPE solution if better
|
// Update MPE solution if better
|
||||||
if (pValueS > maxP) {
|
if (pValueS > maxP) {
|
||||||
maxP = pValueS;
|
maxP = pValueS;
|
||||||
mpe = frontalVals;
|
mpe = frontalVals;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t j = 0;
|
|
||||||
for (j = 0; j < nrFrontals(); j++) {
|
|
||||||
Index idx = frontals()[j];
|
|
||||||
frontalVals[idx]++;
|
|
||||||
if (frontalVals[idx] < cardinality(idx))
|
|
||||||
break;
|
|
||||||
//Wrap condition
|
|
||||||
frontalVals[idx] = 0;
|
|
||||||
}
|
|
||||||
if (j == nrFrontals())
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//set values (inPlace) to mpe
|
//set values (inPlace) to mpe
|
||||||
|
@ -197,7 +194,7 @@ namespace gtsam {
|
||||||
/* ******************************************************************************** */
|
/* ******************************************************************************** */
|
||||||
void DiscreteConditional::permuteWithInverse(const Permutation& inversePermutation){
|
void DiscreteConditional::permuteWithInverse(const Permutation& inversePermutation){
|
||||||
IndexConditional::permuteWithInverse(inversePermutation);
|
IndexConditional::permuteWithInverse(inversePermutation);
|
||||||
Potentials::permute(inversePermutation);
|
Potentials::permuteWithInverse(inversePermutation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Potentials::permute(const Permutation& permutation) {
|
void Potentials::permuteWithInverse(const Permutation& permutation) {
|
||||||
// Permute the _cardinalities (TODO: Inefficient Consider Improving)
|
// Permute the _cardinalities (TODO: Inefficient Consider Improving)
|
||||||
DiscreteKeys keys;
|
DiscreteKeys keys;
|
||||||
map<Index, Index> ordering;
|
map<Index, Index> ordering;
|
||||||
|
@ -72,7 +72,6 @@ namespace gtsam {
|
||||||
// Perform Permutation
|
// Perform Permutation
|
||||||
BOOST_FOREACH(DiscreteKey& key, keys) {
|
BOOST_FOREACH(DiscreteKey& key, keys) {
|
||||||
ordering[key.first] = permutation[key.first];
|
ordering[key.first] = permutation[key.first];
|
||||||
//cout << key.first << " -> " << ordering[key.first] << endl;
|
|
||||||
key.first = ordering[key.first];
|
key.first = ordering[key.first];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,10 @@ namespace gtsam {
|
||||||
* @brief Permutes the keys in Potentials
|
* @brief Permutes the keys in Potentials
|
||||||
*
|
*
|
||||||
* This permutes the Indices and performs necessary re-ordering of ADD.
|
* This permutes the Indices and performs necessary re-ordering of ADD.
|
||||||
|
* This is virtual so that derived types e.g. DecisionTreeFactor can
|
||||||
|
* re-implement it.
|
||||||
*/
|
*/
|
||||||
void permute(const Permutation& perm);
|
virtual void permuteWithInverse(const Permutation& inversePermutation);
|
||||||
|
|
||||||
}; // Potentials
|
}; // Potentials
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @ file testDiscreteMarginals.cpp
|
* @file testDiscreteMarginals.cpp
|
||||||
* @date Feb 14, 2011
|
* @date Jun 7, 2012
|
||||||
* @author Abhijit Kundu
|
* @author Abhijit Kundu
|
||||||
* @author Richard Roberts
|
* @author Richard Roberts
|
||||||
* @author Frank Dellaert
|
* @author Frank Dellaert
|
||||||
|
|
Loading…
Reference in New Issue