2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @file    BayesTree.cpp
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @brief   Bayes Tree is a tree of cliques of a Bayes Chain
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @author  Frank Dellaert
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 07:35:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @author  Michael Kaess
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @author  Viorela Ila
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-08 07:00:03 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#pragma once
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-22 12:41:40 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <iostream>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <algorithm>
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-22 12:41:40 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/foreach.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 08:13:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/assign/std/list.hpp> // for operator +=
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <boost/format.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/lambda/lambda.hpp>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <boost/iterator/transform_iterator.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <boost/pool/pool_alloc.hpp>
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <fstream>
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 08:13:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								using namespace boost::assign;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								namespace lam = boost::lambda;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 08:13:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <gtsam/inference/Conditional.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <gtsam/inference/BayesTree.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <gtsam/inference/inference-inl.h>
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								namespace gtsam {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									using namespace std;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::Clique::Clique() {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-08 03:31:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::Clique::Clique(const sharedConditional& conditional) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										separator_.assign(conditional->parents().begin(), conditional->parents().end());
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-31 15:19:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										this->push_back(conditional);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::Clique::Clique(const BayesNet<Conditional>& bayesNet)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									: BayesNet<Conditional>(bayesNet) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  if(bayesNet.size() > 0) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#ifndef NDEBUG
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // Debug check that each parent variable is either a frontal variable in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // a later conditional in the Bayes net fragment, or that the parent is
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // also a parent of the last conditional.  This checks that the fragment
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // is "enough like a clique".  todo: this should really check that the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // fragment *is* a clique.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    if(bayesNet.size() > 1) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      typename BayesNet<Conditional>::const_reverse_iterator cond = bayesNet.rbegin();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      ++ cond;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      typename Conditional::shared_ptr lastConditional = *cond;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      for( ; cond != bayesNet.rend(); ++cond)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									        for(typename Conditional::const_iterator parent=(*cond)->beginParents(); parent!=(*cond)->endParents(); ++parent) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									          bool infragment = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									          typename BayesNet<Conditional>::const_reverse_iterator parentCond = cond;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									          do {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									            if(*parent == (*parentCond)->key())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									              infragment = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									            --parentCond;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									          } while(parentCond != bayesNet.rbegin());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									          assert(infragment || find(lastConditional->beginParents(), lastConditional->endParents(), *parent) != lastConditional->endParents());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	    separator_.assign((*bayesNet.rbegin())->parents().begin(), (*bayesNet.rbegin())->parents().end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    separator_.assign((*bayesNet.rbegin())->beginParents(), (*bayesNet.rbegin())->endParents());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  }
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-31 15:19:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 06:51:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									vector<Index> BayesTree<Conditional>::Clique::keys() const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  vector<Index> keys;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  keys.reserve(this->size() + separator_.size());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  BOOST_FOREACH(const sharedConditional conditional, *this) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    keys.push_back(conditional->key());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  keys.insert(keys.end(), separator_.begin(), separator_.end());
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 06:51:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return keys;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::Clique::print(const string& s) const {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											cout << s << "Clique ";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											BOOST_FOREACH(const sharedConditional& conditional, this->conditionals_) { cout << conditional->key() << " "; }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											cout << "| ";
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											BOOST_FOREACH(const Index sep, separator_) { cout << sep << " "; }
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											cout << "\n";
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-11 15:30:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											BOOST_FOREACH(const sharedConditional& conditional, this->conditionals_) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												conditional->print("  " + s + "conditional");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//				cout << " " << conditional->key();
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//			if (!separator_.empty()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//				cout << " :";
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//				BOOST_FOREACH(Index key, separator_)
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//					cout << " " << key;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//			}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//			cout << endl;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 02:05:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									size_t BayesTree<Conditional>::Clique::treeSize() const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										size_t size = 1;
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(const shared_ptr& child, children_)
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 02:05:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											size += child->treeSize();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return size;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::Clique::printTree(const string& indent) const {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 02:05:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										print(indent);
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(const shared_ptr& child, children_)
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 02:05:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											child->printTree(indent+"  ");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  /* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  void BayesTree<Conditional>::Clique::permuteWithInverse(const Permutation& inversePermutation) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    BayesNet<Conditional>::permuteWithInverse(inversePermutation);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    BOOST_FOREACH(Index& separatorKey, separator_) { separatorKey = inversePermutation[separatorKey]; }
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if(cachedFactor_) cachedFactor_->permuteWithInverse(inversePermutation);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    BOOST_FOREACH(const shared_ptr& child, children_) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      child->permuteWithInverse(inversePermutation);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  /* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  bool BayesTree<Conditional>::Clique::permuteSeparatorWithInverse(const Permutation& inversePermutation) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool changed = BayesNet<Conditional>::permuteSeparatorWithInverse(inversePermutation);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#ifndef NDEBUG
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if(!changed) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      BOOST_FOREACH(Index& separatorKey, separator_) { assert(separatorKey == inversePermutation[separatorKey]); }
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      BOOST_FOREACH(const shared_ptr& child, children_) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert(child->permuteSeparatorWithInverse(inversePermutation) == false);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if(changed) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      BOOST_FOREACH(Index& separatorKey, separator_) { separatorKey = inversePermutation[separatorKey]; }
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      if(cachedFactor_) cachedFactor_->permuteWithInverse(inversePermutation);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      BOOST_FOREACH(const shared_ptr& child, children_) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        (void)child->permuteSeparatorWithInverse(inversePermutation);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return changed;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-22 12:41:40 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									typename BayesTree<Conditional>::CliqueData
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::getCliqueData() const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										CliqueData data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										getCliqueData(data, root_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::getCliqueData(CliqueData& data,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											BayesTree<Conditional>::sharedClique clique) const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										data.conditionalSizes.push_back(clique->conditionals_.size());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										data.separatorSizes.push_back(clique->separator_.size());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(sharedClique c, clique->children_) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											getCliqueData(data, c);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::saveGraph(const std::string &s) const {
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-20 06:44:45 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (!root_.get()) throw invalid_argument("the root of bayes tree has not been initialized!");
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ofstream of(s.c_str());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										of<< "digraph G{\n";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										saveGraph(of, root_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										of<<"}";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										of.close();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::saveGraph(ostream &s,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											BayesTree<Conditional>::sharedClique clique,
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-10 05:32:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											int parentnum) const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										static int num = 0;
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										bool first = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										std::stringstream out;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										out << num;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										string parent = out.str();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										parent += "[label=\"";
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-10 05:32:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(boost::shared_ptr<Conditional> c, clique->conditionals_) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if(!first) parent += ","; first = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											parent += (string(c->key())).c_str();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-10 05:32:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if( clique != root_){
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											parent += " : ";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											s << parentnum << "->" << num << "\n";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-10 05:32:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										first = true;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(Index sep, clique->separator_) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if(!first) parent += ","; first = false;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											parent += (boost::format("%1%")%sep).str();
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										parent += "\"];\n";
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										s << parent;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										parentnum = num;
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-10 05:32:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(sharedClique c, clique->children_) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-10 05:32:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											num++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											saveGraph(s, c, parentnum);
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-23 07:52:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-22 12:41:40 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									typename BayesTree<Conditional>::CliqueStats
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::CliqueData::getStats() const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										CliqueStats stats;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										double sum = 0.0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										size_t max = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(size_t s, conditionalSizes) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sum += (double)s;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if(s > max) max = s;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										stats.avgConditionalSize = sum / (double)conditionalSizes.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										stats.maxConditionalSize = max;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sum = 0.0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										max = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(size_t s, separatorSizes) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sum += (double)s;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if(s > max) max = s;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										stats.avgSeparatorSize = sum / (double)separatorSizes.size();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										stats.maxSeparatorSize = max;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return stats;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// The shortcut density is a conditional P(S|R) of the separator of this
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// clique on the root. We can compute it recursively from the parent shortcut
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// P(Sp|R) as \int P(Fp|Sp) P(Sp|R), where Fp are the frontal nodes in p
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// TODO, why do we actually return a shared pointer, why does eliminate?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class FactorGraph>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesNet<Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::Clique::shortcut(shared_ptr R) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// A first base case is when this clique or its parent is the root,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// in which case we return an empty Bayes net.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  sharedClique parent(parent_.lock());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (R.get()==this || parent==R) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											BayesNet<Conditional> empty;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return empty;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// The parent clique has a Conditional for each frontal node in Fp
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// so we can obtain P(Fp|Sp) in factor graph form
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										FactorGraph p_Fp_Sp(*parent);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// If not the base case, obtain the parent shortcut P(Sp|R) as factors
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										FactorGraph p_Sp_R(parent->shortcut<FactorGraph>(R));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// now combine P(Cp|R) = P(Fp|Sp) * P(Sp|R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										FactorGraph p_Cp_R = combine(p_Fp_Sp, p_Sp_R);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Eliminate into a Bayes net with ordering designed to integrate out
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// any variables not in *our* separator. Variables to integrate out must be
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// eliminated first hence the desired ordering is [Cp\S S].
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// However, an added wrinkle is that Cp might overlap with the root.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Keys corresponding to the root should not be added to the ordering at all.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										typedef set<Index, std::less<Index>, boost::fast_pool_allocator<Index> > FastJSet;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Get the key list Cp=Fp+Sp, which will form the basis for the integrands
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										vector<Index> parentKeys(parent->keys());
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										FastJSet integrands(parentKeys.begin(), parentKeys.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Start ordering with the separator
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										FastJSet separator(separator_.begin(), separator_.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// remove any variables in the root, after this integrands = Cp\R, ordering = S\R
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(Index key, R->ordering()) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											integrands.erase(key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											separator.erase(key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// remove any variables in the separator, after this integrands = Cp\R\S
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(Index key, separator_) integrands.erase(key);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// form the ordering as [Cp\R\S S\R]
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										vector<Index> ordering; ordering.reserve(integrands.size() + separator.size());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(Index key, integrands) ordering.push_back(key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(Index key, separator) ordering.push_back(key);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// eliminate to get marginal
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										typename FactorGraph::variableindex_type varIndex(p_Cp_R);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										Permutation toFront = Permutation::PullToFront(ordering, varIndex.size());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										Permutation::shared_ptr toFrontInverse(toFront.inverse());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(const typename FactorGraph::sharedFactor& factor, p_Cp_R) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  factor->permuteWithInverse(*toFrontInverse);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										varIndex.permute(toFront);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BayesNet<Conditional> p_S_R = *Inference::EliminateUntil(p_Cp_R, ordering.size(), varIndex);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// remove all integrands
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										for(Index j=0; j<integrands.size(); ++j)
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										  p_S_R.pop_front();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Undo the permutation on the shortcut
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										p_S_R.permuteWithInverse(toFront);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// return the parent shortcut P(Sp|R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return p_S_R;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 00:02:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// P(C) = \int_R P(F|S) P(S|R) P(R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// TODO: Maybe we should integrate given parent marginal P(Cp),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// \int(Cp\S) P(F|S)P(S|Cp)P(Cp)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Because the root clique could be very big.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class FactorGraph>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									FactorGraph
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::Clique::marginal(shared_ptr R) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// If we are the root, just return this root
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (R.get()==this) return *R;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Combine P(F|S), P(S|R), and P(R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BayesNet<Conditional> p_FSR = this->shortcut<FactorGraph>(R);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										p_FSR.push_front(*this);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										p_FSR.push_back(*R);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Find marginal on the keys we are interested in
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-14 04:41:26 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return Inference::Marginal(FactorGraph(p_FSR), keys());
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 00:02:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	// P(C1,C2) = \int_R P(F1|S1) P(S1|R) P(F2|S1) P(S2|R) P(R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	template<class Factor>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	pair<FactorGraph<Factor>, Ordering>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	BayesTree<Conditional>::Clique::joint(shared_ptr C2, shared_ptr R) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// For now, assume neither is the root
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// Combine P(F1|S1), P(S1|R), P(F2|S2), P(S2|R), and P(R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		sharedBayesNet bn(new BayesNet<Conditional>);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		if (!isRoot())     bn->push_back(*this);                   // P(F1|S1)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		if (!isRoot())     bn->push_back(shortcut<Factor>(R));     // P(S1|R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		if (!C2->isRoot()) bn->push_back(*C2);                     // P(F2|S2)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		if (!C2->isRoot()) bn->push_back(C2->shortcut<Factor>(R)); // P(S2|R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		bn->push_back(*R);                                         // P(R)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// Find the keys of both C1 and C2
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		Ordering keys12 = keys();
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//		BOOST_FOREACH(Index key,C2->keys()) keys12.push_back(key);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//		keys12.unique();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// Calculate the marginal
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		return make_pair(marginalize<Factor,Conditional>(*bn,keys12), keys12);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 06:51:12 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:40:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::Cliques::print(const std::string& s) const {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 02:06:28 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cout << s << ":\n";
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:40:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(sharedClique clique, *this)
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 02:06:28 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												clique->printTree();
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:40:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									bool BayesTree<Conditional>::Cliques::equals(const Cliques& other, double tol) const {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return other == *this;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									typename BayesTree<Conditional>::sharedClique BayesTree<Conditional>::addClique(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    const sharedConditional& conditional, sharedClique parent_clique) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sharedClique new_clique(new Clique(conditional));
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										Index key = conditional->key();
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										nodes_.resize(std::max(key+1, nodes_.size()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nodes_[key] = new_clique;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (parent_clique != NULL) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											new_clique->parent_ = parent_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											parent_clique->children_.push_back(new_clique);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									typename BayesTree<Conditional>::sharedClique BayesTree<Conditional>::addClique(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    const sharedConditional& conditional, list<sharedClique>& child_cliques) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sharedClique new_clique(new Clique(conditional));
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    Index key = conditional->key();
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    nodes_.resize(max(key+1, nodes_.size()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    nodes_[key] = new_clique;
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										new_clique->children_ = child_cliques;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(sharedClique& child, child_cliques)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											child->parent_ = new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  /* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									inline void BayesTree<Conditional>::addToCliqueFront(const sharedConditional& conditional, const sharedClique& clique) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  static const bool debug = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#ifndef NDEBUG
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  // Debug check to make sure the conditional variable is ordered lower than
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  // its parents and that all of its parents are present either in this
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  // clique or its separator.
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  BOOST_FOREACH(Index parent, conditional->parents()) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    assert(parent > conditional->key());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    bool hasParent = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    const Clique& cliquer(*clique);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    BOOST_FOREACH(const sharedConditional& child, cliquer) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      if(child->key() == parent) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									        hasParent = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									        break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    if(!hasParent)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      if(find(clique->separator_.begin(), clique->separator_.end(), parent) != clique->separator_.end())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									        hasParent = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    assert(hasParent);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  if(debug) conditional->print("Adding conditional ");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  if(debug) clique->print("To clique ");
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  Index key = conditional->key();
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  nodes_.resize(std::max(key+1, nodes_.size()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  nodes_[key] = clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  clique->push_front(conditional);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  if(debug) clique->print("Expanded clique is ");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::removeClique(sharedClique clique) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-22 05:48:10 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (clique->isRoot())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											root_.reset();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										else // detach clique from parent
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    clique->parent_.lock()->children_.remove(clique);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-22 05:48:10 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  // orphan my children
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(sharedClique child, clique->children_)
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  	child->parent_ = typename BayesTree<Conditional>::Clique::weak_ptr();
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-22 05:48:10 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  BOOST_FOREACH(Index key, clique->separator_) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											nodes_[key].reset();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  const Clique& cliquer(*clique);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  BOOST_FOREACH(const sharedConditional& conditional, cliquer) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    nodes_[conditional->key()].reset();
							 | 
						
					
						
							
								
									
										
										
										
											2009-12-14 04:54:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  }
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::BayesTree() {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::BayesTree(const BayesNet<Conditional>& bayesNet) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-02 11:50:30 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										typename BayesNet<Conditional>::const_reverse_iterator rit;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-03 14:29:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for ( rit=bayesNet.rbegin(); rit != bayesNet.rend(); ++rit )
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											insert(*rit);
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-11 15:30:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::BayesTree(const BayesNet<Conditional>& bayesNet, std::list<BayesTree<Conditional> > subtrees) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (bayesNet.size() == 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											throw invalid_argument("BayesTree::insert: empty bayes net!");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// get the roots of child subtrees and merge their nodes_
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										list<sharedClique> childRoots;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(const BayesTree<Conditional>& subtree, subtrees) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nodes_.insert(subtree.nodes_.begin(), subtree.nodes_.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											childRoots.push_back(subtree.root());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// create a new clique and add all the conditionals to the clique
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sharedClique new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										typename BayesNet<Conditional>::sharedConditional conditional;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_REVERSE_FOREACH(conditional, bayesNet) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (!new_clique.get())
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-11 15:30:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												new_clique = addClique(conditional,childRoots);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											  addToCliqueFront(conditional, new_clique);
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-11 15:30:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										root_ = new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::print(const string& s) const {
							 | 
						
					
						
							
								
									
										
										
										
											2009-12-26 12:44:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (root_.use_count() == 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printf("WARNING: BayesTree.print encountered a forest...\n");
							 | 
						
					
						
							
								
									
										
										
										
											2009-12-26 12:44:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cout << s << ": clique size == " << size() << ", node size == " << nodes_.size() <<  endl;
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (nodes_.empty()) return;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-05 13:29:47 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										root_->printTree("");
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 00:30:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// binary predicate to test equality of a pair for use in equals
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									bool check_sharedCliques(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											const typename BayesTree<Conditional>::sharedClique& v1,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											const typename BayesTree<Conditional>::sharedClique& v2
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 00:30:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return v1->equals(*v2);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 00:30:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-30 21:03:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									bool BayesTree<Conditional>::equals(const BayesTree<Conditional>& other,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											double tol) const {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-19 00:30:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return size()==other.size() &&
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												std::equal(nodes_.begin(), nodes_.end(), other.nodes_.begin(), &check_sharedCliques<Conditional>);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-20 09:52:40 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									template<class Container>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									inline Index BayesTree<Conditional>::findParentClique(const Container& parents) const {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  typename Container::const_iterator lowestOrderedParent = min_element(parents.begin(), parents.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  assert(lowestOrderedParent != parents.end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  return *lowestOrderedParent;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//		boost::optional<Index> parentCliqueRepresentative;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//		boost::optional<size_t> lowest;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//		BOOST_FOREACH(Index p, parents) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//			size_t i = index(p);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//			if (!lowest || i<*lowest) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//				lowest.reset(i);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//				parentCliqueRepresentative.reset(p);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//			}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		if (!lowest) throw
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//			invalid_argument("BayesTree::findParentClique: no parents given or key not present in index");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		return *parentCliqueRepresentative;
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-20 09:52:40 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::insert(const sharedConditional& conditional)
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  static const bool debug = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// get key and parents
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										typename Conditional::Parents parents = conditional->parents(); // todo: const reference?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if(debug) conditional->print("Adding conditional ");
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// if no parents, start a new root clique
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (parents.empty()) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										  if(debug) cout << "No parents so making root" << endl;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-05 13:29:47 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											root_ = addClique(conditional);
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-22 10:27:26 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// otherwise, find the parent clique by using the index data structure
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// to find the lowest-ordered parent
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										Index parentRepresentative = findParentClique(parents);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if(debug) cout << "First-eliminated parent is " << parentRepresentative << endl;
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-22 10:27:26 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sharedClique parent_clique = (*this)[parentRepresentative];
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if(debug) parent_clique->print("Parent clique is ");
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// if the parents and parent clique have the same size, add to parent clique
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (parent_clique->size() == size_t(parents.size())) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  if(debug) cout << "Adding to parent clique" << endl;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#ifndef NDEBUG
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  // Debug check that the parent keys of the new conditional match the keys
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  // currently in the clique.
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//		  list<Index>::const_iterator parent = parents.begin();
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//		  typename Clique::const_iterator cond = parent_clique->begin();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		  while(parent != parents.end()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		    assert(cond != parent_clique->end());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		    assert(*parent == (*cond)->key());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		    ++ parent;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		    ++ cond;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  addToCliqueFront(conditional, parent_clique);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  if(debug) cout << "Starting new clique" << endl;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  // otherwise, start a new clique and add it to the tree
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  addClique(conditional,parent_clique);
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-11 15:30:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									//TODO: remove this function after removing TSAM.cpp
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									typename BayesTree<Conditional>::sharedClique BayesTree<Conditional>::insert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											const BayesNet<Conditional>& bayesNet, list<sharedClique>& children, bool isRootClique)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  static const bool debug = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (bayesNet.size() == 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											throw invalid_argument("BayesTree::insert: empty bayes net!");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// create a new clique and add all the conditionals to the clique
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sharedClique new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										typename BayesNet<Conditional>::sharedConditional conditional;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_REVERSE_FOREACH(conditional, bayesNet) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										  if(debug) conditional->print("Inserting conditional: ");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!new_clique.get())
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												new_clique = addClique(conditional,children);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											  addToCliqueFront(conditional, new_clique);
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-13 15:09:27 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (isRootClique) root_ = new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return new_clique;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  /* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::fillNodesIndex(const sharedClique& subtree) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  // Add each frontal variable of this root node
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  BOOST_FOREACH(const typename Conditional::shared_ptr& cond, *subtree) { nodes_[cond->key()] = subtree; }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  // Fill index for each child
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  BOOST_FOREACH(const typename BayesTree<Conditional>::sharedClique& child, subtree->children_) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    fillNodesIndex(child); }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  /* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::insert(const sharedClique& subtree) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  if(subtree) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // Find the parent clique of the new subtree.  By the running intersection
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // property, those separator variables in the subtree that are ordered
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // lower than the highest frontal variable of the subtree root will all
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // appear in the separator of the subtree root.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    if(subtree->separator_.empty()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      assert(!root_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      root_ = subtree;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    } else {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									      Index parentRepresentative = findParentClique(subtree->separator_);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									      sharedClique parent = (*this)[parentRepresentative];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      parent->children_ += subtree;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      subtree->parent_ = parent; // set new parent!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    }
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-12 12:56:30 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    // Now fill in the nodes index
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    if(subtree->back()->key() > (nodes_.size() - 1))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      nodes_.resize(subtree->back()->key() + 1);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    fillNodesIndex(subtree);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  }
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-12 12:56:30 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 00:02:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// First finds clique marginal then marginalizes that
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class FactorGraph>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									FactorGraph
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::marginal(Index key) const {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 00:02:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// get clique containing key
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sharedClique clique = (*this)[key];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// calculate or retrieve its marginal
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										FactorGraph cliqueMarginal = clique->marginal<FactorGraph>(root_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Reorder so that only the requested key is not eliminated
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										typename FactorGraph::variableindex_type varIndex(cliqueMarginal);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										vector<Index> keyAsVector(1); keyAsVector[0] = key;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 00:02:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										Permutation toBack(Permutation::PushToBack(keyAsVector, varIndex.size()));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										Permutation::shared_ptr toBackInverse(toBack.inverse());
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										varIndex.permute(toBack);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										BOOST_FOREACH(const typename FactorGraph::sharedFactor& factor, cliqueMarginal) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										  factor->permuteWithInverse(*toBackInverse);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 00:02:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										// partially eliminate, remaining factor graph is requested marginal
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										Inference::EliminateUntil(cliqueMarginal, varIndex.size()-1, varIndex);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    BOOST_FOREACH(const typename FactorGraph::sharedFactor& factor, cliqueMarginal) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      if(factor)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        factor->permuteWithInverse(toBack);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return cliqueMarginal;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class FactorGraph>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									BayesNet<Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									BayesTree<Conditional>::marginalBayesNet(Index key) const {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 00:02:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// calculate marginal as a factor graph
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  FactorGraph fg = this->marginal<FactorGraph>(key);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// eliminate further to Bayes net
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return *Inference::Eliminate(fg);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	// Find two cliques, their joint, then marginalizes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	template<class Factor>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	FactorGraph<Factor>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//	BayesTree<Conditional>::joint(Index key1, Index key2) const {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// get clique C1 and C2
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		sharedClique C1 = (*this)[key1], C2 = (*this)[key2];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// calculate joint
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		Ordering ord;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		FactorGraph<Factor> p_C1C2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		boost::tie(p_C1C2,ord) = C1->joint<Factor>(C2,root_);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// create an ordering where both requested keys are not eliminated
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		ord.remove(key1);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		ord.remove(key2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// partially eliminate, remaining factor graph is requested joint
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// TODO, make eliminate functional
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		eliminate<Factor,Conditional>(p_C1C2,ord);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		return p_C1C2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	template<class Factor>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	BayesNet<Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//	BayesTree<Conditional>::jointBayesNet(Index key1, Index key2) const {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// calculate marginal as a factor graph
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	  FactorGraph<Factor> fg = this->joint<Factor>(key1,key2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		// eliminate further to Bayes net
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		Ordering ordering;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		ordering += key1, key2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//		return eliminate<Factor,Conditional>(fg,ordering);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//	}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 00:04:51 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-20 12:23:35 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::clear() {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Remove all nodes and clear the root pointer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nodes_.clear();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										root_.reset();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-01 00:57:36 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 11:38:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-20 09:24:32 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									void BayesTree<Conditional>::removePath(sharedClique clique,
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-21 08:38:22 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											BayesNet<Conditional>& bn, typename BayesTree<Conditional>::Cliques& orphans) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 11:38:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 00:04:51 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// base case is NULL, if so we do nothing and return empties above
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (clique!=NULL) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-22 07:41:43 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-20 09:24:32 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											// remove the clique from orphans in case it has been added earlier
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											orphans.remove(clique);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:40:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											// remove me
							 | 
						
					
						
							
								
									
										
										
										
											2009-12-26 12:44:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											this->removeClique(clique);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:40:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 00:04:51 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											// remove path above me
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											this->removePath(clique->parent_.lock(), bn, orphans);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 11:38:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-12-14 04:54:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											// add children to list of orphans (splice also removed them from clique->children_)
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 06:59:56 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											orphans.splice (orphans.begin(), clique->children_);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-21 08:38:22 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											bn.push_back(*clique);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 00:04:51 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-20 09:24:32 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 11:38:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 00:04:51 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-21 11:38:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* ************************************************************************* */
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:34:59 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									template<class Conditional>
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  template<class Container>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  void BayesTree<Conditional>::removeTop(const Container& keys,
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-21 08:38:22 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  		BayesNet<Conditional>& bn, typename BayesTree<Conditional>::Cliques& orphans) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:34:59 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// process each key of the new factor
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									  BOOST_FOREACH(const Index& key, keys) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-13 04:20:24 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    // get the clique
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    if(key < nodes_.size()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      const sharedClique& clique(nodes_[key]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      if(clique) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									        // remove path from clique to root
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									        this->removePath(clique, bn, orphans);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									      }
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-13 04:20:24 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									  }
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-23 01:34:59 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-12-14 14:01:15 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* ************************************************************************* */
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-02 11:50:30 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/// namespace gtsam
							 |