Ejemplo n.º 1
0
template <unsigned DIM> inline
bool TUntangleMu::hess( const MsqMatrix<DIM,DIM>& T,
                        double& result,
                        MsqMatrix<DIM,DIM>& deriv_wrt_T,
                        MsqMatrix<DIM,DIM>* second_wrt_T,
                        MsqError& err )
{
    bool valid = mBaseMetric->evaluate_with_hess( T, result, deriv_wrt_T, second_wrt_T, err );
    if (MSQ_CHKERR(err) || !valid)
        return false;

    if (mConstant < result) {
        const double s = result - mConstant;
        result = s*s*s;
        hess_scale( second_wrt_T, 3*s*s );
        pluseq_scaled_outer_product( second_wrt_T, 6*s, deriv_wrt_T );
        deriv_wrt_T *= 3*s*s;
    }
    else {
        result = 0;
        deriv_wrt_T = MsqMatrix<DIM,DIM>(0.0);
        set_scaled_I( second_wrt_T, 0.0 ); // zero everything
    }

    return true;
}
bool Target3DShapeSizeBarrierAlt1::evaluate_with_hess( const MsqMatrix<3,3>& A,
                                                       const MsqMatrix<3,3>& W,
                                                       double& result,
                                                       MsqMatrix<3,3>& wrt_A,
                                                       MsqMatrix<3,3> second[6],
                                                       MsqError& err )
{
  const MsqMatrix<3,3> Winv = inverse(W);
  const MsqMatrix<3,3> T = A * Winv;
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const double f = sqr_Frobenius(T);
  const double g = sqr_Frobenius(adj(T));
  result = (f + g)/(6 * tau);
  
  MsqMatrix<3,3> dtau = transpose_adj(T);
  MsqMatrix<3,3> dg = -transpose(T) * T;
  dg(0,0) += f;
  dg(1,1) += f;
  dg(2,2) += f;
  dg = T * dg;
  dg *= 2;
  
  wrt_A = T;
  wrt_A += 0.5*dg;
  wrt_A *= 1.0/3.0;
  wrt_A -= result * dtau;
  wrt_A *= 1.0/tau;
  wrt_A = wrt_A * transpose(Winv);
  
  set_scaled_2nd_deriv_norm_sqr_adj( second, 1.0/6.0, T );
  pluseq_scaled_I( second, 1.0/3.0 );
  pluseq_scaled_sum_outer_product( second, -1./3./tau, T, dtau );
  pluseq_scaled_sum_outer_product( second, -1./6./tau, dg, dtau );
  pluseq_scaled_outer_product( second, 2*result/tau, dtau );
  pluseq_scaled_2nd_deriv_of_det( second, -result, T );
  hess_scale( second, 1.0/tau );
  second_deriv_wrt_product_factor( second, Winv );
  
  result -= 1.0;
  return true;
}
Ejemplo n.º 3
0
bool TShapeSize3DB2::evaluate_with_hess( const MsqMatrix<3,3>& T,
                                         double& result,
                                         MsqMatrix<3,3>& wrt_T,
                                         MsqMatrix<3,3> second[6],
                                         MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const double f = sqr_Frobenius(T);
  const double g = sqr_Frobenius(adj(T));
  result = (f + g)/(6 * tau);
  
  MsqMatrix<3,3> dtau = transpose_adj(T);
  MsqMatrix<3,3> dg = -transpose(T) * T;
  dg(0,0) += f;
  dg(1,1) += f;
  dg(2,2) += f;
  dg = T * dg;
  dg *= 2;
  
  wrt_T = T;
  wrt_T += 0.5*dg;
  wrt_T *= 1.0/3.0;
  wrt_T -= result * dtau;
  wrt_T *= 1.0/tau;
  
  set_scaled_2nd_deriv_norm_sqr_adj( second, 1.0/6.0, T );
  pluseq_scaled_I( second, 1.0/3.0 );
  pluseq_scaled_sum_outer_product( second, -1./3./tau, T, dtau );
  pluseq_scaled_sum_outer_product( second, -1./6./tau, dg, dtau );
  pluseq_scaled_outer_product( second, 2*result/tau, dtau );
  pluseq_scaled_2nd_deriv_of_det( second, -result, T );
  hess_scale( second, 1.0/tau );
  
  result -= 1.0;
  return true;
}