template <unsigned DIM> static inline
bool grad( const MsqMatrix<DIM,DIM>& T, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv_wrt_T )
{
  const double tr = trace(T);
  const double f = DimConst<DIM>::inv() * fabs(tr);
  result = sqr_Frobenius( T ) - f * tr;
  deriv_wrt_T = T;
  pluseq_scaled_I( deriv_wrt_T, -f );
  deriv_wrt_T *= 2;
  return true;
}
Пример #2
0
bool TShape3DB2::evaluate_with_grad( const MsqMatrix<3,3>& T, 
                                     double& result, 
                                     MsqMatrix<3,3>& wrt_T,
                                     MsqError& err )
{
  double f = sqr_Frobenius(T);
  double g = sqr_Frobenius(adj(T));
  double d = det(T);
  if (invalid_determinant(d)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  result = (f*g) / (9*d*d) - 1;
  
  wrt_T = T;
  wrt_T *= (g + f*f);
  wrt_T -= f * (T * transpose(T) * T);
  wrt_T -= f * g / d * transpose_adj(T);
  wrt_T *= 2 / (9*d*d);
  
  return true;
}
Пример #3
0
bool TShapeOrientB2::evaluate( const MsqMatrix<2,2>& T, 
                               double& result, 
                               MsqError& err )
{
  double tau = det(T);
  if (TMetric::invalid_determinant(tau)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  const double tr = trace(T);
  result = (0.5/tau) * (sqr_Frobenius( T ) - 0.5 * tr * fabs(tr));
  return true;
}
bool TShapeB1::evaluate( const MsqMatrix<2,2>& T, 
                         double& result, 
                         MsqError& err)
{
  const double d = det(T);
  if (invalid_determinant(d)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
    
  result = 0.5 * sqr_Frobenius(T) / d - 1;
  return true;
}
Пример #5
0
bool TShapeSize2DNB2::evaluate_with_hess( const MsqMatrix<2,2>& T, 
                                          double& result, 
                                          MsqMatrix<2,2>& deriv_wrt_T,
                                          MsqMatrix<2,2> second[3],
                                          MsqError& err )
{
  double frob_sqr = sqr_Frobenius(T);
  double psi = sqrt( frob_sqr + 2.0*det(T) );

  double a = 1e-12;
  while (!Mesquite::divide(frob_sqr+2,2*psi,result)) {
    MsqMatrix<2,2> Tdelta(T);
    Tdelta(0,0) += a;
    Tdelta(1,1) += a;
    a *= 2.0;
    frob_sqr = sqr_Frobenius(Tdelta);
    psi = sqrt( frob_sqr + 2.0*det(Tdelta) );
    if (psi > 1e-50) 
      result = (frob_sqr+2) / 2*psi;
  }
  
  const double inv_psi = 1.0/psi;
  MsqMatrix<2,2> d_psi = T + transpose_adj(T);
  d_psi *= inv_psi;

  deriv_wrt_T = d_psi;
  deriv_wrt_T *= -result;
  deriv_wrt_T += T;
  deriv_wrt_T *= inv_psi; 
  
  set_scaled_2nd_deriv_wrt_psi( second, -result*inv_psi, psi, T );
  pluseq_scaled_outer_product( second,  2*result*inv_psi*inv_psi, d_psi );
  pluseq_scaled_sum_outer_product( second, -inv_psi*inv_psi, d_psi, T );
  pluseq_scaled_I( second, inv_psi );
  
  result -= 1.0;
  
  return true;
}
Пример #6
0
/** \f$ \mu(T) = \frac{|T|^2+2}{2\psi(T)} - 1 \f$
 *  \f$ \psi(T) = \sqrt{|T|^2 + 2 \tau}\f$
 *  \f$ \tau = det(T) \f$
 */
bool TShapeSize2DNB2::evaluate( const MsqMatrix<2,2>& T, 
                                double& result, 
                                MsqError&  )
{
  double frob_sqr = sqr_Frobenius(T);
  double psi = sqrt( frob_sqr + 2.0*det(T) );

  double a = 1e-12;
  while (!Mesquite::divide(frob_sqr+2,2*psi,result)) {
    MsqMatrix<2,2> Tdelta(T);
    Tdelta(0,0) += a;
    Tdelta(1,1) += a;
    a *= 2.0;
    frob_sqr = sqr_Frobenius(Tdelta);
    psi = sqrt( frob_sqr + 2.0*det(Tdelta) );
    if (psi > 1e-50) 
     result = (frob_sqr+2) / 2*psi;
  }

  result -= 1.0;
  return true;
}
Пример #7
0
bool TShapeSizeB3::evaluate( const MsqMatrix<2,2>& T, 
                                           double& result, 
                                           MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  result = sqr_Frobenius(T) - 2.0 * std::log(tau) - 2;
  return true;
}
Пример #8
0
template <unsigned DIM> static inline
bool hess( const MsqMatrix<DIM,DIM>& A, 
           const MsqMatrix<DIM,DIM>& W, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv, 
           MsqMatrix<DIM,DIM>* second )
{
  deriv = A - W;
  result = sqr_Frobenius( deriv );
  deriv *= 2.0;
  set_scaled_I( second, 2.0 );
  return true;
}
bool TShapeSize2DB2::evaluate( const MsqMatrix<2,2>& T, 
                               double& result, 
                               MsqError& err )
{
  const double two_det = 2.0 * det(T);
  if (invalid_determinant(two_det)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
    
  const double frob_sqr = sqr_Frobenius(T);
  result = (frob_sqr - 2.0 * sqrt( frob_sqr + two_det ) + 2.0)/two_det;
  return true;
}
bool AWShape2DNB1::evaluate_with_grad( const MsqMatrix<2,2>& A,
                                       const MsqMatrix<2,2>& W,
                                       double& result,
                                       MsqMatrix<2,2>& deriv_wrt_A,
                                       MsqError& )
{
  const double alpha = det(A);
  const double omega = det(W);
  const MsqMatrix<2,2> AtA = transpose(A) * A;
  const MsqMatrix<2,2> WtW = transpose(W) * W;
  const MsqMatrix<2,2> AWt = A * transpose(W);
  const double alphaWtW = alpha * sqr_Frobenius(WtW);
  const double omegaAtA = omega * sqr_Frobenius(AtA);
  const double omegaAWt = omega * sqr_Frobenius(AWt);
  result  =  omega*omegaAtA;
  result +=  alpha*alphaWtW;
  result -=  2*alpha*omegaAWt;
  
  deriv_wrt_A =  4*omega*omega * A * transpose(A) * A;
  deriv_wrt_A -= 4*alpha*omega * AWt * W;
  deriv_wrt_A += 2*(alphaWtW - omegaAWt) * transpose_adj(A);
  return true;
}
bool Target3DShapeOrientBarrierAlt1::evaluate_with_Hess( const MsqMatrix<3,3>& A, 
                                                        const MsqMatrix<3,3>& W, 
                                                        double& result, 
                                                        MsqMatrix<3,3>& deriv_wrt_A,
                                                        MsqMatrix<3,3> second_wrt_A[6],
                                                        MsqError& err )
{
  MsqMatrix<3,3> Winv = inverse(W);
  MsqMatrix<3,3> T = A * Winv;
  double tau = det(T);
  if (invalid_determinant(tau)) {
    result = 0.0;
    return false;
  }
  const double b = 0.5/tau;

    // calculate non-barrier value (ShapeOrientAlt1)
  const double tr = trace(T);
  const double f = MSQ_ONE_THIRD * fabs(tr);
  result = sqr_Frobenius( T ) - f * tr;
  
    // calculate non-barrier first derivatives
  deriv_wrt_A = T;
  deriv_wrt_A(0,0) -= f;
  deriv_wrt_A(1,1) -= f;
  deriv_wrt_A(2,2) -= f;
  deriv_wrt_A *= 2;
  
    // calculate barrier second derivs
  const MsqMatrix<3,3> adjt = transpose_adj(T);
  set_scaled_sum_outer_product( second_wrt_A, -b/tau, deriv_wrt_A, adjt );
  pluseq_scaled_outer_product( second_wrt_A, result/(tau*tau*tau), adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_A, -result * b / tau, T );
    // calculate non-barrier barrier portion of second derivs
  pluseq_scaled_I( second_wrt_A, 1/tau );
  pluseq_scaled_outer_product_I_I( second_wrt_A, MSQ_ONE_THIRD/tau * (tr < 0 ? 1 : -1) );
  
    // calculate barrier derivs from non-barrier
  deriv_wrt_A *= tau;
  deriv_wrt_A -= result * adjt;
  deriv_wrt_A *= b/tau;
  
    // barrier value from non-barrier
  result *= b;
  
    // convert from derivs wrt T to derivs wrt A
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);
  second_deriv_wrt_product_factor( second_wrt_A, Winv );
  return true;
}
Пример #12
0
bool Target2DShapeBarrier::evaluate( const MsqMatrix<2,2>& A, 
                                     const MsqMatrix<2,2>& W, 
                                     double& result, 
                                     MsqError& )
{
  const MsqMatrix<2,2> T = A * inverse(W);
  const double d = det(T);
  if (invalid_determinant(d)) { // barrier
    result = 0.0;
    return false;
  }
    
  result = 0.5 * sqr_Frobenius(T) / d - 1;
  return true;
}
bool Target3DShapeOrientBarrierAlt1::evaluate( const MsqMatrix<3,3>& A, 
                                              const MsqMatrix<3,3>& W, 
                                              double& result, 
                                              MsqError&  )
{
  const MsqMatrix<3,3> T = A * inverse(W);
  double tau = det(T);
  if (invalid_determinant(tau)) {
    result = 0.0;
    return false;
  }
  const double tr = trace(T);
  result = (0.5/tau) * (sqr_Frobenius( T ) - MSQ_ONE_THIRD * tr * fabs(tr));
  return true;
}
Пример #14
0
bool TShapeSizeB1::evaluate( const MsqMatrix<2,2>& T, 
                             double& result, 
                             MsqError&  )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const double nT = sqr_Frobenius(T);
  const double f = 1/(tau*tau);
  result = (1 + f) * nT - 4;
  return true;
}
Пример #15
0
bool TShapeSizeOrientB1::evaluate( const MsqMatrix<2,2>& T, 
                                   double& result, 
                                   MsqError& err )
{
  double tau = det(T);
  if (TMetric::invalid_determinant(tau)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  MsqMatrix<2,2> T_I(T);
  pluseq_scaled_I( T_I, -1 );
  result = sqr_Frobenius( T_I ) / (2*tau);
  return true;
}
template <unsigned DIM> static inline
bool hess( const MsqMatrix<DIM,DIM>& T, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv_wrt_T, 
           MsqMatrix<DIM,DIM>* second_wrt_T )
{
  const double tr = trace(T);
  const double f = DimConst<DIM>::inv() * fabs(tr);
  result = sqr_Frobenius( T ) - f * tr;
  deriv_wrt_T = T;
  pluseq_scaled_I( deriv_wrt_T, -f );
  deriv_wrt_T *= 2;
  set_scaled_I( second_wrt_T, 2.0 );
  pluseq_scaled_outer_product_I_I( second_wrt_T, DimConst<DIM>::inv() * (tr < 0 ? 2 : -2) );
  return true;
}
Пример #17
0
bool InverseMeanRatio2D::evaluate( const MsqMatrix<2,2>& A, 
                                   const MsqMatrix<2,2>& W, 
                                   double& result, 
                                   MsqError& err )
{
  const MsqMatrix<2,2> T = A * inverse(W);
  const double d = det( T );
  if (invalid_determinant(d)) {
    result = 0.0;
    return false;
  }
  else {
    result = sqr_Frobenius(T) / (2 * d) - 1;
    return true;
  }
}
Пример #18
0
bool TShapeSizeB3::evaluate_with_grad( const MsqMatrix<2,2>& T,
                                                     double& result,
                                                     MsqMatrix<2,2>& deriv_wrt_T,
                                                     MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  result = sqr_Frobenius(T) - 2.0 * std::log(tau) - 2;
  deriv_wrt_T = T;
  deriv_wrt_T -= 1/tau * transpose_adj(T);
  deriv_wrt_T *= 2;
  
  return true;
}
Пример #19
0
bool TShapeOrientB2::evaluate_with_hess( const MsqMatrix<3,3>& T, 
                                         double& result, 
                                         MsqMatrix<3,3>& deriv_wrt_T,
                                         MsqMatrix<3,3> second_wrt_T[6],
                                         MsqError& err )
{
  double tau = det(T);
  if (TMetric::invalid_determinant(tau)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    result = 0.0;
    return false;
  }
  const double b = 0.5/tau;

    // calculate non-barrier value (ShapeOrientAlt1)
  const double tr = trace(T);
  const double f = MSQ_ONE_THIRD * fabs(tr);
  result = sqr_Frobenius( T ) - f * tr;
  
    // calculate non-barrier first derivatives
  deriv_wrt_T = T;
  pluseq_scaled_I( deriv_wrt_T, -f );
  deriv_wrt_T *= 2;
  
    // calculate barrier second derivs
  const MsqMatrix<3,3> adjt = transpose_adj(T);
  set_scaled_sum_outer_product( second_wrt_T, -b/tau, deriv_wrt_T, adjt );
  pluseq_scaled_outer_product( second_wrt_T, result/(tau*tau*tau), adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -result * b / tau, T );
    // calculate non-barrier barrier portion of second derivs
  pluseq_scaled_I( second_wrt_T, 1/tau );
  pluseq_scaled_outer_product_I_I( second_wrt_T, MSQ_ONE_THIRD/tau * (tr < 0 ? 1 : -1) );
  
    // calculate barrier derivs from non-barrier
  deriv_wrt_T *= tau;
  deriv_wrt_T -= result * adjt;
  deriv_wrt_T *= b/tau;
  
    // barrier value from non-barrier
  result *= b;
  return true;
}
bool TShapeB1::evaluate_with_grad( const MsqMatrix<2,2>& T,
                                   double& result,
                                   MsqMatrix<2,2>& deriv_wrt_T,
                                   MsqError& err )
{
  const double d = det(T);
  if (invalid_determinant(d)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  double inv_d = 1.0/d;
  result = 0.5 * sqr_Frobenius(T) * inv_d;
  deriv_wrt_T = T;
  deriv_wrt_T -= result * transpose_adj(T);
  deriv_wrt_T *= inv_d;

  result -= 1.0;
  return true;
}
Пример #21
0
bool TShapeSizeOrientB1::evaluate_with_grad( const MsqMatrix<3,3>& T,
                                            double& result,
                                            MsqMatrix<3,3>& deriv_wrt_T,
                                            MsqError& err )
{
  const double d = det(T);
  if (TMetric::invalid_determinant(d)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  deriv_wrt_T = T;
  pluseq_scaled_I( deriv_wrt_T, -1 );
  double inv_d = 1.0/d;
  result = 0.5 * sqr_Frobenius(deriv_wrt_T) * inv_d;
  
  deriv_wrt_T -= result * transpose_adj(T);
  deriv_wrt_T *= inv_d;
  
  return true;
}
Пример #22
0
bool TShapeSizeB1::evaluate_with_grad( const MsqMatrix<2,2>& T,
                                       double& result,
                                       MsqMatrix<2,2>& deriv_wrt_T,
                                       MsqError& )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const MsqMatrix<2,2> adjt = transpose_adj(T);
  const double nT = sqr_Frobenius(T);
  const double f = 1/(tau*tau);
  result = (1 + f) * nT - 4;
  
  deriv_wrt_T = T;
  deriv_wrt_T *= 2 + 2*f;
  deriv_wrt_T -= 2 * f/tau * nT * adjt;
  
  return true;
}
Пример #23
0
bool Target2DShapeBarrier::evaluate_with_grad( const MsqMatrix<2,2>& A,
                                               const MsqMatrix<2,2>& W,
                                               double& result,
                                               MsqMatrix<2,2>& deriv_wrt_A,
                                               MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  const double d = det(T);
  if (invalid_determinant(d)) { // barrier
    result = 0.0;
    return false;
  }
  
  double inv_d = 1.0/d;
  result = 0.5 * sqr_Frobenius(T) * inv_d;
  deriv_wrt_A = T;
  deriv_wrt_A -= result * transpose_adj(T);
  deriv_wrt_A *= inv_d;
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);

  result -= 1.0;
  return true;
}
bool TShapeSize2DB2::evaluate_with_grad( const MsqMatrix<2,2>& T, 
                                         double& result, 
                                         MsqMatrix<2,2>& deriv_wrt_T,
                                         MsqError& err )
{
  const double d = det(T);
  if (invalid_determinant(d)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  const double frob_sqr = sqr_Frobenius(T);
  const double psi = sqrt( frob_sqr + 2.0*det(T) );
  const double v = frob_sqr - 2.0 * psi + 2.0;
  result = v / (2*d);

    // deriv of V wrt T
  MsqMatrix<2,2> adjt = transpose_adj(T);
  MsqMatrix<2,2> v_wrt_T(T);
  if (psi > 1e-50)
  {
    v_wrt_T *= (1.0 - 1.0/psi);
    v_wrt_T -= 1.0/psi * adjt;
    v_wrt_T *= 2;
  }
  else
  {
    std::cout << "Warning: Division by zero avoided in TShapeSize2DB2::evaluate_with_grad()" << std::endl;
  }
  
    // deriv of mu wrt T
  deriv_wrt_T = v_wrt_T;
  deriv_wrt_T *= 0.5/d;
  deriv_wrt_T -= v / (2*d*d) * adjt;
  
  return true;
}
Пример #25
0
template <unsigned DIM> static inline
bool eval( const MsqMatrix<DIM,DIM>& T, double& result)
{
    result = sqr_Frobenius( T );
    return true;
}