MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2008 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 AWMetricTest.cpp 00028 * \brief Unit tests AWMetric base class functionality 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "AWMetric.hpp" 00034 #include "UnitUtil.hpp" 00035 #include "MsqError.hpp" 00036 00037 using namespace MBMesquite; 00038 00039 // Test functions implemented in class AWMetric 00040 class AWMetricTest : public CppUnit::TestFixture 00041 { 00042 CPPUNIT_TEST_SUITE( AWMetricTest ); 00043 CPPUNIT_TEST( test_numerical_gradient_2D ); 00044 CPPUNIT_TEST( test_numerical_hessian_2D ); 00045 CPPUNIT_TEST( test_numerical_gradient_3D ); 00046 CPPUNIT_TEST( test_numerical_hessian_3D ); 00047 CPPUNIT_TEST_SUITE_END(); 00048 00049 public: 00050 void test_numerical_gradient_2D(); 00051 void test_numerical_hessian_2D(); 00052 void test_numerical_gradient_3D(); 00053 void test_numerical_hessian_3D(); 00054 }; 00055 00056 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AWMetricTest, "Unit" ); 00057 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AWMetricTest, "AWMetricTest" ); 00058 00059 // implement metric such that the expected derivatives 00060 // at each location r,c in dm/dA are 3r+c+1 00061 class GradTestMetricAbs : public AWMetric 00062 { 00063 public: 00064 std::string get_name() const 00065 { 00066 return "GradTest"; 00067 } 00068 00069 static double grad( int r, int c ) 00070 { 00071 return 3 * r + c + 1; 00072 } 00073 00074 bool evaluate( const MsqMatrix< 2, 2 >& A, const MsqMatrix< 2, 2 >& W, double& result, MsqError& ) 00075 { 00076 result = 0; 00077 for( int r = 0; r < 2; ++r ) 00078 for( int c = 0; c < 2; ++c ) 00079 result += grad( r, c ) * ( A( r, c ) - W( r, c ) ); 00080 return true; 00081 } 00082 00083 bool evaluate( const MsqMatrix< 3, 3 >& A, const MsqMatrix< 3, 3 >& W, double& result, MsqError& ) 00084 { 00085 result = 0; 00086 for( int r = 0; r < 3; ++r ) 00087 for( int c = 0; c < 3; ++c ) 00088 result += grad( r, c ) * ( A( r, c ) - W( r, c ) ); 00089 return true; 00090 } 00091 }; 00092 00093 // implement metric that is the |2A - A^T - W|^2 00094 // such that the Hessian is the constant: 00095 // _ _ 00096 // | 2 0 0 0 | 00097 // | 0 10 -8 0 | 00098 // | 0 -8 10 0 | 00099 // |_0 0 0 2_| 00100 // _ _ 00101 // | 2 0 0 0 0 0 0 0 0 | 00102 // | 0 10 0 -8 0 0 0 0 0 | 00103 // | 0 0 10 0 0 0 -8 0 0 | 00104 // | 0 -8 0 10 0 0 0 0 0 | 00105 // | 0 0 0 0 2 0 0 0 0 | 00106 // | 0 0 0 0 0 10 0 -8 0 | 00107 // | 0 0 -8 0 0 0 10 0 0 | 00108 // | 0 0 0 0 0 -8 0 10 0 | 00109 // |_0 0 0 0 0 0 0 0 2_| 00110 class HessTestMetricAbs : public AWMetric 00111 { 00112 public: 00113 std::string get_name() const 00114 { 00115 return "HessTest"; 00116 } 00117 00118 bool evaluate( const MsqMatrix< 2, 2 >& A, const MsqMatrix< 2, 2 >& W, double& result, MsqError& ) 00119 { 00120 result = sqr_Frobenius( 2 * A - transpose( A ) - W ); 00121 return true; 00122 } 00123 bool evaluate_with_grad( const MsqMatrix< 2, 2 >& A, 00124 const MsqMatrix< 2, 2 >& W, 00125 double& result, 00126 MsqMatrix< 2, 2 >& wrt_A, 00127 MsqError& ) 00128 { 00129 result = sqr_Frobenius( 2 * A - transpose( A ) - W ); 00130 wrt_A = 10 * A - 8 * transpose( A ) - 4 * W + 2 * transpose( W ); 00131 return true; 00132 } 00133 00134 bool evaluate( const MsqMatrix< 3, 3 >& A, const MsqMatrix< 3, 3 >& W, double& result, MsqError& ) 00135 { 00136 result = sqr_Frobenius( 2 * A - transpose( A ) - W ); 00137 return true; 00138 } 00139 bool evaluate_with_grad( const MsqMatrix< 3, 3 >& A, 00140 const MsqMatrix< 3, 3 >& W, 00141 double& result, 00142 MsqMatrix< 3, 3 >& wrt_A, 00143 MsqError& ) 00144 { 00145 result = sqr_Frobenius( 2 * A - transpose( A ) - W ); 00146 wrt_A = 10 * A - 8 * transpose( A ) - 4 * W + 2 * transpose( W ); 00147 return true; 00148 } 00149 }; 00150 00151 /** Simple target metric for testing second partial derivatives. 00152 * \f$\mu(T) = |T|\f$ 00153 * \f$\frac{\partial\mu}{\partial T} = \frac{1}{|T|} T \f$ 00154 * \f$\frac{\partial^{2}\mu}{\partial t_{i,i}^2} = \frac{1}{|T|} - \frac{t_{i,i}^2}{|T|^3}\f$ 00155 * \f$\frac{\partial^{2}\mu}{\partial t_{i,j} \partial t_{k,l} (i \ne k or j \ne l)} = 00156 * -\frac{t_{i,j} a_{k,l}}{|T|^3}\f$ 00157 */ 00158 /** Simple target metric for testing second partial derivatives. 00159 * \f$\mu(A,W) = |A|\f$ 00160 * \f$\frac{\partial\mu}{\partial A} = \frac{1}{|A|} A \f$ 00161 * \f$\frac{\partial^{2}\mu}{\partial a_{i,i}^2} = \frac{1}{|A|} - \frac{a_{i,i}^2}{|A|^3}\f$ 00162 * \f$\frac{\partial^{2}\mu}{\partial a_{i,j} \partial a_{k,l} (i \ne k or j \ne l)} = 00163 * -\frac{a_{i,j} a_{k,l}}{|A|^3}\f$ 00164 */ 00165 class HessTestMetricAbs_2 : public AWMetric 00166 { 00167 public: 00168 std::string get_name() const 00169 { 00170 return "HessTest2"; 00171 } 00172 00173 bool evaluate( const MsqMatrix< 2, 2 >& A, const MsqMatrix< 2, 2 >&, double& result, MsqError& err ) 00174 { 00175 result = Frobenius( A ); 00176 return true; 00177 } 00178 00179 bool evaluate_with_grad( const MsqMatrix< 2, 2 >& A, 00180 const MsqMatrix< 2, 2 >&, 00181 double& result, 00182 MsqMatrix< 2, 2 >& d, 00183 MsqError& err ) 00184 { 00185 result = Frobenius( A ); 00186 d = A / result; 00187 return true; 00188 } 00189 00190 bool evaluate_with_hess( const MsqMatrix< 2, 2 >& A, 00191 const MsqMatrix< 2, 2 >&, 00192 double& result, 00193 MsqMatrix< 2, 2 >& d, 00194 MsqMatrix< 2, 2 > d2[3], 00195 MsqError& err ) 00196 { 00197 result = Frobenius( A ); 00198 d = A / result; 00199 int h = 0; 00200 for( int r = 0; r < 2; ++r ) 00201 { 00202 int i = h; 00203 for( int c = r; c < 2; ++c ) 00204 d2[h++] = transpose( A.row( r ) ) * A.row( c ) / -( result * result * result ); 00205 d2[i] += MsqMatrix< 2, 2 >( 1.0 / result ); 00206 } 00207 return true; 00208 } 00209 00210 bool evaluate( const MsqMatrix< 3, 3 >& A, const MsqMatrix< 3, 3 >&, double& result, MsqError& err ) 00211 { 00212 result = Frobenius( A ); 00213 return true; 00214 } 00215 00216 bool evaluate_with_grad( const MsqMatrix< 3, 3 >& A, 00217 const MsqMatrix< 3, 3 >&, 00218 double& result, 00219 MsqMatrix< 3, 3 >& d, 00220 MsqError& err ) 00221 { 00222 result = Frobenius( A ); 00223 d = A / result; 00224 return true; 00225 } 00226 00227 bool evaluate_with_hess( const MsqMatrix< 3, 3 >& A, 00228 const MsqMatrix< 3, 3 >&, 00229 double& result, 00230 MsqMatrix< 3, 3 >& d, 00231 MsqMatrix< 3, 3 > d2[6], 00232 MsqError& err ) 00233 { 00234 result = Frobenius( A ); 00235 d = A / result; 00236 int h = 0; 00237 for( int r = 0; r < 3; ++r ) 00238 { 00239 int i = h; 00240 for( int c = r; c < 3; ++c ) 00241 d2[h++] = transpose( A.row( r ) ) * A.row( c ) / -( result * result * result ); 00242 d2[i] += MsqMatrix< 3, 3 >( 1.0 / result ); 00243 } 00244 return true; 00245 } 00246 }; 00247 00248 void AWMetricTest::test_numerical_gradient_2D() 00249 { 00250 GradTestMetricAbs metric; 00251 HessTestMetricAbs_2 metric2; 00252 const double Avals[] = { 1, 2, 2, 5 }; 00253 const double Bvals[] = { -0.1, -0.15, -0.25, -0.8 }; 00254 const MsqMatrix< 2, 2 > I( 1.0 ); 00255 const MsqMatrix< 2, 2 > A( Avals ); 00256 const MsqMatrix< 2, 2 > B( Bvals ); 00257 00258 MsqError err; 00259 MsqMatrix< 2, 2 > d; 00260 bool valid; 00261 double val, gval; 00262 00263 MsqMatrix< 2, 2 > expected; 00264 for( int r = 0; r < 2; ++r ) 00265 for( int c = 0; c < 2; ++c ) 00266 expected( r, c ) = metric.grad( r, c ); 00267 00268 valid = metric.evaluate( I, A, val, err ); 00269 ASSERT_NO_ERROR( err ); 00270 CPPUNIT_ASSERT( valid ); 00271 valid = metric.evaluate_with_grad( I, A, gval, d, err ); 00272 ASSERT_NO_ERROR( err ); 00273 CPPUNIT_ASSERT( valid ); 00274 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00275 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00276 00277 valid = metric.evaluate( A, I, val, err ); 00278 ASSERT_NO_ERROR( err ); 00279 CPPUNIT_ASSERT( valid ); 00280 valid = metric.evaluate_with_grad( A, I, gval, d, err ); 00281 ASSERT_NO_ERROR( err ); 00282 CPPUNIT_ASSERT( valid ); 00283 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00284 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00285 00286 valid = metric.evaluate( I, B, val, err ); 00287 ASSERT_NO_ERROR( err ); 00288 CPPUNIT_ASSERT( valid ); 00289 valid = metric.evaluate_with_grad( I, B, gval, d, err ); 00290 ASSERT_NO_ERROR( err ); 00291 CPPUNIT_ASSERT( valid ); 00292 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00293 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00294 00295 valid = metric.evaluate( B, I, val, err ); 00296 ASSERT_NO_ERROR( err ); 00297 CPPUNIT_ASSERT( valid ); 00298 valid = metric.evaluate_with_grad( B, I, gval, d, err ); 00299 ASSERT_NO_ERROR( err ); 00300 CPPUNIT_ASSERT( valid ); 00301 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00302 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00303 00304 valid = metric.evaluate( A, B, val, err ); 00305 ASSERT_NO_ERROR( err ); 00306 CPPUNIT_ASSERT( valid ); 00307 valid = metric.evaluate_with_grad( A, B, gval, d, err ); 00308 ASSERT_NO_ERROR( err ); 00309 CPPUNIT_ASSERT( valid ); 00310 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00311 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00312 00313 valid = metric.evaluate( B, A, val, err ); 00314 ASSERT_NO_ERROR( err ); 00315 CPPUNIT_ASSERT( valid ); 00316 valid = metric.evaluate_with_grad( B, A, gval, d, err ); 00317 ASSERT_NO_ERROR( err ); 00318 CPPUNIT_ASSERT( valid ); 00319 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00320 00321 MsqMatrix< 2, 2 > da; 00322 valid = metric2.evaluate_with_grad( A, I, val, da, err ); 00323 ASSERT_NO_ERROR( err ); 00324 CPPUNIT_ASSERT( valid ); 00325 valid = metric2.AWMetric::evaluate_with_grad( A, I, gval, d, err ); 00326 ASSERT_NO_ERROR( err ); 00327 CPPUNIT_ASSERT( valid ); 00328 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00329 ASSERT_MATRICES_EQUAL( da, d, 1e-6 ); 00330 00331 valid = metric2.evaluate_with_grad( B, I, val, da, err ); 00332 ASSERT_NO_ERROR( err ); 00333 CPPUNIT_ASSERT( valid ); 00334 valid = metric2.AWMetric::evaluate_with_grad( B, I, gval, d, err ); 00335 ASSERT_NO_ERROR( err ); 00336 CPPUNIT_ASSERT( valid ); 00337 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00338 ASSERT_MATRICES_EQUAL( da, d, 1e-6 ); 00339 } 00340 00341 void AWMetricTest::test_numerical_gradient_3D() 00342 { 00343 GradTestMetricAbs metric; 00344 HessTestMetricAbs_2 metric2; 00345 const double Avals[] = { 1, 2, 3, 4, 1, 4, 3, 2, 1 }; 00346 const double Bvals[] = { 0.1, 0.15, 0.05, 0.2, -0.1, -0.15, -0.05, -0.2, 2 }; 00347 const MsqMatrix< 3, 3 > I( 1.0 ); 00348 const MsqMatrix< 3, 3 > A( Avals ); 00349 const MsqMatrix< 3, 3 > B( Bvals ); 00350 00351 MsqError err; 00352 MsqMatrix< 3, 3 > d; 00353 bool valid; 00354 double val, gval; 00355 00356 MsqMatrix< 3, 3 > expected; 00357 for( int r = 0; r < 3; ++r ) 00358 for( int c = 0; c < 3; ++c ) 00359 expected( r, c ) = metric.grad( r, c ); 00360 00361 valid = metric.evaluate( I, A, val, err ); 00362 ASSERT_NO_ERROR( err ); 00363 CPPUNIT_ASSERT( valid ); 00364 valid = metric.evaluate_with_grad( I, A, gval, d, err ); 00365 ASSERT_NO_ERROR( err ); 00366 CPPUNIT_ASSERT( valid ); 00367 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00368 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00369 00370 valid = metric.evaluate( A, I, val, err ); 00371 ASSERT_NO_ERROR( err ); 00372 CPPUNIT_ASSERT( valid ); 00373 valid = metric.evaluate_with_grad( A, I, gval, d, err ); 00374 ASSERT_NO_ERROR( err ); 00375 CPPUNIT_ASSERT( valid ); 00376 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00377 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00378 00379 valid = metric.evaluate( I, B, val, err ); 00380 ASSERT_NO_ERROR( err ); 00381 CPPUNIT_ASSERT( valid ); 00382 valid = metric.evaluate_with_grad( I, B, gval, d, err ); 00383 ASSERT_NO_ERROR( err ); 00384 CPPUNIT_ASSERT( valid ); 00385 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00386 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00387 00388 valid = metric.evaluate( B, I, val, err ); 00389 ASSERT_NO_ERROR( err ); 00390 CPPUNIT_ASSERT( valid ); 00391 valid = metric.evaluate_with_grad( B, I, gval, d, err ); 00392 ASSERT_NO_ERROR( err ); 00393 CPPUNIT_ASSERT( valid ); 00394 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00395 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00396 00397 valid = metric.evaluate( A, B, val, err ); 00398 ASSERT_NO_ERROR( err ); 00399 CPPUNIT_ASSERT( valid ); 00400 valid = metric.evaluate_with_grad( A, B, gval, d, err ); 00401 ASSERT_NO_ERROR( err ); 00402 CPPUNIT_ASSERT( valid ); 00403 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00404 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00405 00406 valid = metric.evaluate( B, A, val, err ); 00407 ASSERT_NO_ERROR( err ); 00408 CPPUNIT_ASSERT( valid ); 00409 valid = metric.evaluate_with_grad( B, A, gval, d, err ); 00410 ASSERT_NO_ERROR( err ); 00411 CPPUNIT_ASSERT( valid ); 00412 ASSERT_MATRICES_EQUAL( expected, d, 1e-6 ); 00413 00414 MsqMatrix< 3, 3 > da; 00415 valid = metric2.evaluate_with_grad( A, I, val, da, err ); 00416 ASSERT_NO_ERROR( err ); 00417 CPPUNIT_ASSERT( valid ); 00418 valid = metric2.AWMetric::evaluate_with_grad( A, I, gval, d, err ); 00419 ASSERT_NO_ERROR( err ); 00420 CPPUNIT_ASSERT( valid ); 00421 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00422 ASSERT_MATRICES_EQUAL( da, d, 1e-6 ); 00423 00424 valid = metric2.evaluate_with_grad( B, I, val, da, err ); 00425 ASSERT_NO_ERROR( err ); 00426 CPPUNIT_ASSERT( valid ); 00427 valid = metric2.AWMetric::evaluate_with_grad( B, I, gval, d, err ); 00428 ASSERT_NO_ERROR( err ); 00429 CPPUNIT_ASSERT( valid ); 00430 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, gval, 1e-6 ); 00431 ASSERT_MATRICES_EQUAL( da, d, 1e-6 ); 00432 } 00433 00434 void AWMetricTest::test_numerical_hessian_2D() 00435 { 00436 HessTestMetricAbs metric; 00437 HessTestMetricAbs_2 metric2; 00438 const double Avals[] = { 1, 2, 2, 5 }; 00439 const double Bvals[] = { -0.1, -0.15, -0.25, -0.8 }; 00440 const MsqMatrix< 2, 2 > I( 1.0 ); 00441 const MsqMatrix< 2, 2 > A( Avals ); 00442 const MsqMatrix< 2, 2 > B( Bvals ); 00443 00444 MsqError err; 00445 MsqMatrix< 2, 2 > g, gh; 00446 MsqMatrix< 2, 2 > h[6]; 00447 bool valid; 00448 double val, hval; 00449 00450 const double h_00[] = { 2, 0, 0, 10 }; 00451 const double h_01[] = { 0, 0, -8, 0 }; 00452 const double h_11[] = { 10, 0, 0, 2 }; 00453 MsqMatrix< 2, 2 > h00( h_00 ), h01( h_01 ), h11( h_11 ); 00454 00455 valid = metric.evaluate_with_grad( I, A, val, g, err ); 00456 ASSERT_NO_ERROR( err ); 00457 CPPUNIT_ASSERT( valid ); 00458 valid = metric.evaluate_with_hess( I, A, hval, gh, h, err ); 00459 ASSERT_NO_ERROR( err ); 00460 CPPUNIT_ASSERT( valid ); 00461 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00462 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00463 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00464 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00465 ASSERT_MATRICES_EQUAL( h11, h[2], 1e-6 ); 00466 00467 valid = metric.evaluate_with_grad( A, I, val, g, err ); 00468 ASSERT_NO_ERROR( err ); 00469 CPPUNIT_ASSERT( valid ); 00470 valid = metric.evaluate_with_hess( A, I, hval, gh, h, err ); 00471 ASSERT_NO_ERROR( err ); 00472 CPPUNIT_ASSERT( valid ); 00473 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00474 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00475 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00476 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00477 ASSERT_MATRICES_EQUAL( h11, h[2], 1e-6 ); 00478 00479 valid = metric.evaluate_with_grad( I, B, val, g, err ); 00480 ASSERT_NO_ERROR( err ); 00481 CPPUNIT_ASSERT( valid ); 00482 valid = metric.evaluate_with_hess( I, B, hval, gh, h, err ); 00483 ASSERT_NO_ERROR( err ); 00484 CPPUNIT_ASSERT( valid ); 00485 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00486 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00487 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00488 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00489 ASSERT_MATRICES_EQUAL( h11, h[2], 1e-6 ); 00490 00491 valid = metric.evaluate_with_grad( B, I, val, g, err ); 00492 ASSERT_NO_ERROR( err ); 00493 CPPUNIT_ASSERT( valid ); 00494 valid = metric.evaluate_with_hess( B, I, hval, gh, h, err ); 00495 ASSERT_NO_ERROR( err ); 00496 CPPUNIT_ASSERT( valid ); 00497 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00498 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00499 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00500 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00501 ASSERT_MATRICES_EQUAL( h11, h[2], 1e-6 ); 00502 00503 valid = metric.evaluate_with_grad( A, B, val, g, err ); 00504 ASSERT_NO_ERROR( err ); 00505 CPPUNIT_ASSERT( valid ); 00506 valid = metric.evaluate_with_hess( A, B, hval, gh, h, err ); 00507 ASSERT_NO_ERROR( err ); 00508 CPPUNIT_ASSERT( valid ); 00509 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00510 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00511 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00512 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00513 ASSERT_MATRICES_EQUAL( h11, h[2], 1e-6 ); 00514 00515 valid = metric.evaluate_with_grad( B, A, val, g, err ); 00516 ASSERT_NO_ERROR( err ); 00517 CPPUNIT_ASSERT( valid ); 00518 valid = metric.evaluate_with_hess( B, A, hval, gh, h, err ); 00519 ASSERT_NO_ERROR( err ); 00520 CPPUNIT_ASSERT( valid ); 00521 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00522 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00523 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00524 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00525 ASSERT_MATRICES_EQUAL( h11, h[2], 1e-6 ); 00526 00527 MsqMatrix< 2, 2 > ah[6]; 00528 valid = metric2.evaluate_with_hess( A, I, val, g, ah, err ); 00529 ASSERT_NO_ERROR( err ); 00530 CPPUNIT_ASSERT( valid ); 00531 valid = metric2.AWMetric::evaluate_with_hess( A, I, hval, gh, h, err ); 00532 ASSERT_NO_ERROR( err ); 00533 CPPUNIT_ASSERT( valid ); 00534 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00535 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00536 ASSERT_MATRICES_EQUAL( ah[0], h[0], 1e-6 ); 00537 ASSERT_MATRICES_EQUAL( ah[1], h[1], 1e-6 ); 00538 ASSERT_MATRICES_EQUAL( ah[2], h[2], 1e-6 ); 00539 00540 valid = metric2.evaluate_with_hess( B, I, val, g, ah, err ); 00541 ASSERT_NO_ERROR( err ); 00542 CPPUNIT_ASSERT( valid ); 00543 valid = metric2.AWMetric::evaluate_with_hess( B, I, hval, gh, h, err ); 00544 ASSERT_NO_ERROR( err ); 00545 CPPUNIT_ASSERT( valid ); 00546 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00547 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00548 ASSERT_MATRICES_EQUAL( ah[0], h[0], 1e-6 ); 00549 ASSERT_MATRICES_EQUAL( ah[1], h[1], 1e-6 ); 00550 ASSERT_MATRICES_EQUAL( ah[2], h[2], 1e-6 ); 00551 } 00552 00553 void AWMetricTest::test_numerical_hessian_3D() 00554 { 00555 HessTestMetricAbs metric; 00556 HessTestMetricAbs_2 metric2; 00557 const double Avals[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 00558 const double Bvals[] = { 0.1, 0.15, 0.05, 0.2, -0.1, -0.15, -0.05, -0.2, 2 }; 00559 const MsqMatrix< 3, 3 > I( 1.0 ); 00560 const MsqMatrix< 3, 3 > A( Avals ); 00561 const MsqMatrix< 3, 3 > B( Bvals ); 00562 00563 MsqError err; 00564 MsqMatrix< 3, 3 > g, gh; 00565 MsqMatrix< 3, 3 > h[6]; 00566 bool valid; 00567 double val, hval; 00568 00569 const double h_00[] = { 2, 0, 0, 0, 10, 0, 0, 0, 10 }; 00570 const double h_01[] = { 0, 0, 0, -8, 0, 0, 0, 0, 0 }; 00571 const double h_02[] = { 0, 0, 0, 0, 0, 0, -8, 0, 0 }; 00572 const double h_11[] = { 10, 0, 0, 0, 2, 0, 0, 0, 10 }; 00573 const double h_12[] = { 0, 0, 0, 0, 0, 0, 0, -8, 0 }; 00574 const double h_22[] = { 10, 0, 0, 0, 10, 0, 0, 0, 2 }; 00575 MsqMatrix< 3, 3 > h00( h_00 ), h01( h_01 ), h02( h_02 ), h11( h_11 ), h12( h_12 ), h22( h_22 ); 00576 00577 valid = metric.evaluate_with_grad( I, A, val, g, err ); 00578 ASSERT_NO_ERROR( err ); 00579 CPPUNIT_ASSERT( valid ); 00580 valid = metric.evaluate_with_hess( I, A, hval, gh, h, err ); 00581 ASSERT_NO_ERROR( err ); 00582 CPPUNIT_ASSERT( valid ); 00583 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00584 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00585 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00586 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00587 ASSERT_MATRICES_EQUAL( h02, h[2], 1e-6 ); 00588 ASSERT_MATRICES_EQUAL( h11, h[3], 1e-6 ); 00589 ASSERT_MATRICES_EQUAL( h12, h[4], 1e-6 ); 00590 ASSERT_MATRICES_EQUAL( h22, h[5], 1e-6 ); 00591 00592 valid = metric.evaluate_with_grad( A, I, val, g, err ); 00593 ASSERT_NO_ERROR( err ); 00594 CPPUNIT_ASSERT( valid ); 00595 valid = metric.evaluate_with_hess( A, I, hval, gh, h, err ); 00596 ASSERT_NO_ERROR( err ); 00597 CPPUNIT_ASSERT( valid ); 00598 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00599 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00600 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00601 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00602 ASSERT_MATRICES_EQUAL( h02, h[2], 1e-6 ); 00603 ASSERT_MATRICES_EQUAL( h11, h[3], 1e-6 ); 00604 ASSERT_MATRICES_EQUAL( h12, h[4], 1e-6 ); 00605 ASSERT_MATRICES_EQUAL( h22, h[5], 1e-6 ); 00606 00607 valid = metric.evaluate_with_grad( I, B, val, g, err ); 00608 ASSERT_NO_ERROR( err ); 00609 CPPUNIT_ASSERT( valid ); 00610 valid = metric.evaluate_with_hess( I, B, hval, gh, h, err ); 00611 ASSERT_NO_ERROR( err ); 00612 CPPUNIT_ASSERT( valid ); 00613 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00614 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00615 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00616 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00617 ASSERT_MATRICES_EQUAL( h02, h[2], 1e-6 ); 00618 ASSERT_MATRICES_EQUAL( h11, h[3], 1e-6 ); 00619 ASSERT_MATRICES_EQUAL( h12, h[4], 1e-6 ); 00620 ASSERT_MATRICES_EQUAL( h22, h[5], 1e-6 ); 00621 00622 valid = metric.evaluate_with_grad( B, I, val, g, err ); 00623 ASSERT_NO_ERROR( err ); 00624 CPPUNIT_ASSERT( valid ); 00625 valid = metric.evaluate_with_hess( B, I, hval, gh, h, err ); 00626 ASSERT_NO_ERROR( err ); 00627 CPPUNIT_ASSERT( valid ); 00628 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00629 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00630 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00631 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00632 ASSERT_MATRICES_EQUAL( h02, h[2], 1e-6 ); 00633 ASSERT_MATRICES_EQUAL( h11, h[3], 1e-6 ); 00634 ASSERT_MATRICES_EQUAL( h12, h[4], 1e-6 ); 00635 ASSERT_MATRICES_EQUAL( h22, h[5], 1e-6 ); 00636 00637 valid = metric.evaluate_with_grad( A, B, val, g, err ); 00638 ASSERT_NO_ERROR( err ); 00639 CPPUNIT_ASSERT( valid ); 00640 valid = metric.evaluate_with_hess( A, B, hval, gh, h, err ); 00641 ASSERT_NO_ERROR( err ); 00642 CPPUNIT_ASSERT( valid ); 00643 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00644 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00645 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00646 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00647 ASSERT_MATRICES_EQUAL( h02, h[2], 1e-6 ); 00648 ASSERT_MATRICES_EQUAL( h11, h[3], 1e-6 ); 00649 ASSERT_MATRICES_EQUAL( h12, h[4], 1e-6 ); 00650 ASSERT_MATRICES_EQUAL( h22, h[5], 1e-6 ); 00651 00652 valid = metric.evaluate_with_grad( B, A, val, g, err ); 00653 ASSERT_NO_ERROR( err ); 00654 CPPUNIT_ASSERT( valid ); 00655 valid = metric.evaluate_with_hess( B, A, hval, gh, h, err ); 00656 ASSERT_NO_ERROR( err ); 00657 CPPUNIT_ASSERT( valid ); 00658 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00659 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00660 ASSERT_MATRICES_EQUAL( h00, h[0], 1e-6 ); 00661 ASSERT_MATRICES_EQUAL( h01, h[1], 1e-6 ); 00662 ASSERT_MATRICES_EQUAL( h02, h[2], 1e-6 ); 00663 ASSERT_MATRICES_EQUAL( h11, h[3], 1e-6 ); 00664 ASSERT_MATRICES_EQUAL( h12, h[4], 1e-6 ); 00665 ASSERT_MATRICES_EQUAL( h22, h[5], 1e-6 ); 00666 00667 MsqMatrix< 3, 3 > ah[6]; 00668 valid = metric2.evaluate_with_hess( A, I, val, g, ah, err ); 00669 ASSERT_NO_ERROR( err ); 00670 CPPUNIT_ASSERT( valid ); 00671 valid = metric2.AWMetric::evaluate_with_hess( A, I, hval, gh, h, err ); 00672 ASSERT_NO_ERROR( err ); 00673 CPPUNIT_ASSERT( valid ); 00674 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00675 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00676 ASSERT_MATRICES_EQUAL( ah[0], h[0], 1e-6 ); 00677 ASSERT_MATRICES_EQUAL( ah[1], h[1], 1e-6 ); 00678 ASSERT_MATRICES_EQUAL( ah[2], h[2], 1e-6 ); 00679 ASSERT_MATRICES_EQUAL( ah[3], h[3], 1e-6 ); 00680 ASSERT_MATRICES_EQUAL( ah[4], h[4], 1e-6 ); 00681 ASSERT_MATRICES_EQUAL( ah[5], h[5], 1e-6 ); 00682 00683 valid = metric2.evaluate_with_hess( B, I, val, g, ah, err ); 00684 ASSERT_NO_ERROR( err ); 00685 CPPUNIT_ASSERT( valid ); 00686 valid = metric2.AWMetric::evaluate_with_hess( B, I, hval, gh, h, err ); 00687 ASSERT_NO_ERROR( err ); 00688 CPPUNIT_ASSERT( valid ); 00689 CPPUNIT_ASSERT_DOUBLES_EQUAL( val, hval, 1e-6 ); 00690 ASSERT_MATRICES_EQUAL( g, gh, 1e-6 ); 00691 ASSERT_MATRICES_EQUAL( ah[0], h[0], 1e-6 ); 00692 ASSERT_MATRICES_EQUAL( ah[1], h[1], 1e-6 ); 00693 ASSERT_MATRICES_EQUAL( ah[2], h[2], 1e-6 ); 00694 ASSERT_MATRICES_EQUAL( ah[3], h[3], 1e-6 ); 00695 ASSERT_MATRICES_EQUAL( ah[4], h[4], 1e-6 ); 00696 ASSERT_MATRICES_EQUAL( ah[5], h[5], 1e-6 ); 00697 }