| 
									
										
										
										
											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-08-22 06:23:24 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:41:18 +08:00
										 |  |  |  * @file   GaussianConditional.cpp | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |  * @brief  Conditional Gaussian Base class | 
					
						
							|  |  |  |  * @author Christian Potthast | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <boost/numeric/ublas/vector.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | #include <boost/numeric/ublas/operation.hpp>
 | 
					
						
							|  |  |  | #include <boost/format.hpp>
 | 
					
						
							|  |  |  | #include <boost/lambda/bind.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | #include <gtsam/linear/GaussianConditional.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | #include <gtsam/base/Matrix-inl.h>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | namespace ublas = boost::numeric::ublas; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | GaussianConditional::GaussianConditional() : rsd_(matrix_) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-20 05:31:13 +08:00
										 |  |  | GaussianConditional::GaussianConditional(Index key) : IndexConditional(key), rsd_(matrix_) {} | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | GaussianConditional::GaussianConditional(Index key,const Vector& d, const Matrix& R, const Vector& sigmas) : | 
					
						
							| 
									
										
										
										
											2010-10-20 05:31:13 +08:00
										 |  |  | 	    IndexConditional(key), rsd_(matrix_), sigmas_(sigmas) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   assert(R.size1() <= R.size2()); | 
					
						
							|  |  |  |   size_t dims[] = { R.size2(), 1 }; | 
					
						
							|  |  |  |   rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+2, d.size())); | 
					
						
							|  |  |  |   ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R); | 
					
						
							|  |  |  |   ublas::noalias(get_d_()) = d; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | GaussianConditional::GaussianConditional(Index key, const Vector& d, const Matrix& R, | 
					
						
							|  |  |  |     Index name1, const Matrix& S, const Vector& sigmas) : | 
					
						
							| 
									
										
										
										
											2010-10-20 05:31:13 +08:00
										 |  |  |     IndexConditional(key,name1), rsd_(matrix_), sigmas_(sigmas) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   assert(R.size1() <= R.size2()); | 
					
						
							|  |  |  |   size_t dims[] = { R.size2(), S.size2(), 1 }; | 
					
						
							|  |  |  |   rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+3, d.size())); | 
					
						
							|  |  |  |   ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R); | 
					
						
							|  |  |  |   ublas::noalias(rsd_(1)) = S; | 
					
						
							|  |  |  |   ublas::noalias(get_d_()) = d; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | GaussianConditional::GaussianConditional(Index key, const Vector& d, const Matrix& R, | 
					
						
							|  |  |  | 		Index name1, const Matrix& S, Index name2, const Matrix& T, const Vector& sigmas) : | 
					
						
							| 
									
										
										
										
											2010-10-20 05:31:13 +08:00
										 |  |  | 		IndexConditional(key,name1,name2), rsd_(matrix_), sigmas_(sigmas) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   assert(R.size1() <= R.size2()); | 
					
						
							|  |  |  |   size_t dims[] = { R.size2(), S.size2(), T.size2(), 1 }; | 
					
						
							|  |  |  |   rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+4, d.size())); | 
					
						
							|  |  |  |   ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R); | 
					
						
							|  |  |  |   ublas::noalias(rsd_(1)) = S; | 
					
						
							|  |  |  |   ublas::noalias(rsd_(2)) = T; | 
					
						
							|  |  |  |   ublas::noalias(get_d_()) = d; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-08 21:57:22 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | GaussianConditional::GaussianConditional(Index key, const Vector& d, const Matrix& R, const list<pair<Index, Matrix> >& parents, const Vector& sigmas) : | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     rsd_(matrix_), sigmas_(sigmas) { | 
					
						
							|  |  |  |   assert(R.size1() <= R.size2()); | 
					
						
							| 
									
										
										
										
											2010-10-20 05:31:13 +08:00
										 |  |  |   IndexConditional::nrFrontals_ = 1; | 
					
						
							| 
									
										
										
										
											2010-10-14 04:43:58 +08:00
										 |  |  |   keys_.resize(1+parents.size()); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   size_t dims[1+parents.size()+1]; | 
					
						
							|  |  |  |   dims[0] = R.size2(); | 
					
						
							| 
									
										
										
										
											2010-10-14 04:43:58 +08:00
										 |  |  |   keys_[0] = key; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   size_t j=1; | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |   for(std::list<std::pair<Index, Matrix> >::const_iterator parent=parents.begin(); parent!=parents.end(); ++parent) { | 
					
						
							| 
									
										
										
										
											2010-10-14 04:43:58 +08:00
										 |  |  |     keys_[j] = parent->first; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     dims[j] = parent->second.size2(); | 
					
						
							|  |  |  |     ++ j; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   dims[j] = 1; | 
					
						
							|  |  |  |   rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+1+parents.size()+1, d.size())); | 
					
						
							|  |  |  |   ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R); | 
					
						
							|  |  |  |   j = 1; | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |   for(std::list<std::pair<Index, Matrix> >::const_iterator parent=parents.begin(); parent!=parents.end(); ++parent) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     ublas::noalias(rsd_(j)) = parent->second; | 
					
						
							|  |  |  |     ++ j; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   ublas::noalias(get_d_()) = d; | 
					
						
							| 
									
										
										
										
											2009-11-02 11:50:30 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-10-08 21:57:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:41:18 +08:00
										 |  |  | void GaussianConditional::print(const string &s) const | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   cout << s << ": density on " << key() << endl; | 
					
						
							|  |  |  |   gtsam::print(get_R(),"R"); | 
					
						
							|  |  |  |   for(const_iterator it = beginParents() ; it != endParents() ; it++ ) { | 
					
						
							|  |  |  |     gtsam::print(get_S(it), (boost::format("A[%1%]")%(*it)).str()); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   gtsam::print(get_d(),"d"); | 
					
						
							| 
									
										
										
										
											2009-11-05 14:59:59 +08:00
										 |  |  |   gtsam::print(sigmas_,"sigmas"); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | }     | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 07:14:14 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | bool GaussianConditional::equals(const GaussianConditional &c, double tol) const { | 
					
						
							| 
									
										
										
										
											2009-10-25 07:14:14 +08:00
										 |  |  | 	// check if the size of the parents_ map is the same
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 	if (parents().size() != c.parents().size()) return false; | 
					
						
							| 
									
										
										
										
											2009-10-25 07:14:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-11 15:30:27 +08:00
										 |  |  | 	// check if R_ and d_ are linear independent
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 	for (size_t i=0; i<rsd_.size1(); i++) { | 
					
						
							|  |  |  | 		list<Vector> rows1; rows1.push_back(row_(get_R(), i)); | 
					
						
							|  |  |  | 		list<Vector> rows2; rows2.push_back(row_(c.get_R(), i)); | 
					
						
							| 
									
										
										
										
											2009-11-05 04:59:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-05 07:50:21 +08:00
										 |  |  | 		// check if the matrices are the same
 | 
					
						
							|  |  |  | 		// iterate over the parents_ map
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 		for (const_iterator it = beginParents(); it != endParents(); ++it) { | 
					
						
							|  |  |  | 		  const_iterator it2 = c.beginParents() + (it-beginParents()); | 
					
						
							|  |  |  | 		  if(*it != *(it2)) | 
					
						
							|  |  |  | 		    return false; | 
					
						
							|  |  |  | 		  rows1.push_back(row_(get_S(it), i)); | 
					
						
							|  |  |  | 		  rows2.push_back(row_(c.get_S(it2), i)); | 
					
						
							| 
									
										
										
										
											2010-07-05 07:50:21 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-11 15:30:27 +08:00
										 |  |  | 		Vector row1 = concatVectors(rows1); | 
					
						
							|  |  |  | 		Vector row2 = concatVectors(rows2); | 
					
						
							|  |  |  | 		if (!linear_dependent(row1, row2, tol)) return false; | 
					
						
							| 
									
										
										
										
											2009-10-25 07:14:14 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-05 07:50:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// check if sigmas are equal
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 	if (!(equal_with_abs_tol(sigmas_, c.sigmas_, tol))) return false; | 
					
						
							| 
									
										
										
										
											2010-07-05 07:50:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 07:14:14 +08:00
										 |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 05:12:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | Vector GaussianConditional::solve(const VectorValues& x) const { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   static const bool debug = false; | 
					
						
							|  |  |  |   if(debug) print("Solving conditional "); | 
					
						
							|  |  |  | 	Vector rhs(get_d()); | 
					
						
							|  |  |  | 	for (const_iterator parent = beginParents(); parent != endParents(); ++parent) { | 
					
						
							|  |  |  |     ublas::axpy_prod(-get_S(parent), x[*parent], rhs, false); | 
					
						
							| 
									
										
										
										
											2010-10-22 05:12:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-27 09:23:05 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 	if(debug) gtsam::print(get_R(), "Calling backSubstituteUpper on "); | 
					
						
							|  |  |  | 	if(debug) gtsam::print(rhs, "rhs: "); | 
					
						
							|  |  |  | 	if(debug) { | 
					
						
							|  |  |  | 	  Vector soln = backSubstituteUpper(get_R(), rhs, false); | 
					
						
							|  |  |  | 	  gtsam::print(soln, "back-substitution solution: "); | 
					
						
							|  |  |  | 	  return soln; | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 	  return backSubstituteUpper(get_R(), rhs, false); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | Vector GaussianConditional::solve(const Permuted<VectorValues>& x) const { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   Vector rhs(get_d()); | 
					
						
							|  |  |  |   for (const_iterator parent = beginParents(); parent != endParents(); ++parent) { | 
					
						
							|  |  |  |     ublas::axpy_prod(-get_S(parent), x[*parent], rhs, false); | 
					
						
							| 
									
										
										
										
											2010-10-22 05:12:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return backSubstituteUpper(get_R(), rhs, false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |