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; }
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; }