251 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
| /**
 | |
|  * @file testConditioning.cpp
 | |
|  *
 | |
|  * @brief Experiments using backsubstitution for conditioning (not summarization, it turns out)
 | |
|  *
 | |
|  * @date Sep 3, 2012
 | |
|  * @author Alex Cunningham
 | |
|  */
 | |
| 
 | |
| #include <CppUnitLite/TestHarness.h>
 | |
| 
 | |
| #include <gtsam/base/TestableAssertions.h>
 | |
| 
 | |
| #include <boost/assign/std/set.hpp>
 | |
| 
 | |
| #include <gtsam_unstable/linear/conditioning.h>
 | |
| 
 | |
| using namespace std;
 | |
| using namespace boost::assign;
 | |
| using namespace gtsam;
 | |
| 
 | |
| const double tol = 1e-5;
 | |
| 
 | |
| // Simple example
 | |
| Matrix R = Matrix_(3,3,
 | |
|     1.0,-2.0,-3.0,
 | |
|     0.0, 3.0,-5.0,
 | |
|     0.0, 0.0, 6.0);
 | |
| Vector d = Vector_(3,
 | |
|     0.1, 0.2, 0.3);
 | |
| Vector x = Vector_(3,
 | |
|     0.55,
 | |
|     0.15,
 | |
|     0.05);
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( testConditioning, directed_elimination_example ) {
 | |
| 
 | |
|   // create a 3-variable system from which to eliminate variables
 | |
|   // Scalar variables, pre-factorized into R,d system
 | |
|   // Use multifrontal representation
 | |
|   // Variables 0, 1, 2 - want to summarize out 1
 | |
|   Vector expx = R.triangularView<Eigen::Upper>().solve(d);
 | |
|   EXPECT(assert_equal(x, expx, tol));
 | |
|   EXPECT(assert_equal(Vector(R*x), d, tol));
 | |
| 
 | |
|   // backsub-summarized version
 | |
|   Matrix Rprime = Matrix_(2,2,
 | |
|       1.0,-3.0,
 | |
|       0.0, 6.0);
 | |
|   Vector dprime = Vector_(2,
 | |
|       d(0) - R(0,1)*x(1),
 | |
|       d(2));
 | |
|   Vector xprime = Vector_(2,
 | |
|       x(0), // Same solution, just smaller
 | |
|       x(2));
 | |
|   EXPECT(assert_equal(Vector(Rprime*xprime), dprime, tol));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( testConditioning, directed_elimination_singlefrontal ) {
 | |
|   // Gaussian conditional with a single frontal variable, parent is to be removed
 | |
|   // Top row from above example
 | |
| 
 | |
|   Index root_key = 0, removed_key = 1, remaining_parent = 2;
 | |
|   Matrix R11 = Matrix_(1,1, 1.0), R22 = Matrix_(1,1, 3.0), S = Matrix_(1,1,-2.0), T = Matrix_(1,1,-3.0);
 | |
|   Vector d0 = d.segment(0,1), d1 = d.segment(1,1), sigmas = Vector_(1, 1.0);
 | |
|   GaussianConditional::shared_ptr initConditional(new
 | |
|       GaussianConditional(root_key, d0, R11, removed_key, S, remaining_parent, T, sigmas));
 | |
| 
 | |
|   VectorValues solution;
 | |
|   solution.insert(0, x.segment(0,1));
 | |
|   solution.insert(1, x.segment(1,1));
 | |
|   solution.insert(2, x.segment(2,1));
 | |
| 
 | |
|   std::set<Index> saved_indices;
 | |
|   saved_indices += root_key, remaining_parent;
 | |
| 
 | |
|   GaussianConditional::shared_ptr actSummarized = conditionDensity(initConditional, saved_indices, solution);
 | |
|   GaussianConditional::shared_ptr expSummarized(new
 | |
|       GaussianConditional(root_key, d0 - S*x(1), R11, remaining_parent, T, sigmas));
 | |
| 
 | |
|   CHECK(actSummarized);
 | |
|   EXPECT(assert_equal(*expSummarized, *actSummarized, tol));
 | |
| 
 | |
|   // Simple test of base case: if target index isn't present, return clone
 | |
|   GaussianConditional::shared_ptr actSummarizedSimple = conditionDensity(expSummarized, saved_indices, solution);
 | |
|   CHECK(actSummarizedSimple);
 | |
|   EXPECT(assert_equal(*expSummarized, *actSummarizedSimple, tol));
 | |
| 
 | |
|   // case where frontal variable is to be eliminated - return null
 | |
|   GaussianConditional::shared_ptr removeFrontalInit(new
 | |
|         GaussianConditional(removed_key, d1, R22, remaining_parent, T, sigmas));
 | |
|   GaussianConditional::shared_ptr actRemoveFrontal = conditionDensity(removeFrontalInit, saved_indices, solution);
 | |
|   EXPECT(!actRemoveFrontal);
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( testConditioning, directed_elimination_multifrontal ) {
 | |
|   // Use top two rows from the previous example
 | |
|   Index root_key = 0, removed_key = 1, remaining_parent = 2;
 | |
|   Matrix R11 = R.topLeftCorner(2,2), S = R.block(0,2,2,1),
 | |
|       Sprime = Matrix_(1,1,-2.0), R11prime = Matrix_(1,1, 1.0);
 | |
|   Vector d1 = d.segment(0,2), sigmas1 = Vector_(1, 1.0), sigmas2 = Vector_(2, 1.0, 1.0);
 | |
| 
 | |
| 
 | |
|   std::list<std::pair<Index, Matrix> > terms;
 | |
|   terms += make_pair(root_key, Matrix(R11.col(0)));
 | |
|   terms += make_pair(removed_key, Matrix(R11.col(1)));
 | |
|   terms += make_pair(remaining_parent, S);
 | |
|   GaussianConditional::shared_ptr initConditional(new GaussianConditional(terms, 2, d1, sigmas2));
 | |
| 
 | |
|   VectorValues solution;
 | |
|   solution.insert(0, x.segment(0,1));
 | |
|   solution.insert(1, x.segment(1,1));
 | |
|   solution.insert(2, x.segment(2,1));
 | |
| 
 | |
|   std::set<Index> saved_indices;
 | |
|   saved_indices += root_key, remaining_parent;
 | |
| 
 | |
|   GaussianConditional::shared_ptr actSummarized = conditionDensity(initConditional, saved_indices, solution);
 | |
|   GaussianConditional::shared_ptr expSummarized(new
 | |
|       GaussianConditional(root_key, d.segment(0,1) - Sprime*x(1), R11prime, remaining_parent, R.block(0,2,1,1), sigmas1));
 | |
| 
 | |
|   CHECK(actSummarized);
 | |
|   EXPECT(assert_equal(*expSummarized, *actSummarized, tol));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( testConditioning, directed_elimination_multifrontal_multidim ) {
 | |
|   // use larger example, three frontal variables, dim = 2 each, two parents (one removed)
 | |
|   // Vars: 0, 1, 2, 3, 4; frontal: 0, 1, 2. parents: 3, 4;
 | |
|   // Remove 1, 3
 | |
|   Matrix Rinit = Matrix_(6, 11,
 | |
|       1.0, 0.0,  2.0, 0.0,  3.0, 0.0,  1.0, 0.0, -1.0, 0.0,  0.1,
 | |
|       0.0, 1.0,  0.0, 2.0,  0.0, 3.0,  0.0, 1.0,  0.0, 1.0,  0.2,
 | |
|       0.0, 0.0,  3.0, 0.0,  4.0, 0.0,  0.0,-1.0,  1.0, 0.0,  0.3,
 | |
|       0.0, 0.0,  0.0, 4.0,  0.0, 4.0,  3.0, 2.0,  0.0, 9.0,  0.4,
 | |
|       0.0, 0.0,  0.0, 0.0,  5.0, 0.0,  7.0, 0.0,  3.0, 0.0,  0.5,
 | |
|       0.0, 0.0,  0.0, 0.0,  0.0, 4.0,  0.0, 8.0,  0.0, 6.0,  0.6);
 | |
| 
 | |
|   vector<size_t> init_dims; init_dims += 2, 2, 2, 2, 2, 1;
 | |
|   GaussianConditional::rsd_type init_matrices(Rinit, init_dims.begin(), init_dims.end());
 | |
|   Vector sigmas = ones(6);
 | |
|   vector<size_t> init_keys; init_keys += 0, 1, 2, 3, 4;
 | |
|   GaussianConditional::shared_ptr initConditional(new
 | |
|       GaussianConditional(init_keys.begin(), init_keys.end(), 3, init_matrices, sigmas));
 | |
| 
 | |
|   // Construct a solution vector
 | |
|   VectorValues solution;
 | |
|   solution.insert(0, zero(2));
 | |
|   solution.insert(1, zero(2));
 | |
|   solution.insert(2, zero(2));
 | |
|   solution.insert(3, Vector_(2, 1.0, 2.0));
 | |
|   solution.insert(4, Vector_(2, 3.0, 4.0));
 | |
| 
 | |
|   initConditional->solveInPlace(solution);
 | |
| 
 | |
|   std::set<Index> saved_indices;
 | |
|   saved_indices += 0, 2, 4;
 | |
| 
 | |
|   GaussianConditional::shared_ptr actSummarized = conditionDensity(initConditional, saved_indices, solution);
 | |
|   CHECK(actSummarized);
 | |
| 
 | |
|   Matrix Rexp = Matrix_(4, 7,
 | |
|       1.0, 0.0,  3.0, 0.0,  -1.0, 0.0,  0.1,
 | |
|       0.0, 1.0,  0.0, 3.0,   0.0, 1.0,  0.2,
 | |
|       0.0, 0.0,  5.0, 0.0,   3.0, 0.0,  0.5,
 | |
|       0.0, 0.0,  0.0, 4.0,   0.0, 6.0,  0.6);
 | |
| 
 | |
|   // Update rhs
 | |
|   Rexp.block(0, 6, 2, 1) -= Rinit.block(0, 2, 2, 2) * solution.at(1) + Rinit.block(0, 6, 2, 2) * solution.at(3);
 | |
|   Rexp.block(2, 6, 2, 1) -= Rinit.block(4, 6, 2, 2) * solution.at(3);
 | |
| 
 | |
|   vector<size_t> exp_dims; exp_dims += 2, 2, 2, 1;
 | |
|   GaussianConditional::rsd_type exp_matrices(Rexp, exp_dims.begin(), exp_dims.end());
 | |
|   Vector exp_sigmas = ones(4);
 | |
|   vector<size_t> exp_keys; exp_keys += 0, 2, 4;
 | |
|   GaussianConditional expSummarized(exp_keys.begin(), exp_keys.end(), 2, exp_matrices, exp_sigmas);
 | |
| 
 | |
|   EXPECT(assert_equal(expSummarized, *actSummarized, tol));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| TEST( testConditioning, directed_elimination_multifrontal_multidim2 ) {
 | |
|   // Example from LinearAugmentedSystem
 | |
|   // 4 variables, last two in ordering kept - should be able to do this with no computation.
 | |
| 
 | |
|   vector<size_t> init_dims; init_dims += 3, 3, 2, 2, 1;
 | |
| 
 | |
|   //Full initial conditional: density on [3] [4] [5] [6]
 | |
|   Matrix Rinit = Matrix_(10, 11,
 | |
|       8.78422312,  -0.0375455118,  -0.0387376278,     -5.059576,           0.0,           0.0,  -0.0887200041,  0.00429643583,  -0.130078263,  0.0193260727,  0.0,
 | |
|       0.0,    8.46951839,    9.51456887,  -0.0224291821,   -5.24757636,           0.0,  0.0586258904,  -0.173455825,    0.11090295,  -0.330696013,        0.0,
 | |
|       0.0,           0.0,    16.5539485,  0.00105159359,   -2.35354497,   -6.04085484,  -0.0212095105,  0.0978729072,  0.00471054272,  0.0694956367,    0.0,
 | |
|       0.0,           0.0,           0.0,    10.9015885,  -0.0105694572,  0.000582715469,  -0.0410535006,  0.00162772139,  -0.0601433772,  0.0082824087,0.0,
 | |
|       0.0,           0.0,           0.0,           0.0,    10.5531086,   -1.34722553,    0.02438072,  -0.0644224578,  0.0561372492,  -0.148932792,        0.0,
 | |
|       0.0,           0.0,           0.0,           0.0,           0.0,    21.4870439,  -0.00443305851,  0.0234766354,  0.00484572411,  0.0101997356,      0.0,
 | |
|       0.0,           0.0,           0.0,           0.0,           0.0,           0.0,    2.73892865,  0.0242046766,  -0.0459727048,  0.0445071938,        0.0,
 | |
|       0.0,           0.0,           0.0,           0.0,           0.0,           0.0,           0.0,    2.61246954,    0.02287419,  -0.102870789,          0.0,
 | |
|       0.0,           0.0,           0.0,           0.0,           0.0,           0.0,           0.0,           0.0,    2.04823446,  -0.302033014,          0.0,
 | |
|       0.0,           0.0,           0.0,           0.0,           0.0,           0.0,           0.0,           0.0,           0.0,    2.24068986,          0.0);
 | |
|   Vector dinit = Vector_(10,
 | |
|       -0.00186915, 0.00318554, 0.000592421, -0.000861, 0.00171528, 0.000274123, -0.0284011, 0.0275465, 0.0439795, -0.0222134);
 | |
|   Rinit.rightCols(1) = dinit;
 | |
|   Vector sigmas = ones(10);
 | |
| 
 | |
|   GaussianConditional::rsd_type init_matrices(Rinit, init_dims.begin(), init_dims.end());
 | |
|   vector<size_t> init_keys; init_keys += 3, 4, 5, 6;
 | |
|   GaussianConditional::shared_ptr initConditional(new
 | |
|       GaussianConditional(init_keys.begin(), init_keys.end(), 4, init_matrices, sigmas));
 | |
| 
 | |
|   // Calculate a solution
 | |
|   VectorValues solution;
 | |
|   solution.insert(0, zero(3));
 | |
|   solution.insert(1, zero(3));
 | |
|   solution.insert(2, zero(3));
 | |
|   solution.insert(3, zero(3));
 | |
|   solution.insert(4, zero(3));
 | |
|   solution.insert(5, zero(2));
 | |
|   solution.insert(6, zero(2));
 | |
| 
 | |
|   initConditional->solveInPlace(solution);
 | |
| 
 | |
|   // Perform summarization
 | |
|   std::set<Index> saved_indices;
 | |
|   saved_indices += 5, 6;
 | |
| 
 | |
|   GaussianConditional::shared_ptr actSummarized = conditionDensity(initConditional, saved_indices, solution);
 | |
|   CHECK(actSummarized);
 | |
| 
 | |
|   // Create expected value on [5], [6]
 | |
|   Matrix Rexp = Matrix_(4, 5,
 | |
|       2.73892865,  0.0242046766,  -0.0459727048,  0.0445071938,  -0.0284011,
 | |
|              0.0,    2.61246954,    0.02287419,  -0.102870789,     0.0275465,
 | |
|              0.0,           0.0,    2.04823446,  -0.302033014,     0.0439795,
 | |
|              0.0,           0.0,           0.0,    2.24068986,    -0.0222134);
 | |
|   Vector expsigmas = ones(4);
 | |
| 
 | |
|   vector<size_t> exp_dims; exp_dims += 2, 2, 1;
 | |
|   GaussianConditional::rsd_type exp_matrices(Rexp, exp_dims.begin(), exp_dims.end());
 | |
|   vector<size_t> exp_keys; exp_keys += 5, 6;
 | |
|   GaussianConditional expConditional(exp_keys.begin(), exp_keys.end(), 2, exp_matrices, expsigmas);
 | |
| 
 | |
|   EXPECT(assert_equal(expConditional, *actSummarized, tol));
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
 | |
| /* ************************************************************************* */
 |