コード例 #1
0
void ObjectiveFunctionTests::compare_hessian_diagonal( ObjectiveFunction* of )
{
  MsqPrintError err(std::cout);
  PatchData pd;
  create_twelve_hex_patch( pd, err ); 
  ASSERT_NO_ERROR( err );
  
  std::vector<Vector3D> diag_grad, hess_grad;
  std::vector<SymMatrix3D> diag;
  MsqHessian hess;
  double diag_val, hess_val;
  bool valid;
  
  valid = of->evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, diag_val, diag_grad, diag, err );
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(valid);
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), diag_grad.size() );
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), diag.size() );
  
  hess.initialize( pd, err );
  ASSERT_NO_ERROR( err );
  valid = of->evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, hess_val, hess_grad, hess, err );
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(valid);
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess_grad.size() );
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess.size() );
  
  CPPUNIT_ASSERT_DOUBLES_EQUAL( hess_val, diag_val, 1e-6 );
  for (size_t i = 0; i < pd.num_free_vertices(); ++i) {
    CPPUNIT_ASSERT_VECTORS_EQUAL( hess_grad[i], diag_grad[i], 1e-6 );
    CPPUNIT_ASSERT_MATRICES_EQUAL( *hess.get_block(i,i), diag[i], 1e-6 );
  }
}
コード例 #2
0
/** Internal helper function for test_eval_type */
double ObjectiveFunctionTests::evaluate_internal( 
                                 ObjectiveFunction::EvalType type, 
                                 OFTestMode test_mode,
                                 ObjectiveFunction* of )
{
  MsqPrintError err(cout);
  vector<Vector3D> grad;
  vector<SymMatrix3D> diag;
  MsqHessian hess;
  bool valid = false;
  double result;
  
  switch (test_mode) {
    case EVAL:
      valid = of->evaluate( type, patch(), result, OF_FREE_EVALS_ONLY, err );
      break;
    case GRAD:
      valid = of->evaluate_with_gradient( type, patch(), result, grad, err );
      break;
    case DIAG:
      valid = of->evaluate_with_Hessian_diagonal( type, patch(), result, grad, diag, err );
      break;
    case HESS:
      hess.initialize( patch(), err );
      ASSERT_NO_ERROR( err );
      valid = of->evaluate_with_Hessian( type, patch(), result, grad, hess, err );
      break;
    default:
      CPPUNIT_ASSERT(false);
  }
  
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(valid);
  return result;
}
コード例 #3
0
void ObjectiveFunctionTests::compare_diagonal_gradient( ObjectiveFunction* of )
{
  MsqPrintError err(std::cout);
  PatchData pd;
  create_twelve_hex_patch( pd, err ); 
  ASSERT_NO_ERROR( err );
  
  std::vector<Vector3D> grad, hess_grad;
  std::vector<SymMatrix3D> hess;
  double grad_val, hess_val;
  bool valid;
  
  valid = of->evaluate_with_gradient( ObjectiveFunction::CALCULATE, pd, grad_val, grad, err );
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(valid);
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), grad.size() );
  
  valid = of->evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, hess_val, hess_grad, hess, err );
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(valid);
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), hess_grad.size() );
  
  CPPUNIT_ASSERT_DOUBLES_EQUAL( grad_val, hess_val, 1e-6 );
  for (size_t i = 0; i < pd.num_free_vertices(); ++i) {
    CPPUNIT_ASSERT_VECTORS_EQUAL( grad[i], hess_grad[i], 1e-6 );
  }
}
コード例 #4
0
void ObjectiveFunctionTests::compare_numerical_gradient( ObjectiveFunction* of )
{
  MsqPrintError err(std::cout);
  PatchData pd;
  create_twelve_hex_patch( pd, err ); 
  ASSERT_NO_ERROR( err );
  
  std::vector<Vector3D> num_grad, ana_grad;
  double num_val, ana_val;
  bool valid;
  
  valid = of->evaluate_with_gradient( ObjectiveFunction::CALCULATE, pd, ana_val, ana_grad, err );
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(valid);
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), ana_grad.size() );
  
  valid = of->ObjectiveFunction::evaluate_with_gradient( ObjectiveFunction::CALCULATE, pd, num_val, num_grad, err );
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(valid);
  CPPUNIT_ASSERT_EQUAL( pd.num_free_vertices(), num_grad.size() );
  
  CPPUNIT_ASSERT_DOUBLES_EQUAL( ana_val, num_val, 1e-6 );
  for (size_t i = 0; i < pd.num_free_vertices(); ++i) {
    CPPUNIT_ASSERT_VECTORS_EQUAL( num_grad[i], ana_grad[i], 1e-3 );
  }
}
コード例 #5
0
ファイル: list.c プロジェクト: Ewald123/midikit
/**
 * Test that lists can be created and items can be added and reference counting works.
 */
int test001_list( void ) {
  struct MIDIList * list = MIDIListCreate( TestType );

  ASSERT_NOT_EQUAL( list, NULL, "Could not create list!" );

  ASSERT_NO_ERROR( MIDIListAdd( list, &_testitem ), "Could not add item." );
  ASSERT_EQUAL( _testitem.refs, 2, "Item was not retained." );
  ASSERT_NO_ERROR( MIDIListRemove( list, &_testitem ), "Could not add item." );
  ASSERT_EQUAL( _testitem.refs, 1, "Item was not released." );
  ASSERT_NO_ERROR( MIDIListAdd( list, &_testitem ), "Could not add item." );
  ASSERT_EQUAL( _testitem.refs, 2, "Item was not retained." );
  MIDIListRelease( list );
  ASSERT_EQUAL( _testitem.refs, 1, "Item was not released on destruction." );
  return 0;
}
コード例 #6
0
void CircleDomainTest::test_position_from_length()
{
  MsqPrintError err(std::cerr);
  
  Vector3D origin(0,0,0);
  Vector3D z(0,0,1);
  double rad1 = 4.0/3.0;
  CircleDomain dom1( origin, z, rad1 );
  
  Vector3D xp = Vector3D(1,0,0);
  Vector3D xn = Vector3D(-1,0,0);
  Vector3D yp = Vector3D(0,1,0);
  
  const double qc = 0.5 * rad1 * M_PI;
  
  Vector3D result;
  dom1.position_from_length( xp.to_array(), qc, result.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_VECTORS_EQUAL( yp*rad1, result, 1e-6 );
  
  dom1.position_from_length( xp.to_array(), 2*qc, result.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_VECTORS_EQUAL( xn*rad1, result, 1e-6 );
  
  dom1.position_from_length( yp.to_array(), -qc, result.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_VECTORS_EQUAL( xp*rad1, result, 1e-6 );
  
  dom1.position_from_length( (xp+z).to_array(), qc, result.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_VECTORS_EQUAL( yp*rad1, result, 1e-6 );
  
  Vector3D center(-1,-2,-1);
  Vector3D normal(-2,-1,-2);
  double rad2 = 1.5;
  CircleDomain dom2( center, normal, rad2 );
  
  Vector3D v(1,0,0);
  v = v * normal;
  v *= rad2 / v.length();
  v += center;
  dom2.position_from_length( v.to_array(), 0.0, result.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_VECTORS_EQUAL( v, result, 1e-6 );
}
コード例 #7
0
ファイル: list.c プロジェクト: Ewald123/midikit
/**
 * Test that apply functionality works.
 */
int test002_list( void ) {
  int a, b, c;
  int v = 123;
  struct MIDIList * list = MIDIListCreate( TestType );

  ASSERT_NOT_EQUAL( list, NULL, "Could not create list!" );

  ASSERT_NO_ERROR( MIDIListAdd( list, &a ), "Could not add item." );
  ASSERT_NO_ERROR( MIDIListAdd( list, &b ), "Could not add item." );
  ASSERT_NO_ERROR( MIDIListAdd( list, &c ), "Could not add item." );

  ASSERT_NO_ERROR( MIDIListApply( list, &v, &_apply_set ), "Could not apply set function." );
  ASSERT_EQUAL( a, v, "Setter did not set list item a." );
  ASSERT_EQUAL( b, v, "Setter did not set list item b." );
  ASSERT_EQUAL( c, v, "Setter did not set list item c." );

  MIDIListRelease( list );
  return 0;
}
コード例 #8
0
void ObjectiveFunctionTests::test_handles_invalid_qm( 
                                     OFTestMode test_mode,
                                     ObjectiveFunctionTemplate* of )
{
  OFTestBadQM metric(false);
  of->set_quality_metric( &metric );
  
  MsqPrintError err(cout);
  vector<Vector3D> grad;
  vector<SymMatrix3D> diag;
  MsqHessian hess;
  double result;
  bool valid = false;
  
  switch (test_mode) {
    case EVAL:
      valid = of->evaluate( ObjectiveFunction::CALCULATE, patch(), result, OF_FREE_EVALS_ONLY, err );
      break;
    case GRAD:
      valid = of->evaluate_with_gradient( ObjectiveFunction::CALCULATE, patch(), result, grad, err );
      break;
    case DIAG:
      valid = of->evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, patch(), result, grad, diag, err );
      break;
    case HESS:
      hess.initialize( patch(), err );
      ASSERT_NO_ERROR( err );
      valid = of->evaluate_with_Hessian( ObjectiveFunction::CALCULATE, patch(), result, grad, hess, err );
      break;
    default:
      CPPUNIT_ASSERT(false);
  }
  
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT(!valid);
}
コード例 #9
0
void CircleDomainTest::test_arc_length()
{
  MsqPrintError err(std::cerr);
  
  Vector3D origin(0,0,0);
  Vector3D z(0,0,1);
  double rad1 = 4.0/3.0;
  CircleDomain dom1( origin, z, rad1 );
  
  Vector3D xp = Vector3D(1,0,0);
  Vector3D xn = Vector3D(-1,0,0);
  Vector3D yp = Vector3D(0,1,0);
  
  double len = dom1.arc_length( xp.to_array(), yp.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_DOUBLES_EQUAL( rad1 * M_PI * 0.5, len, 1e-6 );
  
  len = dom1.arc_length( xp.to_array(), xn.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_DOUBLES_EQUAL( rad1 * M_PI, len, 1e-6 );
  
  len = dom1.arc_length( yp.to_array(), xp.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_DOUBLES_EQUAL( -rad1 * M_PI * 0.5, len, 1e-6 );
  
  len = dom1.arc_length( (xp+z).to_array(), yp.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_DOUBLES_EQUAL( rad1 * M_PI * 0.5, len, 1e-6 );
  
  len = dom1.arc_length( xp.to_array(), (yp+z).to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_DOUBLES_EQUAL( rad1 * M_PI * 0.5, len, 1e-6 );
  
  Vector3D center(-1,-2,-1);
  Vector3D normal(-2,-1,-2);
  double rad = 1.5;
  CircleDomain dom2( center, normal, rad );
  
  Vector3D v(1,0,0);
  v = v * normal;
  v *= rad / v.length();
  v += center;
  len = dom2.arc_length( v.to_array(), v.to_array(), err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, len, 1e-6 );
}
コード例 #10
0
/** Test correct handling of QM negate flag */
void ObjectiveFunctionTests::test_negate_flag( 
                                       OFTestMode test_mode, 
                                       ObjectiveFunctionTemplate* of )
{
  const double some_vals[] = { 1, 2, 3, 4, 5, 6, 0.5 };
  const unsigned num_vals = sizeof(some_vals)/sizeof(some_vals[0]);
  OFTestQM metric( some_vals, num_vals );
  of->set_quality_metric(&metric);

  MsqPrintError err(cout);
  bool rval = false;
  double value[2];
  vector<Vector3D> grad[2];
  vector<SymMatrix3D> diag[2];
  MsqHessian hess[2];
  
    // Do twice, once w/out negate flag set and then once
    // with negate flag == -1.
  ObjectiveFunction::EvalType type = ObjectiveFunction::CALCULATE;
  for (unsigned i = 0; i < 2; ++i ) {
    switch (test_mode) {
      case EVAL:
        rval = of->evaluate( type, patch(), value[i], false, err );
        break;
      case GRAD:
        rval = of->evaluate_with_gradient( type, patch(), value[i], grad[i], err );
        break;
      case DIAG:
        rval = of->evaluate_with_Hessian_diagonal( type, patch(), value[i], grad[i], diag[i], err );
        break;
      case HESS:
        hess[i].initialize(patch(),err);
        ASSERT_NO_ERROR( err );
        rval = of->evaluate_with_Hessian( type, patch(), value[i], grad[i], hess[i], err );
        break;
      default:
        CPPUNIT_ASSERT_MESSAGE("Invalid enum value in test code",false);
        break;
    }
    ASSERT_NO_ERROR( err );
    CPPUNIT_ASSERT(rval);
    metric.set_negate_flag(-1);
  }
  
  switch (test_mode) {
    case HESS:
      CPPUNIT_ASSERT_EQUAL( hess[0].size(), hess[1].size() );
      for (size_t r = 0; r < hess[0].size(); ++r)
        for (size_t c = r; c < hess[0].size(); ++c)
          if (hess[0].get_block(r,c))
            CPPUNIT_ASSERT_MATRICES_EQUAL( -*hess[0].get_block(r,c),
                                           *hess[1].get_block(r,c),
                                           1e-6 );
    case DIAG:
      // NOTE: When case HESS: falls through to here, diag[0] and diag[1]
      // will be empty, making this a no-op.
      CPPUNIT_ASSERT_EQUAL( diag[0].size(), diag[1].size() );
      for (size_t j = 0; j < diag[0].size(); ++j) 
        CPPUNIT_ASSERT_MATRICES_EQUAL( -diag[0][j], diag[1][j], 1e-6 );
    case GRAD:
      CPPUNIT_ASSERT_EQUAL( grad[0].size(), grad[1].size() );
      for (size_t j = 0; j < grad[0].size(); ++j)
        CPPUNIT_ASSERT_VECTORS_EQUAL( -grad[0][j], grad[1][j], 1e-6 );
    default:
      CPPUNIT_ASSERT_DOUBLES_EQUAL( -value[0], value[1], 1e-6 );
  }
}
コード例 #11
0
void ObjectiveFunctionTests::compare_numerical_hessian( ObjectiveFunction* of,
                                                        bool diagonal_only )
{
  const double delta = 0.0001;

  MsqPrintError err(std::cout);
  PatchData pd;
  create_qm_two_tet_patch( pd, err ); 
  ASSERT_NO_ERROR( err );
  CPPUNIT_ASSERT( pd.num_free_vertices() != 0 );
  
    // get analytical Hessian from objective function
  std::vector<Vector3D> grad;
  std::vector<SymMatrix3D> diag;
  MsqHessian hess;
  hess.initialize( pd, err );
  ASSERT_NO_ERROR( err );
  double value;
  bool valid;
  if (diagonal_only)
    valid = of->evaluate_with_Hessian_diagonal( ObjectiveFunction::CALCULATE, pd, value, grad, diag, err );
  else
    valid = of->evaluate_with_Hessian( ObjectiveFunction::CALCULATE, pd, value, grad, hess, err );
  ASSERT_NO_ERROR(err); CPPUNIT_ASSERT(valid);

  
    // do numerical approximation of each block and compare to analytical value
  for (size_t i = 0; i < pd.num_free_vertices(); ++i) {
    const size_t j_end = diagonal_only ? i+1 : pd.num_free_vertices();
    for (size_t j = i; j < j_end; ++j) {
        // do numerical approximation for block corresponding to
        // coorindates for ith and jth vertices.
      Matrix3D block;    
      for (int k = 0; k < 3; ++k) {
        for (int m = 0; m < 3; ++m) {
          double dk, dm, dkm;
          Vector3D ik = pd.vertex_by_index(i);
          Vector3D im = pd.vertex_by_index(j);
          
          Vector3D delta_k(0.0); delta_k[k] = delta;
          pd.move_vertex( delta_k, i, err ); ASSERT_NO_ERROR(err);
          valid = of->evaluate( ObjectiveFunction::CALCULATE, pd, dk, true, err );
          ASSERT_NO_ERROR(err); CPPUNIT_ASSERT(valid);
          
          Vector3D delta_m(0.0); delta_m[m] = delta;
          pd.move_vertex( delta_m, j, err ); ASSERT_NO_ERROR(err);
          valid = of->evaluate( ObjectiveFunction::CALCULATE, pd, dkm, true, err );
          ASSERT_NO_ERROR(err); CPPUNIT_ASSERT(valid);
          
            // be careful here that we do the right thing if i==j
          pd.set_vertex_coordinates( ik, i, err ); ASSERT_NO_ERROR(err);
          pd.set_vertex_coordinates( im, j, err ); ASSERT_NO_ERROR(err);
          pd.move_vertex( delta_m, j, err ); ASSERT_NO_ERROR(err);
          valid = of->evaluate( ObjectiveFunction::CALCULATE, pd, dm, true, err );
          ASSERT_NO_ERROR(err); CPPUNIT_ASSERT(valid);
          
          pd.set_vertex_coordinates( ik, i, err ); ASSERT_NO_ERROR(err);
          pd.set_vertex_coordinates( im, j, err ); ASSERT_NO_ERROR(err);
          
          block[k][m] = (dkm - dk - dm + value)/(delta*delta);
        }
      }
        // compare to analytical value
      if (diagonal_only) {
        CPPUNIT_ASSERT(i == j); // see j_end above
        CPPUNIT_ASSERT(i < diag.size());
        CHECK_EQUAL_MATRICES( block, Matrix3D(diag[i]) );
      }
      else {
        Matrix3D* m = hess.get_block( i, j );
        Matrix3D* mt = hess.get_block( j, i );
        if (NULL != m) {
          CHECK_EQUAL_MATRICES( block, *m );
        }
        if (NULL != mt) {
          CHECK_EQUAL_MATRICES( transpose(block), *m );
        }
        if (NULL == mt && NULL == m) {
          CHECK_EQUAL_MATRICES( Matrix3D(0.0), block );
        }
      }
    }
  }
}
コード例 #12
0
ファイル: message_queue.c プロジェクト: Ewald123/midikit
/**
 * Test that items can be pushed and popped to and from
 * the MIDIMessageQueue.
 */
int test001_message_queue( void ) {
  struct MIDIMessageQueue * queue = MIDIMessageQueueCreate();
  struct MIDIMessage * message[3] = {
    MIDIMessageCreate( MIDI_STATUS_NOTE_ON ),
    MIDIMessageCreate( MIDI_STATUS_POLYPHONIC_KEY_PRESSURE ),
    MIDIMessageCreate( MIDI_STATUS_NOTE_OFF )
  };
  struct MIDIMessage * m;
  size_t length;
  MIDIKey key = 60;
  
  ASSERT_NOT_EQUAL( queue, NULL, "Could not create message queue." );
  ASSERT_NOT_EQUAL( message[0], NULL, "Could not create message 0." );
  ASSERT_NOT_EQUAL( message[1], NULL, "Could not create message 1." );
  ASSERT_NOT_EQUAL( message[2], NULL, "Could not create message 2." );
  
  ASSERT_NO_ERROR( MIDIMessageSet( message[0], MIDI_KEY, sizeof(MIDIKey), &key ),
    "Could not set key for message 0." );
  ASSERT_NO_ERROR( MIDIMessageSet( message[1], MIDI_KEY, sizeof(MIDIKey), &key ),
    "Could not set key for message 1." );
  ASSERT_NO_ERROR( MIDIMessageSet( message[2], MIDI_KEY, sizeof(MIDIKey), &key ),
    "Could not set key for message 2." );
  
  ASSERT_NO_ERROR( MIDIMessageQueuePush( queue, message[0] ),
    "Could not enqueue message 0." );
  ASSERT_NO_ERROR( MIDIMessageQueuePush( queue, message[1] ),
    "Could not enqueue message 1." );
  ASSERT_NO_ERROR( MIDIMessageQueuePush( queue, message[2] ),
    "Could not enqueue message 2." );
  
  ASSERT_NO_ERROR( MIDIMessageQueuePeek( queue, &m ),
    "Could not peek into queue." );
  ASSERT_EQUAL( m, message[0], "Queue returned wrong message." );
  
  ASSERT_NO_ERROR( MIDIMessageQueueGetLength( queue, &length),
    "Could not determine queue length." );
  ASSERT_EQUAL( length, 3, "Message queue returned wrong length." );
  
  ASSERT_NO_ERROR( MIDIMessageQueuePop( queue, &m), "Could not pop message." );
  ASSERT_EQUAL( m, message[0], "Queue returned wrong message." );
  MIDIMessageRelease( m );
  
  ASSERT_NO_ERROR( MIDIMessageQueuePop( queue, &m), "Could not pop message." );
  ASSERT_EQUAL( m, message[1], "Queue returned wrong message." );
  MIDIMessageRelease( m );
  
  ASSERT_NO_ERROR( MIDIMessageQueueGetLength( queue, &length),
    "Could not determine queue length." );
  ASSERT_EQUAL( length, 1, "Message queue returned wrong length." );
  
  MIDIMessageRelease( message[0] );
  MIDIMessageRelease( message[1] );
  MIDIMessageRelease( message[2] );
  MIDIMessageQueueRelease( queue );
  return 0;
}