MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Objective function: p-mean^p of p-mean^p of patch metric values. More...
#include <PatchPowerMeanP.hpp>
Public Member Functions | |
MESQUITE_EXPORT | PatchPowerMeanP (double power, QualityMetric *qm=0) |
MESQUITE_EXPORT | PatchPowerMeanP (const PatchPowerMeanP ©) |
copy constructor | |
virtual MESQUITE_EXPORT | ~PatchPowerMeanP () |
virtual MESQUITE_EXPORT bool | initialize_block_coordinate_descent (Mesh *mesh, MeshDomain *domain, const Settings *settings, PatchSet *user_set, MsqError &err) |
virtual MESQUITE_EXPORT bool | evaluate (EvalType type, PatchData &pd, double &value_out, bool free, MsqError &err) |
Evaluate objective function for specified patch. | |
virtual MESQUITE_EXPORT bool | evaluate_with_gradient (EvalType type, PatchData &pd, double &value_out, std::vector< Vector3D > &grad_out, MsqError &err) |
Evaluate objective function and gradient for specified patch. | |
virtual MESQUITE_EXPORT bool | evaluate_with_Hessian (EvalType type, PatchData &pd, double &value_out, std::vector< Vector3D > &grad_out, MsqHessian &Hessian_out, MsqError &err) |
Evaluate objective function and Hessian for specified patch. | |
virtual MESQUITE_EXPORT ObjectiveFunction * | clone () const |
Create copy with same state. |
Objective function: p-mean^p of p-mean^p of patch metric values.
Definition at line 45 of file PatchPowerMeanP.hpp.
MESQUITE_EXPORT MBMesquite::PatchPowerMeanP::PatchPowerMeanP | ( | double | power, |
QualityMetric * | qm = 0 |
||
) | [inline] |
power | The exponent to use for the power-mean |
qm | The quality metric. |
Definition at line 53 of file PatchPowerMeanP.hpp.
Referenced by clone().
: PMeanPTemplate( power, qm ) {}
MESQUITE_EXPORT MBMesquite::PatchPowerMeanP::PatchPowerMeanP | ( | const PatchPowerMeanP & | copy | ) | [inline] |
copy constructor
Define a copy constructor because the compiler-provided default one would also copy the temporary arrays, which would be a waste of time.
Definition at line 62 of file PatchPowerMeanP.hpp.
: PMeanPTemplate( copy ) {}
virtual MESQUITE_EXPORT MBMesquite::PatchPowerMeanP::~PatchPowerMeanP | ( | ) | [inline, virtual] |
Definition at line 65 of file PatchPowerMeanP.hpp.
{}
ObjectiveFunction * MBMesquite::PatchPowerMeanP::clone | ( | ) | const [virtual] |
Create copy with same state.
Create a new instance of the objective function that is a copy of the callee with the same accumulated values, parameters, etc.
Reimplemented from MBMesquite::PMeanPTemplate.
Definition at line 43 of file PatchPowerMeanP.cpp.
References PatchPowerMeanP().
{ return new PatchPowerMeanP( *this ); }
bool MBMesquite::PatchPowerMeanP::evaluate | ( | EvalType | type, |
PatchData & | pd, | ||
double & | value_out, | ||
bool | free, | ||
MsqError & | err | ||
) | [virtual] |
Evaluate objective function for specified patch.
Either evaluate the objective function over the passed patch or update the accumulated, global objective function value for changes in the passed patch, depending on the value of the EvalType.
type | Evaluation type. |
pd | The patch. |
value_out | The passed-back value of the objective fuction. |
free | If true, incorporate the quality metric values only for those metric evaluations that depend on at least one free vertex |
Reimplemented from MBMesquite::PMeanPTemplate.
Definition at line 73 of file PatchPowerMeanP.cpp.
References MBMesquite::ObjectiveFunction::ACCUMULATE, MBMesquite::QualityMetric::evaluate(), MBMesquite::QualityMetric::get_evaluations(), MBMesquite::QualityMetric::get_negate_flag(), MBMesquite::ObjectiveFunctionTemplate::get_quality_metric(), MBMesquite::QualityMetric::get_single_pass(), MBMesquite::PMeanPTemplate::get_value(), MBMesquite::PMeanPTemplate::mPower, MSQ_CHKERR, MSQ_ERRFALSE, MBMesquite::PMeanPTemplate::qmHandles, MBMesquite::Exponent::raise(), and value().
Referenced by initialize_block_coordinate_descent().
{ QualityMetric* qm = get_quality_metric(); if( type == ObjectiveFunction::ACCUMULATE ) qm->get_single_pass( pd, qmHandles, free, err ); else qm->get_evaluations( pd, qmHandles, free, err ); MSQ_ERRFALSE( err ); // calculate OF value for just the patch std::vector< size_t >::const_iterator i; double value, working_sum = 0.0; for( i = qmHandles.begin(); i != qmHandles.end(); ++i ) { bool result = qm->evaluate( pd, *i, value, err ); if( MSQ_CHKERR( err ) || !result ) return false; working_sum += mPower.raise( value ); } working_sum /= qmHandles.size(); // get overall OF value, update member data, etc. size_t global_count; value_out = qm->get_negate_flag() * get_value( working_sum, 1, type, global_count ); return true; }
bool MBMesquite::PatchPowerMeanP::evaluate_with_gradient | ( | EvalType | eval_type, |
PatchData & | pd, | ||
double & | OF_val, | ||
std::vector< Vector3D > & | grad, | ||
MsqError & | err | ||
) | [virtual] |
Evaluate objective function and gradient for specified patch.
Either evaluate the objective function over the passed patch or update the accumulated, global objective function value for changes in the passed patch, depending on the value of the EvalType.
The default implementation of this function will use the value-only variation of the evaluate method and numerical approximation to calculate gradients. Whenever possible, objective function implementations should provide more efficient analyical gradient calculations.
type | Evaluation type. |
pd | The patch. |
value_out | The passed-back value of the objective fuction. |
grad_out | The gradient of the OF wrt the coordinates of each *free* vertex in the patch. |
Numerically Calculates the gradient of the ObjectiveFunction for the free vertices in the patch. Returns 'false' if the patch is outside of a required feasible region, returns 'ture' otherwise. The behavior of the function depends on the value of the boolean useLocalGradient. If useLocalGradient is set to 'true', compute_numerical_gradient creates a sub-patch around a free vertex, and then perturbs that vertex in one of the coordinate directions. Only the ObjectiveFunction value on the local sub-patch is used in the computation of the gradient. Therefore, useLocalGradient should only be set to 'true' for ObjectiveFunctions which can use this method. Unless the concrete ObjectiveFunction sets useLocalGradient to 'true' in its constructor, the value will be 'false'. In this case, the objective function value for the entire patch is used in the calculation of the gradient. This is computationally expensive, but it is numerically correct for all (C_1) functions.
pd | PatchData on which the gradient is taken. |
grad | Array of Vector3D of length the number of vertices used to store gradient. |
OF_val | will be set to the objective function value. |
Reimplemented from MBMesquite::PMeanPTemplate.
Definition at line 100 of file PatchPowerMeanP.cpp.
References MBMesquite::QualityMetric::evaluate_with_gradient(), MBMesquite::QualityMetric::get_evaluations(), MBMesquite::QualityMetric::get_negate_flag(), MBMesquite::ObjectiveFunctionTemplate::get_quality_metric(), MBMesquite::PMeanPTemplate::get_value(), MBMesquite::PMeanPTemplate::mGradient, MBMesquite::PMeanPTemplate::mIndices, MBMesquite::PMeanPTemplate::mPower, MSQ_CHKERR, MSQ_ERRFALSE, MBMesquite::PatchData::num_free_vertices(), MBMesquite::OF_FREE_EVALS_ONLY, MBMesquite::PMeanPTemplate::qmHandles, MBMesquite::Exponent::raise(), MBMesquite::Exponent::value(), and value().
{ QualityMetric* qm = get_quality_metric(); qm->get_evaluations( pd, qmHandles, OF_FREE_EVALS_ONLY, err ); MSQ_ERRFALSE( err ); // zero gradient grad_out.clear(); grad_out.resize( pd.num_free_vertices(), Vector3D( 0.0, 0.0, 0.0 ) ); // calculate OF value and gradient for just the patch std::vector< size_t >::const_iterator i; double value, working_sum = 0.0; const double f = qm->get_negate_flag() * mPower.value() / qmHandles.size(); for( i = qmHandles.begin(); i != qmHandles.end(); ++i ) { bool result = qm->evaluate_with_gradient( pd, *i, value, mIndices, mGradient, err ); if( MSQ_CHKERR( err ) || !result ) return false; if( fabs( value ) < DBL_EPSILON ) continue; const double qmp = mPower.raise( value ); working_sum += mPower.raise( value ); value = f * qmp / value; for( size_t j = 0; j < mIndices.size(); ++j ) { mGradient[j] *= value; grad_out[mIndices[j]] += mGradient[j]; } } // get overall OF value, update member data, etc. size_t global_count; value_out = qm->get_negate_flag() * get_value( working_sum, 1, type, global_count ); const double inv_n = 1.0 / global_count; std::vector< Vector3D >::iterator g; for( g = grad_out.begin(); g != grad_out.end(); ++g ) *g *= inv_n; return true; }
bool MBMesquite::PatchPowerMeanP::evaluate_with_Hessian | ( | EvalType | type, |
PatchData & | pd, | ||
double & | value_out, | ||
std::vector< Vector3D > & | grad_out, | ||
MsqHessian & | Hessian_out, | ||
MsqError & | err | ||
) | [virtual] |
Evaluate objective function and Hessian for specified patch.
Either evaluate the objective function over the passed patch or update the accumulated, global objective function value for changes in the passed patch, depending on the value of the EvalType.
The default implementation of this function will fail.
type | Evaluation type. |
pd | The patch. |
value_out | The passed-back value of the objective fuction. |
grad_out | The gradient of the OF wrt the coordinates of each *free* vertex in the patch. |
Hessian_out | The Hessian of the OF wrt the coordinates of each *free* vertex in the patch. |
Reimplemented from MBMesquite::PMeanPTemplate.
Definition at line 145 of file PatchPowerMeanP.cpp.
References MBMesquite::MsqHessian::add(), MBMesquite::QualityMetric::evaluate_with_Hessian(), MBMesquite::QualityMetric::get_evaluations(), MBMesquite::QualityMetric::get_negate_flag(), MBMesquite::ObjectiveFunctionTemplate::get_quality_metric(), MBMesquite::PMeanPTemplate::get_value(), MBMesquite::PMeanPTemplate::mGradient, MBMesquite::PMeanPTemplate::mHessian, MBMesquite::PMeanPTemplate::mIndices, MBMesquite::PMeanPTemplate::mPower, MSQ_CHKERR, MSQ_ERRFALSE, n, MBMesquite::PatchData::num_free_vertices(), MBMesquite::OF_FREE_EVALS_ONLY, MBMesquite::PMeanPTemplate::qmHandles, MBMesquite::Exponent::raise(), MBMesquite::MsqHessian::scale(), MBMesquite::Exponent::value(), value(), and MBMesquite::MsqHessian::zero_out().
{ QualityMetric* qm = get_quality_metric(); qm->get_evaluations( pd, qmHandles, OF_FREE_EVALS_ONLY, err ); MSQ_ERRFALSE( err ); // zero gradient and hessian grad_out.clear(); grad_out.resize( pd.num_free_vertices(), 0.0 ); Hessian_out.zero_out(); // calculate OF value and gradient for just the patch std::vector< size_t >::const_iterator i; size_t j, k, n; double value, working_sum = 0.0; const double f1 = qm->get_negate_flag() * mPower.value() / qmHandles.size(); const double f2 = f1 * ( mPower.value() - 1 ); Matrix3D m; for( i = qmHandles.begin(); i != qmHandles.end(); ++i ) { bool result = qm->evaluate_with_Hessian( pd, *i, value, mIndices, mGradient, mHessian, err ); if( MSQ_CHKERR( err ) || !result ) return false; if( fabs( value ) < DBL_EPSILON ) continue; const double qmp = mPower.raise( value ); const double hf = f2 * qmp / ( value * value ); const double gf = f1 * qmp / value; working_sum += qmp; const size_t nfree = mIndices.size(); n = 0; for( j = 0; j < nfree; ++j ) { for( k = j; k < nfree; ++k ) { m.outer_product( mGradient[j], mGradient[k] ); m *= hf; mHessian[n] *= gf; m += mHessian[n]; ++n; Hessian_out.add( mIndices[j], mIndices[k], m, err ); MSQ_ERRFALSE( err ); } } for( j = 0; j < nfree; ++j ) { mGradient[j] *= gf; grad_out[mIndices[j]] += mGradient[j]; } } // get overall OF value, update member data, etc. size_t global_count; value_out = qm->get_negate_flag() * get_value( working_sum, 1, type, global_count ); const double inv_n = 1.0 / global_count; std::vector< Vector3D >::iterator g; for( g = grad_out.begin(); g != grad_out.end(); ++g ) *g *= inv_n; Hessian_out.scale( inv_n ); return true; }
bool MBMesquite::PatchPowerMeanP::initialize_block_coordinate_descent | ( | Mesh * | mesh, |
MeshDomain * | domain, | ||
const Settings * | settings, | ||
PatchSet * | user_set, | ||
MsqError & | err | ||
) | [virtual] |
Definition at line 48 of file PatchPowerMeanP.cpp.
References MBMesquite::ObjectiveFunction::ACCUMULATE, MBMesquite::PatchData::attach_settings(), b, MBMesquite::PMeanPTemplate::clear(), evaluate(), MBMesquite::PatchIterator::get_next_patch(), MSQ_CHKERR, MSQ_ERRZERO, MBMesquite::PatchData::set_domain(), MBMesquite::PatchData::set_mesh(), and value().
{ clear(); PatchIterator patches( patch_set ); PatchData pd; pd.set_mesh( mesh ); pd.set_domain( domain ); if( settings ) pd.attach_settings( settings ); bool result = true; while( patches.get_next_patch( pd, err ) && !MSQ_CHKERR( err ) ) { double value; bool b = evaluate( ObjectiveFunction::ACCUMULATE, pd, value, false, err ); MSQ_ERRZERO( err ); result = result && b; } return result; }