Minor Improvements
parent
f3b9bccfd5
commit
9fdb28f9bf
|
@ -13,7 +13,7 @@
|
|||
* @file small.cpp
|
||||
* @brief UGM (undirected graphical model) examples: chain
|
||||
* @author Frank Dellaert
|
||||
* @author Abhijit
|
||||
* @author Abhijit Kundu
|
||||
*
|
||||
* See http://www.di.ens.fr/~mschmidt/Software/UGM/chain.html
|
||||
* 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
|
||||
cout << "\nUGM distribution:" << endl;
|
||||
for (size_t a = 0; a < nrStates; a++)
|
||||
for (size_t m = 0; m < nrStates; m++)
|
||||
for (size_t h = 0; h < nrStates; h++)
|
||||
for (size_t c = 0; c < nrStates; c++) {
|
||||
DiscreteFactor::Values values;
|
||||
values[1] = c;
|
||||
values[2] = h;
|
||||
values[3] = m;
|
||||
values[4] = a;
|
||||
double prodPot = graph(values);
|
||||
cout << c << " " << h << " " << m << " " << a << " :\t"
|
||||
<< prodPot << "\t" << prodPot/3790 << endl;
|
||||
}
|
||||
vector<DiscreteFactor::Values> allPosbValues = cartesianProduct(
|
||||
Cathy & Heather & Mark & Allison);
|
||||
for (size_t i = 0; i < allPosbValues.size(); ++i) {
|
||||
DiscreteFactor::Values values = allPosbValues[i];
|
||||
double prodPot = graph(values);
|
||||
cout << values[Cathy.first] << " " << values[Heather.first] << " "
|
||||
<< 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
|
||||
DiscreteSequentialSolver solver(graph);
|
||||
DiscreteFactor::sharedValues optimalDecoding = solver.optimize();
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/**
|
||||
|
@ -42,6 +44,44 @@ namespace gtsam {
|
|||
bool equals(const Assignment& other, double tol = 1e-9) const {
|
||||
return (*this == other);
|
||||
}
|
||||
}; //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
|
||||
|
|
|
@ -127,9 +127,16 @@ namespace gtsam {
|
|||
*/
|
||||
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){
|
||||
DiscreteFactor::permuteWithInverse(inversePermutation);
|
||||
Potentials::permute(inversePermutation);
|
||||
Potentials::permuteWithInverse(inversePermutation);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -75,41 +75,38 @@ namespace gtsam {
|
|||
|
||||
/* ******************************************************************************** */
|
||||
void DiscreteConditional::solveInPlace(Values& values) const {
|
||||
// OLD
|
||||
// assert(nrFrontals() == 1);
|
||||
// Index j = (firstFrontalKey());
|
||||
// size_t mpe = solve(values); // Solve for variable
|
||||
// values[j] = mpe; // store result in partial solution
|
||||
// OLD
|
||||
|
||||
// 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)
|
||||
|
||||
// Initialize
|
||||
Values mpe;
|
||||
Values frontalVals;
|
||||
BOOST_FOREACH(Index j, frontals()) {
|
||||
frontalVals[j] = 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)
|
||||
// Update MPE solution if better
|
||||
if (pValueS > maxP) {
|
||||
maxP = pValueS;
|
||||
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
|
||||
|
@ -197,7 +194,7 @@ namespace gtsam {
|
|||
/* ******************************************************************************** */
|
||||
void DiscreteConditional::permuteWithInverse(const Permutation& 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)
|
||||
DiscreteKeys keys;
|
||||
map<Index, Index> ordering;
|
||||
|
@ -72,7 +72,6 @@ namespace gtsam {
|
|||
// Perform Permutation
|
||||
BOOST_FOREACH(DiscreteKey& key, keys) {
|
||||
ordering[key.first] = permutation[key.first];
|
||||
//cout << key.first << " -> " << ordering[key.first] << endl;
|
||||
key.first = ordering[key.first];
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,10 @@ namespace gtsam {
|
|||
* @brief Permutes the keys in Potentials
|
||||
*
|
||||
* 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
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* @ file testDiscreteMarginals.cpp
|
||||
* @date Feb 14, 2011
|
||||
* @file testDiscreteMarginals.cpp
|
||||
* @date Jun 7, 2012
|
||||
* @author Abhijit Kundu
|
||||
* @author Richard Roberts
|
||||
* @author Frank Dellaert
|
||||
|
|
Loading…
Reference in New Issue