| 
									
										
										
										
											2010-10-14 12:54:38 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation,  | 
					
						
							|  |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-12 12:52:40 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file   inference-inl.h | 
					
						
							|  |  |  |  * @brief  inference template definitions | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |  * @author Frank Dellaert, Richard Roberts | 
					
						
							| 
									
										
										
										
											2009-11-12 12:52:40 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 07:00:03 +08:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 09:07:51 +08:00
										 |  |  | #include <limits>
 | 
					
						
							|  |  |  | #include <map>
 | 
					
						
							|  |  |  | #include <stdexcept>
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <boost/foreach.hpp>
 | 
					
						
							|  |  |  | #include <boost/format.hpp>
 | 
					
						
							|  |  |  | #include <boost/lambda/bind.hpp>
 | 
					
						
							|  |  |  | #include <boost/lambda/lambda.hpp>
 | 
					
						
							|  |  |  | #include <boost/pool/pool_alloc.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-10-15 09:07:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 09:15:14 +08:00
										 |  |  | #include <ccolamd.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-15 09:07:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/base/timing.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/inference.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/FactorGraph-inl.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/BayesNet-inl.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  | #include <gtsam/inference/ConditionalBase.h>
 | 
					
						
							| 
									
										
										
										
											2009-11-12 12:52:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-20 09:10:27 +08:00
										 |  |  | template<class VARIABLEINDEXTYPE, typename CONSTRAINTCONTAINER> | 
					
						
							|  |  |  | Permutation::shared_ptr Inference::PermutationCOLAMD(const VARIABLEINDEXTYPE& variableIndex, const CONSTRAINTCONTAINER& constrainLast) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   size_t nEntries = variableIndex.nEntries(), nFactors = variableIndex.nFactors(), nVars = variableIndex.size(); | 
					
						
							|  |  |  |   // Convert to compressed column major format colamd wants it in (== MATLAB format!)
 | 
					
						
							|  |  |  |   int Alen = ccolamd_recommended(nEntries, nFactors, nVars); /* colamd arg 3: size of the array A */ | 
					
						
							|  |  |  |   int * A = new int[Alen]; /* colamd arg 4: row indices of A, of size Alen */ | 
					
						
							|  |  |  |   int * p = new int[nVars + 1]; /* colamd arg 5: column pointers of A, of size n_col+1 */ | 
					
						
							|  |  |  |   int * cmember = new int[nVars]; /* Constraint set of A, of size n_col */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static const bool debug = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   p[0] = 0; | 
					
						
							|  |  |  |   int count = 0; | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |   for(Index var = 0; var < variableIndex.size(); ++var) { | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |     const typename VARIABLEINDEXTYPE::Factors& column(variableIndex[var]); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     size_t lastFactorId = numeric_limits<size_t>::max(); | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |     BOOST_FOREACH(const size_t& factorIndex, column) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |       if(lastFactorId != numeric_limits<size_t>::max()) | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |         assert(factorIndex > lastFactorId); | 
					
						
							|  |  |  |       A[count++] = factorIndex; // copy sparse column
 | 
					
						
							|  |  |  |       if(debug) cout << "A[" << count-1 << "] = " << factorIndex << endl; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     p[var+1] = count; // column j (base 1) goes from A[j-1] to A[j]-1
 | 
					
						
							|  |  |  |     cmember[var] = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // If at least some variables are not constrained to be last, constrain the
 | 
					
						
							|  |  |  |   // ones that should be constrained.
 | 
					
						
							|  |  |  |   if(constrainLast.size() < variableIndex.size()) { | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |     BOOST_FOREACH(Index var, constrainLast) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |       assert(var < nVars); | 
					
						
							|  |  |  |       cmember[var] = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   assert((size_t)count == variableIndex.nEntries()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if(debug) | 
					
						
							|  |  |  |     for(size_t i=0; i<nVars+1; ++i) | 
					
						
							|  |  |  |       cout << "p[" << i << "] = " << p[i] << endl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 22:56:52 +08:00
										 |  |  |   double* knobs = NULL; /* colamd arg 6: parameters (uses defaults if NULL) */ | 
					
						
							|  |  |  | //  double knobs[CCOLAMD_KNOBS];
 | 
					
						
							|  |  |  | //  ccolamd_set_defaults(knobs);
 | 
					
						
							|  |  |  | //  knobs[CCOLAMD_DENSE_ROW]=-1;
 | 
					
						
							|  |  |  | //  knobs[CCOLAMD_DENSE_COL]=-1;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   int stats[CCOLAMD_STATS]; /* colamd arg 7: colamd output statistics and error codes */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // call colamd, result will be in p
 | 
					
						
							|  |  |  |   /* returns (1) if successful, (0) otherwise*/ | 
					
						
							|  |  |  |   int rv = ccolamd(nFactors, nVars, Alen, A, p, knobs, stats, cmember); | 
					
						
							|  |  |  |   if(rv != 1) | 
					
						
							|  |  |  |     throw runtime_error((boost::format("ccolamd failed with return value %1%")%rv).str()); | 
					
						
							|  |  |  |   delete[] A; // delete symbolic A
 | 
					
						
							|  |  |  |   delete[] cmember; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 22:56:52 +08:00
										 |  |  | //  ccolamd_report(stats);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   // Convert elimination ordering in p to an ordering
 | 
					
						
							|  |  |  |   Permutation::shared_ptr permutation(new Permutation(nVars)); | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |   for (Index j = 0; j < nVars; j++) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     permutation->operator[](j) = p[j]; | 
					
						
							|  |  |  |     if(debug) cout << "COLAMD:  " << j << "->" << p[j] << endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if(debug) cout << "COLAMD:  p[" << nVars << "] = " << p[nVars] << endl; | 
					
						
							|  |  |  |   delete[] p; // delete colamd result vector
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return permutation; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-12 12:52:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } // namespace gtsam
 |