testLoopyBelief.cpp
Go to the documentation of this file.
1 
12 #include <boost/range/adaptor/map.hpp>
13 #include <boost/assign/list_of.hpp>
14 #include <iostream>
15 #include <fstream>
16 
17 using namespace std;
18 using namespace boost;
19 using namespace boost::assign;
20 using namespace gtsam;
21 
25 class LoopyBelief {
26 
32  typedef std::map<Key, size_t> CorrectedBeliefIndices;
33  struct StarGraph {
35  CorrectedBeliefIndices correctedBeliefIndices;
39  const CorrectedBeliefIndices& _beliefIndices,
40  const DecisionTreeFactor::shared_ptr& _unary) :
41  star(_star), correctedBeliefIndices(_beliefIndices), unary(_unary), varIndex_(
42  *_star) {
43  }
44 
45  void print(const std::string& s = "") const {
46  cout << s << ":" << endl;
47  star->print("Star graph: ");
48  for(Key key: correctedBeliefIndices | boost::adaptors::map_keys) {
49  cout << "Belief factor index for " << key << ": "
50  << correctedBeliefIndices.at(key) << endl;
51  }
52  if (unary)
53  unary->print("Unary: ");
54  }
55  };
56 
57  typedef std::map<Key, StarGraph> StarGraphs;
58  StarGraphs starGraphs_;
59 
60 public:
66  const std::map<Key, DiscreteKey>& allDiscreteKeys) :
67  starGraphs_(buildStarGraphs(graph, allDiscreteKeys)) {
68  }
69 
71  void print(const std::string& s = "") const {
72  cout << s << ":" << endl;
73  for(Key key: starGraphs_ | boost::adaptors::map_keys) {
74  starGraphs_.at(key).print((boost::format("Node %d:") % key).str());
75  }
76  }
77 
80  const std::map<Key, DiscreteKey>& allDiscreteKeys) {
81  static const bool debug = false;
82  static DiscreteConditional::shared_ptr dummyCond; // unused by-product of elimination
84  std::map<Key, std::map<Key, DiscreteFactor::shared_ptr> > allMessages;
85  // Eliminate each star graph
86  for(Key key: starGraphs_ | boost::adaptors::map_keys) {
87 // cout << "***** Node " << key << "*****" << endl;
88  // initialize belief to the unary factor from the original graph
90 
91  // keep intermediate messages to divide later
92  std::map<Key, DiscreteFactor::shared_ptr> messages;
93 
94  // eliminate each neighbor in this star graph one by one
95  for(Key neighbor: starGraphs_.at(key).correctedBeliefIndices | boost::adaptors::map_keys) {
96  DiscreteFactorGraph subGraph;
97  for(size_t factor: starGraphs_.at(key).varIndex_[neighbor]) {
98  subGraph.push_back(starGraphs_.at(key).star->at(factor));
99  }
100  if (debug) subGraph.print("------- Subgraph:");
102  boost::tie(dummyCond, message) = EliminateDiscrete(subGraph,
103  Ordering(list_of(neighbor)));
104  // store the new factor into messages
105  messages.insert(make_pair(neighbor, message));
106  if (debug) message->print("------- Message: ");
107 
108  // Belief is the product of all messages and the unary factor
109  // Incorporate new the factor to belief
110  if (!beliefAtKey)
111  beliefAtKey = boost::dynamic_pointer_cast<DecisionTreeFactor>(
112  message);
113  else
114  beliefAtKey =
115  boost::make_shared<DecisionTreeFactor>(
116  (*beliefAtKey)
117  * (*boost::dynamic_pointer_cast<DecisionTreeFactor>(
118  message)));
119  }
120  if (starGraphs_.at(key).unary)
121  beliefAtKey = boost::make_shared<DecisionTreeFactor>(
122  (*beliefAtKey) * (*starGraphs_.at(key).unary));
123  if (debug) beliefAtKey->print("New belief at key: ");
124  // normalize belief
125  double sum = 0.0;
126  for (size_t v = 0; v < allDiscreteKeys.at(key).second; ++v) {
128  val[key] = v;
129  sum += (*beliefAtKey)(val);
130  }
131  string sumFactorTable;
132  for (size_t v = 0; v < allDiscreteKeys.at(key).second; ++v)
133  sumFactorTable = (boost::format("%s %f") % sumFactorTable % sum).str();
134  DecisionTreeFactor sumFactor(allDiscreteKeys.at(key), sumFactorTable);
135  if (debug) sumFactor.print("denomFactor: ");
136  beliefAtKey = boost::make_shared<DecisionTreeFactor>((*beliefAtKey) / sumFactor);
137  if (debug) beliefAtKey->print("New belief at key normalized: ");
138  beliefs->push_back(beliefAtKey);
139  allMessages[key] = messages;
140  }
141 
142  // Update corrected beliefs
143  VariableIndex beliefFactors(*beliefs);
144  for(Key key: starGraphs_ | boost::adaptors::map_keys) {
145  std::map<Key, DiscreteFactor::shared_ptr> messages = allMessages[key];
146  for(Key neighbor: starGraphs_.at(key).correctedBeliefIndices | boost::adaptors::map_keys) {
147  DecisionTreeFactor correctedBelief = (*boost::dynamic_pointer_cast<
148  DecisionTreeFactor>(beliefs->at(beliefFactors[key].front())))
149  / (*boost::dynamic_pointer_cast<DecisionTreeFactor>(
150  messages.at(neighbor)));
151  if (debug) correctedBelief.print("correctedBelief: ");
152  size_t beliefIndex = starGraphs_.at(neighbor).correctedBeliefIndices.at(
153  key);
154  starGraphs_.at(neighbor).star->replace(beliefIndex,
155  boost::make_shared<DecisionTreeFactor>(correctedBelief));
156  }
157  }
158 
159  if (debug) print("After update: ");
160 
161  return beliefs;
162  }
163 
164 private:
169  const std::map<Key, DiscreteKey>& allDiscreteKeys) const {
170  StarGraphs starGraphs;
171  VariableIndex varIndex(graph);
172  for(Key key: varIndex | boost::adaptors::map_keys) {
173  // initialize to multiply with other unary factors later
174  DecisionTreeFactor::shared_ptr prodOfUnaries;
175 
176  // collect all factors involving this key in the original graph
178  for(size_t factorIndex: varIndex[key]) {
179  star->push_back(graph.at(factorIndex));
180 
181  // accumulate unary factors
182  if (graph.at(factorIndex)->size() == 1) {
183  if (!prodOfUnaries)
184  prodOfUnaries = boost::dynamic_pointer_cast<DecisionTreeFactor>(
185  graph.at(factorIndex));
186  else
187  prodOfUnaries = boost::make_shared<DecisionTreeFactor>(
188  *prodOfUnaries
189  * (*boost::dynamic_pointer_cast<DecisionTreeFactor>(
190  graph.at(factorIndex))));
191  }
192  }
193 
194  // add the belief factor for each neighbor variable to this star graph
195  // also record the factor index for later modification
196  KeySet neighbors = star->keys();
197  neighbors.erase(key);
198  CorrectedBeliefIndices correctedBeliefIndices;
199  for(Key neighbor: neighbors) {
200  // TODO: default table for keys with more than 2 values?
201  string initialBelief;
202  for (size_t v = 0; v < allDiscreteKeys.at(neighbor).second - 1; ++v) {
203  initialBelief = initialBelief + "0.0 ";
204  }
205  initialBelief = initialBelief + "1.0";
206  star->push_back(
207  DecisionTreeFactor(allDiscreteKeys.at(neighbor), initialBelief));
208  correctedBeliefIndices.insert(make_pair(neighbor, star->size() - 1));
209  }
210  starGraphs.insert(
211  make_pair(key,
212  StarGraph(star, correctedBeliefIndices, prodOfUnaries)));
213  }
214  return starGraphs;
215  }
216 };
217 
218 /* ************************************************************************* */
219 
220 TEST_UNSAFE(LoopyBelief, construction) {
221  // Variables: Cloudy, Sprinkler, Rain, Wet
222  DiscreteKey C(0, 2), S(1, 2), R(2, 2), W(3, 2);
223 
224  // Map from key to DiscreteKey for building belief factor.
225  // TODO: this is bad!
226  std::map<Key, DiscreteKey> allKeys = map_list_of(0, C)(1, S)(2, R)(3, W);
227 
228  // Build graph
229  DecisionTreeFactor pC(C, "0.5 0.5");
230  DiscreteConditional pSC(S | C = "0.5/0.5 0.9/0.1");
231  DiscreteConditional pRC(R | C = "0.8/0.2 0.2/0.8");
232  DecisionTreeFactor pSR(S & R, "0.0 0.9 0.9 0.99");
233 
235  graph.push_back(pC);
236  graph.push_back(pSC);
237  graph.push_back(pRC);
238  graph.push_back(pSR);
239 
240  graph.print("graph: ");
241 
242  LoopyBelief solver(graph, allKeys);
243  solver.print("Loopy belief: ");
244 
245  // Main loop
246  for (size_t iter = 0; iter < 20; ++iter) {
247  cout << "==================================" << endl;
248  cout << "iteration: " << iter << endl;
249  DiscreteFactorGraph::shared_ptr beliefs = solver.iterate(allKeys);
250  beliefs->print();
251  }
252 
253 }
254 
255 /* ************************************************************************* */
256 int main() {
257  TestResult tr;
258  return TestRegistry::runAllTests(tr);
259 }
260 /* ************************************************************************* */
void print(const Matrix &A, const string &s, ostream &stream)
Definition: Matrix.cpp:155
std::map< Key, StarGraph > StarGraphs
static int runAllTests(TestResult &result)
DiscreteFactorGraph::shared_ptr iterate(const std::map< Key, DiscreteKey > &allDiscreteKeys)
One step of belief propagation.
ArrayXcf v
Definition: Cwise_arg.cpp:1
std::map< Key, size_t > CorrectedBeliefIndices
Rot2 R(Rot2::fromAngle(0.1))
Definition: Half.h:150
Key W(std::uint64_t j)
iterator iter(handle obj)
Definition: pytypes.h:1547
BiCGSTAB< SparseMatrix< double > > solver
int main()
IsDerived< DERIVEDFACTOR > push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:166
NonlinearFactorGraph graph
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
DiscreteFactorGraph::shared_ptr star
Key S(std::uint64_t j)
std::pair< Key, size_t > DiscreteKey
Definition: DiscreteKey.h:34
static bool debug
void print(const std::string &s="") const
StarGraph(const DiscreteFactorGraph::shared_ptr &_star, const CorrectedBeliefIndices &_beliefIndices, const DecisionTreeFactor::shared_ptr &_unary)
const mpreal sum(const mpreal tab[], const unsigned long int n, int &status, mp_rnd_t mode=mpreal::get_default_rnd())
Definition: mpreal.h:2381
RealScalar s
std::pair< DiscreteConditional::shared_ptr, DecisionTreeFactor::shared_ptr > EliminateDiscrete(const DiscreteFactorGraph &factors, const Ordering &frontalKeys)
LoopyBelief(const DiscreteFactorGraph &graph, const std::map< Key, DiscreteKey > &allDiscreteKeys)
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
boost::shared_ptr< DiscreteFactor > shared_ptr
shared_ptr to this class
Matrix< Scalar, Dynamic, Dynamic > C
Definition: bench_gemm.cpp:37
traits
Definition: chartTesting.h:28
const sharedFactor at(size_t i) const
Definition: FactorGraph.h:315
DecisionTreeFactor::shared_ptr unary
boost::shared_ptr< DecisionTreeFactor > shared_ptr
void print(const std::string &s="DiscreteFactorGraph", const KeyFormatter &formatter=DefaultKeyFormatter) const override
print
CorrectedBeliefIndices correctedBeliefIndices
TEST_UNSAFE(LoopyBelief, construction)
StarGraphs buildStarGraphs(const DiscreteFactorGraph &graph, const std::map< Key, DiscreteKey > &allDiscreteKeys) const
void print(const std::string &s="DecisionTreeFactor:\n", const KeyFormatter &formatter=DefaultKeyFormatter) const override
print
StarGraphs starGraphs_
star graph at each variable
void print(const std::string &s="") const
print
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:47:59