MOAB: Mesh Oriented datABase  (version 5.4.1)
CompositeOFTest.cpp
Go to the documentation of this file.
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) [email protected]
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines