bool TShapeSizeB1::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 result = 0.0; return false; } const MsqMatrix<2,2> adjt = transpose_adj(T); const double nT = sqr_Frobenius(T); const double f = 1/(tau*tau); result = (1 + f) * nT - 4; deriv_wrt_T = T; deriv_wrt_T *= 2 + 2*f; deriv_wrt_T -= 2 * f/tau * nT * adjt; set_scaled_sum_outer_product( second_wrt_T, -4*f/tau, T, adjt ); pluseq_scaled_I( second_wrt_T, 2 + 2*f ); pluseq_scaled_outer_product( second_wrt_T, 6*nT*f*f, adjt ); pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -2*nT*f/tau ); return true; }
bool Target3DShapeOrientBarrierAlt1::evaluate_with_Hess( const MsqMatrix<3,3>& A, const MsqMatrix<3,3>& W, double& result, MsqMatrix<3,3>& deriv_wrt_A, MsqMatrix<3,3> second_wrt_A[6], MsqError& err ) { MsqMatrix<3,3> Winv = inverse(W); MsqMatrix<3,3> T = A * Winv; double tau = det(T); if (invalid_determinant(tau)) { result = 0.0; return false; } const double b = 0.5/tau; // calculate non-barrier value (ShapeOrientAlt1) const double tr = trace(T); const double f = MSQ_ONE_THIRD * fabs(tr); result = sqr_Frobenius( T ) - f * tr; // calculate non-barrier first derivatives deriv_wrt_A = T; deriv_wrt_A(0,0) -= f; deriv_wrt_A(1,1) -= f; deriv_wrt_A(2,2) -= f; deriv_wrt_A *= 2; // calculate barrier second derivs const MsqMatrix<3,3> adjt = transpose_adj(T); set_scaled_sum_outer_product( second_wrt_A, -b/tau, deriv_wrt_A, adjt ); pluseq_scaled_outer_product( second_wrt_A, result/(tau*tau*tau), adjt ); pluseq_scaled_2nd_deriv_of_det( second_wrt_A, -result * b / tau, T ); // calculate non-barrier barrier portion of second derivs pluseq_scaled_I( second_wrt_A, 1/tau ); pluseq_scaled_outer_product_I_I( second_wrt_A, MSQ_ONE_THIRD/tau * (tr < 0 ? 1 : -1) ); // calculate barrier derivs from non-barrier deriv_wrt_A *= tau; deriv_wrt_A -= result * adjt; deriv_wrt_A *= b/tau; // barrier value from non-barrier result *= b; // convert from derivs wrt T to derivs wrt A deriv_wrt_A = deriv_wrt_A * transpose(Winv); second_deriv_wrt_product_factor( second_wrt_A, Winv ); return true; }
bool TShapeOrientB2::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 tau = det(T); if (TMetric::invalid_determinant(tau)) { MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); result = 0.0; return false; } const double b = 0.5/tau; // calculate non-barrier value (ShapeOrientAlt1) const double tr = trace(T); const double f = MSQ_ONE_THIRD * fabs(tr); result = sqr_Frobenius( T ) - f * tr; // calculate non-barrier first derivatives deriv_wrt_T = T; pluseq_scaled_I( deriv_wrt_T, -f ); deriv_wrt_T *= 2; // calculate barrier second derivs const MsqMatrix<3,3> adjt = transpose_adj(T); set_scaled_sum_outer_product( second_wrt_T, -b/tau, deriv_wrt_T, adjt ); pluseq_scaled_outer_product( second_wrt_T, result/(tau*tau*tau), adjt ); pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -result * b / tau, T ); // calculate non-barrier barrier portion of second derivs pluseq_scaled_I( second_wrt_T, 1/tau ); pluseq_scaled_outer_product_I_I( second_wrt_T, MSQ_ONE_THIRD/tau * (tr < 0 ? 1 : -1) ); // calculate barrier derivs from non-barrier deriv_wrt_T *= tau; deriv_wrt_T -= result * adjt; deriv_wrt_T *= b/tau; // barrier value from non-barrier result *= b; return true; }