MOAB: Mesh Oriented datABase  (version 5.3.0)
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) 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, MsqHessian& LP2_hess, ObjectiveFunction& OF,
00272                                     MsqHessian& OF_hess )
00273 {
00274     MsqPrintError err( cout );
00275     PatchData pd;
00276     create_twelve_hex_patch( pd, err );
00277     ASSERT_NO_ERROR( err );
00278 
00279     LP1_hess.initialize( pd, err );
00280     ASSERT_NO_ERROR( err );
00281     LP2_hess.initialize( pd, err );
00282     ASSERT_NO_ERROR( err );
00283     OF_hess.initialize( pd, err );
00284     ASSERT_NO_ERROR( err );
00285 
00286     std::vector< Vector3D > grad;
00287     bool rval;
00288     double value;
00289     rval = LP1.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, LP1_hess, err );
00290     ASSERT_NO_ERROR( err );
00291     CPPUNIT_ASSERT( rval );
00292     rval = LP2.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, LP2_hess, err );
00293     ASSERT_NO_ERROR( err );
00294     CPPUNIT_ASSERT( rval );
00295     rval = OF.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, OF_hess, err );
00296     ASSERT_NO_ERROR( err );
00297     CPPUNIT_ASSERT( rval );
00298 }
00299 
00300 void CompositeOFTest::test_add_hess_diagonal()
00301 {
00302     CompositeOFAdd OF( &LP1, &LP2 );
00303     compare_hessian_diagonal( &OF );
00304 }
00305 
00306 void CompositeOFTest::test_multiply_hess_diagonal()
00307 {
00308     CompositeOFMultiply OF( &LP1, &LP2 );
00309     std::vector< SymMatrix3D > hess1, hess2, hess;
00310 
00311     MsqPrintError err( cout );
00312     PatchData pd;
00313     create_twelve_hex_patch( pd, err );
00314     ASSERT_NO_ERROR( err );
00315 
00316     std::vector< Vector3D > grad1, grad2, grad;
00317     bool rval;
00318     double value1, value2, value;
00319     rval = LP1.evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, value1, grad1, hess1, err );
00320     ASSERT_NO_ERROR( err );
00321     CPPUNIT_ASSERT( rval );
00322     rval = LP2.evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, value2, grad2, hess2, err );
00323     ASSERT_NO_ERROR( err );
00324     CPPUNIT_ASSERT( rval );
00325     rval = OF.evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, value, grad, hess, err );
00326     ASSERT_NO_ERROR( err );
00327     CPPUNIT_ASSERT( rval );
00328 
00329     CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), grad1.size() );
00330     CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), grad2.size() );
00331     CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), grad.size() );
00332 
00333     CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess1.size() );
00334     CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess2.size() );
00335     CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess.size() );
00336 
00337     CPPUNIT_ASSERT_DOUBLES_EQUAL( value1 * value2, value, 1e-6 );
00338 
00339     for( size_t i = 0; i < pd.num_free_vertices(); ++i )
00340     {
00341         const Vector3D expected_grad = value2 * grad1[i] + value1 * grad2[i];
00342         CPPUNIT_ASSERT_VECTORS_EQUAL( expected_grad, grad[i], 1e-6 );
00343 
00344         Matrix3D o;
00345         o.outer_product( grad1[i], grad2[i] );
00346         Matrix3D expect = o + transpose( o );
00347         expect += value2 * hess1[i];
00348         expect += value1 * hess2[i];
00349         CPPUNIT_ASSERT_MATRICES_EQUAL( expect, Matrix3D( hess[i] ), 1e-6 );
00350     }
00351 }
00352 
00353 void CompositeOFTest::test_scalar_add_hess_diagonal()
00354 {
00355     CompositeOFScalarAdd OF( 1111.1, &LP1 );
00356     compare_hessian_diagonal( &OF );
00357 }
00358 
00359 void CompositeOFTest::test_scalar_multiply_hess_diagonal()
00360 {
00361     const double scale = 2.5;
00362     CompositeOFScalarMultiply OF( scale, &LP1 );
00363     compare_hessian_diagonal( &OF );
00364 }
00365 
00366 void CompositeOFTest::test_add_hessian()
00367 {
00368     // test value and gradient
00369     CompositeOFAdd OF( &LP1, &LP2 );
00370     compare_hessian_gradient( &OF );
00371 
00372     // test actual hessian values
00373     MsqHessian hess1, hess2, hess;
00374     get_hessians( hess1, hess2, OF, hess );
00375     Matrix3D *b1, *b2, *b;
00376     for( unsigned r = 0; r < hess.size(); ++r )
00377     {
00378         for( unsigned c = r; c < hess.size(); ++c )
00379         {
00380             b1 = hess1.get_block( r, c );
00381             b2 = hess2.get_block( r, c );
00382             b  = hess.get_block( r, c );
00383             if( b ) { CPPUNIT_ASSERT_MATRICES_EQUAL( *b1 + *b2, *b, 1e-6 ); }
00384         }
00385     }
00386 }
00387 
00388 void CompositeOFTest::test_multiply_hessian()
00389 {
00390     MsqError err;
00391     PatchData pd;
00392     create_twelve_hex_patch( pd, err );
00393     ASSERT_NO_ERROR( err );
00394 
00395     // this should always fail because the Hessian is not sparse
00396     CompositeOFMultiply OF( &LP1, &LP2 );
00397     double value;
00398     MsqHessian hess;
00399     hess.initialize( pd, err );
00400     ASSERT_NO_ERROR( err );
00401     std::vector< Vector3D > grad;
00402     OF.evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, hess, err );
00403     CPPUNIT_ASSERT( err );
00404 }
00405 
00406 void CompositeOFTest::test_scalar_add_hessian()
00407 {
00408     // test value and gradient
00409     CompositeOFScalarAdd OF( 1111.1, &LP1 );
00410     compare_hessian_gradient( &OF );
00411 
00412     // test actual hessian values
00413     MsqHessian hess1, hess2, hess;
00414     get_hessians( hess1, hess2, OF, hess );
00415     Matrix3D *b1, *b;
00416     for( unsigned r = 0; r < hess.size(); ++r )
00417     {
00418         for( unsigned c = r; c < hess.size(); ++c )
00419         {
00420             b1 = hess1.get_block( r, c );
00421             b  = hess.get_block( r, c );
00422             if( b ) { CPPUNIT_ASSERT_MATRICES_EQUAL( *b1, *b, 1e-6 ); }
00423         }
00424     }
00425 }
00426 
00427 void CompositeOFTest::test_scalar_multiply_hessian()
00428 {
00429     // test value and gradient
00430     const double scale = 2.5;
00431     CompositeOFScalarMultiply OF( scale, &LP1 );
00432     compare_hessian_gradient( &OF );
00433 
00434     // test actual hessian values
00435     MsqHessian hess1, hess2, hess;
00436     get_hessians( hess1, hess2, OF, hess );
00437     Matrix3D *b1, *b;
00438     for( unsigned r = 0; r < hess.size(); ++r )
00439     {
00440         for( unsigned c = r; c < hess.size(); ++c )
00441         {
00442             b1 = hess1.get_block( r, c );
00443             b  = hess.get_block( r, c );
00444             if( b ) { CPPUNIT_ASSERT_MATRICES_EQUAL( scale * *b1, *b, 1e-6 ); }
00445         }
00446     }
00447 }
00448 
00449 void CompositeOFTest::test_composite_clone( ObjectiveFunction& OF )
00450 {
00451     // save current count of instances of underlying OFs for later
00452     const int init_count = FauxObjectiveFunction::get_instance_count();
00453 
00454     // clone the objective function
00455     ObjectiveFunction* clone = OF.clone();
00456 
00457     // check that the underlying OFs were also cloned
00458     CPPUNIT_ASSERT( init_count < FauxObjectiveFunction::get_instance_count() );
00459 
00460     // check that the value is the same
00461     MsqPrintError err( cout );
00462     double orig_val, clone_val;
00463     bool rval;
00464     rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), orig_val, false, err );
00465     ASSERT_NO_ERROR( err );
00466     CPPUNIT_ASSERT( rval );
00467     rval = clone->evaluate( ObjectiveFunction::CALCULATE, patch(), clone_val, false, err );
00468     ASSERT_NO_ERROR( err );
00469     CPPUNIT_ASSERT( rval );
00470     CPPUNIT_ASSERT_DOUBLES_EQUAL( orig_val, clone_val, 1e-6 );
00471 
00472     // check that cloned instances of underlying OFs are deleted
00473     delete clone;
00474     CPPUNIT_ASSERT_EQUAL( init_count, FauxObjectiveFunction::get_instance_count() );
00475 }
00476 
00477 void CompositeOFTest::test_clone_add()
00478 {
00479     CompositeOFAdd OF( &OF1, &OF2 );
00480     test_composite_clone( OF );
00481 }
00482 void CompositeOFTest::test_clone_multiply()
00483 {
00484     CompositeOFMultiply OF( &OF1, &OF2 );
00485     test_composite_clone( OF );
00486 }
00487 void CompositeOFTest::test_clone_scalar_add()
00488 {
00489     CompositeOFScalarAdd OF( 2.1, &OF2 );
00490     test_composite_clone( OF );
00491 }
00492 void CompositeOFTest::test_clone_scalar_multiply()
00493 {
00494     CompositeOFScalarMultiply OF( 0.333, &OF2 );
00495     test_composite_clone( OF );
00496 }
00497 
00498 void CompositeOFTest::test_invalid_eval( ObjectiveFunction& OF )
00499 {
00500     MsqPrintError err( cout );
00501     bool rval;
00502     double value;
00503     rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err );
00504     ASSERT_NO_ERROR( err );
00505     CPPUNIT_ASSERT( rval == false );
00506 }
00507 
00508 void CompositeOFTest::test_eval_fails( ObjectiveFunction& OF )
00509 {
00510     MsqError err;
00511     double value;
00512     OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err );
00513     CPPUNIT_ASSERT_EQUAL( MsqError::INTERNAL_ERROR, err.error_code() );
00514 }
00515 
00516 void CompositeOFTest::test_add_invalid()
00517 {
00518     CompositeOFAdd add1( &OF1, &invalidOF );
00519     test_invalid_eval( add1 );
00520 
00521     CompositeOFAdd add2( &invalidOF, &OF3 );
00522     test_invalid_eval( add2 );
00523 }
00524 
00525 void CompositeOFTest::test_multiply_invalid()
00526 {
00527     CompositeOFMultiply mult1( &OF1, &invalidOF );
00528     test_invalid_eval( mult1 );
00529 
00530     CompositeOFMultiply mult2( &invalidOF, &OF3 );
00531     test_invalid_eval( mult2 );
00532 }
00533 
00534 void CompositeOFTest::test_scalar_add_invalid()
00535 {
00536     CompositeOFScalarAdd OF( 2.0, &invalidOF );
00537     test_invalid_eval( OF );
00538 }
00539 
00540 void CompositeOFTest::test_scalar_multiply_invalid()
00541 {
00542     CompositeOFScalarMultiply OF( 2.0, &invalidOF );
00543     test_invalid_eval( OF );
00544 }
00545 
00546 void CompositeOFTest::test_add_error()
00547 {
00548     CompositeOFAdd add1( &OF1, &errorOF );
00549     test_eval_fails( add1 );
00550 
00551     CompositeOFAdd add2( &errorOF, &OF3 );
00552     test_eval_fails( add2 );
00553 }
00554 
00555 void CompositeOFTest::test_multiply_error()
00556 {
00557     CompositeOFMultiply mult1( &OF1, &errorOF );
00558     test_eval_fails( mult1 );
00559 
00560     CompositeOFMultiply mult2( &errorOF, &OF3 );
00561     test_eval_fails( mult2 );
00562 }
00563 
00564 void CompositeOFTest::test_scalar_add_error()
00565 {
00566     CompositeOFScalarAdd OF( 2.0, &errorOF );
00567     test_eval_fails( OF );
00568 }
00569 
00570 void CompositeOFTest::test_scalar_multiply_error()
00571 {
00572     CompositeOFScalarMultiply OF( 2.0, &errorOF );
00573     test_eval_fails( OF );
00574 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines