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; }
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 ) { result = sqr_Frobenius( T ); deriv_wrt_T = 2 * T; set_scaled_I( second_wrt_T, 2.0 ); return true; }
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; }
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; }