| 
									
										
										
										
											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-12-31 20:56:47 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * BayesNetPreconditioner.cpp | 
					
						
							|  |  |  |  * Created on: Dec 31, 2009 | 
					
						
							|  |  |  |  * @Author: Frank Dellaert | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/foreach.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | #include <gtsam/linear/BayesNetPreconditioner.h>
 | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	BayesNetPreconditioner::BayesNetPreconditioner(const GaussianFactorGraph& Ab, | 
					
						
							|  |  |  | 			const GaussianBayesNet& Rd) : | 
					
						
							|  |  |  | 		Ab_(Ab), Rd_(Rd) { | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// R*x = y by solving x=inv(R)*y
 | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	VectorValues BayesNetPreconditioner::backSubstitute(const VectorValues& y) const { | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 		return gtsam::backSubstitute(Rd_, y); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// gy=inv(L)*gx by solving L*gy=gx.
 | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	VectorValues BayesNetPreconditioner::backSubstituteTranspose( | 
					
						
							|  |  |  | 			const VectorValues& gx) const { | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 		return gtsam::backSubstituteTranspose(Rd_, gx); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	double BayesNetPreconditioner::error(const VectorValues& y) const { | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 		return Ab_.error(x(y)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// gradient is inv(R')*A'*(A*inv(R)*y-b),
 | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	VectorValues BayesNetPreconditioner::gradient(const VectorValues& y) const { | 
					
						
							|  |  |  | 		VectorValues gx = VectorValues::zero(y); | 
					
						
							| 
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 |  |  | 		Errors e = Ab_.errors(x(y)); | 
					
						
							|  |  |  | 		Ab_.transposeMultiplyAdd(1.0,e,gx); | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 		return gtsam::backSubstituteTranspose(Rd_, gx); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// Apply operator *
 | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	Errors BayesNetPreconditioner::operator*(const VectorValues& y) const { | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 		return Ab_ * x(y); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-31 01:31:05 +08:00
										 |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// In-place version that overwrites e
 | 
					
						
							| 
									
										
										
										
											2010-01-31 12:39:41 +08:00
										 |  |  | 	// TODO: version that takes scratch space for x
 | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	void BayesNetPreconditioner::multiplyInPlace(const VectorValues& y, Errors& e) const { | 
					
						
							|  |  |  | 		VectorValues x = y; | 
					
						
							| 
									
										
										
										
											2010-01-31 12:39:41 +08:00
										 |  |  | 		backSubstituteInPlace(Rd_,x); | 
					
						
							|  |  |  | 		Ab_.multiplyInPlace(x,e); | 
					
						
							| 
									
										
										
										
											2010-01-31 01:31:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// Apply operator inv(R')*A'*e
 | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	VectorValues BayesNetPreconditioner::operator^(const Errors& e) const { | 
					
						
							|  |  |  | 		VectorValues x = Ab_ ^ e; // x = A'*e2
 | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 		return gtsam::backSubstituteTranspose(Rd_, x); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-31 07:59:29 +08:00
										 |  |  | 	// y += alpha*inv(R')*A'*e
 | 
					
						
							|  |  |  | 	void BayesNetPreconditioner::transposeMultiplyAdd(double alpha, | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 			const Errors& e, VectorValues& y) const { | 
					
						
							|  |  |  | 		VectorValues x = VectorValues::zero(y); | 
					
						
							| 
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 |  |  | 		Ab_.transposeMultiplyAdd(1.0,e,x); // x += A'*e
 | 
					
						
							|  |  |  | 		axpy(alpha, gtsam::backSubstituteTranspose(Rd_, x), y); // y += alpha*inv(R')*x
 | 
					
						
							| 
									
										
										
										
											2010-01-31 07:59:29 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } // namespace gtsam
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |