MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 }