MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2006) kraftche@cae.wisc.edu 00024 00025 ***************************************************************** */ 00026 00027 /** \file CompositeOFTest.cpp 00028 * \brief Unit tests for Composite Objective Functions 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "CompositeOFAdd.hpp" 00034 #include "CompositeOFMultiply.hpp" 00035 #include "CompositeOFScalarAdd.hpp" 00036 #include "CompositeOFScalarMultiply.hpp" 00037 #include "MsqHessian.hpp" 00038 #include "IdealWeightInverseMeanRatio.hpp" 00039 #include "LPtoPTemplate.hpp" 00040 00041 #include "ObjectiveFunctionTests.hpp" 00042 #include "PatchDataInstances.hpp" 00043 #include "cppunit/extensions/HelperMacros.h" 00044 #include "UnitUtil.hpp" 00045 #include "Matrix3D.hpp" 00046 #include <iterator> 00047 00048 using namespace MBMesquite; 00049 using std::cerr; 00050 using std::cout; 00051 using std::endl; 00052 00053 /** Fake ObjectiveFunction to pass to Composite OFs */ 00054 class FauxObjectiveFunction : public ObjectiveFunction 00055 { 00056 public: 00057 FauxObjectiveFunction( double value, bool invalid = false, bool error = false ) 00058 : mValue( value ), mInvalid( invalid ), mError( error ) 00059 { 00060 ++instanceCount; 00061 } 00062 ~FauxObjectiveFunction() 00063 { 00064 --instanceCount; 00065 } 00066 bool initialize_block_coordinate_descent( MeshDomainAssoc*, const Settings*, PatchSet*, MsqError& ) 00067 { 00068 CPPUNIT_ASSERT_MESSAGE( "This shouldn't ever get called", false ); 00069 return false; 00070 } 00071 bool evaluate( EvalType, PatchData&, double& value_out, bool, MsqError& err ) 00072 { 00073 if( mError ) MSQ_SETERR( err )( MsqError::INTERNAL_ERROR ); 00074 value_out = mValue; 00075 return !mInvalid; 00076 } 00077 ObjectiveFunction* clone() const 00078 { 00079 ++instanceCount; 00080 return new FauxObjectiveFunction( *this ); 00081 } 00082 void clear() {} 00083 int min_patch_layers() const 00084 { 00085 return 0; 00086 } 00087 00088 void initialize_queue( MeshDomainAssoc*, const Settings*, MsqError& ) {} 00089 00090 double get_value() const 00091 { 00092 return mValue; 00093 } 00094 static int get_instance_count() 00095 { 00096 return instanceCount; 00097 } 00098 00099 private: 00100 double mValue; 00101 bool mInvalid, mError; 00102 static int instanceCount; 00103 }; 00104 int FauxObjectiveFunction::instanceCount = 0; 00105 00106 class CompositeOFTest : public CppUnit::TestFixture, public ObjectiveFunctionTests 00107 { 00108 private: 00109 CPPUNIT_TEST_SUITE( CompositeOFTest ); 00110 00111 CPPUNIT_TEST( test_add_value ); 00112 CPPUNIT_TEST( test_multiply_value ); 00113 CPPUNIT_TEST( test_scalar_add_value ); 00114 CPPUNIT_TEST( test_scalar_multiply_value ); 00115 00116 CPPUNIT_TEST( test_add_gradient ); 00117 CPPUNIT_TEST( test_multiply_gradient ); 00118 CPPUNIT_TEST( test_scalar_add_gradient ); 00119 CPPUNIT_TEST( test_scalar_multiply_gradient ); 00120 00121 CPPUNIT_TEST( test_add_hess_diagonal ); 00122 CPPUNIT_TEST( test_multiply_hess_diagonal ); 00123 CPPUNIT_TEST( test_scalar_add_hess_diagonal ); 00124 CPPUNIT_TEST( test_scalar_multiply_hess_diagonal ); 00125 00126 CPPUNIT_TEST( test_add_hessian ); 00127 CPPUNIT_TEST( test_multiply_hessian ); 00128 CPPUNIT_TEST( test_scalar_add_hessian ); 00129 CPPUNIT_TEST( test_scalar_multiply_hessian ); 00130 00131 CPPUNIT_TEST( test_clone_add ); 00132 CPPUNIT_TEST( test_clone_multiply ); 00133 CPPUNIT_TEST( test_clone_scalar_add ); 00134 CPPUNIT_TEST( test_clone_scalar_multiply ); 00135 00136 CPPUNIT_TEST( test_add_invalid ); 00137 CPPUNIT_TEST( test_multiply_invalid ); 00138 CPPUNIT_TEST( test_scalar_add_invalid ); 00139 CPPUNIT_TEST( test_scalar_multiply_invalid ); 00140 00141 CPPUNIT_TEST( test_add_error ); 00142 CPPUNIT_TEST( test_multiply_error ); 00143 CPPUNIT_TEST( test_scalar_add_error ); 00144 CPPUNIT_TEST( test_scalar_multiply_error ); 00145 00146 CPPUNIT_TEST_SUITE_END(); 00147 00148 FauxObjectiveFunction OF1, OF2, OF3, OF4, invalidOF, errorOF; 00149 IdealWeightInverseMeanRatio metric; 00150 LPtoPTemplate LP1, LP2; 00151 00152 public: 00153 CompositeOFTest() 00154 : OF1( 1.0 ), OF2( 3.0 ), OF3( -7.0 ), OF4( M_PI ), invalidOF( 1.0, true, false ), errorOF( 1.0, false, true ), 00155 LP1( 1, &metric ), LP2( 2, &metric ) 00156 { 00157 } 00158 00159 void test_add_value(); 00160 void test_multiply_value(); 00161 void test_scalar_add_value(); 00162 void test_scalar_multiply_value(); 00163 00164 void test_add_gradient(); 00165 void test_multiply_gradient(); 00166 void test_scalar_add_gradient(); 00167 void test_scalar_multiply_gradient(); 00168 00169 void test_add_hess_diagonal(); 00170 void test_multiply_hess_diagonal(); 00171 void test_scalar_add_hess_diagonal(); 00172 void test_scalar_multiply_hess_diagonal(); 00173 00174 void test_add_hessian(); 00175 void test_multiply_hessian(); 00176 void test_scalar_add_hessian(); 00177 void test_scalar_multiply_hessian(); 00178 00179 void test_clone_add(); 00180 void test_clone_multiply(); 00181 void test_clone_scalar_add(); 00182 void test_clone_scalar_multiply(); 00183 00184 void test_add_invalid(); 00185 void test_multiply_invalid(); 00186 void test_scalar_add_invalid(); 00187 void test_scalar_multiply_invalid(); 00188 00189 void test_add_error(); 00190 void test_multiply_error(); 00191 void test_scalar_add_error(); 00192 void test_scalar_multiply_error(); 00193 00194 void test_evaluate( double expected_value, ObjectiveFunction& of ); 00195 void get_hessians( MsqHessian& LP1_hess, MsqHessian& LP2_hess, ObjectiveFunction& OF, MsqHessian& OF_hess ); 00196 void test_composite_clone( ObjectiveFunction& of ); 00197 void test_invalid_eval( ObjectiveFunction& of ); 00198 void test_eval_fails( ObjectiveFunction& of ); 00199 }; 00200 00201 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CompositeOFTest, "CompositeOFTest" ); 00202 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CompositeOFTest, "Unit" ); 00203 00204 void CompositeOFTest::test_evaluate( double expected, ObjectiveFunction& OF ) 00205 { 00206 MsqPrintError err( cout ); 00207 double value; 00208 bool rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err ); 00209 ASSERT_NO_ERROR( err ); 00210 CPPUNIT_ASSERT( rval ); 00211 CPPUNIT_ASSERT_DOUBLES_EQUAL( expected, value, 1e-6 ); 00212 } 00213 00214 void CompositeOFTest::test_add_value() 00215 { 00216 CompositeOFAdd add1( &OF1, &OF2 ); 00217 test_evaluate( OF1.get_value() + OF2.get_value(), add1 ); 00218 00219 CompositeOFAdd add2( &OF3, &OF4 ); 00220 test_evaluate( OF3.get_value() + OF4.get_value(), add2 ); 00221 } 00222 00223 void CompositeOFTest::test_multiply_value() 00224 { 00225 CompositeOFMultiply mult1( &OF1, &OF2 ); 00226 test_evaluate( OF1.get_value() * OF2.get_value(), mult1 ); 00227 00228 CompositeOFMultiply mult2( &OF3, &OF4 ); 00229 test_evaluate( OF3.get_value() * OF4.get_value(), mult2 ); 00230 } 00231 00232 void CompositeOFTest::test_scalar_add_value() 00233 { 00234 CompositeOFScalarAdd add1( sqrt( 2.0 ), &OF1 ); 00235 test_evaluate( OF1.get_value() + sqrt( 2.0 ), add1 ); 00236 00237 CompositeOFScalarAdd add2( -1.0, &OF4 ); 00238 test_evaluate( OF4.get_value() - 1, add2 ); 00239 } 00240 00241 void CompositeOFTest::test_scalar_multiply_value() 00242 { 00243 CompositeOFScalarMultiply mult1( sqrt( 2.0 ), &OF1 ); 00244 test_evaluate( OF1.get_value() * sqrt( 2.0 ), mult1 ); 00245 00246 CompositeOFScalarMultiply mult2( -1.0, &OF4 ); 00247 test_evaluate( -OF4.get_value(), mult2 ); 00248 } 00249 00250 void CompositeOFTest::test_add_gradient() 00251 { 00252 CompositeOFAdd OF( &LP1, &LP2 ); 00253 compare_numerical_gradient( &OF ); 00254 } 00255 void CompositeOFTest::test_multiply_gradient() 00256 { 00257 CompositeOFMultiply OF( &LP1, &LP2 ); 00258 compare_numerical_gradient( &OF ); 00259 } 00260 void CompositeOFTest::test_scalar_add_gradient() 00261 { 00262 CompositeOFScalarAdd OF( M_PI, &LP1 ); 00263 compare_numerical_gradient( &OF ); 00264 } 00265 void CompositeOFTest::test_scalar_multiply_gradient() 00266 { 00267 CompositeOFScalarMultiply OF( M_PI, &LP1 ); 00268 compare_numerical_gradient( &OF ); 00269 } 00270 00271 void CompositeOFTest::get_hessians( MsqHessian& LP1_hess, 00272 MsqHessian& LP2_hess, 00273 ObjectiveFunction& OF, 00274 MsqHessian& OF_hess ) 00275 { 00276 MsqPrintError err( cout ); 00277 PatchData pd; 00278 create_twelve_hex_patch( pd, err ); 00279 ASSERT_NO_ERROR( err ); 00280 00281 LP1_hess.initialize( pd, err ); 00282 ASSERT_NO_ERROR( err ); 00283 LP2_hess.initialize( pd, err ); 00284 ASSERT_NO_ERROR( err ); 00285 OF_hess.initialize( pd, err ); 00286 ASSERT_NO_ERROR( err ); 00287 00288 std::vector< Vector3D > grad; 00289 bool rval; 00290 double value; 00291 rval = LP1.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, LP1_hess, err ); 00292 ASSERT_NO_ERROR( err ); 00293 CPPUNIT_ASSERT( rval ); 00294 rval = LP2.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, LP2_hess, err ); 00295 ASSERT_NO_ERROR( err ); 00296 CPPUNIT_ASSERT( rval ); 00297 rval = OF.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, OF_hess, err ); 00298 ASSERT_NO_ERROR( err ); 00299 CPPUNIT_ASSERT( rval ); 00300 } 00301 00302 void CompositeOFTest::test_add_hess_diagonal() 00303 { 00304 CompositeOFAdd OF( &LP1, &LP2 ); 00305 compare_hessian_diagonal( &OF ); 00306 } 00307 00308 void CompositeOFTest::test_multiply_hess_diagonal() 00309 { 00310 CompositeOFMultiply OF( &LP1, &LP2 ); 00311 std::vector< SymMatrix3D > hess1, hess2, hess; 00312 00313 MsqPrintError err( cout ); 00314 PatchData pd; 00315 create_twelve_hex_patch( pd, err ); 00316 ASSERT_NO_ERROR( err ); 00317 00318 std::vector< Vector3D > grad1, grad2, grad; 00319 bool rval; 00320 double value1, value2, value; 00321 rval = LP1.evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, value1, grad1, hess1, err ); 00322 ASSERT_NO_ERROR( err ); 00323 CPPUNIT_ASSERT( rval ); 00324 rval = LP2.evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, value2, grad2, hess2, err ); 00325 ASSERT_NO_ERROR( err ); 00326 CPPUNIT_ASSERT( rval ); 00327 rval = OF.evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, value, grad, hess, err ); 00328 ASSERT_NO_ERROR( err ); 00329 CPPUNIT_ASSERT( rval ); 00330 00331 CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), grad1.size() ); 00332 CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), grad2.size() ); 00333 CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), grad.size() ); 00334 00335 CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess1.size() ); 00336 CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess2.size() ); 00337 CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess.size() ); 00338 00339 CPPUNIT_ASSERT_DOUBLES_EQUAL( value1 * value2, value, 1e-6 ); 00340 00341 for( size_t i = 0; i < pd.num_free_vertices(); ++i ) 00342 { 00343 const Vector3D expected_grad = value2 * grad1[i] + value1 * grad2[i]; 00344 CPPUNIT_ASSERT_VECTORS_EQUAL( expected_grad, grad[i], 1e-6 ); 00345 00346 Matrix3D o; 00347 o.outer_product( grad1[i], grad2[i] ); 00348 Matrix3D expect = o + transpose( o ); 00349 expect += value2 * hess1[i]; 00350 expect += value1 * hess2[i]; 00351 CPPUNIT_ASSERT_MATRICES_EQUAL( expect, Matrix3D( hess[i] ), 1e-6 ); 00352 } 00353 } 00354 00355 void CompositeOFTest::test_scalar_add_hess_diagonal() 00356 { 00357 CompositeOFScalarAdd OF( 1111.1, &LP1 ); 00358 compare_hessian_diagonal( &OF ); 00359 } 00360 00361 void CompositeOFTest::test_scalar_multiply_hess_diagonal() 00362 { 00363 const double scale = 2.5; 00364 CompositeOFScalarMultiply OF( scale, &LP1 ); 00365 compare_hessian_diagonal( &OF ); 00366 } 00367 00368 void CompositeOFTest::test_add_hessian() 00369 { 00370 // test value and gradient 00371 CompositeOFAdd OF( &LP1, &LP2 ); 00372 compare_hessian_gradient( &OF ); 00373 00374 // test actual hessian values 00375 MsqHessian hess1, hess2, hess; 00376 get_hessians( hess1, hess2, OF, hess ); 00377 Matrix3D *b1, *b2, *b; 00378 for( unsigned r = 0; r < hess.size(); ++r ) 00379 { 00380 for( unsigned c = r; c < hess.size(); ++c ) 00381 { 00382 b1 = hess1.get_block( r, c ); 00383 b2 = hess2.get_block( r, c ); 00384 b = hess.get_block( r, c ); 00385 if( b ) 00386 { 00387 CPPUNIT_ASSERT_MATRICES_EQUAL( *b1 + *b2, *b, 1e-6 ); 00388 } 00389 } 00390 } 00391 } 00392 00393 void CompositeOFTest::test_multiply_hessian() 00394 { 00395 MsqError err; 00396 PatchData pd; 00397 create_twelve_hex_patch( pd, err ); 00398 ASSERT_NO_ERROR( err ); 00399 00400 // this should always fail because the Hessian is not sparse 00401 CompositeOFMultiply OF( &LP1, &LP2 ); 00402 double value; 00403 MsqHessian hess; 00404 hess.initialize( pd, err ); 00405 ASSERT_NO_ERROR( err ); 00406 std::vector< Vector3D > grad; 00407 OF.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, hess, err ); 00408 CPPUNIT_ASSERT( err ); 00409 } 00410 00411 void CompositeOFTest::test_scalar_add_hessian() 00412 { 00413 // test value and gradient 00414 CompositeOFScalarAdd OF( 1111.1, &LP1 ); 00415 compare_hessian_gradient( &OF ); 00416 00417 // test actual hessian values 00418 MsqHessian hess1, hess2, hess; 00419 get_hessians( hess1, hess2, OF, hess ); 00420 Matrix3D *b1, *b; 00421 for( unsigned r = 0; r < hess.size(); ++r ) 00422 { 00423 for( unsigned c = r; c < hess.size(); ++c ) 00424 { 00425 b1 = hess1.get_block( r, c ); 00426 b = hess.get_block( r, c ); 00427 if( b ) 00428 { 00429 CPPUNIT_ASSERT_MATRICES_EQUAL( *b1, *b, 1e-6 ); 00430 } 00431 } 00432 } 00433 } 00434 00435 void CompositeOFTest::test_scalar_multiply_hessian() 00436 { 00437 // test value and gradient 00438 const double scale = 2.5; 00439 CompositeOFScalarMultiply OF( scale, &LP1 ); 00440 compare_hessian_gradient( &OF ); 00441 00442 // test actual hessian values 00443 MsqHessian hess1, hess2, hess; 00444 get_hessians( hess1, hess2, OF, hess ); 00445 Matrix3D *b1, *b; 00446 for( unsigned r = 0; r < hess.size(); ++r ) 00447 { 00448 for( unsigned c = r; c < hess.size(); ++c ) 00449 { 00450 b1 = hess1.get_block( r, c ); 00451 b = hess.get_block( r, c ); 00452 if( b ) 00453 { 00454 CPPUNIT_ASSERT_MATRICES_EQUAL( scale * *b1, *b, 1e-6 ); 00455 } 00456 } 00457 } 00458 } 00459 00460 void CompositeOFTest::test_composite_clone( ObjectiveFunction& OF ) 00461 { 00462 // save current count of instances of underlying OFs for later 00463 const int init_count = FauxObjectiveFunction::get_instance_count(); 00464 00465 // clone the objective function 00466 ObjectiveFunction* clone = OF.clone(); 00467 00468 // check that the underlying OFs were also cloned 00469 CPPUNIT_ASSERT( init_count < FauxObjectiveFunction::get_instance_count() ); 00470 00471 // check that the value is the same 00472 MsqPrintError err( cout ); 00473 double orig_val, clone_val; 00474 bool rval; 00475 rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), orig_val, false, err ); 00476 ASSERT_NO_ERROR( err ); 00477 CPPUNIT_ASSERT( rval ); 00478 rval = clone->evaluate( ObjectiveFunction::CALCULATE, patch(), clone_val, false, err ); 00479 ASSERT_NO_ERROR( err ); 00480 CPPUNIT_ASSERT( rval ); 00481 CPPUNIT_ASSERT_DOUBLES_EQUAL( orig_val, clone_val, 1e-6 ); 00482 00483 // check that cloned instances of underlying OFs are deleted 00484 delete clone; 00485 CPPUNIT_ASSERT_EQUAL( init_count, FauxObjectiveFunction::get_instance_count() ); 00486 } 00487 00488 void CompositeOFTest::test_clone_add() 00489 { 00490 CompositeOFAdd OF( &OF1, &OF2 ); 00491 test_composite_clone( OF ); 00492 } 00493 void CompositeOFTest::test_clone_multiply() 00494 { 00495 CompositeOFMultiply OF( &OF1, &OF2 ); 00496 test_composite_clone( OF ); 00497 } 00498 void CompositeOFTest::test_clone_scalar_add() 00499 { 00500 CompositeOFScalarAdd OF( 2.1, &OF2 ); 00501 test_composite_clone( OF ); 00502 } 00503 void CompositeOFTest::test_clone_scalar_multiply() 00504 { 00505 CompositeOFScalarMultiply OF( 0.333, &OF2 ); 00506 test_composite_clone( OF ); 00507 } 00508 00509 void CompositeOFTest::test_invalid_eval( ObjectiveFunction& OF ) 00510 { 00511 MsqPrintError err( cout ); 00512 bool rval; 00513 double value; 00514 rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err ); 00515 ASSERT_NO_ERROR( err ); 00516 CPPUNIT_ASSERT( rval == false ); 00517 } 00518 00519 void CompositeOFTest::test_eval_fails( ObjectiveFunction& OF ) 00520 { 00521 MsqError err; 00522 double value; 00523 OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err ); 00524 CPPUNIT_ASSERT_EQUAL( MsqError::INTERNAL_ERROR, err.error_code() ); 00525 } 00526 00527 void CompositeOFTest::test_add_invalid() 00528 { 00529 CompositeOFAdd add1( &OF1, &invalidOF ); 00530 test_invalid_eval( add1 ); 00531 00532 CompositeOFAdd add2( &invalidOF, &OF3 ); 00533 test_invalid_eval( add2 ); 00534 } 00535 00536 void CompositeOFTest::test_multiply_invalid() 00537 { 00538 CompositeOFMultiply mult1( &OF1, &invalidOF ); 00539 test_invalid_eval( mult1 ); 00540 00541 CompositeOFMultiply mult2( &invalidOF, &OF3 ); 00542 test_invalid_eval( mult2 ); 00543 } 00544 00545 void CompositeOFTest::test_scalar_add_invalid() 00546 { 00547 CompositeOFScalarAdd OF( 2.0, &invalidOF ); 00548 test_invalid_eval( OF ); 00549 } 00550 00551 void CompositeOFTest::test_scalar_multiply_invalid() 00552 { 00553 CompositeOFScalarMultiply OF( 2.0, &invalidOF ); 00554 test_invalid_eval( OF ); 00555 } 00556 00557 void CompositeOFTest::test_add_error() 00558 { 00559 CompositeOFAdd add1( &OF1, &errorOF ); 00560 test_eval_fails( add1 ); 00561 00562 CompositeOFAdd add2( &errorOF, &OF3 ); 00563 test_eval_fails( add2 ); 00564 } 00565 00566 void CompositeOFTest::test_multiply_error() 00567 { 00568 CompositeOFMultiply mult1( &OF1, &errorOF ); 00569 test_eval_fails( mult1 ); 00570 00571 CompositeOFMultiply mult2( &errorOF, &OF3 ); 00572 test_eval_fails( mult2 ); 00573 } 00574 00575 void CompositeOFTest::test_scalar_add_error() 00576 { 00577 CompositeOFScalarAdd OF( 2.0, &errorOF ); 00578 test_eval_fails( OF ); 00579 } 00580 00581 void CompositeOFTest::test_scalar_multiply_error() 00582 { 00583 CompositeOFScalarMultiply OF( 2.0, &errorOF ); 00584 test_eval_fails( OF ); 00585 }