MOAB: Mesh Oriented datABase  (version 5.4.1)
MBMesquite::PMeanPMetric Class Reference

#include <PMeanPMetric.hpp>

+ Inheritance diagram for MBMesquite::PMeanPMetric:
+ Collaboration diagram for MBMesquite::PMeanPMetric:

Public Member Functions

 PMeanPMetric (double p)
const Exponentget_power () const

Protected Member Functions

bool average (PatchData &pd, QualityMetric *qm, const std::vector< size_t > &qm_handles, double &value, MsqError &)
bool average_with_indices (PatchData &pd, QualityMetric *qm, const std::vector< size_t > &qm_handles, double &value, std::vector< size_t > &indices, MsqError &err)
bool average_with_gradient (PatchData &pd, QualityMetric *qm, const std::vector< size_t > &qm_handles, double &value, std::vector< size_t > &indices, std::vector< Vector3D > &gradient, MsqError &err)
bool average_with_Hessian_diagonal (PatchData &pd, QualityMetric *metric, const std::vector< size_t > &qm_handles, double &value, std::vector< size_t > &indices, std::vector< Vector3D > &gradient, std::vector< SymMatrix3D > &Hessian_diagonal, MsqError &err)
bool average_with_Hessian (PatchData &pd, QualityMetric *metric, const std::vector< size_t > &qm_handles, double &value, std::vector< size_t > &indices, std::vector< Vector3D > &gradient, std::vector< Matrix3D > &Hessian, MsqError &err)

Private Attributes

Exponent P
Exponent P1
Exponent P2
std::vector< size_t > mIndices
std::vector< size_t > mOffsets
std::vector< Vector3DmGrad
std::vector< Matrix3DmHess
std::vector< SymMatrix3DmDiag
std::vector< double > mValues

Detailed Description

Definition at line 50 of file PMeanPMetric.hpp.


Constructor & Destructor Documentation

Definition at line 53 of file PMeanPMetric.hpp.

: P( p ), P1( p - 1.0 ), P2( p - 2.0 ) {}

Member Function Documentation

bool MBMesquite::PMeanPMetric::average ( PatchData pd,
QualityMetric qm,
const std::vector< size_t > &  qm_handles,
double &  value,
MsqError err 
) [protected]

Definition at line 44 of file PMeanPMetric.cpp.

References MBMesquite::QualityMetric::evaluate(), MSQ_ERRZERO, P, and MBMesquite::Exponent::raise().

Referenced by MBMesquite::ElementPMeanP::evaluate(), and MBMesquite::VertexPMeanP::evaluate().

{
    bool rval = true;
    value     = 0;
    for( std::vector< size_t >::const_iterator i = qm_handles.begin(); i != qm_handles.end(); ++i )
    {
        double mval;
        if( !metric->evaluate( pd, *i, mval, err ) ) rval = false;
        MSQ_ERRZERO( err );
        value += P.raise( mval );
    }
    value /= qm_handles.size();
    return rval;
}
bool MBMesquite::PMeanPMetric::average_with_gradient ( PatchData pd,
QualityMetric qm,
const std::vector< size_t > &  qm_handles,
double &  value,
std::vector< size_t > &  indices,
std::vector< Vector3D > &  gradient,
MsqError err 
) [protected]

Definition at line 91 of file PMeanPMetric.cpp.

References MBMesquite::QualityMetric::evaluate_with_gradient(), mGrad, mIndices, MSQ_ERRZERO, P, P1, MBMesquite::Exponent::raise(), and MBMesquite::Exponent::value().

Referenced by MBMesquite::ElementPMeanP::evaluate_with_gradient(), and MBMesquite::VertexPMeanP::evaluate_with_gradient().

