Exemple #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;
}
Exemple #2
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;
}
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;
}