MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2010) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file TargetMetricTest.hpp 00028 * \brief Templatized common code for testing various target metric 00029 * implementation types. 00030 * \author Jason Kraftcheck 00031 */ 00032 00033 #include "UnitUtil.hpp" 00034 #include "MsqError.hpp" 00035 #include "MsqMatrix.hpp" 00036 00037 #include "TMetric.hpp" 00038 #include "TMetricBarrier.hpp" 00039 #include "AWMetric.hpp" 00040 #include "AWMetricBarrier.hpp" 00041 00042 // NOTE: Caller must define TARGET_TEST_GROUP to be a quoted string, 00043 // typically the base file name of the file containing the 00044 // calls to TEST_METRIC_* 00045 00046 // Macro arguments: 00047 // shape_invariant 00048 // size_invariant 00049 // orient_invariant 00050 // barrier 00051 00052 #define REGISTER_BASE_TESTS \ 00053 CPPUNIT_TEST( test_ideal_eval ); \ 00054 CPPUNIT_TEST( test_ideal_gradient ); \ 00055 CPPUNIT_TEST( test_inverted ); \ 00056 CPPUNIT_TEST( test_shape ); \ 00057 CPPUNIT_TEST( test_scale ); \ 00058 CPPUNIT_TEST( test_orient ) 00059 00060 #define REGISTER_GRAD_TESTS \ 00061 CPPUNIT_TEST( compare_eval_and_eval_with_grad ); \ 00062 CPPUNIT_TEST( compare_anaytic_and_numeric_grads ) 00063 00064 #define REGISTER_HESS_TESTS \ 00065 CPPUNIT_TEST( compare_eval_with_grad_and_eval_with_hess ); \ 00066 CPPUNIT_TEST( compare_anaytic_and_numeric_hess ) 00067 00068 #define BEGIN_TEST_DECL( METRIC, DIM, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00069 class METRIC##_##DIM##DTest : public TMetricTest< METRIC, DIM > \ 00070 { \ 00071 public: \ 00072 METRIC##_##DIM##DTest() \ 00073 : TMetricTest< METRIC, DIM >( ( SHAPE_INVAR ), ( SIZE_INVAR ), ( ORIENT_INVAR ), ( BARRIER ), IDEAL ) \ 00074 { \ 00075 } \ 00076 CPPUNIT_TEST_SUITE( METRIC##_##DIM##DTest ) 00077 00078 #define END_TEST_DECL( SUITE, DIM, METRIC ) \ 00079 CPPUNIT_TEST_SUITE_END(); \ 00080 } \ 00081 ; \ 00082 CPPUNIT_NS::AutoRegisterSuite< METRIC##_##DIM##DTest > METRIC##_##DIM##D_UnitRegister( "Unit" ); \ 00083 CPPUNIT_NS::AutoRegisterSuite< METRIC##_##DIM##DTest > METRIC##_##DIM##D_FileRegister( TARGET_TEST_GROUP ); \ 00084 CPPUNIT_NS::AutoRegisterSuite< METRIC##_##DIM##DTest > METRIC##_##DIM##D_BaseRegister( #SUITE "Test" ) 00085 00086 /** Register tests for metric with no derivative implementations */ 00087 #define TEST_METRIC_NO_DERIVS_2D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00088 BEGIN_TEST_DECL( METRIC, 2, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00089 REGISTER_BASE_TESTS; \ 00090 END_TEST_DECL( METRIC, 2, METRIC ) 00091 00092 /** Register tests for metric with no derivative implementations */ 00093 #define TEST_METRIC_NO_DERIVS_3D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00094 BEGIN_TEST_DECL( METRIC, 3, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIE, IDEALR ); \ 00095 REGISTER_BASE_TESTS; \ 00096 END_TEST_DECL( METRIC, 3, METRIC ) 00097 00098 /** Register tests for metric with no derivative implementations */ 00099 #define TEST_METRIC_NO_DERIVS( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00100 TEST_METRIC_NO_DERIVS_2D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00101 TEST_METRIC_NO_DERIVS_3D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) 00102 00103 /** Register tests for metric with implementation of analytic gradient */ 00104 #define TEST_METRIC_WITH_GRAD_2D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00105 BEGIN_TEST_DECL( METRIC, 2, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00106 REGISTER_BASE_TESTS; \ 00107 REGISTER_GRAD_TESTS; \ 00108 END_TEST_DECL( METRIC, 2, METRIC ) 00109 00110 /** Register tests for metric with implementation of analytic gradient */ 00111 #define TEST_METRIC_WITH_GRAD_3D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00112 BEGIN_TEST_DECL( METRIC, 3, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00113 REGISTER_BASE_TESTS; \ 00114 REGISTER_GRAD_TESTS; \ 00115 END_TEST_DECL( METRIC, 3, METRIC ) 00116 00117 /** Register tests for metric with implementation of analytic gradient */ 00118 #define TEST_METRIC_WITH_GRAD( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00119 TEST_METRIC_WITH_GRAD_2D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00120 TEST_METRIC_WITH_GRAD_3D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) 00121 00122 #define TEST_NAMED_METRIC_WITH_HESS_2D( METRIC, NAME, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00123 BEGIN_TEST_DECL( METRIC, 2, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00124 REGISTER_BASE_TESTS; \ 00125 REGISTER_GRAD_TESTS; \ 00126 REGISTER_HESS_TESTS; \ 00127 END_TEST_DECL( NAME, 2, METRIC ) 00128 00129 #define TEST_NAMED_METRIC_WITH_HESS_3D( METRIC, NAME, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00130 BEGIN_TEST_DECL( METRIC, 3, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00131 REGISTER_BASE_TESTS; \ 00132 REGISTER_GRAD_TESTS; \ 00133 REGISTER_HESS_TESTS; \ 00134 END_TEST_DECL( NAME, 3, METRIC ) 00135 00136 /** Register tests for metric with implementation of analytic gradient and Hessian */ 00137 #define TEST_NAMED_METRIC_WITH_HESS( METRIC, NAME, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00138 TEST_NAMED_METRIC_WITH_HESS_2D( METRIC, NAME, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00139 TEST_NAMED_METRIC_WITH_HESS_3D( METRIC, NAME, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) 00140 00141 /** Register tests for metric with implementation of analytic gradient and Hessian */ 00142 #define TEST_METRIC_WITH_HESS_2D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00143 TEST_NAMED_METRIC_WITH_HESS_2D( METRIC, METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) 00144 00145 /** Register tests for metric with implementation of analytic gradient and Hessian */ 00146 #define TEST_METRIC_WITH_HESS_3D( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00147 TEST_NAMED_METRIC_WITH_HESS_3D( METRIC, METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) 00148 00149 /** Register tests for metric with implementation of analytic gradient and Hessian */ 00150 #define TEST_METRIC_WITH_HESS( METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) \ 00151 TEST_NAMED_METRIC_WITH_HESS_2D( METRIC, METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ); \ 00152 TEST_NAMED_METRIC_WITH_HESS_3D( METRIC, METRIC, SHAPE_INVAR, SIZE_INVAR, ORIENT_INVAR, BARRIER, IDEAL ) 00153 00154 #define TEST_NON_QUALITY_METRIC_WITH_HESS_2D( METRIC ) \ 00155 BEGIN_TEST_DECL( METRIC, 2, true, true, true, true, 0.0 ); \ 00156 REGISTER_GRAD_TESTS; \ 00157 REGISTER_HESS_TESTS; \ 00158 END_TEST_DECL( NAME, 2, METRIC ) 00159 00160 #define TEST_NON_QUALITY_METRIC_WITH_HESS_3D( METRIC ) \ 00161 BEGIN_TEST_DECL( METRIC, 3, true, true, true, true, 0.0 ); \ 00162 REGISTER_GRAD_TESTS; \ 00163 REGISTER_HESS_TESTS; \ 00164 END_TEST_DECL( NAME, 3, METRIC ) 00165 00166 /** Regsiter tests for a metric that doesn't really measure quality */ 00167 #define TEST_NON_QUALITY_METRIC_WITH_HESS( METRIC ) \ 00168 TEST_NON_QUALITY_METRIC_WITH_HESS_2D( METRIC ); \ 00169 TEST_NON_QUALITY_METRIC_WITH_HESS_3D( METRIC ); 00170 00171 using namespace MBMesquite; 00172 00173 const double Avals[][9] = { { 0 }, 00174 { 2 }, 00175 { 2, 1, // 2x2 values 00176 1, 2 }, 00177 { 2, 1, 1, // 3x3 values 00178 1, 2, 1, 1, 1, 2 } }; 00179 const double Bvals[][9] = { { 0 }, 00180 { -0.1 }, 00181 { -0.1, -0.15, // 2x2 values 00182 -0.25, -0.8 }, 00183 { 1.5, -0.7, -0.8, // 3x3 values 00184 0.8, -1.3, -0.7, 0.6, -0.9, -2.0 } }; 00185 const double Cvals[][9] = { { 0 }, 00186 { 0.5 }, 00187 { -1.0, 0.5, // 2x2 values 00188 0.0, 1.0 }, 00189 { 0.5, 0.0, 0.1, // 3x3 values 00190 0.5, 1.0, 0.1, 0.0, 0.0, -1.5 } }; 00191 00192 /**\brief Common tests for all target metric types 00193 * 00194 * Commont test framework for implementations of the following types: 00195 * \c TMetric , \c AWMetric 00196 */ 00197 template < class Metric, unsigned DIM > 00198 class TMetricTest : public CppUnit::TestFixture 00199 { 00200 00201 private: 00202 Metric testMetric; 00203 const double idealVal; 00204 const bool shapeInvariant, sizeInvariant, orientInvariant, Barrier; 00205 00206 public: 00207 typedef MsqMatrix< DIM, DIM > Matrix; 00208 00209 TMetricTest( bool shape_invariant, bool size_invariant, bool orient_invariant, bool barrier, double ideal_val ) 00210 : idealVal( ideal_val ), shapeInvariant( shape_invariant ), sizeInvariant( size_invariant ), 00211 orientInvariant( orient_invariant ), Barrier( barrier ), Zero( 0.0 ), I( 1.0 ), A( Avals[DIM] ), 00212 B( Bvals[DIM] ), C( Cvals[DIM] ) 00213 { 00214 } 00215 00216 // Some initial matrix values used in many tests 00217 const Matrix Zero, I, A, B, C; 00218 00219 void test_ideal_eval(); 00220 void test_ideal_gradient(); 00221 void test_inverted(); 00222 void test_shape(); 00223 void test_scale(); 00224 void test_orient(); 00225 00226 void compare_anaytic_and_numeric_grads(); 00227 void compare_anaytic_and_numeric_hess(); 00228 void compare_eval_and_eval_with_grad(); 00229 void compare_eval_with_grad_and_eval_with_hess(); 00230 00231 private: 00232 /**\brief Test if metric is or is not sensitive to difference between A and W 00233 * 00234 * Given an active matrix A and a target matrix W, test whether or 00235 * not the metric is sensitive to the difference. Fail if actual 00236 * sensitivity to difference is not equal to expected sensitivity 00237 * passed as the first argument 00238 */ 00239 void test_non_ideal( bool sensitive, Matrix A, Matrix W ); 00240 00241 /************************************************************************* 00242 * Use overloaded function names to do the stuff 00243 * that is different for different base metric types 00244 *************************************************************************/ 00245 00246 // TMetric 00247 inline bool eval( TMetric& metric, MsqMatrix< DIM, DIM > A, MsqMatrix< DIM, DIM > W, double& value, MsqError& err ) 00248 { 00249 return metric.evaluate( A * inverse( W ), value, err ); 00250 } 00251 inline bool grad( TMetric& metric, 00252 MsqMatrix< DIM, DIM > A, 00253 MsqMatrix< DIM, DIM > W, 00254 double& value, 00255 MsqMatrix< DIM, DIM >& dmdA, 00256 MsqError& err ) 00257 { 00258 bool rval = metric.evaluate_with_grad( A * inverse( W ), value, dmdA, err ); 00259 dmdA = dmdA * transpose( inverse( W ) ); 00260 return rval; 00261 } 00262 inline bool num_grad( TMetric& metric, 00263 MsqMatrix< DIM, DIM > A, 00264 MsqMatrix< DIM, DIM > W, 00265 double& value, 00266 MsqMatrix< DIM, DIM >& dmdA, 00267 MsqError& err ) 00268 { 00269 bool rval = metric.evaluate_with_grad( A * inverse( W ), value, dmdA, err ); 00270 dmdA = dmdA * transpose( inverse( W ) ); 00271 return rval; 00272 } 00273 inline bool hess( TMetric& metric, 00274 MsqMatrix< DIM, DIM > A, 00275 MsqMatrix< DIM, DIM > W, 00276 double& value, 00277 MsqMatrix< DIM, DIM >& dmdA, 00278 MsqMatrix< DIM, DIM > d2mdA2[3], 00279 MsqError& err ) 00280 { 00281 bool rval = metric.evaluate_with_hess( A * inverse( W ), value, dmdA, d2mdA2, err ); 00282 dmdA = dmdA * transpose( inverse( W ) ); 00283 for( unsigned i = 0; i < DIM * ( DIM + 1 ) / 2; ++i ) 00284 d2mdA2[i] = inverse( W ) * d2mdA2[i] * transpose( inverse( W ) ); 00285 return rval; 00286 } 00287 inline bool num_hess( TMetric& metric, 00288 MsqMatrix< DIM, DIM > A, 00289 MsqMatrix< DIM, DIM > W, 00290 double& value, 00291 MsqMatrix< DIM, DIM >& dmdA, 00292 MsqMatrix< DIM, DIM > d2mdA2[3], 00293 MsqError& err ) 00294 { 00295 bool rval = metric.evaluate_with_hess( A * inverse( W ), value, dmdA, d2mdA2, err ); 00296 dmdA = dmdA * transpose( inverse( W ) ); 00297 for( unsigned i = 0; i < DIM * ( DIM + 1 ) / 2; ++i ) 00298 d2mdA2[i] = inverse( W ) * d2mdA2[i] * transpose( inverse( W ) ); 00299 return rval; 00300 } 00301 00302 // AWMetric 00303 inline bool eval( AWMetric& metric, MsqMatrix< DIM, DIM > A, MsqMatrix< DIM, DIM > W, double& value, MsqError& err ) 00304 { 00305 bool rval = metric.evaluate( A, W, value, err ); 00306 return rval; 00307 } 00308 inline bool grad( AWMetric& metric, 00309 MsqMatrix< DIM, DIM > A, 00310 MsqMatrix< DIM, DIM > W, 00311 double& value, 00312 MsqMatrix< DIM, DIM >& dmdA, 00313 MsqError& err ) 00314 { 00315 bool rval = metric.evaluate_with_grad( A, W, value, dmdA, err ); 00316 return rval; 00317 } 00318 inline bool num_grad( AWMetric& metric, 00319 MsqMatrix< DIM, DIM > A, 00320 MsqMatrix< DIM, DIM > W, 00321 double& value, 00322 MsqMatrix< DIM, DIM >& dmdA, 00323 MsqError& err ) 00324 { 00325 bool rval = metric.evaluate_with_grad( A, W, value, dmdA, err ); 00326 return rval; 00327 } 00328 inline bool hess( AWMetric& metric, 00329 MsqMatrix< DIM, DIM > A, 00330 MsqMatrix< DIM, DIM > W, 00331 double& value, 00332 MsqMatrix< DIM, DIM >& dmdA, 00333 MsqMatrix< DIM, DIM > d2mdA2[3], 00334 MsqError& err ) 00335 { 00336 bool rval = metric.evaluate_with_hess( A, W, value, dmdA, d2mdA2, err ); 00337 return rval; 00338 } 00339 inline bool num_hess( AWMetric& metric, 00340 MsqMatrix< DIM, DIM > A, 00341 MsqMatrix< DIM, DIM > W, 00342 double& value, 00343 MsqMatrix< DIM, DIM >& dmdA, 00344 MsqMatrix< DIM, DIM > d2mdA2[3], 00345 MsqError& err ) 00346 { 00347 bool rval = metric.evaluate_with_hess( A, W, value, dmdA, d2mdA2, err ); 00348 return rval; 00349 } 00350 }; 00351 00352 #define TMETRIC_FUNC \ 00353 template < class Metric, unsigned DIM > \ 00354 void TMetricTest< Metric, DIM > 00355 #define MAT_TYPE TMetricTest< Metric, DIM >::Matrix 00356 00357 /************************************************************************* 00358 * Implement actual (templatized) test code 00359 *************************************************************************/ 00360 00361 TMETRIC_FUNC::test_ideal_eval() 00362 { 00363 MsqPrintError err( std::cerr ); 00364 double val, eps = 5e-5; 00365 bool valid; 00366 00367 valid = eval( testMetric, I, I, val, err ); 00368 ASSERT_NO_ERROR( err ); 00369 CPPUNIT_ASSERT( valid ); 00370 CPPUNIT_ASSERT_DOUBLES_EQUAL( idealVal, val, eps ); 00371 00372 valid = eval( testMetric, A, A, val, err ); 00373 ASSERT_NO_ERROR( err ); 00374 CPPUNIT_ASSERT( valid ); 00375 CPPUNIT_ASSERT_DOUBLES_EQUAL( idealVal, val, eps ); 00376 00377 valid = eval( testMetric, B, B, val, err ); 00378 ASSERT_NO_ERROR( err ); 00379 CPPUNIT_ASSERT( valid ); 00380 CPPUNIT_ASSERT_DOUBLES_EQUAL( idealVal, val, eps ); 00381 } 00382 00383 TMETRIC_FUNC::test_ideal_gradient() 00384 { 00385 MsqPrintError err( std::cerr ); 00386 MsqMatrix< DIM, DIM > g; 00387 double val, eps = 5e-3; 00388 bool valid; 00389 00390 valid = grad( testMetric, I, I, val, g, err ); 00391 ASSERT_NO_ERROR( err ); 00392 CPPUNIT_ASSERT( valid ); 00393 ASSERT_MATRICES_EQUAL( Zero, g, eps ); 00394 00395 valid = grad( testMetric, A, A, val, g, err ); 00396 ASSERT_NO_ERROR( err ); 00397 CPPUNIT_ASSERT( valid ); 00398 ASSERT_MATRICES_EQUAL( Zero, g, eps ); 00399 00400 valid = grad( testMetric, B, B, val, g, err ); 00401 ASSERT_NO_ERROR( err ); 00402 CPPUNIT_ASSERT( valid ); 00403 ASSERT_MATRICES_EQUAL( Zero, g, eps ); 00404 } 00405 00406 TMETRIC_FUNC::test_inverted() 00407 { 00408 MsqPrintError err( std::cerr ); 00409 MsqMatrix< DIM, DIM > V( 1.0 ), W( 1.0 ), g, h[6]; 00410 V( DIM - 1, DIM - 1 ) = -1.0; 00411 double val; 00412 bool valid; 00413 00414 if( Barrier ) 00415 { 00416 valid = eval( testMetric, V, W, val, err ); 00417 if( err.error_code() == err.BARRIER_VIOLATED ) err.clear(); 00418 ASSERT_NO_ERROR( err ); 00419 CPPUNIT_ASSERT( !valid ); 00420 00421 valid = grad( testMetric, V, W, val, g, err ); 00422 if( err.error_code() == err.BARRIER_VIOLATED ) err.clear(); 00423 ASSERT_NO_ERROR( err ); 00424 CPPUNIT_ASSERT( !valid ); 00425 00426 valid = hess( testMetric, V, W, val, g, h, err ); 00427 if( err.error_code() == err.BARRIER_VIOLATED ) err.clear(); 00428 ASSERT_NO_ERROR( err ); 00429 CPPUNIT_ASSERT( !valid ); 00430 } 00431 else 00432 { 00433 valid = eval( testMetric, V, W, val, err ); 00434 ASSERT_NO_ERROR( err ); 00435 CPPUNIT_ASSERT( valid ); 00436 CPPUNIT_ASSERT( val > idealVal ); 00437 00438 valid = grad( testMetric, V, W, val, g, err ); 00439 ASSERT_NO_ERROR( err ); 00440 CPPUNIT_ASSERT( valid ); 00441 CPPUNIT_ASSERT( val > idealVal ); 00442 CPPUNIT_ASSERT( sqr_Frobenius( g ) > 1e-6 ); 00443 } 00444 } 00445 00446 TMETRIC_FUNC::test_non_ideal( bool sensitive, Matrix J, Matrix W ) 00447 { 00448 MsqPrintError err( std::cerr ); 00449 MsqMatrix< DIM, DIM > g; 00450 double val, eps = 1e-5; 00451 bool valid; 00452 if( !sensitive ) 00453 { 00454 valid = eval( testMetric, J, W, val, err ); 00455 ASSERT_NO_ERROR( err ); 00456 CPPUNIT_ASSERT( valid ); 00457 CPPUNIT_ASSERT_DOUBLES_EQUAL( idealVal, val, eps ); 00458 00459 valid = grad( testMetric, J, W, val, g, err ); 00460 ASSERT_NO_ERROR( err ); 00461 CPPUNIT_ASSERT( valid ); 00462 CPPUNIT_ASSERT_DOUBLES_EQUAL( idealVal, val, eps ); 00463 ASSERT_MATRICES_EQUAL( ( MsqMatrix< DIM, DIM >( 0.0 ) ), g, eps ); 00464 } 00465 else 00466 { 00467 valid = eval( testMetric, J, W, val, err ); 00468 ASSERT_NO_ERROR( err ); 00469 CPPUNIT_ASSERT( valid ); 00470 CPPUNIT_ASSERT( val > idealVal ); 00471 } 00472 } 00473 00474 TMETRIC_FUNC::test_shape() 00475 { 00476 const double r3 = sqrt( 3.0 ); 00477 const double U_vals[][9] = { { 2 / r3, 1 / r3, 1 / r3, 2 / r3 }, 00478 { 2 / r3, 1 / r3, 0, 1 / r3, 2 / r3, 0, 0, 0, 1 } }; 00479 Matrix U( U_vals[DIM - 2] ), W( 1.0 ); 00480 test_non_ideal( !shapeInvariant, U, W ); 00481 } 00482 00483 TMETRIC_FUNC::test_scale() 00484 { 00485 Matrix L( 2.0 ), W( 1.0 ); 00486 test_non_ideal( !sizeInvariant, L, W ); 00487 } 00488 00489 TMETRIC_FUNC::test_orient() 00490 { 00491 const double V_vals[][9] = { { 0, -1, 1, 0 }, { 0, -1, 0, 1, 0, 0, 0, 0, 1 } }; 00492 Matrix V( V_vals[DIM - 2] ), W( 1.0 ); 00493 test_non_ideal( !orientInvariant, V, W ); 00494 } 00495 00496 static double releps( double a ) 00497 { 00498 return std::max( 1e-6, 1e-8 * fabs( a ) ); 00499 } 00500 00501 TMETRIC_FUNC::compare_eval_and_eval_with_grad() 00502 { 00503 MsqError err; 00504 Matrix g; 00505 bool valid; 00506 double gv, v; 00507 00508 valid = grad( testMetric, I, A, gv, g, err ); 00509 ASSERT_NO_ERROR( err ); 00510 CPPUNIT_ASSERT( valid ); 00511 valid = eval( testMetric, I, A, v, err ); 00512 ASSERT_NO_ERROR( err ); 00513 CPPUNIT_ASSERT( valid ); 00514 CPPUNIT_ASSERT_DOUBLES_EQUAL( v, gv, releps( v ) ); 00515 00516 valid = grad( testMetric, A, B, gv, g, err ); 00517 ASSERT_NO_ERROR( err ); 00518 CPPUNIT_ASSERT( valid ); 00519 valid = eval( testMetric, A, B, v, err ); 00520 ASSERT_NO_ERROR( err ); 00521 CPPUNIT_ASSERT( valid ); 00522 CPPUNIT_ASSERT_DOUBLES_EQUAL( v, gv, releps( v ) ); 00523 00524 // also test inverted for non-barrier metrics 00525 if( Barrier ) return; 00526 00527 valid = grad( testMetric, C, I, gv, g, err ); 00528 ASSERT_NO_ERROR( err ); 00529 CPPUNIT_ASSERT( valid ); 00530 valid = eval( testMetric, C, I, v, err ); 00531 ASSERT_NO_ERROR( err ); 00532 CPPUNIT_ASSERT( valid ); 00533 CPPUNIT_ASSERT_DOUBLES_EQUAL( v, gv, releps( v ) ); 00534 } 00535 00536 TMETRIC_FUNC::compare_eval_with_grad_and_eval_with_hess() 00537 { 00538 MsqError err; 00539 Matrix g, h, H[DIM * ( DIM + 1 ) / 2]; 00540 bool valid; 00541 double gv, hv; 00542 00543 valid = grad( testMetric, I, A, gv, g, err ); 00544 ASSERT_NO_ERROR( err ); 00545 CPPUNIT_ASSERT( valid ); 00546 valid = hess( testMetric, I, A, hv, h, H, err ); 00547 ASSERT_NO_ERROR( err ); 00548 CPPUNIT_ASSERT( valid ); 00549 CPPUNIT_ASSERT_DOUBLES_EQUAL( gv, hv, releps( gv ) ); 00550 ASSERT_MATRICES_EQUAL( g, h, 1e-5 ); 00551 00552 valid = grad( testMetric, A, B, gv, g, err ); 00553 ASSERT_NO_ERROR( err ); 00554 CPPUNIT_ASSERT( valid ); 00555 valid = hess( testMetric, A, B, hv, h, H, err ); 00556 ASSERT_NO_ERROR( err ); 00557 CPPUNIT_ASSERT( valid ); 00558 CPPUNIT_ASSERT_DOUBLES_EQUAL( gv, hv, releps( gv ) ); 00559 ASSERT_MATRICES_EQUAL( g, h, 1e-5 ); 00560 00561 // also test inverted for non-barrier metrics 00562 if( Barrier ) return; 00563 00564 valid = grad( testMetric, C, I, gv, g, err ); 00565 ASSERT_NO_ERROR( err ); 00566 CPPUNIT_ASSERT( valid ); 00567 valid = hess( testMetric, C, I, hv, h, H, err ); 00568 ASSERT_NO_ERROR( err ); 00569 CPPUNIT_ASSERT( valid ); 00570 CPPUNIT_ASSERT_DOUBLES_EQUAL( gv, hv, releps( gv ) ); 00571 ASSERT_MATRICES_EQUAL( g, h, 1e-5 ); 00572 } 00573 00574 template < typename M > 00575 double eps_mat( const M& mu ) 00576 { 00577 return std::max( Frobenius( mu ) * 1e-2, 1e-4 ); 00578 } 00579 00580 TMETRIC_FUNC::compare_anaytic_and_numeric_grads() 00581 { 00582 const double EPS_VAL = 1e-6; 00583 00584 MsqError err; 00585 Matrix num, ana; 00586 bool valid; 00587 double nval, aval; 00588 00589 Matrix D( I ); 00590 D( 0, 0 ) += 1e-5; 00591 valid = num_grad( testMetric, D, I, nval, num, err ); 00592 ASSERT_NO_ERROR( err ); 00593 CPPUNIT_ASSERT( valid ); 00594 valid = grad( testMetric, D, I, aval, ana, err ); 00595 ASSERT_NO_ERROR( err ); 00596 CPPUNIT_ASSERT( valid ); 00597 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00598 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00599 00600 valid = num_grad( testMetric, I, A, nval, num, err ); 00601 ASSERT_NO_ERROR( err ); 00602 CPPUNIT_ASSERT( valid ); 00603 valid = grad( testMetric, I, A, aval, ana, err ); 00604 ASSERT_NO_ERROR( err ); 00605 CPPUNIT_ASSERT( valid ); 00606 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00607 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00608 00609 valid = num_grad( testMetric, A, I, nval, num, err ); 00610 ASSERT_NO_ERROR( err ); 00611 CPPUNIT_ASSERT( valid ); 00612 valid = grad( testMetric, A, I, aval, ana, err ); 00613 ASSERT_NO_ERROR( err ); 00614 CPPUNIT_ASSERT( valid ); 00615 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00616 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00617 00618 valid = num_grad( testMetric, I, B, nval, num, err ); 00619 ASSERT_NO_ERROR( err ); 00620 CPPUNIT_ASSERT( valid ); 00621 valid = grad( testMetric, I, B, aval, ana, err ); 00622 ASSERT_NO_ERROR( err ); 00623 CPPUNIT_ASSERT( valid ); 00624 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00625 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00626 00627 valid = num_grad( testMetric, B, I, nval, num, err ); 00628 ASSERT_NO_ERROR( err ); 00629 CPPUNIT_ASSERT( valid ); 00630 valid = grad( testMetric, B, I, aval, ana, err ); 00631 ASSERT_NO_ERROR( err ); 00632 CPPUNIT_ASSERT( valid ); 00633 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00634 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00635 00636 valid = num_grad( testMetric, A, B, nval, num, err ); 00637 ASSERT_NO_ERROR( err ); 00638 CPPUNIT_ASSERT( valid ); 00639 valid = grad( testMetric, A, B, aval, ana, err ); 00640 ASSERT_NO_ERROR( err ); 00641 CPPUNIT_ASSERT( valid ); 00642 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00643 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00644 00645 valid = num_grad( testMetric, A, I, nval, num, err ); 00646 ASSERT_NO_ERROR( err ); 00647 CPPUNIT_ASSERT( valid ); 00648 valid = grad( testMetric, A, I, aval, ana, err ); 00649 ASSERT_NO_ERROR( err ); 00650 CPPUNIT_ASSERT( valid ); 00651 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00652 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00653 00654 // also test inverted for non-barrier metrics 00655 if( Barrier ) return; 00656 00657 valid = num_grad( testMetric, C, I, nval, num, err ); 00658 ASSERT_NO_ERROR( err ); 00659 CPPUNIT_ASSERT( valid ); 00660 valid = grad( testMetric, C, I, aval, ana, err ); 00661 ASSERT_NO_ERROR( err ); 00662 CPPUNIT_ASSERT( valid ); 00663 CPPUNIT_ASSERT_DOUBLES_EQUAL( nval, aval, EPS_VAL ); 00664 ASSERT_MATRICES_EQUAL( num, ana, eps_mat( num ) ); 00665 } 00666 00667 TMETRIC_FUNC::compare_anaytic_and_numeric_hess() 00668 { 00669 const double EPS_VAL = 1e-6; 00670 00671 MsqError err; 00672 Matrix dmdA_num, dmdA_ana, d2mdA2_num[DIM * ( DIM + 1 ) / 2], d2mdA2_ana[DIM * ( DIM + 1 ) / 2]; 00673 bool valid; 00674 double val_num, val_ana; 00675 00676 valid = num_hess( testMetric, I, I, val_num, dmdA_num, d2mdA2_num, err ); 00677 ASSERT_NO_ERROR( err ); 00678 CPPUNIT_ASSERT( valid ); 00679 valid = hess( testMetric, I, I, val_ana, dmdA_ana, d2mdA2_ana, err ); 00680 ASSERT_NO_ERROR( err ); 00681 CPPUNIT_ASSERT( valid ); 00682 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00683 ASSERT_MATRICES_EQUAL( dmdA_num, dmdA_ana, eps_mat( dmdA_num ) ); 00684 00685 switch( DIM ) 00686 { 00687 default: 00688 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00689 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00690 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00691 case 2: 00692 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00693 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00694 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00695 } 00696 00697 valid = num_hess( testMetric, I, A, val_num, dmdA_num, d2mdA2_num, err ); 00698 ASSERT_NO_ERROR( err ); 00699 CPPUNIT_ASSERT( valid ); 00700 valid = hess( testMetric, I, A, val_ana, dmdA_ana, d2mdA2_ana, err ); 00701 ASSERT_NO_ERROR( err ); 00702 CPPUNIT_ASSERT( valid ); 00703 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00704 ASSERT_MATRICES_EQUAL( dmdA_num, dmdA_ana, eps_mat( dmdA_num ) ); 00705 switch( DIM ) 00706 { 00707 default: 00708 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00709 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00710 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00711 case 2: 00712 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00713 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00714 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00715 } 00716 00717 valid = num_hess( testMetric, A, I, val_num, dmdA_num, d2mdA2_num, err ); 00718 ASSERT_NO_ERROR( err ); 00719 CPPUNIT_ASSERT( valid ); 00720 valid = hess( testMetric, A, I, val_ana, dmdA_ana, d2mdA2_ana, err ); 00721 ASSERT_NO_ERROR( err ); 00722 CPPUNIT_ASSERT( valid ); 00723 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00724 ASSERT_MATRICES_EQUAL( dmdA_num, dmdA_ana, eps_mat( dmdA_num ) ); 00725 switch( DIM ) 00726 { 00727 default: 00728 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00729 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00730 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00731 case 2: 00732 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00733 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00734 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00735 } 00736 00737 valid = num_hess( testMetric, B, I, val_num, dmdA_num, d2mdA2_num, err ); 00738 ASSERT_NO_ERROR( err ); 00739 CPPUNIT_ASSERT( valid ); 00740 valid = hess( testMetric, B, I, val_ana, dmdA_ana, d2mdA2_ana, err ); 00741 ASSERT_NO_ERROR( err ); 00742 CPPUNIT_ASSERT( valid ); 00743 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00744 ASSERT_MATRICES_EQUAL( dmdA_num, dmdA_ana, eps_mat( dmdA_num ) ); 00745 switch( DIM ) 00746 { 00747 default: 00748 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00749 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00750 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00751 case 2: 00752 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00753 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00754 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00755 } 00756 00757 valid = num_hess( testMetric, I, B, val_num, dmdA_num, d2mdA2_num, err ); 00758 ASSERT_NO_ERROR( err ); 00759 CPPUNIT_ASSERT( valid ); 00760 valid = hess( testMetric, I, B, val_ana, dmdA_ana, d2mdA2_ana, err ); 00761 ASSERT_NO_ERROR( err ); 00762 CPPUNIT_ASSERT( valid ); 00763 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00764 ASSERT_MATRICES_EQUAL( dmdA_num, dmdA_ana, eps_mat( dmdA_num ) ); 00765 switch( DIM ) 00766 { 00767 default: 00768 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00769 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00770 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00771 case 2: 00772 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00773 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00774 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00775 } 00776 00777 valid = num_hess( testMetric, A, B, val_num, dmdA_num, d2mdA2_num, err ); 00778 ASSERT_NO_ERROR( err ); 00779 CPPUNIT_ASSERT( valid ); 00780 valid = hess( testMetric, A, B, val_ana, dmdA_ana, d2mdA2_ana, err ); 00781 ASSERT_NO_ERROR( err ); 00782 CPPUNIT_ASSERT( valid ); 00783 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00784 ASSERT_MATRICES_EQUAL( dmdA_num, dmdA_ana, eps_mat( dmdA_num ) ); 00785 switch( DIM ) 00786 { 00787 default: 00788 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00789 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00790 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00791 case 2: 00792 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00793 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00794 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00795 } 00796 00797 valid = num_hess( testMetric, B, A, val_num, dmdA_num, d2mdA2_num, err ); 00798 ASSERT_NO_ERROR( err ); 00799 CPPUNIT_ASSERT( valid ); 00800 valid = hess( testMetric, B, A, val_ana, dmdA_ana, d2mdA2_ana, err ); 00801 ASSERT_NO_ERROR( err ); 00802 CPPUNIT_ASSERT( valid ); 00803 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00804 ASSERT_MATRICES_EQUAL( dmdA_num, dmdA_ana, eps_mat( dmdA_num ) ); 00805 switch( DIM ) 00806 { 00807 default: 00808 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00809 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00810 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00811 case 2: 00812 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00813 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00814 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00815 } 00816 00817 // also test inverted for non-barrier metrics 00818 if( Barrier ) return; 00819 00820 valid = num_hess( testMetric, C, I, val_num, dmdA_num, d2mdA2_num, err ); 00821 ASSERT_NO_ERROR( err ); 00822 CPPUNIT_ASSERT( valid ); 00823 valid = hess( testMetric, C, I, val_ana, dmdA_ana, d2mdA2_ana, err ); 00824 ASSERT_NO_ERROR( err ); 00825 CPPUNIT_ASSERT( valid ); 00826 CPPUNIT_ASSERT_DOUBLES_EQUAL( val_num, val_ana, EPS_VAL ); 00827 switch( DIM ) 00828 { 00829 default: 00830 ASSERT_MATRICES_EQUAL( d2mdA2_num[3], d2mdA2_ana[3], eps_mat( d2mdA2_num[3] ) ); 00831 ASSERT_MATRICES_EQUAL( d2mdA2_num[4], d2mdA2_ana[4], eps_mat( d2mdA2_num[4] ) ); 00832 ASSERT_MATRICES_EQUAL( d2mdA2_num[5], d2mdA2_ana[5], eps_mat( d2mdA2_num[5] ) ); 00833 case 2: 00834 ASSERT_MATRICES_EQUAL( d2mdA2_num[0], d2mdA2_ana[0], eps_mat( d2mdA2_num[0] ) ); 00835 ASSERT_MATRICES_EQUAL( d2mdA2_num[1], d2mdA2_ana[1], eps_mat( d2mdA2_num[1] ) ); 00836 ASSERT_MATRICES_EQUAL( d2mdA2_num[2], d2mdA2_ana[2], eps_mat( d2mdA2_num[2] ) ); 00837 } 00838 }