{
    indices.clear();
    gradient.clear();

    std::vector< Vector3D >::iterator g;
    std::vector< size_t >::iterator j, k;
    std::vector< size_t >::const_iterator i;

    bool rval = true;
    value     = 0;
    for( i = qm_handles.begin(); i != qm_handles.end(); ++i )
    {

        double mval;
        mIndices.clear();
        mGrad.clear();
        if( !metric->evaluate_with_gradient( pd, *i, mval, mIndices, mGrad, err ) ) rval = false;
        MSQ_ERRZERO( err );
        value += P.raise( mval );

        double p1val = P.value() * P1.raise( mval );
        for( j = mIndices.begin(), g = mGrad.begin(); j != mIndices.end(); ++j, ++g )
        {

            *g *= p1val;
            k = std::lower_bound( indices.begin(), indices.end(), *j );
            if( k == indices.end() || *k != *j )
            {
                k          = indices.insert( k, *j );
                size_t idx = k - indices.begin();
                gradient.insert( gradient.begin() + idx, *g );
            }
            else
            {
                size_t idx = k - indices.begin();
                gradient[idx] += *g;
            }
        }
    }

    double inv_n = 1.0 / qm_handles.size();
    value *= inv_n;
    for( g = gradient.begin(); g != gradient.end(); ++g )
        *g *= inv_n;

    return rval;
}
bool MBMesquite::PMeanPMetric::average_with_Hessian ( PatchData pd,
QualityMetric metric,
const std::vector< size_t > &  qm_handles,
double &  value,
std::vector< size_t > &  indices,
std::vector< Vector3D > &  gradient,
std::vector< Matrix3D > &  Hessian,
MsqError err 
) [protected]

Definition at line 252 of file PMeanPMetric.cpp.

References MBMesquite::QualityMetric::evaluate_with_Hessian(), mGrad, mHess, mIndices, mOffsets, MSQ_ERRZERO, mValues, N, nr, MBMesquite::outer(), MBMesquite::Matrix3D::outer_product(), P, P2, MBMesquite::Exponent::raise(), and MBMesquite::Exponent::value().

Referenced by MBMesquite::ElementPMeanP::evaluate_with_Hessian(), and MBMesquite::VertexPMeanP::evaluate_with_Hessian().

{
    // clear temporary storage
    mIndices.clear();
    mGrad.clear();
    mHess.clear();
    mOffsets.clear();
    mValues.clear();

    // Evaluate metric for all sample points,
    // accumulating indices, gradients, and Hessians
    bool rval = true;
    std::vector< size_t >::const_iterator q;
    for( q = qm_handles.begin(); q != qm_handles.end(); ++q )
    {
        double mval;
        indices.clear();
        gradient.clear();
        Hessian.clear();
        if( !metric->evaluate_with_Hessian( pd, *q, mval, indices, gradient, Hessian, err ) ) rval = false;
        MSQ_ERRZERO( err );

        mValues.push_back( mval );
        mOffsets.push_back( mIndices.size() );
        std::copy( indices.begin(), indices.end(), std::back_inserter( mIndices ) );
        std::copy( gradient.begin(), gradient.end(), std::back_inserter( mGrad ) );
        std::copy( Hessian.begin(), Hessian.end(), std::back_inserter( mHess ) );
    }
    mOffsets.push_back( mIndices.size() );

    // Combine lists of free vertex indices, and update indices
    // in per-evaluation lists to point into the combined gradient
    // and Hessian lists.
    indices = mIndices;
    std::sort( indices.begin(), indices.end() );
    indices.erase( std::unique( indices.begin(), indices.end() ), indices.end() );
    std::vector< size_t >::iterator i, j;
    for( i = mIndices.begin(); i != mIndices.end(); ++i )
    {
        j = std::lower_bound( indices.begin(), indices.end(), *i );
        assert( *j == *i );
        *i = j - indices.begin();
    }

    // Allocate space and zero output gradient and Hessian lists
    const size_t N     = indices.size();
    const size_t m     = mValues.size();
    const double inv_n = 1.0 / m;
    double v;
    gradient.clear();
    gradient.resize( N, Vector3D( 0, 0, 0 ) );
    Hessian.clear();
    Hessian.resize( N * ( N + 1 ) / 2, Matrix3D( 0.0 ) );

    // Average values, gradients, Hessians
    Matrix3D outer;
    value                                           = 0.0;
    std::vector< Matrix3D >::iterator met_hess_iter = mHess.begin();
    for( size_t k = 0; k < m; ++k )
    {  // for each metric evaluate
        if( P.value() == 1.0 )
        {
            v = P.raise( mValues[k] );
            // for each gradient (or Hessian row) for the local metric evaluation
            for( size_t r = mOffsets[k]; r < mOffsets[k + 1]; ++r )
            {
                const size_t nr = mIndices[r];
                // for each column of the local metric Hessian
                for( size_t c = r; c < mOffsets[k + 1]; ++c )
                {
                    const size_t nc = mIndices[c];
                    *met_hess_iter *= inv_n;
                    if( nr <= nc )
                        Hessian[N * nr - nr * ( nr + 1 ) / 2 + nc] += *met_hess_iter;
                    else
                        Hessian[N * nc - nc * ( nc + 1 ) / 2 + nr].plus_transpose_equal( *met_hess_iter );
                    ++met_hess_iter;
                }
                mGrad[r] *= inv_n;
                gradient[nr] += mGrad[r];
            }
        }
        else
        {
            const double r2 = P2.raise( mValues[k] );
            const double r1 = r2 * mValues[k];
            v               = r1 * mValues[k];
            const double h  = r2 * P.value() * ( P.value() - 1 ) * inv_n;
            const double g  = r1 * P.value() * inv_n;
            // for each gradient (or Hessian row) for the local metric evaluation
            for( size_t r = mOffsets[k]; r < mOffsets[k + 1]; ++r )
            {
                const size_t nr = mIndices[r];
                // for each column of the local metric Hessian
                for( size_t c = r; c < mOffsets[k + 1]; ++c )
                {
                    const size_t nc = mIndices[c];
                    *met_hess_iter *= g;
                    outer.outer_product( mGrad[r], mGrad[c] );
                    outer *= h;
                    outer += *met_hess_iter;
                    if( nr <= nc )
                        Hessian[N * nr - nr * ( nr + 1 ) / 2 + nc] += outer;
                    else
                        Hessian[N * nc - nc * ( nc + 1 ) / 2 + nr].plus_transpose_equal( outer );
                    ++met_hess_iter;
                }
                mGrad[r] *= g;
                gradient[nr] += mGrad[r];
            }
        }
        value += v;
    }

    value *= inv_n;

    return rval;
}
bool MBMesquite::PMeanPMetric::average_with_Hessian_diagonal ( PatchData pd,
QualityMetric metric,
const std::vector< size_t > &  qm_handles,
double &  value,
std::vector< size_t > &  indices,
std::vector< Vector3D > &  gradient,
std::vector< SymMatrix3D > &  Hessian_diagonal,
MsqError err 
) [protected]

