| 
									
										
										
										
											2009-12-31 20:56:47 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * BayesNetPreconditioner.cpp | 
					
						
							|  |  |  |  * Created on: Dec 31, 2009 | 
					
						
							|  |  |  |  * @Author: Frank Dellaert | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/foreach.hpp>
 | 
					
						
							|  |  |  | #include "BayesNetPreconditioner.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	BayesNetPreconditioner::BayesNetPreconditioner(const GaussianFactorGraph& Ab, | 
					
						
							|  |  |  | 			const GaussianBayesNet& Rd) : | 
					
						
							|  |  |  | 		Ab_(Ab), Rd_(Rd) { | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// R*x = y by solving x=inv(R)*y
 | 
					
						
							|  |  |  | 	VectorConfig BayesNetPreconditioner::backSubstitute(const VectorConfig& y) const { | 
					
						
							|  |  |  | 		return gtsam::backSubstitute(Rd_, y); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// gy=inv(L)*gx by solving L*gy=gx.
 | 
					
						
							|  |  |  | 	VectorConfig BayesNetPreconditioner::backSubstituteTranspose( | 
					
						
							|  |  |  | 			const VectorConfig& gx) const { | 
					
						
							|  |  |  | 		return gtsam::backSubstituteTranspose(Rd_, gx); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	double BayesNetPreconditioner::error(const VectorConfig& y) const { | 
					
						
							|  |  |  | 		return Ab_.error(x(y)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	// gradient is inv(R')*A'*(A*inv(R)*y-b),
 | 
					
						
							|  |  |  | 	VectorConfig BayesNetPreconditioner::gradient(const VectorConfig& y) const { | 
					
						
							| 
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 |  |  | 		VectorConfig gx = VectorConfig::zero(y); | 
					
						
							|  |  |  | 		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 *
 | 
					
						
							|  |  |  | 	Errors BayesNetPreconditioner::operator*(const VectorConfig& y) const { | 
					
						
							|  |  |  | 		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-01-31 01:31:05 +08:00
										 |  |  | 	void BayesNetPreconditioner::multiplyInPlace(const VectorConfig& y, Errors& e) const { | 
					
						
							| 
									
										
										
										
											2010-01-31 12:39:41 +08:00
										 |  |  | 		VectorConfig x = y; | 
					
						
							|  |  |  | 		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
 | 
					
						
							|  |  |  | 	VectorConfig BayesNetPreconditioner::operator^(const Errors& e) const { | 
					
						
							|  |  |  | 		VectorConfig x = Ab_ ^ e; // x = A'*e2
 | 
					
						
							|  |  |  | 		return gtsam::backSubstituteTranspose(Rd_, x); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-31 07:59:29 +08:00
										 |  |  | 	// y += alpha*inv(R')*A'*e
 | 
					
						
							|  |  |  | 	void BayesNetPreconditioner::transposeMultiplyAdd(double alpha, | 
					
						
							|  |  |  | 			const Errors& e, VectorConfig& y) const { | 
					
						
							| 
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 |  |  | 		VectorConfig x = VectorConfig::zero(y); | 
					
						
							|  |  |  | 		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
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |