bool TMPQualityMetric::evaluate_with_indices( PatchData& pd, size_t handle, double& value, std::vector<size_t>& indices, MsqError& err ) { indices.resize( MAX_ELEM_NODES ); size_t num_idx = 0; bool result = evaluate_internal( pd, handle, value, arrptr(indices), num_idx, err ); if (MSQ_CHKERR(err) || !result) return false; indices.resize( num_idx ); // apply target weight to value if (weightCalc) { const Sample s = ElemSampleQM::sample( handle ); const size_t e = ElemSampleQM:: elem( handle ); double ck = weightCalc->get_weight( pd, e, s, err ); MSQ_ERRZERO(err); value *= ck; } return true; }
void ObjectiveFunctionTests::test_value( const double* input_values, unsigned num_input_values, double expected_value, OFTestMode test_mode, ObjectiveFunctionTemplate* of ) { OFTestQM metric( input_values, num_input_values ); of->set_quality_metric( &metric ); double val = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( expected_value, val, 1e-6 ); }
bool TMPQualityMetric::evaluate( PatchData& pd, size_t handle, double& value, MsqError& err ) { size_t num_idx; bool valid = evaluate_internal( pd, handle, value, mIndices, num_idx, err ); if (MSQ_CHKERR(err) || !valid) return false; // apply target weight to value if (weightCalc) { const Sample s = ElemSampleQM::sample( handle ); const size_t e = ElemSampleQM:: elem( handle ); double ck = weightCalc->get_weight( pd, e, s, err ); MSQ_ERRZERO(err); value *= ck; } return true; }
void ObjectiveFunctionTests::test_clone( 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); // test that we get the same value from both auto_ptr<ObjectiveFunction> of2( of->clone() ); double exp_val, val; exp_val = evaluate_internal( ObjectiveFunction::CALCULATE, EVAL, of ); val = evaluate_internal( ObjectiveFunction::CALCULATE, EVAL, of2.get() ); CPPUNIT_ASSERT_DOUBLES_EQUAL( exp_val, val, 1e-12 ); // check if OF supports BCD -- if not then done MsqError err; of->evaluate( ObjectiveFunction::UPDATE, patch(), val, false, err ); if (err) { err.clear(); return; } // build up some saved state in the objective function of->clear(); const double vals1[] = { 1.0, 3.0, 4.0, 8.0 }; const size_t vals1_len = sizeof(vals1)/sizeof(vals1[0]); const double vals2[] = { 21.5, 11.1, 30.0, 0.5 }; const size_t vals2_len = sizeof(vals2)/sizeof(vals2[0]); metric.set_values( vals1, vals1_len ); evaluate_internal( ObjectiveFunction::SAVE, EVAL, of ); metric.append_values( vals2, vals2_len ); evaluate_internal( ObjectiveFunction::ACCUMULATE, EVAL, of ); // check that clone has same accumulated data of2 = auto_ptr<ObjectiveFunction>(of->clone()); metric.set_values( some_vals, num_vals ); exp_val = evaluate_internal( ObjectiveFunction::UPDATE, EVAL, of ); val = evaluate_internal( ObjectiveFunction::UPDATE, EVAL, of2.get() ); CPPUNIT_ASSERT_DOUBLES_EQUAL( exp_val, val, 1e-12 ); }
void ObjectiveFunctionTests::test_eval_type( ObjectiveFunction::EvalType type, OFTestMode test_mode, ObjectiveFunctionTemplate* of ) { // define two sets of quality metric values const double vals1[] = { 1.0, 3.0, 4.0, 8.0 }; const size_t vals1_len = sizeof(vals1)/sizeof(vals1[0]); const double vals2[] = { 21.5, 11.1, 30.0, 0.5 }; const size_t vals2_len = sizeof(vals2)/sizeof(vals2[0]); // create a quality metric to use OFTestQM metric; of->set_quality_metric( &metric ); // get some initial values to compare to of->clear(); metric.set_values( vals1, vals1_len ); const double init1 = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); of->clear(); metric.set_values( vals2, vals2_len ); const double init2 = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); of->clear(); metric.append_values( vals1, vals1_len ); const double inits = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); of->clear(); double val, expected; switch (type) { case ObjectiveFunction::CALCULATE: // first make sure we get back the same values metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init1, val, 1e-6 ); metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init2, val, 1e-6 ); // now do something that should modify the accumulated value of the OF evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); // check that the values are unchanged metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init1, val, 1e-6 ); metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init2, val, 1e-6 ); break; case ObjectiveFunction::ACCUMULATE: // begin with first set metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init1, val, 1e-6 ); // add in second set metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( inits, val, 1e-6 ); // clear of->clear(); // begin with second set metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init2, val, 1e-6 ); // add in first set metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( inits, val, 1e-6 ); break; case ObjectiveFunction::SAVE: // calculate value for first set twice metric.set_values( vals1, vals1_len ); metric.append_values( vals1, vals1_len ); expected = evaluate_internal( ObjectiveFunction::CALCULATE, test_mode, of ); // begin with the first set metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init1, val, 1e-6 ); // add the second set metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( inits, val, 1e-6 ); // now save the second set of values - OF value should not change metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::SAVE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( inits, val, 1e-6 ); // now replace the second set with the first metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::UPDATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( expected, val, 1e-6 ); // check that saved values are cleared of->clear(); metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::UPDATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init2, val, 1e-6 ); break; case ObjectiveFunction::UPDATE: // With no saved data, an update should produce the same // result as CALCULATE metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::UPDATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init1, val, 1e-6 ); // Doing an update with a second patch should change // the global value to that of the second set metric.set_values( vals2, vals2_len ); val = evaluate_internal( ObjectiveFunction::UPDATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init2, val, 1e-6 ); // Now add in the second set again metric.set_values( vals2, vals2_len ); evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); // Now replace one accumulation of the second set with the first // Should result in the first set + the second set metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::UPDATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( inits, val, 1e-6 ); break; case ObjectiveFunction::TEMPORARY: // With no saved data, an TEMPORARY should produce the same // result as CALCULATE metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::TEMPORARY, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( init1, val, 1e-6 ); // Begin with two instances of the second set in the // accumulated value, with one instance saved so it // can be removed later metric.set_values( vals2, vals2_len ); evaluate_internal( ObjectiveFunction::ACCUMULATE, test_mode, of ); evaluate_internal( ObjectiveFunction::UPDATE, test_mode, of ); // Now do a temporary eval, replacing one instance of the // second set wiht the first set metric.set_values( vals1, vals1_len ); val = evaluate_internal( ObjectiveFunction::TEMPORARY, test_mode, of ); // TEMPORARY should produce the same value as UPDATE, but without // modifying any internal state. expected = evaluate_internal( ObjectiveFunction::UPDATE, test_mode, of ); CPPUNIT_ASSERT_DOUBLES_EQUAL( expected, val, 1e-6 ); break; default: CPPUNIT_ASSERT_MESSAGE("No test for specified evaluation type", false); break; } }