206 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
| /* ----------------------------------------------------------------------------
 | |
| 
 | |
|  * 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
 | |
| 
 | |
|  * -------------------------------------------------------------------------- */
 | |
| 
 | |
| /**
 | |
|  * @file    testGaussianBayesNet.cpp
 | |
|  * @brief   Unit tests for GaussianBayesNet
 | |
|  * @author  Frank Dellaert
 | |
|  */
 | |
| 
 | |
| // STL/C++
 | |
| #include <iostream>
 | |
| #include <sstream>
 | |
| #include <CppUnitLite/TestHarness.h>
 | |
| #include <boost/tuple/tuple.hpp>
 | |
| #include <boost/foreach.hpp>
 | |
| 
 | |
| #include <boost/assign/std/list.hpp> // for operator +=
 | |
| using namespace boost::assign;
 | |
| 
 | |
| // Magically casts strings like "x3" to a Symbol('x',3) key, see Key.h
 | |
| #define GTSAM_MAGIC_KEY
 | |
| 
 | |
| #include <gtsam/linear/GaussianBayesNet.h>
 | |
| #include <gtsam/inference/BayesNet.h>
 | |
| #include <gtsam/linear/GaussianSequentialSolver.h>
 | |
| #include <gtsam/slam/smallExample.h>
 | |
| 
 | |
| using namespace std;
 | |
| using namespace gtsam;
 | |
| using namespace example;
 | |
| 
 | |
| static const Index _x_=0, _y_=1, _z_=2;
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, constructor )
 | |
| {
 | |
|   // small Bayes Net x <- y
 | |
|   // x y d
 | |
|   // 1 1 9
 | |
|   //   1 5
 | |
|   Matrix R11 = Matrix_(1,1,1.0), S12 = Matrix_(1,1,1.0);
 | |
|   Matrix                         R22 = Matrix_(1,1,1.0);
 | |
|   Vector d1(1), d2(1);
 | |
|   d1(0) = 9; d2(0) = 5;
 | |
|   Vector sigmas(1);
 | |
|   sigmas(0) = 1.;
 | |
| 
 | |
|   // define nodes and specify in reverse topological sort (i.e. parents last)
 | |
|   GaussianConditional x(_x_,d1,R11,_y_,S12, sigmas), y(_y_,d2,R22, sigmas);
 | |
| 
 | |
|   // check small example which uses constructor
 | |
|   GaussianBayesNet cbn = createSmallGaussianBayesNet();
 | |
|   EXPECT( x.equals(*cbn[_x_]) );
 | |
|   EXPECT( y.equals(*cbn[_y_]) );
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, matrix )
 | |
| {
 | |
|   // Create a test graph
 | |
|   GaussianBayesNet cbn = createSmallGaussianBayesNet();
 | |
| 
 | |
|   Matrix R; Vector d;
 | |
|   boost::tie(R,d) = matrix(cbn); // find matrix and RHS
 | |
| 
 | |
|   Matrix R1 = Matrix_(2,2,
 | |
| 		      1.0, 1.0,
 | |
| 		      0.0, 1.0
 | |
|     );
 | |
|   Vector d1 = Vector_(2, 9.0, 5.0);
 | |
| 
 | |
|   EXPECT(assert_equal(R,R1));
 | |
|   EXPECT(assert_equal(d,d1));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, optimize )
 | |
| {
 | |
|   GaussianBayesNet cbn = createSmallGaussianBayesNet();
 | |
|   VectorValues actual = optimize(cbn);
 | |
| 
 | |
|   VectorValues expected(vector<size_t>(2,1));
 | |
|   expected[_x_] = Vector_(1,4.);
 | |
|   expected[_y_] = Vector_(1,5.);
 | |
| 
 | |
|   EXPECT(assert_equal(expected,actual));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, optimize2 )
 | |
