MOAB: Mesh Oriented datABase  (version 5.4.1)
ObjectiveFunctionTest.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Sandia Corporation and Argonne National
00005     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
00006     with Sandia Corporation, the U.S. Government retains certain
00007     rights in 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     [email protected], [email protected], [email protected],
00024     [email protected], [email protected], [email protected]
00025 
00026   ***************************************************************** */
00027 // -*- Mode : c++; tab-width: 3; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 3
00028 // -*-
00029 //
00030 //   SUMMARY:
00031 //     USAGE:
00032 //
00033 //    AUTHOR: Thomas Leurent <[email protected]>
00034 //       ORG: Argonne National Laboratory
00035 //    E-MAIL: [email protected]
00036 //
00037 // ORIG-DATE: 13-Nov-02 at 18:05:56
00038 //  LAST-MOD: 23-Jul-03 at 17:40:28 by Thomas Leurent
00039 //
00040 // DESCRIPTION:
00041 // ============
00042 /*! \file ObjectiveFunctionTest.cpp
00043 
00044 Unit testing of various functions in the ObjectiveFunction class.
00045 */
00046 // DESCRIP-END.
00047 //
00048 
00049 #include "Mesquite.hpp"
00050 #include "LPtoPTemplate.hpp"
00051 #include "MaxTemplate.hpp"
00052 #include "LInfTemplate.hpp"
00053 #include "IdealWeightInverseMeanRatio.hpp"
00054 #include "MsqHessian.hpp"
00055 
00056 #include "PatchDataInstances.hpp"
00057 #include "ObjectiveFunctionTests.hpp"
00058 #include "cppunit/extensions/HelperMacros.h"
00059 #include "UnitUtil.hpp"
00060 #include <iterator>
00061 #include <algorithm>
00062 
00063 using namespace MBMesquite;
00064 using std::cerr;
00065 using std::cout;
00066 using std::endl;
00067 
00068 class ObjectiveFunctionTest : public CppUnit::TestFixture, public ObjectiveFunctionTests
00069 {
00070   private:
00071     CPPUNIT_TEST_SUITE( ObjectiveFunctionTest );
00072 
00073     CPPUNIT_TEST( test_eval_OF_value_LPtoP_L1 );
00074     CPPUNIT_TEST( test_grad_OF_value_LPtoP_L1 );
00075     CPPUNIT_TEST( test_diag_OF_value_LPtoP_L1 );
00076     CPPUNIT_TEST( test_hess_OF_value_LPtoP_L1 );
00077     CPPUNIT_TEST( test_eval_OF_value_LPtoP_L2 );
00078     CPPUNIT_TEST( test_grad_OF_value_LPtoP_L2 );
00079     CPPUNIT_TEST( test_diag_OF_value_LPtoP_L2 );
00080     CPPUNIT_TEST( test_hess_OF_value_LPtoP_L2 );
00081     CPPUNIT_TEST( test_eval_OF_value_LPtoP_scaled );
00082     CPPUNIT_TEST( test_grad_OF_value_LPtoP_scaled );
00083     CPPUNIT_TEST( test_diag_OF_value_LPtoP_scaled );
00084     CPPUNIT_TEST( test_hess_OF_value_LPtoP_scaled );
00085     CPPUNIT_TEST( test_eval_OF_value_LInf );
00086     CPPUNIT_TEST( test_eval_OF_value_max );
00087 
00088     CPPUNIT_TEST( test_compute_gradient_LPtoPTemplate_L1 );
00089     CPPUNIT_TEST( test_compute_gradient_LPtoPTemplate_L2 );
00090     CPPUNIT_TEST( test_compute_gradient_LPtoPTemplate_L2_scaled );
00091     CPPUNIT_TEST( test_hessian_gradient_LPtoPTemplate_L1 );
00092     CPPUNIT_TEST( test_hessian_gradient_LPtoPTemplate_L2 );
00093     CPPUNIT_TEST( test_hessian_gradient_LPtoPTemplate_L2_scaled );
00094     CPPUNIT_TEST( test_diagonal_gradient_LPtoPTemplate_L1 );
00095     CPPUNIT_TEST( test_diagonal_gradient_LPtoPTemplate_L2 );
00096     CPPUNIT_TEST( test_diagonal_gradient_LPtoPTemplate_L2_scaled );
00097     CPPUNIT_TEST( test_hessian_diagonal_LPtoPTemplate_L1 );
00098     CPPUNIT_TEST( test_hessian_diagonal_LPtoPTemplate_L2 );
00099     CPPUNIT_TEST( test_hessian_diagonal_LPtoPTemplate_L2_scaled );
00100     CPPUNIT_TEST( test_compute_ana_hessian_tet );
00101     CPPUNIT_TEST( test_compute_ana_hessian_tet_scaled );
00102 
00103     CPPUNIT_TEST( test_LPtoP_invalid_qm_eval );
00104     CPPUNIT_TEST( test_LPtoP_invalid_qm_grad );
00105     CPPUNIT_TEST( test_LPtoP_invalid_qm_diag );
00106     CPPUNIT_TEST( test_LPtoP_invalid_qm_hess );
00107     CPPUNIT_TEST( test_LInf_invalid_qm_eval );
00108     CPPUNIT_TEST( test_max_invalid_qm_eval );
00109 
00110     CPPUNIT_TEST( test_LPtoP_qm_error_eval );
00111     CPPUNIT_TEST( test_LPtoP_qm_error_grad );
00112     CPPUNIT_TEST( test_LPtoP_qm_error_diag );
00113     CPPUNIT_TEST( test_LPtoP_qm_error_hess );
00114     CPPUNIT_TEST( test_LInf_qm_error_eval );
00115     CPPUNIT_TEST( test_max_qm_error_eval );
00116 
00117     CPPUNIT_TEST( test_LPtoP_eval_calc );
00118     CPPUNIT_TEST( test_LPtoP_eval_accum );
00119     CPPUNIT_TEST( test_LPtoP_eval_save );
00120     CPPUNIT_TEST( test_LPtoP_eval_update );
00121     CPPUNIT_TEST( test_LPtoP_eval_temp );
00122 
00123     CPPUNIT_TEST( test_LPtoP_grad_calc );
00124     CPPUNIT_TEST( test_LPtoP_grad_save );
00125     CPPUNIT_TEST( test_LPtoP_grad_update );
00126     CPPUNIT_TEST( test_LPtoP_grad_temp );
00127 
00128     CPPUNIT_TEST( test_LPtoP_diag_calc );
00129     CPPUNIT_TEST( test_LPtoP_diag_save );
00130     CPPUNIT_TEST( test_LPtoP_diag_update );
00131     CPPUNIT_TEST( test_LPtoP_diag_temp );
00132 
00133     CPPUNIT_TEST( test_LPtoP_hess_calc );
00134     CPPUNIT_TEST( test_LPtoP_hess_save );
00135     CPPUNIT_TEST( test_LPtoP_hess_update );
00136     CPPUNIT_TEST( test_LPtoP_hess_temp );
00137 
00138     CPPUNIT_TEST( test_LPtoP_clone_L1 );
00139     CPPUNIT_TEST( test_LPtoP_clone_L2 );
00140     CPPUNIT_TEST( test_LInf_clone );
00141     CPPUNIT_TEST( test_max_clone );
00142 
00143     CPPUNIT_TEST( test_LPtoP_negate_flag_eval );
00144     CPPUNIT_TEST( test_LPtoP_negate_flag_grad );
00145     CPPUNIT_TEST( test_LPtoP_negate_flag_diag );
00146     CPPUNIT_TEST( test_LPtoP_negate_flag_hess );
00147     CPPUNIT_TEST( test_LInf_negate_flag_eval );
00148     CPPUNIT_TEST( test_max_negate_flag_eval );
00149 
00150     CPPUNIT_TEST_SUITE_END();
00151 
00152     void test_LPtoP_value( short P, bool scale, const std::vector< double >& values, OFTestMode mode );
00153 
00154     void test_LInf_value( const std::vector< double >& values );
00155 
00156     void test_max_value( const std::vector< double >& values );
00157 
00158     void test_max_negate_flag( ObjectiveFunctionTemplate& OF );
00159 
00160     std::vector< double > values1, values2;
00161 
00162   public:
00163     ObjectiveFunctionTest() {}
00164 
00165     void setUp()
00166     {
00167         const double v1[] = { 0, 1, 2, 3, 4, 5 };
00168         const double v2[] = { -2.5, 0.5, 3.0, M_PI, -25.0, 1.0 };
00169         std::copy( v1, v1 + sizeof( v1 ) / sizeof( v1[0] ), std::back_inserter( values1 ) );
00170         std::copy( v2, v2 + sizeof( v2 ) / sizeof( v2[0] ), std::back_inserter( values2 ) );
00171     }
00172 
00173     void test_eval_OF_value_LPtoP_L1()
00174     {
00175         test_LPtoP_value( 1, false, values1, EVAL );
00176         test_LPtoP_value( 1, false, values2, EVAL );
00177     }
00178 
00179     void test_grad_OF_value_LPtoP_L1()
00180     {
00181         test_LPtoP_value( 1, false, values1, GRAD );
00182         test_LPtoP_value( 1, false, values2, GRAD );
00183     }
00184 
00185     void test_diag_OF_value_LPtoP_L1()
00186     {
00187         test_LPtoP_value( 1, false, values1, DIAG );
00188         test_LPtoP_value( 1, false, values2, DIAG );
00189     }
00190 
00191     void test_hess_OF_value_LPtoP_L1()
00192     {
00193         test_LPtoP_value( 1, false, values1, HESS );
00194         test_LPtoP_value( 1, false, values2, HESS );
00195     }
00196 
00197     void test_eval_OF_value_LPtoP_L2()
00198     {
00199         test_LPtoP_value( 2, false, values1, EVAL );
00200         test_LPtoP_value( 2, false, values2, EVAL );
00201     }
00202 
00203     void test_grad_OF_value_LPtoP_L2()
00204     {
00205         test_LPtoP_value( 2, false, values1, GRAD );
00206         test_LPtoP_value( 2, false, values2, GRAD );
00207     }
00208 
00209     void test_diag_OF_value_LPtoP_L2()
00210     {
00211         test_LPtoP_value( 2, false, values1, DIAG );
00212         test_LPtoP_value( 2, false, values2, DIAG );
00213     }
00214 
00215     void test_hess_OF_value_LPtoP_L2()
00216     {
00217         test_LPtoP_value( 2, false, values1, HESS );
00218         test_LPtoP_value( 2, false, values2, HESS );
00219     }
00220 
00221     void test_eval_OF_value_LPtoP_scaled()
00222     {
00223         test_LPtoP_value( 2, true, values1, EVAL );
00224         test_LPtoP_value( 2, true, values2, EVAL );
00225     }
00226 
00227     void test_grad_OF_value_LPtoP_scaled()
00228     {
00229         test_LPtoP_value( 2, true, values1, GRAD );
00230         test_LPtoP_value( 2, true, values2, GRAD );
00231     }
00232 
00233     void test_diag_OF_value_LPtoP_scaled()
00234     {
00235         test_LPtoP_value( 2, true, values1, DIAG );
00236         test_LPtoP_value( 2, true, values2, DIAG );
00237     }
00238 
00239     void test_hess_OF_value_LPtoP_scaled()
00240     {
00241         test_LPtoP_value( 2, true, values1, EVAL );
00242         test_LPtoP_value( 2, true, values2, EVAL );
00243     }
00244 
00245     void test_eval_OF_value_LInf()
00246     {
00247         test_LInf_value( values1 );
00248         test_LInf_value( values2 );
00249     }
00250 
00251     void test_eval_OF_value_max()
00252     {
00253         test_max_value( values1 );
00254         test_max_value( values2 );
00255     }
00256 
00257     void test_compute_gradient_LPtoPTemplate_L1()
00258     {
00259         LPtoPTemplate LP1( 1, NULL );
00260         compare_numerical_gradient( &LP1 );
00261     }
00262 
00263     void test_compute_gradient_LPtoPTemplate_L2()
00264     {
00265         LPtoPTemplate LP1( 2, NULL );
00266         compare_numerical_gradient( &LP1 );
00267     }
00268 
00269     void test_compute_gradient_LPtoPTemplate_L2_scaled()
00270     {
00271         LPtoPTemplate LP1( 2, NULL );
00272         LP1.set_dividing_by_n( true );
00273         compare_numerical_gradient( &LP1 );
00274     }
00275 
00276     void test_hessian_gradient_LPtoPTemplate_L1()
00277     {
00278         LPtoPTemplate LP1( 1, NULL );
00279         compare_hessian_gradient( &LP1 );
00280     }
00281 
00282     void test_hessian_gradient_LPtoPTemplate_L2()
00283     {
00284         LPtoPTemplate LP1( 2, NULL );
00285         compare_hessian_gradient( &LP1 );
00286     }
00287 
00288     void test_hessian_gradient_LPtoPTemplate_L2_scaled()
00289     {
00290         LPtoPTemplate LP1( 2, NULL );
00291         LP1.set_dividing_by_n( true );
00292         compare_hessian_gradient( &LP1 );
00293     }
00294 
00295     void test_diagonal_gradient_LPtoPTemplate_L1()
00296     {
00297         LPtoPTemplate LP1( 1, NULL );
00298         compare_diagonal_gradient( &LP1 );
00299     }
00300 
00301     void test_diagonal_gradient_LPtoPTemplate_L2()
00302     {
00303         LPtoPTemplate LP1( 2, NULL );
00304         compare_diagonal_gradient( &LP1 );
00305     }
00306 
00307     void test_diagonal_gradient_LPtoPTemplate_L2_scaled()
00308     {
00309         LPtoPTemplate LP1( 2, NULL );
00310         LP1.set_dividing_by_n( true );
00311         compare_diagonal_gradient( &LP1 );
00312     }
00313 
00314     void test_hessian_diagonal_LPtoPTemplate_L1()
00315     {
00316         LPtoPTemplate LP1( 1, NULL );
00317         compare_hessian_diagonal( &LP1 );
00318     }
00319 
00320     void test_hessian_diagonal_LPtoPTemplate_L2()
00321     {
00322         LPtoPTemplate LP1( 2, NULL );
00323         compare_hessian_diagonal( &LP1 );
00324     }
00325 
00326     void test_hessian_diagonal_LPtoPTemplate_L2_scaled()
00327     {
00328         LPtoPTemplate LP1( 2, NULL );
00329         LP1.set_dividing_by_n( true );
00330         compare_hessian_diagonal( &LP1 );
00331     }
00332 
00333     void test_compute_ana_hessian_tet();
00334 
00335     void test_compute_ana_hessian_tet_scaled();
00336 
00337     void test_LPtoP_invalid_qm_eval()
00338     {
00339         LPtoPTemplate LP1( 1, NULL );
00340         test_handles_invalid_qm( EVAL, &LP1 );
00341     }
00342     void test_LPtoP_invalid_qm_grad()
00343     {
00344         LPtoPTemplate LP1( 1, NULL );
00345         test_handles_invalid_qm( GRAD, &LP1 );
00346     }
00347     void test_LPtoP_invalid_qm_diag()
00348     {
00349         LPtoPTemplate LP1( 1, NULL );
00350         test_handles_invalid_qm( DIAG, &LP1 );
00351     }
00352     void test_LPtoP_invalid_qm_hess()
00353     {
00354         LPtoPTemplate LP1( 1, NULL );
00355         test_handles_invalid_qm( HESS, &LP1 );
00356     }
00357     void test_LInf_invalid_qm_eval()
00358     {
00359         LInfTemplate OF( NULL );
00360         test_handles_invalid_qm( EVAL, &OF );
00361     }
00362     void test_max_invalid_qm_eval()
00363     {
00364         MaxTemplate OF( NULL );
00365         test_handles_invalid_qm( EVAL, &OF );
00366     }
00367 
00368     void test_LPtoP_qm_error_eval()
00369     {
00370         LPtoPTemplate LP1( 1, NULL );
00371         test_handles_qm_error( EVAL, &LP1 );
00372     }
00373     void test_LPtoP_qm_error_grad()
00374     {
00375         LPtoPTemplate LP1( 1, NULL );
00376         test_handles_qm_error( GRAD, &LP1 );
00377     }
00378     void test_LPtoP_qm_error_diag()
00379     {
00380         LPtoPTemplate LP1( 1, NULL );
00381         test_handles_qm_error( DIAG, &LP1 );
00382     }
00383     void test_LPtoP_qm_error_hess()
00384     {
00385         LPtoPTemplate LP1( 1, NULL );
00386         test_handles_qm_error( HESS, &LP1 );
00387     }
00388     void test_LInf_qm_error_eval()
00389     {
00390         LInfTemplate OF( NULL );
00391         test_handles_qm_error( EVAL, &OF );
00392     }
00393     void test_max_qm_error_eval()
00394     {
00395         MaxTemplate OF( NULL );
00396         test_handles_qm_error( EVAL, &OF );
00397     }
00398 
00399     void test_LPtoP_eval_calc()
00400     {
00401         LPtoPTemplate OF( 1, NULL );
00402         test_eval_type( ObjectiveFunction::CALCULATE, EVAL, &OF );
00403     }
00404     void test_LPtoP_eval_accum()
00405     {
00406         LPtoPTemplate OF( 1, NULL );
00407         test_eval_type( ObjectiveFunction::ACCUMULATE, EVAL, &OF );
00408     }
00409     void test_LPtoP_eval_save()
00410     {
00411         LPtoPTemplate OF( 1, NULL );
00412         test_eval_type( ObjectiveFunction::SAVE, EVAL, &OF );
00413     }
00414     void test_LPtoP_eval_update()
00415     {
00416         LPtoPTemplate OF( 1, NULL );
00417         test_eval_type( ObjectiveFunction::UPDATE, EVAL, &OF );
00418     }
00419     void test_LPtoP_eval_temp()
00420     {
00421         LPtoPTemplate OF( 1, NULL );
00422         test_eval_type( ObjectiveFunction::TEMPORARY, EVAL, &OF );
00423     }
00424 
00425     void test_LPtoP_grad_calc()
00426     {
00427         LPtoPTemplate OF( 1, NULL );
00428         test_eval_type( ObjectiveFunction::CALCULATE, GRAD, &OF );
00429     }
00430     void test_LPtoP_grad_save()
00431     {
00432         LPtoPTemplate OF( 1, NULL );
00433         test_eval_type( ObjectiveFunction::SAVE, GRAD, &OF );
00434     }
00435     void test_LPtoP_grad_update()
00436     {
00437         LPtoPTemplate OF( 1, NULL );
00438         test_eval_type( ObjectiveFunction::UPDATE, GRAD, &OF );
00439     }
00440     void test_LPtoP_grad_temp()
00441     {
00442         LPtoPTemplate OF( 1, NULL );
00443         test_eval_type( ObjectiveFunction::TEMPORARY, GRAD, &OF );
00444     }
00445 
00446     void test_LPtoP_diag_calc()
00447     {
00448         LPtoPTemplate OF( 1, NULL );
00449         test_eval_type( ObjectiveFunction::CALCULATE, DIAG, &OF );
00450     }
00451     void test_LPtoP_diag_save()
00452     {
00453         LPtoPTemplate OF( 1, NULL );
00454         test_eval_type( ObjectiveFunction::SAVE, DIAG, &OF );
00455     }
00456     void test_LPtoP_diag_update()
00457     {
00458         LPtoPTemplate OF( 1, NULL );
00459         test_eval_type( ObjectiveFunction::UPDATE, DIAG, &OF );
00460     }
00461     void test_LPtoP_diag_temp()
00462     {
00463         LPtoPTemplate OF( 1, NULL );
00464         test_eval_type( ObjectiveFunction::TEMPORARY, DIAG, &OF );
00465     }
00466 
00467     void test_LPtoP_hess_calc()
00468     {
00469         LPtoPTemplate OF( 1, NULL );
00470         test_eval_type( ObjectiveFunction::CALCULATE, HESS, &OF );
00471     }
00472     void test_LPtoP_hess_save()
00473     {
00474         LPtoPTemplate OF( 1, NULL );
00475         test_eval_type( ObjectiveFunction::SAVE, HESS, &OF );
00476     }
00477     void test_LPtoP_hess_update()
00478     {
00479         LPtoPTemplate OF( 1, NULL );
00480         test_eval_type( ObjectiveFunction::UPDATE, HESS, &OF );
00481     }
00482     void test_LPtoP_hess_temp()
00483     {
00484         LPtoPTemplate OF( 1, NULL );
00485         test_eval_type( ObjectiveFunction::TEMPORARY, HESS, &OF );
00486     }
00487 
00488     void test_LPtoP_clone_L1()
00489     {
00490         LPtoPTemplate OF( 1, NULL );
00491         test_clone( &OF );
00492     }
00493     void test_LPtoP_clone_L2()
00494     {
00495         LPtoPTemplate OF( 2, NULL );
00496         test_clone( &OF );
00497     }
00498     void test_LInf_clone()
00499     {
00500         LInfTemplate OF( NULL );
00501         test_clone( &OF );
00502     }
00503     void test_max_clone()
00504     {
00505         MaxTemplate OF( NULL );
00506         test_clone( &OF );
00507     }
00508 
00509     // This function tests to make sure that LPtoP handles the negate
00510     // flag correctly for the analytical Hessian, gradient, and evaluate.
00511     // It does this by creating two objective functions that are
00512     // identical except that the metric in one has negate flag of -1
00513     // and the metric in the other has a negate flag of 1.  Thus,
00514     // the Hessians, gradients, and function values should be the
00515     // the same except for a negative sign.
00516     void test_LPtoP_negate_flag_eval()
00517     {
00518         LPtoPTemplate LP( 2, NULL );
00519         test_negate_flag( EVAL, &LP );
00520     }
00521     void test_LPtoP_negate_flag_grad()
00522     {
00523         LPtoPTemplate LP( 2, NULL );
00524         test_negate_flag( GRAD, &LP );
00525     }
00526     void test_LPtoP_negate_flag_diag()
00527     {
00528         LPtoPTemplate LP( 2, NULL );
00529         test_negate_flag( DIAG, &LP );
00530     }
00531     void test_LPtoP_negate_flag_hess()
00532     {
00533         LPtoPTemplate LP( 2, NULL );
00534         test_negate_flag( HESS, &LP );
00535     }
00536     void test_LInf_negate_flag_eval()
00537     {
00538         LInfTemplate OF( NULL );
00539         test_max_negate_flag( OF );
00540     }
00541     void test_max_negate_flag_eval()
00542     {
00543         MaxTemplate OF( NULL );
00544         test_max_negate_flag( OF );
00545     }
00546 };
00547 
00548 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ObjectiveFunctionTest, "ObjectiveFunctionTest" );
00549 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ObjectiveFunctionTest, "Unit" );
00550 
00551 void ObjectiveFunctionTest::test_compute_ana_hessian_tet()
00552 {
00553     MsqPrintError err( cout );
00554     PatchData tetPatch;
00555     create_qm_two_tet_patch( tetPatch, err );
00556     ASSERT_NO_ERROR( err );
00557 
00558     // creates a mean ratio quality metric ...
00559     IdealWeightInverseMeanRatio* mean_ratio = new IdealWeightInverseMeanRatio( err );
00560     CPPUNIT_ASSERT( !err );
00561     mean_ratio->set_averaging_method( QualityMetric::SUM );
00562 
00563     // ... and builds an objective function with it
00564     LPtoPTemplate LP2( mean_ratio, 2, err );
00565 
00566     MsqHessian H;
00567     std::vector< Vector3D > g;
00568     double dummy;
00569     H.initialize( tetPatch, err );
00570     CPPUNIT_ASSERT( !err );
00571     LP2.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, tetPatch, dummy, g, H, err );
00572     CPPUNIT_ASSERT( !err );
00573     CPPUNIT_ASSERT_EQUAL( tetPatch.num_free_vertices(), g.size() );
00574 
00575     Matrix3D mat00( " 2.44444  0.2566   0.181444 "
00576                     " 0.2566   2.14815  0.104757 "
00577                     " 0.181444 0.104757 2.07407 " );
00578 
00579     Matrix3D mat13( " 5.47514 3.16659    9.83479 "
00580                     " -1.11704 -5.29718 -3.67406 "
00581                     " 10.3635 -13.5358  -15.5638 " );
00582 
00583     CPPUNIT_ASSERT_MATRICES_EQUAL( mat00, *H.get_block( 0, 0 ), 1e-4 );
00584     CPPUNIT_ASSERT_MATRICES_EQUAL( mat13, *H.get_block( 1, 3 ), 1e-4 );
00585 
00586     delete mean_ratio;
00587 }
00588 
00589 void ObjectiveFunctionTest::test_compute_ana_hessian_tet_scaled()
00590 {
00591     MsqPrintError err( cout );
00592     PatchData tetPatch;
00593     create_qm_two_tet_patch( tetPatch, err );
00594     ASSERT_NO_ERROR( err );
00595 
00596     // creates a mean ratio quality metric ...
00597     IdealWeightInverseMeanRatio* mean_ratio = new IdealWeightInverseMeanRatio( err );
00598     CPPUNIT_ASSERT( !err );
00599     mean_ratio->set_averaging_method( QualityMetric::SUM );
00600 
00601     // ... and builds an objective function with it
00602     LPtoPTemplate LP2( mean_ratio, 2, err );
00603     LP2.set_dividing_by_n( true );
00604 
00605     MsqHessian H;
00606     std::vector< Vector3D > g;
00607     double dummy;
00608     H.initialize( tetPatch, err );
00609     CPPUNIT_ASSERT( !err );
00610     LP2.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, tetPatch, dummy, g, H, err );
00611     CPPUNIT_ASSERT( !err );
00612     CPPUNIT_ASSERT_EQUAL( tetPatch.num_free_vertices(), g.size() );
00613 
00614     Matrix3D mat00( " 2.44444  0.2566   0.181444 "
00615                     " 0.2566   2.14815  0.104757 "
00616                     " 0.181444 0.104757 2.07407 " );
00617 
00618     mat00 *= .5;
00619 
00620     Matrix3D mat13( " 5.47514 3.16659    9.83479 "
00621                     " -1.11704 -5.29718 -3.67406 "
00622                     " 10.3635 -13.5358  -15.5638 " );
00623 
00624     mat13 *= .5;
00625 
00626     CPPUNIT_ASSERT_MATRICES_EQUAL( mat00, *H.get_block( 0, 0 ), 1e-4 );
00627     CPPUNIT_ASSERT_MATRICES_EQUAL( mat13, *H.get_block( 1, 3 ), 1e-4 );
00628 
00629     //    cout << H <<endl;
00630     delete mean_ratio;
00631 }
00632 
00633 void ObjectiveFunctionTest::test_LPtoP_value( short P,
00634                                               bool scale,
00635                                               const std::vector< double >& values,
00636                                               OFTestMode mode )
00637 {
00638     CPPUNIT_ASSERT( !values.empty() );
00639 
00640     LPtoPTemplate OF( P, NULL );
00641     OF.set_dividing_by_n( scale );
00642 
00643     double expected = 0.0;
00644     for( std::vector< double >::const_iterator i = values.begin(); i != values.end(); ++i )
00645         expected += std::pow( fabs( *i ), P );
00646     if( scale ) expected /= values.size();
00647 
00648     test_value( arrptr( values ), values.size(), expected, mode, &OF );
00649 }
00650 
00651 void ObjectiveFunctionTest::test_LInf_value( const std::vector< double >& values )
00652 {
00653     CPPUNIT_ASSERT( !values.empty() );
00654 
00655     LInfTemplate OF( NULL );
00656 
00657     double expected = fabs( values[0] );
00658     for( unsigned i = 1; i < values.size(); ++i )
00659         if( fabs( values[i] ) > expected ) expected = fabs( values[i] );
00660 
00661     test_value( arrptr( values ), values.size(), expected, EVAL, &OF );
00662 }
00663 
00664 void ObjectiveFunctionTest::test_max_value( const std::vector< double >& values )
00665 {
00666     CPPUNIT_ASSERT( !values.empty() );
00667 
00668     MaxTemplate OF( NULL );
00669 
00670     double expected = fabs( values[0] );
00671     for( unsigned i = 1; i < values.size(); ++i )
00672         if( values[i] > expected ) expected = values[i];
00673 
00674     test_value( arrptr( values ), values.size(), expected, EVAL, &OF );
00675 }
00676 
00677 void ObjectiveFunctionTest::test_max_negate_flag( ObjectiveFunctionTemplate& of )
00678 {
00679     // use only positive values so this test works for both
00680     // MaxTemplate and LInfTemplate
00681     const double some_vals[] = { 1, 2, 3, 4, 5, 6, 0.5 };
00682     const unsigned num_vals  = sizeof( some_vals ) / sizeof( some_vals[0] );
00683     OFTestQM metric( some_vals, num_vals );
00684     metric.set_negate_flag( -1 );
00685     of.set_quality_metric( &metric );
00686 
00687     // get OF value
00688     MsqPrintError err( cout );
00689     bool rval;
00690     double value;
00691     rval = of.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err );
00692     ASSERT_NO_ERROR( err );
00693     CPPUNIT_ASSERT( rval );
00694 
00695     // find min value
00696     double expected = *std::min_element( some_vals, some_vals + num_vals );
00697     CPPUNIT_ASSERT_DOUBLES_EQUAL( -expected, value, 1e-6 );
00698 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines