示例#1
0
bool TShapeOrientB1::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                         double& result,
                                         MsqMatrix<2,2>& deriv_wrt_T,
                                         MsqMatrix<2,2> second_wrt_T[3],
                                         MsqError& err )
{
  const double norm = Frobenius(T);
  const double invroot = 1.0/MSQ_SQRT_TWO;
  const double tau = det(T);
  if (TMetric::invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  const double inv_tau = 1.0/tau;
  const double invnorm = 1.0/norm;
  
  const double f = norm - invroot * trace(T);
  result = 0.5 * inv_tau * f;

  const MsqMatrix<2,2> adjt = transpose_adj(T);
  deriv_wrt_T = invnorm * T;
  pluseq_scaled_I( deriv_wrt_T, -invroot );
  deriv_wrt_T *= 0.5;
  deriv_wrt_T -= result * adjt;
  deriv_wrt_T *= inv_tau;
  
  const double a = 0.5 * inv_tau * invnorm;
  set_scaled_outer_product( second_wrt_T, -a*invnorm*invnorm, T );
  pluseq_scaled_I( second_wrt_T, a );
  pluseq_scaled_outer_product( second_wrt_T, f*inv_tau*inv_tau*inv_tau, adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -0.5*f*inv_tau*inv_tau, T );
  pluseq_scaled_sum_outer_product( second_wrt_T, -0.5*inv_tau*inv_tau*invnorm, T, adjt );
  pluseq_scaled_sum_outer_product_I( second_wrt_T, 0.5*inv_tau*inv_tau*invroot, adjt );
  return true;
}
bool TShapeSizeOrientB1::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                             double& result,
                                             MsqMatrix<2,2>& deriv_wrt_T,
                                             MsqMatrix<2,2> second_wrt_T[3],
                                             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.0 );
  double inv_d = 1.0/d;
  result = 0.5 * sqr_Frobenius(deriv_wrt_T) * inv_d;
  
  MsqMatrix<2,2> adjt = transpose_adj(T);
  set_scaled_outer_product( second_wrt_T, 2*result*inv_d*inv_d, adjt );
  pluseq_scaled_sum_outer_product( second_wrt_T, -inv_d*inv_d, deriv_wrt_T, adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -result * inv_d, T );
  pluseq_scaled_I( second_wrt_T, inv_d );
  
  deriv_wrt_T -= result * adjt;
  deriv_wrt_T *= inv_d;

  return true;
}
示例#3
0
bool Target2DUntangle::evaluate_with_hess( const MsqMatrix<2,2>& A,
                                           const MsqMatrix<2,2>& W,
                                           double& result,
                                           MsqMatrix<2,2>& deriv_wrt_A,
                                           MsqMatrix<2,2> second_wrt_A[3],
                                           MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  double tau = det(T);
  if (tau < mGamma) {
    double d = tau - mGamma;
    result = 16 * d*d*d*d;
    const MsqMatrix<2,2> adjt = transpose_adj(T);
    deriv_wrt_A = 64 * d*d*d * adjt;
    deriv_wrt_A = deriv_wrt_A * transpose(Winv);
    set_scaled_outer_product( second_wrt_A, 192*d*d, adjt );
    pluseq_scaled_2nd_deriv_of_det( second_wrt_A, 64*d*d*d );
    second_deriv_wrt_product_factor( second_wrt_A, Winv );
  }
  else {
    result = 0.0;
    second_wrt_A[0] = second_wrt_A[1] = second_wrt_A[2] = deriv_wrt_A = MsqMatrix<2,2>(0.0);
  }
  return true;
}
/** \f$ \frac{\partial^2 \mu}{\partial T^2} 
      = \frac{1}{\tau} I_4 
      - \frac{1}{\tau^2} \left( T \otimes \frac{\partial \tau}{\partial T} 
                          + \frac{\partial \tau}{\partial T} \otimes T \right) 
      + \frac{|T|^2}{\tau^3} \left( \frac{\partial \tau}{\partial T} \otimes
                               \frac{\partial \tau}{\partial T} \right) 
      - \frac{|T|^2}{2 \tau^3} \frac{\partial^2 \tau}{\partial T^2} \f$
  */
bool Target2DShapeBarrier::evaluate_with_hess( const MsqMatrix<2,2>& A,
                                               const MsqMatrix<2,2>& W,
                                               double& result,
                                               MsqMatrix<2,2>& deriv_wrt_A,
                                               MsqMatrix<2,2> second_wrt_A[3],
                                               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;
  double f1 = sqr_Frobenius(T) * inv_d;
  result = 0.5 * f1;
  const MsqMatrix<2,2> adjt = transpose_adj(T);
  deriv_wrt_A = T;
  deriv_wrt_A -= result * adjt;
  deriv_wrt_A *= inv_d;
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);
  
  set_scaled_outer_product( second_wrt_A, f1 * inv_d * inv_d, adjt );
  pluseq_scaled_sum_outer_product( second_wrt_A, -inv_d*inv_d, T, adjt );
  pluseq_scaled_I( second_wrt_A, inv_d );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_A, -result * inv_d );
  second_deriv_wrt_product_factor( second_wrt_A, Winv );

  result -= 1.0;
  return true;
}
bool TShapeB1::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 d = det(T);
  if (invalid_determinant(d)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  double id = 1.0/d;
  double norm = Frobenius(T);
  double den = 1.0/(3 * MSQ_SQRT_THREE * d);
  double norm_cube = norm*norm*norm;
  result = norm_cube * den - 1.0;
  MsqMatrix<3,3> adjt = transpose_adj(T);
  deriv_wrt_T = T;
  deriv_wrt_T *= 3 * norm * den;
  deriv_wrt_T -= norm_cube * den * id * transpose_adj(T);
 
  set_scaled_outer_product( second_wrt_T, 3 * den / norm, T );
  pluseq_scaled_I( second_wrt_T, 3 * norm * den );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -den * norm_cube * id, T );
  pluseq_scaled_outer_product( second_wrt_T, 2 * den * norm_cube * id * id , adjt );
  pluseq_scaled_sum_outer_product( second_wrt_T, -3 * norm * den * id, T, adjt );

  return true;
}
示例#6
0
bool TShapeSizeB3::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                                     double& result,
                                                     MsqMatrix<2,2>& deriv_wrt_T,
                                                     MsqMatrix<2,2> second_wrt_T[3],
                                                     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;

  const MsqMatrix<2,2> adjt = transpose_adj(T);
  const double it = 1/tau;
  deriv_wrt_T = T;
  deriv_wrt_T -= it * adjt;
  deriv_wrt_T *= 2;
  
  set_scaled_outer_product( second_wrt_T, 2*it*it, adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -2*it );
  pluseq_scaled_I( second_wrt_T, 2.0 );

  return true;
}
示例#7
0
template <unsigned DIM> static inline
bool hess( const MsqMatrix<DIM,DIM>& T, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv, 
           MsqMatrix<DIM,DIM>* second )
{
  const double norm = Frobenius(T);
  const double invroot = 1.0/DimConst<DIM>::sqrt();
  const double tau = det(T);
  if (TMetric::invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  const double inv_tau = 1.0/tau;
  const double invnorm = 1.0/norm;
  
  const double f = norm - invroot * trace(T);
  result = 0.5 * inv_tau * f;

  const MsqMatrix<DIM,DIM> adjt = transpose_adj(T);
  deriv = invnorm * T;
  pluseq_scaled_I( deriv, -invroot );
  deriv *= 0.5;
  deriv -= result * adjt;
  deriv *= inv_tau;
  
  const double a = 0.5 * inv_tau * invnorm;
  set_scaled_outer_product( second, -a*invnorm*invnorm, T );
  pluseq_scaled_I( second, a );
  pluseq_scaled_outer_product( second, f*inv_tau*inv_tau*inv_tau, adjt );
  pluseq_scaled_2nd_deriv_of_det( second, -0.5*f*inv_tau*inv_tau, T );
  pluseq_scaled_sum_outer_product( second, -0.5*inv_tau*inv_tau*invnorm, T, adjt );
  pluseq_scaled_sum_outer_product_I( second, 0.5*inv_tau*inv_tau*invroot, adjt );
  return true;
}
示例#8
0
template <unsigned DIM> static inline
bool hess( const MsqMatrix<DIM,DIM>& T, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv, 
           MsqMatrix<DIM,DIM>* second )
{
  double d1 = det(T) - 1;
  result = d1*d1;
  const MsqMatrix<DIM,DIM> adjt = transpose_adj(T);
  deriv = 2 * d1 * adjt;
  set_scaled_outer_product( second, 2, adjt );
  pluseq_scaled_2nd_deriv_of_det( second, 2 * d1, T );
  return true;  
}
示例#9
0
bool TSizeB1::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                  double& result,
                                  MsqMatrix<2,2>& deriv_wrt_T,
                                  MsqMatrix<2,2> second_wrt_T[3],
                                  MsqError& err )
{
  double d = det(T);
  if (TMetric::invalid_determinant(d)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  result = d + 1.0/d - 2.0;
  MsqMatrix<2,2> adjt = transpose_adj(T);
  const double f = 1 - 1/(d*d);
  deriv_wrt_T = f * adjt;
  
  set_scaled_outer_product( second_wrt_T, 2/(d*d*d), adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, f, T );
  return true;  
}
bool Target2DShapeOrientBarrier::evaluate_with_hess( const MsqMatrix<2,2>& A,
                                                     const MsqMatrix<2,2>& W,
                                                     double& result,
                                                     MsqMatrix<2,2>& deriv,
                                                     MsqMatrix<2,2> second[3],
                                                     MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  const double norm = Frobenius(T);
  const double invroot = 1.0/MSQ_SQRT_TWO;
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  const double inv_tau = 1.0/tau;
  const double invnorm = 1.0/norm;
  
  const double f = norm - invroot * trace(T);
  result = 0.5 * inv_tau * f;

  const MsqMatrix<2,2> adjt = transpose_adj(T);
  deriv = invnorm * T;
  deriv(0,0) -= invroot;
  deriv(1,1) -= invroot;
  deriv *= 0.5;
  deriv -= result * adjt;
  deriv *= inv_tau;
  deriv = deriv * transpose(Winv);
  
  const double a = 0.5 * inv_tau * invnorm;
  set_scaled_outer_product( second, -a*invnorm*invnorm, T );
  pluseq_scaled_I( second, a );
  pluseq_scaled_outer_product( second, f*inv_tau*inv_tau*inv_tau, adjt );
  pluseq_scaled_2nd_deriv_of_det( second, -0.5*f*inv_tau*inv_tau );
  pluseq_scaled_sum_outer_product( second, -0.5*inv_tau*inv_tau*invnorm, T, adjt );
  pluseq_scaled_sum_outer_product_I( second, 0.5*inv_tau*inv_tau*invroot, adjt );
  second_deriv_wrt_product_factor( second, Winv );
  return true;
}
示例#11
0
bool TShapeSize3DB4::evaluate_with_hess( const MsqMatrix<3,3>& T,
                                         double& result,
                                         MsqMatrix<3,3>& deriv,
                                         MsqMatrix<3,3> second[6],
                                         MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  const double norm = Frobenius(T);
  const double f = norm*norm/3.0;
  const double h = 1/(MSQ_SQRT_THREE * tau);
  const double g = norm * h;
  const double inv_tau = 1.0/tau;
  result = f * g - 1 + mGamma * (tau + inv_tau - 2);
  
  const double g1 = mGamma * (1 - inv_tau*inv_tau);
  const MsqMatrix<3,3> adjt = transpose_adj(T);
  deriv = g*T;
  deriv += (g1 - f*g*inv_tau) * adjt;
  
  if (norm > 1e-50) 
  {
    const double inv_norm = 1/norm;
    set_scaled_outer_product( second, h*inv_norm, T );
    pluseq_scaled_I( second, norm * h );
    pluseq_scaled_2nd_deriv_of_det( second, g1 - f*g*inv_tau, T );
    pluseq_scaled_outer_product( second, (f*g + mGamma*inv_tau)*2*inv_tau*inv_tau, adjt );
    pluseq_scaled_sum_outer_product( second, -g*inv_tau, T, adjt );
  }
  else
  {
    std::cout << "Warning: Division by zero avoided in TShapeSize3DB4::evaluate_with_hess()" << std::endl;
  }

  
  return true;
}
示例#12
0
bool TShapeSizeB3::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 )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  double n = Frobenius(T);
  result = n*n*n - 3*MSQ_SQRT_THREE*( log(tau) + 1 );
  
  const MsqMatrix<3,3> adjt = transpose_adj(T);
  const double it = 1/tau;
  deriv_wrt_T = T;
  deriv_wrt_T *= 3*n;
  deriv_wrt_T -= 3*MSQ_SQRT_THREE*it * adjt;

  if (n > 1e-50) 
  {
    set_scaled_outer_product( second_wrt_T, 3/n, T );
    pluseq_scaled_I( second_wrt_T, 3*n );
    pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -3*MSQ_SQRT_THREE*it, T );
    pluseq_scaled_outer_product( second_wrt_T, 3*MSQ_SQRT_THREE*it*it, adjt );
  }
  else
  {
    std::cout << "Warning: Division by zero avoided in TShapeSizeB3::evaluate_with_hess()" << std::endl;
  }
  

  return true;
}