| 
									
										
										
										
											2010-10-14 12:54:38 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-11 22:39:48 +08:00
										 |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							| 
									
										
										
										
											2010-10-14 12:54:38 +08:00
										 |  |  |  * 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-08-22 06:23:24 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  @file  testNonlinearFactor.cpp | 
					
						
							| 
									
										
										
										
											2019-02-11 22:39:48 +08:00
										 |  |  |  *  @brief Unit tests for Non-Linear Factor, | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  |  *  create a non linear factor graph and a values structure for it and | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |  *  calculate the error for the factor. | 
					
						
							|  |  |  |  *  @author Christian Potthast | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*STL/C++*/ | 
					
						
							|  |  |  | #include <iostream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-26 04:10:33 +08:00
										 |  |  | #include <CppUnitLite/TestHarness.h>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 13:38:53 +08:00
										 |  |  | // TODO: DANGEROUS, create shared pointers
 | 
					
						
							|  |  |  | #define GTSAM_MAGIC_GAUSSIAN 2
 | 
					
						
							| 
									
										
										
										
											2011-08-18 21:18:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-20 10:11:28 +08:00
										 |  |  | #include <gtsam/base/Testable.h>
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | #include <gtsam/base/Matrix.h>
 | 
					
						
							| 
									
										
										
										
											2012-06-10 04:15:44 +08:00
										 |  |  | #include <tests/smallExample.h>
 | 
					
						
							|  |  |  | #include <tests/simulated2D.h>
 | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:33 +08:00
										 |  |  | #include <gtsam/linear/GaussianFactor.h>
 | 
					
						
							| 
									
										
										
										
											2011-12-21 07:25:43 +08:00
										 |  |  | #include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | 
					
						
							| 
									
										
										
										
											2013-08-19 23:32:16 +08:00
										 |  |  | #include <gtsam/inference/Symbol.h>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							|  |  |  | using namespace gtsam; | 
					
						
							| 
									
										
										
										
											2010-01-19 13:33:44 +08:00
										 |  |  | using namespace example; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-03 00:18:40 +08:00
										 |  |  | // Convenience for named keys
 | 
					
						
							| 
									
										
										
										
											2012-06-03 03:28:21 +08:00
										 |  |  | using symbol_shorthand::X; | 
					
						
							|  |  |  | using symbol_shorthand::L; | 
					
						
							| 
									
										
										
										
											2012-02-07 12:02:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  | typedef std::shared_ptr<NonlinearFactor > shared_nlf; | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, equals ) | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   SharedNoiseModel sigma(noiseModel::Isotropic::Sigma(2,1.0)); | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // create two nonlinear2 factors
 | 
					
						
							|  |  |  |   Point2 z3(0.,-1.); | 
					
						
							|  |  |  |   simulated2D::Measurement f0(z3, sigma, X(1),L(1)); | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // measurement between x2 and l1
 | 
					
						
							|  |  |  |   Point2 z4(-1.5, -1.); | 
					
						
							|  |  |  |   simulated2D::Measurement f1(z4, sigma, X(2),L(1)); | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   CHECK(assert_equal(f0,f0)); | 
					
						
							|  |  |  |   CHECK(f0.equals(f0)); | 
					
						
							|  |  |  |   CHECK(!f0.equals(f1)); | 
					
						
							|  |  |  |   CHECK(!f1.equals(f0)); | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, equals2 ) | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // create a non linear factor graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph fg = createNonlinearFactorGraph(); | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // get two factors
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph::sharedFactor f0 = fg[0], f1 = fg[1]; | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   CHECK(f0->equals(*f0)); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   CHECK(!f0->equals(*f1)); | 
					
						
							|  |  |  |   CHECK(!f1->equals(*f0)); | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, NonlinearFactor ) | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // create a non linear factor graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph fg = createNonlinearFactorGraph(); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  |   // create a values structure for the non linear factor graph
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values cfg = createNoisyValues(); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // get the factor "f1" from the factor graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph::sharedFactor factor = fg[0]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // calculate the error_vector from the factor "f1"
 | 
					
						
							| 
									
										
										
										
											2011-09-03 11:46:19 +08:00
										 |  |  |   // error_vector = [0.1 0.1]
 | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |   Vector actual_e = std::dynamic_pointer_cast<NoiseModelFactor>(factor)->unwhitenedError(cfg); | 
					
						
							| 
									
										
										
										
											2016-04-16 05:30:54 +08:00
										 |  |  |   CHECK(assert_equal(0.1*Vector::Ones(2),actual_e)); | 
					
						
							| 
									
										
										
										
											2010-01-18 13:38:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   // error = 0.5 * [1 1] * [1;1] = 1
 | 
					
						
							| 
									
										
										
										
											2012-01-30 05:12:58 +08:00
										 |  |  |   double expected = 1.0; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // calculate the error from the factor "f1"
 | 
					
						
							|  |  |  |   double actual = factor->error(cfg); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(expected,actual,0.00000001); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-07 00:46:49 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST(NonlinearFactor, Weight) { | 
					
						
							|  |  |  |   // create a values structure for the non linear factor graph
 | 
					
						
							|  |  |  |   Values values; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Instantiate a concrete class version of a NoiseModelFactor
 | 
					
						
							|  |  |  |   PriorFactor<Point2> factor1(X(1), Point2(0, 0)); | 
					
						
							|  |  |  |   values.insert(X(1), Point2(0.1, 0.1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CHECK(assert_equal(1.0, factor1.weight(values))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Factor with noise model
 | 
					
						
							|  |  |  |   auto noise = noiseModel::Isotropic::Sigma(2, 0.2); | 
					
						
							|  |  |  |   PriorFactor<Point2> factor2(X(2), Point2(1, 1), noise); | 
					
						
							|  |  |  |   values.insert(X(2), Point2(1.1, 1.1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CHECK(assert_equal(1.0, factor2.weight(values))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Point2 estimate(3, 3), prior(1, 1); | 
					
						
							|  |  |  |   double distance = (estimate - prior).norm(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   auto gaussian = noiseModel::Isotropic::Sigma(2, 0.2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PriorFactor<Point2> factor; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // vector to store all the robust models in so we can test iteratively.
 | 
					
						
							|  |  |  |   vector<noiseModel::Robust::shared_ptr> robust_models; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Fair noise model
 | 
					
						
							|  |  |  |   auto fair = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::Fair::Create(1.3998), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(fair); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Huber noise model
 | 
					
						
							|  |  |  |   auto huber = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::Huber::Create(1.345), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(huber); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Cauchy noise model
 | 
					
						
							|  |  |  |   auto cauchy = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::Cauchy::Create(0.1), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(cauchy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Tukey noise model
 | 
					
						
							|  |  |  |   auto tukey = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::Tukey::Create(4.6851), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(tukey); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Welsch noise model
 | 
					
						
							|  |  |  |   auto welsch = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::Welsch::Create(2.9846), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(welsch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Geman-McClure noise model
 | 
					
						
							|  |  |  |   auto gm = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::GemanMcClure::Create(1.0), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(gm); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // DCS noise model
 | 
					
						
							|  |  |  |   auto dcs = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::DCS::Create(1.0), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(dcs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // L2WithDeadZone noise model
 | 
					
						
							|  |  |  |   auto l2 = noiseModel::Robust::Create( | 
					
						
							|  |  |  |       noiseModel::mEstimator::L2WithDeadZone::Create(1.0), gaussian); | 
					
						
							|  |  |  |   robust_models.push_back(l2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for(auto&& model: robust_models) { | 
					
						
							|  |  |  |     factor = PriorFactor<Point2>(X(3), prior, model); | 
					
						
							|  |  |  |     values.clear(); | 
					
						
							|  |  |  |     values.insert(X(3), estimate); | 
					
						
							|  |  |  |     CHECK(assert_equal(model->robust()->weight(distance), factor.weight(values))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 12:39:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, linearize_f1 ) | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   Values c = createNoisyValues(); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   // Grab a non-linear factor
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph nfg = createNonlinearFactorGraph(); | 
					
						
							|  |  |  |   NonlinearFactorGraph::sharedFactor nlf = nfg[0]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // We linearize at noisy config from SmallExample
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactor::shared_ptr actual = nlf->linearize(c); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactorGraph lfg = createGaussianFactorGraph(); | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   GaussianFactor::shared_ptr expected = lfg[0]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-10 21:54:34 +08:00
										 |  |  |   CHECK(assert_equal(*expected,*actual)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // The error |A*dx-b| approximates (h(x0+dx)-z) = -error_vector
 | 
					
						
							|  |  |  |   // Hence i.e., b = approximates z-h(x0) = error_vector(x0)
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   //CHECK(assert_equal(nlf->error_vector(c),actual->get_b()));
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 12:39:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, linearize_f2 ) | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   Values c = createNoisyValues(); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   // Grab a non-linear factor
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph nfg = createNonlinearFactorGraph(); | 
					
						
							|  |  |  |   NonlinearFactorGraph::sharedFactor nlf = nfg[1]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // We linearize at noisy config from SmallExample
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactor::shared_ptr actual = nlf->linearize(c); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactorGraph lfg = createGaussianFactorGraph(); | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   GaussianFactor::shared_ptr expected = lfg[1]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 12:39:35 +08:00
										 |  |  |   CHECK(assert_equal(*expected,*actual)); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 12:39:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, linearize_f3 ) | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // Grab a non-linear factor
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph nfg = createNonlinearFactorGraph(); | 
					
						
							|  |  |  |   NonlinearFactorGraph::sharedFactor nlf = nfg[2]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // We linearize at noisy config from SmallExample
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values c = createNoisyValues(); | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactor::shared_ptr actual = nlf->linearize(c); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactorGraph lfg = createGaussianFactorGraph(); | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   GaussianFactor::shared_ptr expected = lfg[2]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 12:39:35 +08:00
										 |  |  |   CHECK(assert_equal(*expected,*actual)); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 12:39:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, linearize_f4 ) | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // Grab a non-linear factor
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph nfg = createNonlinearFactorGraph(); | 
					
						
							|  |  |  |   NonlinearFactorGraph::sharedFactor nlf = nfg[3]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // We linearize at noisy config from SmallExample
 | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values c = createNoisyValues(); | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactor::shared_ptr actual = nlf->linearize(c); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactorGraph lfg = createGaussianFactorGraph(); | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   GaussianFactor::shared_ptr expected = lfg[3]; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-27 12:39:35 +08:00
										 |  |  |   CHECK(assert_equal(*expected,*actual)); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  | TEST( NonlinearFactor, size ) | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // create a non linear factor graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph fg = createNonlinearFactorGraph(); | 
					
						
							| 
									
										
										
										
											2012-01-30 05:12:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // create a values structure for the non linear factor graph
 | 
					
						
							|  |  |  |   Values cfg = createNoisyValues(); | 
					
						
							| 
									
										
										
										
											2012-01-30 05:12:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // get some factors from the graph
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph::sharedFactor factor1 = fg[0], factor2 = fg[1], | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |       factor3 = fg[2]; | 
					
						
							| 
									
										
										
										
											2012-01-30 05:12:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   CHECK(factor1->size() == 1); | 
					
						
							|  |  |  |   CHECK(factor2->size() == 2); | 
					
						
							|  |  |  |   CHECK(factor3->size() == 2); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-12-08 07:17:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-29 01:21:24 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST( NonlinearFactor, linearize_constraint1 ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-10-12 05:06:57 +08:00
										 |  |  |   SharedDiagonal constraint = noiseModel::Constrained::MixedSigmas(Vector2(0.2,0)); | 
					
						
							| 
									
										
										
										
											2010-01-29 01:21:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   Point2 mu(1., -1.); | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   NonlinearFactorGraph::sharedFactor f0(new simulated2D::Prior(mu, constraint, X(1))); | 
					
						
							| 
									
										
										
										
											2010-01-29 01:21:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   Values config; | 
					
						
							|  |  |  |   config.insert(X(1), Point2(1.0, 2.0)); | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactor::shared_ptr actual = f0->linearize(config); | 
					
						
							| 
									
										
										
										
											2010-01-29 01:21:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // create expected
 | 
					
						
							| 
									
										
										
										
											2014-10-12 05:06:57 +08:00
										 |  |  |   Vector2 b(0., -3.); | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |   JacobianFactor expected(X(1), (Matrix(2, 2) << 5.0, 0.0, 0.0, 1.0).finished(), b, | 
					
						
							| 
									
										
										
										
											2014-10-12 05:06:57 +08:00
										 |  |  |     noiseModel::Constrained::MixedSigmas(Vector2(1,0))); | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   CHECK(assert_equal((const GaussianFactor&)expected, *actual)); | 
					
						
							| 
									
										
										
										
											2010-01-29 01:21:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST( NonlinearFactor, linearize_constraint2 ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-10-12 05:06:57 +08:00
										 |  |  |   SharedDiagonal constraint = noiseModel::Constrained::MixedSigmas(Vector2(0.2,0)); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Point2 z3(1.,-1.); | 
					
						
							|  |  |  |   simulated2D::Measurement f0(z3, constraint, X(1),L(1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Values config; | 
					
						
							|  |  |  |   config.insert(X(1), Point2(1.0, 2.0)); | 
					
						
							|  |  |  |   config.insert(L(1), Point2(5.0, 4.0)); | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   GaussianFactor::shared_ptr actual = f0.linearize(config); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // create expected
 | 
					
						
							| 
									
										
										
										
											2014-10-12 05:06:57 +08:00
										 |  |  |   Matrix2 A; A << 5.0, 0.0, 0.0, 1.0; | 
					
						
							|  |  |  |   Vector2 b(-15., -3.); | 
					
						
							| 
									
										
										
										
											2013-08-07 02:04:37 +08:00
										 |  |  |   JacobianFactor expected(X(1), -1*A, L(1), A, b, | 
					
						
							| 
									
										
										
										
											2014-10-12 05:06:57 +08:00
										 |  |  |     noiseModel::Constrained::MixedSigmas(Vector2(1,0))); | 
					
						
							| 
									
										
										
										
											2013-08-06 06:31:44 +08:00
										 |  |  |   CHECK(assert_equal((const GaussianFactor&)expected, *actual)); | 
					
						
							| 
									
										
										
										
											2010-01-29 01:21:24 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-28 07:25:38 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | TEST( NonlinearFactor, cloneWithNewNoiseModel ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // create original factor
 | 
					
						
							|  |  |  |   double sigma1 = 0.1; | 
					
						
							|  |  |  |   NonlinearFactorGraph nfg = example::nonlinearFactorGraphWithGivenSigma(sigma1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // create expected
 | 
					
						
							|  |  |  |   double sigma2 = 10; | 
					
						
							|  |  |  |   NonlinearFactorGraph expected = example::nonlinearFactorGraphWithGivenSigma(sigma2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // create actual
 | 
					
						
							|  |  |  |   NonlinearFactorGraph actual; | 
					
						
							|  |  |  |   SharedNoiseModel noise2 = noiseModel::Isotropic::Sigma(2,sigma2); | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |   actual.push_back( std::dynamic_pointer_cast<NoiseModelFactor>(nfg[0])->cloneWithNewNoiseModel(noise2) ); | 
					
						
							| 
									
										
										
										
											2020-11-28 07:25:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // check it's all good
 | 
					
						
							|  |  |  |   CHECK(assert_equal(expected, actual)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-03 19:17:14 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | class TestFactor1 : public NoiseModelFactor1<double> { | 
					
						
							|  |  |  |   static_assert(std::is_same<Base, NoiseModelFactor>::value, "Base type wrong"); | 
					
						
							|  |  |  |   static_assert(std::is_same<This, NoiseModelFactor1<double>>::value, | 
					
						
							|  |  |  |                 "This type wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   typedef NoiseModelFactor1<double> Base; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-03 19:17:14 +08:00
										 |  |  |   TestFactor1() : Base(noiseModel::Diagonal::Sigmas(Vector1(2.0)), L(1)) {} | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2022-12-20 07:49:20 +08:00
										 |  |  |   using Base::NoiseModelFactor1;  // inherit constructors
 | 
					
						
							| 
									
										
										
										
											2021-12-03 19:17:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |   Vector evaluateError(const double& x1, OptionalMatrixType H1) const override { | 
					
						
							| 
									
										
										
										
											2021-12-03 19:17:14 +08:00
										 |  |  |     if (H1) *H1 = (Matrix(1, 1) << 1.0).finished(); | 
					
						
							|  |  |  |     return (Vector(1) << x1).finished(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gtsam::NonlinearFactor::shared_ptr clone() const override { | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |     return std::static_pointer_cast<gtsam::NonlinearFactor>( | 
					
						
							| 
									
										
										
										
											2021-12-03 19:17:14 +08:00
										 |  |  |         gtsam::NonlinearFactor::shared_ptr(new TestFactor1(*this))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************ */ | 
					
						
							|  |  |  | TEST(NonlinearFactor, NoiseModelFactor1) { | 
					
						
							|  |  |  |   TestFactor1 tf; | 
					
						
							|  |  |  |   Values tv; | 
					
						
							|  |  |  |   tv.insert(L(1), double((1.0))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Vector(1) << 1.0).finished(), tf.unwhitenedError(tv))); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.25 / 2.0, tf.error(tv), 1e-9); | 
					
						
							|  |  |  |   JacobianFactor jf( | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |       *std::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv))); | 
					
						
							| 
									
										
										
										
											2021-12-03 19:17:14 +08:00
										 |  |  |   LONGS_EQUAL((long)L(1), (long)jf.keys()[0]); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 0.5).finished(), | 
					
						
							|  |  |  |                       jf.getA(jf.begin()))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Vector)(Vector(1) << -0.5).finished(), jf.getb())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Test all functions/types for backwards compatibility
 | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor1::X, double>::value, | 
					
						
							|  |  |  |                 "X type incorrect"); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key(), L(1))); | 
					
						
							|  |  |  |   std::vector<Matrix> H = {Matrix()}; | 
					
						
							|  |  |  |   EXPECT(assert_equal(Vector1(1.0), tf.unwhitenedError(tv, H))); | 
					
						
							| 
									
										
										
										
											2022-12-20 07:49:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Test constructors
 | 
					
						
							|  |  |  |   TestFactor1 tf2(noiseModel::Unit::Create(1), L(1)); | 
					
						
							|  |  |  |   TestFactor1 tf3(noiseModel::Unit::Create(1), {L(1)}); | 
					
						
							| 
									
										
										
										
											2022-12-20 09:14:12 +08:00
										 |  |  |   TestFactor1 tf4(noiseModel::Unit::Create(1), gtsam::Symbol('L', 1)); | 
					
						
							| 
									
										
										
										
											2021-12-03 19:17:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  | class TestFactor4 : public NoiseModelFactor4<double, double, double, double> { | 
					
						
							| 
									
										
										
										
											2021-12-03 13:46:23 +08:00
										 |  |  |   static_assert(std::is_same<Base, NoiseModelFactor>::value, "Base type wrong"); | 
					
						
							|  |  |  |   static_assert( | 
					
						
							|  |  |  |       std::is_same<This, | 
					
						
							|  |  |  |                    NoiseModelFactor4<double, double, double, double>>::value, | 
					
						
							|  |  |  |       "This type wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  |   typedef NoiseModelFactor4<double, double, double, double> Base; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 05:07:58 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-20 06:41:21 +08:00
										 |  |  |   TestFactor4() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0).finished()), X(1), X(2), X(3), X(4)) {} | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2022-12-20 07:49:20 +08:00
										 |  |  |   using Base::NoiseModelFactor4;  // inherit constructors
 | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   Vector | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  |     evaluateError(const double& x1, const double& x2, const double& x3, const double& x4, | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |         OptionalMatrixType H1, OptionalMatrixType H2, | 
					
						
							|  |  |  |         OptionalMatrixType H3, OptionalMatrixType H4) const override { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     if(H1) { | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |       *H1 = (Matrix(1, 1) << 1.0).finished(); | 
					
						
							|  |  |  |       *H2 = (Matrix(1, 1) << 2.0).finished(); | 
					
						
							|  |  |  |       *H3 = (Matrix(1, 1) << 3.0).finished(); | 
					
						
							|  |  |  |       *H4 = (Matrix(1, 1) << 4.0).finished(); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |     return (Vector(1) << x1 + 2.0 * x2 + 3.0 * x3 + 4.0 * x4).finished(); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   gtsam::NonlinearFactor::shared_ptr clone() const override { | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |     return std::static_pointer_cast<gtsam::NonlinearFactor>( | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |         gtsam::NonlinearFactor::shared_ptr(new TestFactor4(*this))); } | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************ */ | 
					
						
							| 
									
										
										
										
											2012-02-21 05:52:47 +08:00
										 |  |  | TEST(NonlinearFactor, NoiseModelFactor4) { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |   TestFactor4 tf; | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values tv; | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  |   tv.insert(X(1), double((1.0))); | 
					
						
							|  |  |  |   tv.insert(X(2), double((2.0))); | 
					
						
							|  |  |  |   tv.insert(X(3), double((3.0))); | 
					
						
							|  |  |  |   tv.insert(X(4), double((4.0))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector(1) << 30.0).finished(), tf.unwhitenedError(tv))); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.5 * 30.0 * 30.0 / 4.0, tf.error(tv), 1e-9); | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |   JacobianFactor jf(*std::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv))); | 
					
						
							| 
									
										
										
										
											2013-08-12 02:18:06 +08:00
										 |  |  |   LONGS_EQUAL((long)X(1), (long)jf.keys()[0]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(2), (long)jf.keys()[1]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(3), (long)jf.keys()[2]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(4), (long)jf.keys()[3]); | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 0.5).finished(), jf.getA(jf.begin()))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.0).finished(), jf.getA(jf.begin()+1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.5).finished(), jf.getA(jf.begin()+2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 2.0).finished(), jf.getA(jf.begin()+3))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector)(Vector(1) << 0.5 * -30.).finished(), jf.getb())); | 
					
						
							| 
									
										
										
										
											2021-12-03 13:46:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Test all functions/types for backwards compatibility
 | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor4::X1, double>::value, | 
					
						
							|  |  |  |                 "X1 type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor4::X2, double>::value, | 
					
						
							|  |  |  |                 "X2 type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor4::X3, double>::value, | 
					
						
							|  |  |  |                 "X3 type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor4::X4, double>::value, | 
					
						
							|  |  |  |                 "X4 type incorrect"); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key1(), X(1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key2(), X(2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key3(), X(3))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key4(), X(4))); | 
					
						
							|  |  |  |   std::vector<Matrix> H = {Matrix(), Matrix(), Matrix(), Matrix()}; | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal(Vector1(30.0), tf.unwhitenedError(tv, H))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.).finished(), H.at(0))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 2.).finished(), H.at(1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 3.).finished(), H.at(2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 4.).finished(), H.at(3))); | 
					
						
							| 
									
										
										
										
											2022-12-20 07:06:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // And test "forward compatibility" using `key<N>` and `ValueType<N>` too
 | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor4::ValueType<1>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<1> type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor4::ValueType<2>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<2> type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactor4::ValueType<3>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<3> type incorrect"); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   static_assert(std::is_same<TestFactor4::ValueType<4>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<4> type incorrect"); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<1>(), X(1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<2>(), X(2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<3>(), X(3))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<4>(), X(4))); | 
					
						
							| 
									
										
										
										
											2022-12-20 07:49:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Test constructors
 | 
					
						
							|  |  |  |   TestFactor4 tf2(noiseModel::Unit::Create(1), L(1), L(2), L(3), L(4)); | 
					
						
							|  |  |  |   TestFactor4 tf3(noiseModel::Unit::Create(1), {L(1), L(2), L(3), L(4)}); | 
					
						
							|  |  |  |   TestFactor4 tf4(noiseModel::Unit::Create(1), | 
					
						
							|  |  |  |                   std::array<Key, 4>{L(1), L(2), L(3), L(4)}); | 
					
						
							|  |  |  |   std::vector<Key> keys = {L(1), L(2), L(3), L(4)}; | 
					
						
							|  |  |  |   TestFactor4 tf5(noiseModel::Unit::Create(1), keys); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  | class TestFactor5 : public NoiseModelFactor5<double, double, double, double, double> { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  |   typedef NoiseModelFactor5<double, double, double, double, double> Base; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 05:07:58 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-20 06:41:21 +08:00
										 |  |  |   TestFactor5() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0).finished()), X(1), X(2), X(3), X(4), X(5)) {} | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   Vector | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     evaluateError(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |         OptionalMatrixType H1, OptionalMatrixType H2, OptionalMatrixType H3,  | 
					
						
							|  |  |  | 		OptionalMatrixType H4, OptionalMatrixType H5) const override { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     if(H1) { | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |       *H1 = (Matrix(1, 1) << 1.0).finished(); | 
					
						
							|  |  |  |       *H2 = (Matrix(1, 1) << 2.0).finished(); | 
					
						
							|  |  |  |       *H3 = (Matrix(1, 1) << 3.0).finished(); | 
					
						
							|  |  |  |       *H4 = (Matrix(1, 1) << 4.0).finished(); | 
					
						
							|  |  |  |       *H5 = (Matrix(1, 1) << 5.0).finished(); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |     return (Vector(1) << x1 + 2.0 * x2 + 3.0 * x3 + 4.0 * x4 + 5.0 * x5) | 
					
						
							|  |  |  |         .finished(); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************ */ | 
					
						
							| 
									
										
										
										
											2012-02-21 05:52:47 +08:00
										 |  |  | TEST(NonlinearFactor, NoiseModelFactor5) { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |   TestFactor5 tf; | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values tv; | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  |   tv.insert(X(1), double((1.0))); | 
					
						
							|  |  |  |   tv.insert(X(2), double((2.0))); | 
					
						
							|  |  |  |   tv.insert(X(3), double((3.0))); | 
					
						
							|  |  |  |   tv.insert(X(4), double((4.0))); | 
					
						
							|  |  |  |   tv.insert(X(5), double((5.0))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector(1) << 55.0).finished(), tf.unwhitenedError(tv))); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.5 * 55.0 * 55.0 / 4.0, tf.error(tv), 1e-9); | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |   JacobianFactor jf(*std::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv))); | 
					
						
							| 
									
										
										
										
											2013-08-12 02:18:06 +08:00
										 |  |  |   LONGS_EQUAL((long)X(1), (long)jf.keys()[0]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(2), (long)jf.keys()[1]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(3), (long)jf.keys()[2]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(4), (long)jf.keys()[3]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(5), (long)jf.keys()[4]); | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 0.5).finished(), jf.getA(jf.begin()))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.0).finished(), jf.getA(jf.begin()+1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.5).finished(), jf.getA(jf.begin()+2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 2.0).finished(), jf.getA(jf.begin()+3))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 2.5).finished(), jf.getA(jf.begin()+4))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector)(Vector(1) << 0.5 * -55.).finished(), jf.getb())); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  | class TestFactor6 : public NoiseModelFactor6<double, double, double, double, double, double> { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  |   typedef NoiseModelFactor6<double, double, double, double, double, double> Base; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 05:07:58 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-20 06:41:21 +08:00
										 |  |  |   TestFactor6() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0).finished()), X(1), X(2), X(3), X(4), X(5), X(6)) {} | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   Vector | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     evaluateError(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |         OptionalMatrixType H1, OptionalMatrixType H2, OptionalMatrixType H3, OptionalMatrixType H4,  | 
					
						
							|  |  |  | 		OptionalMatrixType H5, OptionalMatrixType H6) const override { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     if(H1) { | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |       *H1 = (Matrix(1, 1) << 1.0).finished(); | 
					
						
							|  |  |  |       *H2 = (Matrix(1, 1) << 2.0).finished(); | 
					
						
							|  |  |  |       *H3 = (Matrix(1, 1) << 3.0).finished(); | 
					
						
							|  |  |  |       *H4 = (Matrix(1, 1) << 4.0).finished(); | 
					
						
							|  |  |  |       *H5 = (Matrix(1, 1) << 5.0).finished(); | 
					
						
							|  |  |  |       *H6 = (Matrix(1, 1) << 6.0).finished(); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |     return (Vector(1) << x1 + 2.0 * x2 + 3.0 * x3 + 4.0 * x4 + 5.0 * x5 + | 
					
						
							|  |  |  |                              6.0 * x6) | 
					
						
							|  |  |  |         .finished(); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************ */ | 
					
						
							| 
									
										
										
										
											2012-02-21 05:52:47 +08:00
										 |  |  | TEST(NonlinearFactor, NoiseModelFactor6) { | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  |   TestFactor6 tf; | 
					
						
							| 
									
										
										
										
											2012-02-03 00:16:46 +08:00
										 |  |  |   Values tv; | 
					
						
							| 
									
										
										
										
											2014-11-04 22:44:20 +08:00
										 |  |  |   tv.insert(X(1), double((1.0))); | 
					
						
							|  |  |  |   tv.insert(X(2), double((2.0))); | 
					
						
							|  |  |  |   tv.insert(X(3), double((3.0))); | 
					
						
							|  |  |  |   tv.insert(X(4), double((4.0))); | 
					
						
							|  |  |  |   tv.insert(X(5), double((5.0))); | 
					
						
							|  |  |  |   tv.insert(X(6), double((6.0))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector(1) << 91.0).finished(), tf.unwhitenedError(tv))); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.5 * 91.0 * 91.0 / 4.0, tf.error(tv), 1e-9); | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |   JacobianFactor jf(*std::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv))); | 
					
						
							| 
									
										
										
										
											2013-08-12 02:18:06 +08:00
										 |  |  |   LONGS_EQUAL((long)X(1), (long)jf.keys()[0]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(2), (long)jf.keys()[1]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(3), (long)jf.keys()[2]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(4), (long)jf.keys()[3]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(5), (long)jf.keys()[4]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(6), (long)jf.keys()[5]); | 
					
						
							| 
									
										
										
										
											2014-11-23 08:35:27 +08:00
										 |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 0.5).finished(), jf.getA(jf.begin()))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.0).finished(), jf.getA(jf.begin()+1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.5).finished(), jf.getA(jf.begin()+2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 2.0).finished(), jf.getA(jf.begin()+3))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 2.5).finished(), jf.getA(jf.begin()+4))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 3.0).finished(), jf.getA(jf.begin()+5))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector)(Vector(1) << 0.5 * -91.).finished(), jf.getb())); | 
					
						
							| 
									
										
										
										
											2011-10-26 10:07:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-02 05:04:49 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | class TestFactorN : public NoiseModelFactorN<double, double, double, double> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   typedef NoiseModelFactorN<double, double, double, double> Base; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:14:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 05:07:58 +08:00
										 |  |  |   // Provide access to the Matrix& version of evaluateError:
 | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |   using Base::evaluateError; | 
					
						
							| 
									
										
										
										
											2023-01-12 03:01:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:15 +08:00
										 |  |  |   using Type1 = ValueType<1>;  // Test that we can use the ValueType<> template
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-20 06:41:21 +08:00
										 |  |  |   TestFactorN() : Base(noiseModel::Diagonal::Sigmas((Vector(1) << 2.0).finished()), X(1), X(2), X(3), X(4)) {} | 
					
						
							| 
									
										
										
										
											2021-12-02 05:04:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Vector | 
					
						
							|  |  |  |     evaluateError(const double& x1, const double& x2, const double& x3, const double& x4, | 
					
						
							| 
									
										
										
										
											2023-01-07 08:29:15 +08:00
										 |  |  |         OptionalMatrixType H1, OptionalMatrixType H2, | 
					
						
							|  |  |  |         OptionalMatrixType H3, OptionalMatrixType H4) const override { | 
					
						
							| 
									
										
										
										
											2021-12-03 13:39:10 +08:00
										 |  |  |     if (H1) *H1 = (Matrix(1, 1) << 1.0).finished(); | 
					
						
							|  |  |  |     if (H2) *H2 = (Matrix(1, 1) << 2.0).finished(); | 
					
						
							|  |  |  |     if (H3) *H3 = (Matrix(1, 1) << 3.0).finished(); | 
					
						
							|  |  |  |     if (H4) *H4 = (Matrix(1, 1) << 4.0).finished(); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |     return (Vector(1) << x1 + 2.0 * x2 + 3.0 * x3 + 4.0 * x4).finished(); | 
					
						
							| 
									
										
										
										
											2021-12-02 05:04:49 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Key key1() const { return key<1>(); }  // Test that we can use key<> template
 | 
					
						
							| 
									
										
										
										
											2021-12-02 05:04:49 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************ */ | 
					
						
							|  |  |  | TEST(NonlinearFactor, NoiseModelFactorN) { | 
					
						
							|  |  |  |   TestFactorN tf; | 
					
						
							|  |  |  |   Values tv; | 
					
						
							|  |  |  |   tv.insert(X(1), double((1.0))); | 
					
						
							|  |  |  |   tv.insert(X(2), double((2.0))); | 
					
						
							|  |  |  |   tv.insert(X(3), double((3.0))); | 
					
						
							|  |  |  |   tv.insert(X(4), double((4.0))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector(1) << 30.0).finished(), tf.unwhitenedError(tv))); | 
					
						
							|  |  |  |   DOUBLES_EQUAL(0.5 * 30.0 * 30.0 / 4.0, tf.error(tv), 1e-9); | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |   JacobianFactor jf(*std::dynamic_pointer_cast<JacobianFactor>(tf.linearize(tv))); | 
					
						
							| 
									
										
										
										
											2021-12-02 05:04:49 +08:00
										 |  |  |   LONGS_EQUAL((long)X(1), (long)jf.keys()[0]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(2), (long)jf.keys()[1]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(3), (long)jf.keys()[2]); | 
					
						
							|  |  |  |   LONGS_EQUAL((long)X(4), (long)jf.keys()[3]); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 0.5).finished(), jf.getA(jf.begin()))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.0).finished(), jf.getA(jf.begin()+1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 1.5).finished(), jf.getA(jf.begin()+2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal((Matrix)(Matrix(1, 1) << 2.0).finished(), jf.getA(jf.begin()+3))); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   EXPECT(assert_equal((Vector)(Vector(1) << -0.5 * 30.).finished(), jf.getb())); | 
					
						
							| 
									
										
										
										
											2021-12-03 13:39:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Test all evaluateError argument overloads to ensure backward compatibility
 | 
					
						
							|  |  |  |   Matrix H1_expected, H2_expected, H3_expected, H4_expected; | 
					
						
							|  |  |  |   Vector e_expected = tf.evaluateError(9, 8, 7, 6, H1_expected, H2_expected, | 
					
						
							|  |  |  |                                        H3_expected, H4_expected); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::unique_ptr<NoiseModelFactorN<double, double, double, double>> base_ptr( | 
					
						
							|  |  |  |       new TestFactorN(tf)); | 
					
						
							|  |  |  |   Matrix H1, H2, H3, H4; | 
					
						
							|  |  |  |   EXPECT(assert_equal(e_expected, base_ptr->evaluateError(9, 8, 7, 6))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(e_expected, base_ptr->evaluateError(9, 8, 7, 6, H1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H1_expected, H1)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(e_expected,  //
 | 
					
						
							|  |  |  |                       base_ptr->evaluateError(9, 8, 7, 6, H1, H2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H1_expected, H1)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H2_expected, H2)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(e_expected, | 
					
						
							|  |  |  |                       base_ptr->evaluateError(9, 8, 7, 6, H1, H2, H3))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H1_expected, H1)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H2_expected, H2)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H3_expected, H3)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(e_expected, | 
					
						
							|  |  |  |                       base_ptr->evaluateError(9, 8, 7, 6, H1, H2, H3, H4))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H1_expected, H1)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H2_expected, H2)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H3_expected, H3)); | 
					
						
							|  |  |  |   EXPECT(assert_equal(H4_expected, H4)); | 
					
						
							| 
									
										
										
										
											2022-12-20 07:06:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-23 12:56:46 +08:00
										 |  |  |   // Test all functions/types for backwards compatibility
 | 
					
						
							| 
									
										
										
										
											2023-01-05 11:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-23 12:56:46 +08:00
										 |  |  |   static_assert(std::is_same<TestFactor4::X1, double>::value, | 
					
						
							|  |  |  |                 "X1 type incorrect"); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key3(), X(3))); | 
					
						
							| 
									
										
										
										
											2023-01-05 11:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-23 12:56:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-20 07:06:34 +08:00
										 |  |  |   // Test using `key<N>` and `ValueType<N>`
 | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactorN::ValueType<1>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<1> type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactorN::ValueType<2>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<2> type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactorN::ValueType<3>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<3> type incorrect"); | 
					
						
							| 
									
										
										
										
											2022-12-23 03:29:38 +08:00
										 |  |  |   static_assert(std::is_same<TestFactorN::ValueType<4>, double>::value, | 
					
						
							|  |  |  |                 "ValueType<4> type incorrect"); | 
					
						
							|  |  |  |   static_assert(std::is_same<TestFactorN::Type1, double>::value, | 
					
						
							|  |  |  |                 "TestFactorN::Type1 type incorrect"); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<1>(), X(1))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<2>(), X(2))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<3>(), X(3))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key<4>(), X(4))); | 
					
						
							|  |  |  |   EXPECT(assert_equal(tf.key1(), X(1))); | 
					
						
							| 
									
										
										
										
											2021-12-02 05:04:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:40 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:42 +08:00
										 |  |  | TEST( NonlinearFactor, clone_rekey ) | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:40 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   shared_nlf init(new TestFactor4()); | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   EXPECT_LONGS_EQUAL((long)X(1), (long)init->keys()[0]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(2), (long)init->keys()[1]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(3), (long)init->keys()[2]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(4), (long)init->keys()[3]); | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:42 +08:00
										 |  |  |   // Standard clone
 | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:40 +08:00
										 |  |  |   shared_nlf actClone = init->clone(); | 
					
						
							|  |  |  |   EXPECT(actClone.get() != init.get()); // Ensure different pointers
 | 
					
						
							|  |  |  |   EXPECT(assert_equal(*init, *actClone)); | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Re-key factor - clones with different keys
 | 
					
						
							| 
									
										
										
										
											2018-11-09 06:18:47 +08:00
										 |  |  |   KeyVector new_keys {X(5),X(6),X(7),X(8)}; | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:42 +08:00
										 |  |  |   shared_nlf actRekey = init->rekey(new_keys); | 
					
						
							|  |  |  |   EXPECT(actRekey.get() != init.get()); // Ensure different pointers
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Ensure init is unchanged
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   EXPECT_LONGS_EQUAL((long)X(1), (long)init->keys()[0]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(2), (long)init->keys()[1]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(3), (long)init->keys()[2]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(4), (long)init->keys()[3]); | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Check new keys
 | 
					
						
							| 
									
										
										
										
											2013-08-06 21:44:22 +08:00
										 |  |  |   EXPECT_LONGS_EQUAL((long)X(5), (long)actRekey->keys()[0]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(6), (long)actRekey->keys()[1]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(7), (long)actRekey->keys()[2]); | 
					
						
							|  |  |  |   EXPECT_LONGS_EQUAL((long)X(8), (long)actRekey->keys()[3]); | 
					
						
							| 
									
										
										
										
											2012-05-22 04:54:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | int main() { TestResult tr; return TestRegistry::runAllTests(tr);} | 
					
						
							|  |  |  | /* ************************************************************************* */ |