| {
 | |
| 
 | |
| 	// Create empty graph
 | |
| 	GaussianFactorGraph fg;
 | |
| 	SharedDiagonal noise = noiseModel::Unit::Create(1);
 | |
| 
 | |
| 	fg.add(_y_, eye(1), 2*ones(1), noise);
 | |
| 
 | |
| 	fg.add(_x_, eye(1),_y_, -eye(1), -ones(1), noise);
 | |
| 
 | |
| 	fg.add(_y_, eye(1),_z_, -eye(1), -ones(1), noise);
 | |
| 
 | |
| 	fg.add(_x_, -eye(1), _z_, eye(1), 2*ones(1), noise);
 | |
| 
 | |
|   VectorValues actual = *GaussianSequentialSolver(fg).optimize();
 | |
| 
 | |
|   VectorValues expected(vector<size_t>(3,1));
 | |
|   expected[_x_] = Vector_(1,1.);
 | |
|   expected[_y_] = Vector_(1,2.);
 | |
|   expected[_z_] = Vector_(1,3.);
 | |
| 
 | |
|   EXPECT(assert_equal(expected,actual));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, backSubstitute )
 | |
| {
 | |
| 	// y=R*x, x=inv(R)*y
 | |
| 	// 2 = 1 1  -1
 | |
| 	// 3     1   3
 | |
| 	// NOTE: we are supplying a new RHS here
 | |
|   GaussianBayesNet cbn = createSmallGaussianBayesNet();
 | |
| 
 | |
|   VectorValues y(vector<size_t>(2,1)), x(vector<size_t>(2,1));
 | |
|   y[_x_] = Vector_(1,2.);
 | |
|   y[_y_] = Vector_(1,3.);
 | |
|   x[_x_] = Vector_(1,-1.);
 | |
|   x[_y_] = Vector_(1, 3.);
 | |
| 
 | |
|   // test functional version
 | |
|   VectorValues actual = backSubstitute(cbn,y);
 | |
|   EXPECT(assert_equal(x,actual));
 | |
| 
 | |
|   // test imperative version
 | |
|   backSubstituteInPlace(cbn,y);
 | |
|   EXPECT(assert_equal(x,y));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, rhs )
 | |
| {
 | |
| 	// y=R*x, x=inv(R)*y
 | |
| 	// 2 = 1 1  -1
 | |
| 	// 3     1   3
 | |
|   GaussianBayesNet cbn = createSmallGaussianBayesNet();
 | |
| 	VectorValues expected = gtsam::optimize(cbn);
 | |
| 	VectorValues d = rhs(cbn);
 | |
| 	VectorValues actual = backSubstitute(cbn, d);
 | |
| 	EXPECT(assert_equal(expected, actual));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, rhs_with_sigmas )
 | |
| {
 | |
| 	Matrix R11 = Matrix_(1, 1, 1.0), S12 = Matrix_(1, 1, 1.0);
 | |
| 	Matrix R22 = Matrix_(1, 1, 1.0);
 | |
| 	Vector d1(1), d2(1);
 | |
| 	d1(0) = 9;
 | |
| 	d2(0) = 5;
 | |
| 	Vector tau(1);
 | |
| 	tau(0) = 0.25;
 | |
| 
 | |
| 	// define nodes and specify in reverse topological sort (i.e. parents last)
 | |
| 	GaussianConditional::shared_ptr Px_y(new GaussianConditional(_x_, d1, R11,
 | |
| 			_y_, S12, tau)), Py(new GaussianConditional(_y_, d2, R22, tau));
 | |
| 	GaussianBayesNet cbn;
 | |
| 	cbn.push_back(Px_y);
 | |
| 	cbn.push_back(Py);
 | |
| 
 | |
| 	VectorValues expected = gtsam::optimize(cbn);
 | |
| 	VectorValues d = rhs(cbn);
 | |
| 	VectorValues actual = backSubstitute(cbn, d);
 | |
| 	EXPECT(assert_equal(expected, actual));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( GaussianBayesNet, backSubstituteTranspose )
 | |
| {
 | |
| 	// x=R'*y, y=inv(R')*x
 | |
| 	// 2 = 1    2
 | |
| 	// 5   1 1  3
 | |
|   GaussianBayesNet cbn = createSmallGaussianBayesNet();
 | |
| 
 | |
|   VectorValues y(vector<size_t>(2,1)), x(vector<size_t>(2,1));
 | |
|   x[_x_] = Vector_(1,2.);
 | |
|   x[_y_] = Vector_(1,5.);
 | |
|   y[_x_] = Vector_(1,2.);
 | |
|   y[_y_] = Vector_(1,3.);
 | |
| 
 | |
|   // test functional version
 | |
|   VectorValues actual = backSubstituteTranspose(cbn,x);
 | |
|   EXPECT(assert_equal(y,actual));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
 | |
| /* ************************************************************************* */
 |