Definition at line 146 of file PMeanPMetric.cpp.

References MBMesquite::QualityMetric::evaluate_with_Hessian_diagonal(), mDiag, mGrad, mIndices, mOffsets, MSQ_ERRZERO, mValues, n, nr, MBMesquite::outer(), P, P2, MBMesquite::Exponent::raise(), and MBMesquite::Exponent::value().

Referenced by MBMesquite::ElementPMeanP::evaluate_with_Hessian_diagonal(), and MBMesquite::VertexPMeanP::evaluate_with_Hessian_diagonal().

{
    // clear temporary storage
    mIndices.clear();
    mGrad.clear();
    mDiag.clear();
    mOffsets.clear();
    mValues.clear();

    // Evaluate metric for all sample points,
    // accumulating indices, gradients, and Hessians
    bool rval = true;
    std::vector< size_t >::const_iterator q;
    for( q = qm_handles.begin(); q != qm_handles.end(); ++q )
    {
        double mval;
        indices.clear();
        gradient.clear();
        diagonal.clear();
        if( !metric->evaluate_with_Hessian_diagonal( pd, *q, mval, indices, gradient, diagonal, err ) ) rval = false;
        MSQ_ERRZERO( err );

        mValues.push_back( mval );
        mOffsets.push_back( mIndices.size() );
        std::copy( indices.begin(), indices.end(), std::back_inserter( mIndices ) );
        std::copy( gradient.begin(), gradient.end(), std::back_inserter( mGrad ) );
        std::copy( diagonal.begin(), diagonal.end(), std::back_inserter( mDiag ) );
    }
    mOffsets.push_back( mIndices.size() );

    // Combine lists of free vertex indices, and update indices
    // in per-evaluation lists to point into the combined gradient
    // and Hessian lists.
    indices = mIndices;
    std::sort( indices.begin(), indices.end() );
    indices.erase( std::unique( indices.begin(), indices.end() ), indices.end() );
    std::vector< size_t >::iterator i, j;
    for( i = mIndices.begin(); i != mIndices.end(); ++i )
    {
        j = std::lower_bound( indices.begin(), indices.end(), *i );
        assert( *j == *i );
        *i = j - indices.begin();
    }

    // Allocate space and zero output gradient and Hessian lists
    const size_t n     = indices.size();
    const size_t m     = mValues.size();
    const double inv_n = 1.0 / m;
    double v;
    gradient.clear();
    gradient.resize( n, Vector3D( 0, 0, 0 ) );
    diagonal.clear();
    diagonal.resize( n, SymMatrix3D( 0.0 ) );

    // Average values, gradients, Hessians
    value = 0.0;
    for( size_t k = 0; k < m; ++k )
    {  // for each metric evaluate
        if( P.value() == 1.0 )
        {
            v = P.raise( mValues[k] );
            // for each gradient (or Hessian) for the local metric evaluation
            for( size_t r = mOffsets[k]; r < mOffsets[k + 1]; ++r )
            {
                const size_t nr = mIndices[r];

                mDiag[r] *= inv_n;
                diagonal[nr] += mDiag[r];
                mGrad[r] *= inv_n;
                gradient[nr] += mGrad[r];
            }
        }
        else
        {
            const double r2 = P2.raise( mValues[k] );
            const double r1 = r2 * mValues[k];
            v               = r1 * mValues[k];
            const double h  = r2 * P.value() * ( P.value() - 1 ) * inv_n;
            const double g  = r1 * P.value() * inv_n;
            // for each gradient (or Hessian) for the local metric evaluation
            for( size_t r = mOffsets[k]; r < mOffsets[k + 1]; ++r )
            {
                const size_t nr = mIndices[r];

                mDiag[r] *= g;
                diagonal[nr] += mDiag[r];
                diagonal[nr] += h * outer( mGrad[r] );
                mGrad[r] *= g;
                gradient[nr] += mGrad[r];
            }
        }
        value += v;
    }

    value *= inv_n;

    return rval;
}
bool MBMesquite::PMeanPMetric::average_with_indices ( PatchData pd,
QualityMetric qm,
const std::vector< size_t > &  qm_handles,
double &  value,
std::vector< size_t > &  indices,
MsqError err 
) [protected]

