MOAB: Mesh Oriented datABase  (version 5.4.0)
AWMetricTest.cpp
Go to the documentation of this file.
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) kraftche@cae.wisc.edu
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines