예제 #1
0
void CircleDomainTest::test_snap_to()
{
  Vector3D origin(0,0,0);
  Vector3D z(0,0,1);
  double rad1 = 4.0/3.0;
  CircleDomain dom1( origin, z, rad1 );
  Vector3D pt( 1, 0, 0 );
  dom1.snap_to( 0, pt );
  CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D(rad1,0,0), pt, 1e-6 );
  Vector3D a = Vector3D( 1, 2, 3 );
  pt = a;
  dom1.snap_to( 0, pt );
  a = Vector3D( 1, 2, 0 );
  a *= rad1 / a.length();
  CPPUNIT_ASSERT_VECTORS_EQUAL( a, pt, 1e-6 );
  
  Vector3D some_pt(5,-1,6);
  Vector3D some_dir(-5,-4,1);
  double rad2 = 1.0;
  CircleDomain dom2( some_pt, some_dir, rad2 );
  
  a = Vector3D( 0, 0, 0);
  pt = a;
  dom2.snap_to( 0, pt );
  CPPUNIT_ASSERT_DOUBLES_EQUAL( rad2, (pt - some_pt).length(), 1e-6 ); // rad from center
  CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, (pt - some_pt) % some_dir, 1e-6 );// in plane
  CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ((pt - some_pt) * (a - some_pt)) % some_dir, 1e-6 ); // correct direction from center

  a = Vector3D( 0, -1, -2 );
  pt = a;
  dom2.snap_to( 0, pt );
  CPPUNIT_ASSERT_DOUBLES_EQUAL( rad2, (pt - some_pt).length(), 1e-6 ); // rad from center
  CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, (pt - some_pt) % some_dir, 1e-6 );// in plane
  CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ((pt - some_pt) * (a - some_pt)) % some_dir, 1e-6 ); // correct direction from center
}
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 );
  }
}
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 );
  }
}
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
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 );
}
/** 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 );
  }
}