/** * @file testLinearFactorGraph.cpp * @brief Unit tests for Linear Factor Graph * @author Christian Potthast **/ /*STL/C++*/ #include using namespace std; #include #include #include #include "Matrix.h" #include "smallExample.h" using namespace gtsam; /* ************************************************************************* */ /* unit test for equals (LinearFactorGraph1 == LinearFactorGraph2) */ /* ************************************************************************* */ TEST( LinearFactorGraph, equals ){ LinearFactorGraph fg = createLinearFactorGraph(); LinearFactorGraph fg2 = createLinearFactorGraph(); CHECK( fg.equals(fg2) ); } /* ************************************************************************* */ TEST( LinearFactorGraph, error ) { LinearFactorGraph fg = createLinearFactorGraph(); FGConfig cfg = createZeroDelta(); // note the error is the same as in testNonlinearFactorGraph as a // zero delta config in the linear graph is equivalent to noisy in // non-linear, which is really linear under the hood double actual = fg.error(cfg); DOUBLES_EQUAL( 5.625, actual, 1e-9 ); } /* ************************************************************************* */ /* unit test for find factors */ /* ************************************************************************* */ /* TEST( LinearFactorGraph, find_factors ) { int checksum = 0; int expected = 16; LinearFactorGraph fg = createLinearFactorGraph(); // create a shared pointer object to prevent memory leaks set > factors = fg.find_factors_and_remove("x2"); // CHECK whether find the right two factors // odometry between x1 and x2 Matrix A21(2,2); A21(0,0) = -10.0 ; A21(0,1) = 0.0; A21(1,0) = 0.0 ; A21(1,1) = -10.0; Matrix A22(2,2); A22(0,0) = 10.0 ; A22(0,1) = 0.0; A22(1,0) = 0.0 ; A22(1,1) = 10.0; Vector b(2); b(0) = 2 ; b(1) = -1; LinearFactor f2 = LinearFactor("x1", A21, "x2", A22, b); // measurement between x2 and l1 Matrix A41(2,2); A41(0,0) = -5 ; A41(0,1) = 0.0; A41(1,0) = 0.0 ; A41(1,1) = -5; Matrix A42(2,2); A42(0,0) = 5 ; A42(0,1) = 0; A42(1,0) = 0 ; A42(1,1) = 5; b(0)= -1 ; b(1) = 1.5; LinearFactor f4 = LinearFactor("x2", A41, "l1", A42, b); set >::iterator it; for( it = factors.begin() ; it != factors.end() ; it++ ){ if( strcmp( it->get()->name_.c_str(), "f2") == 0){ if(it->get()->equals(f2)){ checksum = checksum + 2; } }else if( strcmp( it->get()->name_.c_str(), "f4") == 0){ if(it->get()->equals(f4)){ checksum = checksum + 4; }else{ } } } // CHECK if the factors are deleted from the factor graph // Create LinearFactorGraph fg2; // prior on x1 Matrix A11(2,2); A11(0,0) = 10 ; A11(0,1) = 0; A11(1,0) = 0 ; A11(1,1) = 10; b(0) = -1 ; b(1) = -1; LinearFactor *f1 = new LinearFactor("x1", A11, b); fg2.push_back(f1); // measurement between x1 and l1 Matrix A31(2,2); A31(0,0) = -5 ; A31(0,1) = 0; A31(1,0) = 0 ; A31(1,1) = -5; Matrix A32(2,2); A32(0,0) = 5 ; A32(0,1) = 0; A32(1,0) = 0 ; A32(1,1) = 5; b(0) = 0 ; b(1) = 1; LinearFactor *f3 = new LinearFactor("x1", A31, "l1", A32, b); fg2.push_back(f3); if( fg.equals(fg2) ){ checksum = checksum + 10; } CHECK( checksum == expected ); } */ /* ************************************************************************* */ /* unit test for find seperator */ /* ************************************************************************* */ TEST( LinearFactorGraph, find_separator ) { LinearFactorGraph fg = createLinearFactorGraph(); set separator = fg.find_separator("x2"); set expected; expected.insert("x1"); expected.insert("l1"); CHECK(separator.size()==expected.size()); set::iterator it1 = separator.begin(), it2 = expected.begin(); for(; it1!=separator.end(); it1++, it2++) CHECK(*it1 == *it2); } /* ************************************************************************* */ // Note: This test does not pass when running on Linux(Ubuntu 9.04, GCC 4.3.3) // systems. TEST( LinearFactorGraph, combine_factors_x1 ) { // create a small example for a linear factor graph LinearFactorGraph fg = createLinearFactorGraph(); // combine all factors LinearFactor::shared_ptr actual = fg.combine_factors("x1"); // the expected linear factor Matrix Al1 = Matrix_(6,2, 0., 0., 0., 0., 0., 0., 0., 0., 5., 0., 0., 5. ); Matrix Ax1 = Matrix_(6,2, 10., 0., 0.00, 10., -10., 0., 0.00,-10., -5., 0., 00., -5. ); Matrix Ax2 = Matrix_(6,2, 0., 0., 0., 0., 10., 0., +0.,10., 0., 0., 0., 0. ); // the expected RHS vector Vector b(6); b(0) = -1; b(1) = -1; b(2) = 2; b(3) = -1; b(4) = 0; b(5) = 1; LinearFactor expected("l1", Al1, "x1", Ax1, "x2", Ax2, b); // check if the two factors are the same CHECK(actual->equals(expected)); //currently fails } /* ************************************************************************* */ TEST( LinearFactorGraph, combine_factors_x2 ) { // create a small example for a linear factor graph LinearFactorGraph fg = createLinearFactorGraph(); // combine all factors LinearFactor::shared_ptr actual = fg.combine_factors("x2"); // the expected linear factor Matrix Al1 = Matrix_(4,2, // l1 0., 0., 0., 0., 5., 0., 0., 5. ); Matrix Ax1 = Matrix_(4,2, // x1 -10., 0., // f2 0.00,-10., // f2 0.00, 0., // f4 0.00, 0. // f4 ); Matrix Ax2 = Matrix_(4,2, // x2 10., 0., +0.,10., -5., 0., +0.,-5. ); // the expected RHS vector Vector b(4); b(0) = 2; b(1) = -1; b(2) = -1; b(3) = 1.5; LinearFactor expected("l1", Al1, "x1", Ax1, "x2", Ax2, b); // check if the two factors are the same CHECK(actual->equals(expected)); // currently fails - ordering is different } /* ************************************************************************* */ TEST( LinearFactorGraph, eliminate_one_x1 ) { LinearFactorGraph fg = createLinearFactorGraph(); ConditionalGaussian::shared_ptr actual = fg.eliminate_one("x1"); // create expected Conditional Gaussian Matrix R11 = Matrix_(2,2, 15.0, 00.0, 00.0, 15.0 ); Matrix S12 = Matrix_(2,2, -1.66667, 0.00, +0.00,-1.66667 ); Matrix S13 = Matrix_(2,2, -6.66667, 0.00, +0.00,-6.66667 ); Vector d(2); d(0) = -2; d(1) = -1.0/3.0; ConditionalGaussian expected(d,R11,"l1",S12,"x2",S13); CHECK( actual->equals(expected) ); } /* ************************************************************************* */ TEST( LinearFactorGraph, eliminate_one_x2 ) { LinearFactorGraph fg = createLinearFactorGraph(); ConditionalGaussian::shared_ptr actual = fg.eliminate_one("x2"); // create expected Conditional Gaussian Matrix R11 = Matrix_(2,2, 11.1803, 0.00, 0.00, 11.1803 ); Matrix S12 = Matrix_(2,2, -2.23607, 0.00, +0.00,-2.23607 ); Matrix S13 = Matrix_(2,2, -8.94427, 0.00, +0.00,-8.94427 ); Vector d(2); d(0) = 2.23607; d(1) = -1.56525; ConditionalGaussian expected(d,R11,"l1",S12,"x1",S13); CHECK( actual->equals(expected) ); } /* ************************************************************************* */ TEST( LinearFactorGraph, eliminate_one_l1 ) { LinearFactorGraph fg = createLinearFactorGraph(); ConditionalGaussian::shared_ptr actual = fg.eliminate_one("l1"); // create expected Conditional Gaussian Matrix R11 = Matrix_(2,2, 7.07107, 0.00, 0.00, 7.07107 ); Matrix S12 = Matrix_(2,2, -3.53553, 0.00, +0.00,-3.53553 ); Matrix S13 = Matrix_(2,2, -3.53553, 0.00, +0.00,-3.53553 ); Vector d(2); d(0) = -0.707107; d(1) = 1.76777; ConditionalGaussian expected(d,R11,"x1",S12,"x2",S13); CHECK( actual->equals(expected) ); } /* ************************************************************************* */ TEST( LinearFactorGraph, eliminateAll ) { // create expected Chordal bayes Net double data1[] = { 10, 0.0, 0.0, 10}; Matrix R1 = Matrix_(2,2, data1); Vector d1(2); d1(0) = -1; d1(1) = -1; ConditionalGaussian::shared_ptr cg1(new ConditionalGaussian(d1, R1)); double data21[] = { 6.7082, 0.0, 0.0, 6.7082}; Matrix R2 = Matrix_(2,2, data21); double data22[] = { -6.7082, 0.0, 0.0, -6.7082}; Matrix A1 = Matrix_(2,2, data22); Vector d2(2); d2(0) = 0.0; d2(1) = 1.34164; ConditionalGaussian::shared_ptr cg2(new ConditionalGaussian(d2, R2, "x1", A1)); double data31[] = { 11.1803, 0.0, 0.0, 11.1803}; Matrix R3 = Matrix_(2,2, data31); double data32[] = { -2.23607, 0.0, 0.0, -2.23607}; Matrix A21 = Matrix_(2,2, data32); double data33[] = { -8.94427, 0.0, 0.0, -8.94427}; Matrix A22 = Matrix_(2,2, data33); Vector d3(2); d3(0) = 2.23607; d3(1) = -1.56525; ConditionalGaussian::shared_ptr cg3(new ConditionalGaussian(d3, R3, "l1", A21, "x1", A22)); ChordalBayesNet expected; expected.insert("x1", cg1); expected.insert("l1", cg2); expected.insert("x2", cg3); // Check one ordering LinearFactorGraph fg1 = createLinearFactorGraph(); Ordering ord1; ord1.push_back("x2"); ord1.push_back("l1"); ord1.push_back("x1"); ChordalBayesNet::shared_ptr actual1 = fg1.eliminate(ord1); CHECK(actual1->equals(expected)); } /* ************************************************************************* */ TEST( LinearFactorGraph, add_priors ) { LinearFactorGraph fg = createLinearFactorGraph(); LinearFactorGraph actual = fg.add_priors(3); LinearFactorGraph expected = createLinearFactorGraph(); Matrix A = 3*eye(2); Vector b = zero(2); expected.push_back(LinearFactor::shared_ptr(new LinearFactor("l1",A,b))); expected.push_back(LinearFactor::shared_ptr(new LinearFactor("x1",A,b))); expected.push_back(LinearFactor::shared_ptr(new LinearFactor("x2",A,b))); CHECK(actual.equals(expected)); } /* ************************************************************************* */ TEST( LinearFactorGraph, copying ) { // Create a graph LinearFactorGraph actual = createLinearFactorGraph(); // Copy the graph ! LinearFactorGraph copy = actual; // now eliminate the copy Ordering ord1; ord1.push_back("x2"); ord1.push_back("l1"); ord1.push_back("x1"); ChordalBayesNet::shared_ptr actual1 = copy.eliminate(ord1); // Create the same graph, but not by copying LinearFactorGraph expected = createLinearFactorGraph(); // and check that original is still the same graph CHECK(actual.equals(expected)); } /* ************************************************************************* */ TEST( LinearFactorGraph, matrix ) { // Create a graph LinearFactorGraph fg = createLinearFactorGraph(); // render with a given ordering Ordering ord; ord.push_back("x2"); ord.push_back("l1"); ord.push_back("x1"); Matrix A; Vector b; boost::tie(A,b) = fg.matrix(ord); Matrix A1 = Matrix_(2*4,3*2, 00.0, 0.0, 0.0, 0.0, 10.0, 0.0, 00.0, 0.0, 0.0, 0.0, 0.0, 10.0, 10.0, 0.0, 0.0, 0.0,-10.0, 0.0, 00.0, 10.0, 0.0, 0.0, 0.0,-10.0, 00.0, 0.0, 5.0, 0.0, -5.0, 0.0, 00.0, 0.0, 0.0, 5.0, 0.0, -5.0, -5.0, 0.0, 5.0, 0.0, 0.0, 0.0, 00.0, -5.0, 0.0, 5.0, 0.0, 0.0 ); Vector b1 = Vector_(8,-1.0, -1.0, 2.0, -1.0, 0.0, 1.0, -1.0, 1.5); EQUALITY(A,A1); // currently fails CHECK(b==b1); // currently fails } /* ************************************************************************* */ TEST( LinearFactorGraph, CONSTRUCTOR_ChordalBayesNet ) { LinearFactorGraph fg = createLinearFactorGraph(); // render with a given ordering Ordering ord; ord.push_back("x2"); ord.push_back("l1"); ord.push_back("x1"); ChordalBayesNet::shared_ptr CBN = fg.eliminate(ord); LinearFactorGraph fg2(*CBN); ChordalBayesNet::shared_ptr CBN2 = fg2.eliminate(ord); CHECK(CBN->equals(*CBN2)); } /* ************************************************************************* */ TEST( LinearFactorGraph, GET_ORDERING) { LinearFactorGraph fg = createLinearFactorGraph(); Ordering ord = fg.getOrdering(); CHECK(ord[0] == string("l1")); CHECK(ord[1] == string("x1")); CHECK(ord[2] == string("x2")); } /* ************************************************************************* */ TEST( LinearFactorGraph, OPTIMIZE ) { // create a graph LinearFactorGraph fg = createLinearFactorGraph(); // create an ordering Ordering ord = fg.getOrdering(); // optimize the graph FGConfig actual = fg.optimize(ord); // verify FGConfig expected = createCorrectDelta(); CHECK(actual.equals(expected)); } /* ************************************************************************* */ TEST( LinearFactorGraph, COMBINE_GRAPHS_INPLACE) { // create a test graph LinearFactorGraph fg1 = createLinearFactorGraph(); // create another factor graph LinearFactorGraph fg2 = createLinearFactorGraph(); // get sizes int size1 = fg1.size(); int size2 = fg2.size(); // combine them fg1.combine(fg2); CHECK(size1+size2 == fg1.size()); } /* ************************************************************************* */ TEST( LinearFactorGraph, COMBINE_GRAPHS) { // create a test graph LinearFactorGraph fg1 = createLinearFactorGraph(); // create another factor graph LinearFactorGraph fg2 = createLinearFactorGraph(); // get sizes int size1 = fg1.size(); int size2 = fg2.size(); // combine them LinearFactorGraph fg3 = LinearFactorGraph::combine2(fg1, fg2); CHECK(size1+size2 == fg3.size()); } /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr);} /* ************************************************************************* */