Definition at line 63 of file PMeanPMetric.cpp.

References MBMesquite::QualityMetric::evaluate_with_indices(), mIndices, MSQ_ERRZERO, P, and MBMesquite::Exponent::raise().

Referenced by MBMesquite::VertexPMeanP::evaluate_with_indices().

{
    indices.clear();

    bool rval = true;
    value     = 0;
    for( std::vector< size_t >::const_iterator i = qm_handles.begin(); i != qm_handles.end(); ++i )
    {
        double mval;
        mIndices.clear();
        if( !metric->evaluate_with_indices( pd, *i, mval, mIndices, err ) ) rval = false;
        MSQ_ERRZERO( err );
        value += P.raise( mval );

        std::copy( mIndices.begin(), mIndices.end(), std::back_inserter( indices ) );
    }
    std::sort( indices.begin(), indices.end() );
    indices.erase( std::unique( indices.begin(), indices.end() ), indices.end() );

    value /= qm_handles.size();
    return rval;
}
const Exponent& MBMesquite::PMeanPMetric::get_power ( ) const [inline]

Definition at line 55 of file PMeanPMetric.hpp.

References P.

    {
        return P;
    }

Member Data Documentation

std::vector< SymMatrix3D > MBMesquite::PMeanPMetric::mDiag [private]

Definition at line 103 of file PMeanPMetric.hpp.

Referenced by average_with_Hessian_diagonal().

std::vector< Matrix3D > MBMesquite::PMeanPMetric::mHess [private]

Definition at line 102 of file PMeanPMetric.hpp.

Referenced by average_with_Hessian().

std::vector< size_t > MBMesquite::PMeanPMetric::mOffsets [private]

Definition at line 100 of file PMeanPMetric.hpp.

Referenced by average_with_Hessian(), and average_with_Hessian_diagonal().

std::vector< double > MBMesquite::PMeanPMetric::mValues [private]

Definition at line 104 of file PMeanPMetric.hpp.

Referenced by average_with_Hessian(), and average_with_Hessian_diagonal().

Definition at line 98 of file PMeanPMetric.hpp.

Referenced by average_with_gradient().

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines