bool TShapeB1::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 d = det(T); if (invalid_determinant(d)) { MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } double id = 1.0/d; double norm = Frobenius(T); double den = 1.0/(3 * MSQ_SQRT_THREE * d); double norm_cube = norm*norm*norm; result = norm_cube * den - 1.0; MsqMatrix<3,3> adjt = transpose_adj(T); deriv_wrt_T = T; deriv_wrt_T *= 3 * norm * den; deriv_wrt_T -= norm_cube * den * id * transpose_adj(T); set_scaled_outer_product( second_wrt_T, 3 * den / norm, T ); pluseq_scaled_I( second_wrt_T, 3 * norm * den ); pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -den * norm_cube * id, T ); pluseq_scaled_outer_product( second_wrt_T, 2 * den * norm_cube * id * id , adjt ); pluseq_scaled_sum_outer_product( second_wrt_T, -3 * norm * den * id, T, adjt ); return true; }
bool TShape3DB2::evaluate_with_hess( const MsqMatrix<3,3>& T, double& result, MsqMatrix<3,3>& wrt_T, MsqMatrix<3,3> second[6], MsqError& err ) { double f = sqr_Frobenius(T); double g = sqr_Frobenius(adj(T)); double d = det(T); if (invalid_determinant(d)) { MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } const double den = 1.0/(9*d*d); result = f*g*den- 1; MsqMatrix<3,3> dg = 2 * (f * T - T * transpose(T) * T); MsqMatrix<3,3> df = 2 * T; MsqMatrix<3,3> dtau = transpose_adj(T); wrt_T = g*df + f*dg - 2*f*g/d * transpose_adj(T); wrt_T *= den; set_scaled_2nd_deriv_norm_sqr_adj( second, den*f, T ); pluseq_scaled_I( second, 2*den*g ); pluseq_scaled_sum_outer_product( second, den, dg, df ); pluseq_scaled_sum_outer_product( second, -2*den*g/d, df, dtau ); pluseq_scaled_sum_outer_product( second, -2*den*f/d, dg, dtau ); pluseq_scaled_outer_product( second, 6*den*f*g/(d*d), dtau ); pluseq_scaled_2nd_deriv_of_det( second, -2*den*f*g/d, T ); return true; }
bool InvTransBarrier2D::evaluate( const MsqMatrix<2,2>& A, const MsqMatrix<2,2>& W, double& result, MsqError& err ) { double da = det(A); double dw = det(W); if (invalid_determinant(da) || invalid_determinant(dw)) return false; MsqMatrix<2,2> Ap = transpose_adj(A); Ap *= 1.0/da; MsqMatrix<2,2> Wp = transpose_adj(W); Wp *= 1.0/dw; bool rval = metricPtr->evaluate( Ap, Wp, result, err ); return !MSQ_CHKERR(err) && rval; }
/** \f$ \frac{\partial^2 \mu}{\partial T^2} = \frac{1}{\tau} I_4 - \frac{1}{\tau^2} \left( T \otimes \frac{\partial \tau}{\partial T} + \frac{\partial \tau}{\partial T} \otimes T \right) + \frac{|T|^2}{\tau^3} \left( \frac{\partial \tau}{\partial T} \otimes \frac{\partial \tau}{\partial T} \right) - \frac{|T|^2}{2 \tau^3} \frac{\partial^2 \tau}{\partial T^2} \f$ */ bool Target2DShapeBarrier::evaluate_with_hess( const MsqMatrix<2,2>& A, const MsqMatrix<2,2>& W, double& result, MsqMatrix<2,2>& deriv_wrt_A, MsqMatrix<2,2> second_wrt_A[3], MsqError& err ) { const MsqMatrix<2,2> Winv = inverse(W); const MsqMatrix<2,2> T = A * Winv; const double d = det(T); if (invalid_determinant(d)) { // barrier result = 0.0; return false; } double inv_d = 1.0/d; double f1 = sqr_Frobenius(T) * inv_d; result = 0.5 * f1; const MsqMatrix<2,2> adjt = transpose_adj(T); deriv_wrt_A = T; deriv_wrt_A -= result * adjt; deriv_wrt_A *= inv_d; deriv_wrt_A = deriv_wrt_A * transpose(Winv); set_scaled_outer_product( second_wrt_A, f1 * inv_d * inv_d, adjt ); pluseq_scaled_sum_outer_product( second_wrt_A, -inv_d*inv_d, T, adjt ); pluseq_scaled_I( second_wrt_A, inv_d ); pluseq_scaled_2nd_deriv_of_det( second_wrt_A, -result * inv_d ); second_deriv_wrt_product_factor( second_wrt_A, Winv ); result -= 1.0; return true; }
bool TShapeOrientB2::evaluate_with_grad( const MsqMatrix<2,2>& T, double& result, MsqMatrix<2,2>& deriv_wrt_T, MsqError& err ) { double tau = det(T); if (TMetric::invalid_determinant(tau)) { MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } const double b = 0.5/tau; const double tr = trace(T); const double f = 0.5 * fabs(tr); result = sqr_Frobenius( T ) - f * tr; deriv_wrt_T = T; pluseq_scaled_I( deriv_wrt_T, -f ); deriv_wrt_T *= 2*tau; deriv_wrt_T -= result * transpose_adj(T); result *= b; deriv_wrt_T *= b/tau; return true; }
bool TShapeSizeB3::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 MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } result = sqr_Frobenius(T) - 2.0 * std::log(tau) - 2; const MsqMatrix<2,2> adjt = transpose_adj(T); const double it = 1/tau; deriv_wrt_T = T; deriv_wrt_T -= it * adjt; deriv_wrt_T *= 2; set_scaled_outer_product( second_wrt_T, 2*it*it, adjt ); pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -2*it ); pluseq_scaled_I( second_wrt_T, 2.0 ); return true; }
bool TShapeSizeB1::evaluate_with_grad( const MsqMatrix<3,3>& T, double& result, MsqMatrix<3,3>& deriv_wrt_T, MsqError& ) { const double tau = det(T); if (invalid_determinant(tau)) { // barrier result = 0.0; return false; } const MsqMatrix<3,3> adjt = transpose_adj(T); const double nT = sqr_Frobenius(T); const double nadj = sqr_Frobenius(adjt); const double f = 1/(tau*tau); result = nT + f*nadj - 6; deriv_wrt_T = T; deriv_wrt_T *= (1+f*nT); deriv_wrt_T -= f * T * transpose(T) * T; deriv_wrt_T -= f/tau * nadj * adjt; deriv_wrt_T *= 2; return true; }
bool TShapeSizeB1::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 ) { const double tau = det(T); if (invalid_determinant(tau)) { // barrier result = 0.0; return false; } const MsqMatrix<3,3> adjt = transpose_adj(T); const double nT = sqr_Frobenius(T); const double nadj = sqr_Frobenius(adjt); const double f = 1/(tau*tau); result = nT + f*nadj - 6; //! \f$ \frac{\partial}{\partial T} |adj T|^2 \f$ const MsqMatrix<3,3> dNadj_dT = 2 * (nT * T - T * transpose(T) * T); deriv_wrt_T = T; deriv_wrt_T -= f/tau * nadj * adjt; deriv_wrt_T *= 2; deriv_wrt_T += f * dNadj_dT; // calculate negative of 2nd wrt T of (|adj T|^2 / tau^2) (sec 3.2.2) set_scaled_2nd_deriv_norm_sqr_adj( second_wrt_T, f, T ); pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -2*f*f*nadj*tau, T ); pluseq_scaled_outer_product( second_wrt_T, 6*f*f*nadj, adjt ); pluseq_scaled_sum_outer_product( second_wrt_T, -2*f*f *tau, adjt, dNadj_dT ); // calculate 2nd wrt T of this metric pluseq_scaled_I( second_wrt_T, 2.0 ); return true; }
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 Target3DShape::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 f = Frobenius(T); double d = det(T); result = f*f*f - 3*MSQ_SQRT_THREE*d; deriv_wrt_A = T; deriv_wrt_A *= f; deriv_wrt_A -= MSQ_SQRT_THREE*transpose_adj(T); deriv_wrt_A *= 3; deriv_wrt_A = deriv_wrt_A * transpose(Winv); set_scaled_2nd_deriv_of_det( second_wrt_A, -3 * MSQ_SQRT_THREE, T ); pluseq_scaled_outer_product( second_wrt_A, 3.0/f, T ); pluseq_scaled_I( second_wrt_A, 3.0*f ); second_deriv_wrt_product_factor( second_wrt_A, Winv ); return true; }
bool Target2DShapeOrientBarrier::evaluate_with_grad( const MsqMatrix<2,2>& A, const MsqMatrix<2,2>& W, double& result, MsqMatrix<2,2>& deriv, 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; result = 0.5*inv_tau*(norm - invroot * trace(T)); deriv = invnorm * T; deriv(0,0) -= invroot; deriv(1,1) -= invroot; deriv *= 0.5; deriv -= result * transpose_adj(T); deriv *= inv_tau; deriv = deriv * transpose(Winv); return true; }
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; }
bool TShapeSize3DB2::evaluate_with_grad( const MsqMatrix<3,3>& T, double& result, MsqMatrix<3,3>& deriv_wrt_T, 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); deriv_wrt_T = -transpose(T) * T; deriv_wrt_T(0,0) += 1+f; deriv_wrt_T(1,1) += 1+f; deriv_wrt_T(2,2) += 1+f; deriv_wrt_T = T * deriv_wrt_T; deriv_wrt_T -= 3*result * transpose_adj(T); deriv_wrt_T *= 1.0/(3*tau); result -= 1.0; return true; }
bool Target3DShapeOrientBarrierAlt1::evaluate_with_grad( const MsqMatrix<3,3>& A, const MsqMatrix<3,3>& W, double& result, MsqMatrix<3,3>& deriv_wrt_A, 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; const double tr = trace(T); const double f = MSQ_ONE_THIRD * fabs(tr); result = sqr_Frobenius( T ) - f * tr; 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*tau; deriv_wrt_A -= result * transpose_adj(T); result *= b; deriv_wrt_A *= b/tau; deriv_wrt_A = deriv_wrt_A * transpose(Winv); return true; }
bool TShapeSize2DNB2::evaluate_with_grad( const MsqMatrix<2,2>& T, double& result, MsqMatrix<2,2>& deriv_wrt_T, MsqError& err ) { double frob_sqr = sqr_Frobenius(T); double psi = sqrt( frob_sqr + 2.0*det(T) ); double a = 1e-12; while (!Mesquite::divide(frob_sqr+2,2*psi,result)) { MsqMatrix<2,2> Tdelta(T); Tdelta(0,0) += a; Tdelta(1,1) += a; a *= 2.0; frob_sqr = sqr_Frobenius(Tdelta); psi = sqrt( frob_sqr + 2.0*det(Tdelta) ); if (psi > 1e-50) result = (frob_sqr+2) / 2*psi; } //MsqMatrix<2,2> d_psi = 1.0/psi * (T + transpose_adj(T)); //deriv_wrt_T = (1.0/psi) * (T - result * d_psi); if (psi > 1e-50) { const double f = result/(psi*psi); deriv_wrt_T = transpose_adj(T); deriv_wrt_T *= -f; deriv_wrt_T += (1.0/psi - f) * T; } result -= 1.0; return true; }
bool InverseMeanRatio2D::evaluate_with_grad( const MsqMatrix<2,2>& A, const MsqMatrix<2,2>& W, double& result, MsqMatrix<2,2>& deriv_wrt_A, MsqError& err ) { const MsqMatrix<2,2> Winv = inverse(W); const MsqMatrix<2,2> T = A * Winv; const double d = det( T ); if (invalid_determinant(d)) { result = 0.0; deriv_wrt_A = MsqMatrix<2,2>(0.0); return false; } else { result = sqr_Frobenius(T) / (2 * d); deriv_wrt_A = transpose_adj(T); deriv_wrt_A *= -result; deriv_wrt_A += T; deriv_wrt_A *= 1.0/d; deriv_wrt_A = deriv_wrt_A * transpose(Winv); result -= 1.0; return true; } }
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 Target2DUntangle::evaluate_with_hess( const MsqMatrix<2,2>& A, const MsqMatrix<2,2>& W, double& result, MsqMatrix<2,2>& deriv_wrt_A, MsqMatrix<2,2> second_wrt_A[3], MsqError& err ) { const MsqMatrix<2,2> Winv = inverse(W); const MsqMatrix<2,2> T = A * Winv; double tau = det(T); if (tau < mGamma) { double d = tau - mGamma; result = 16 * d*d*d*d; const MsqMatrix<2,2> adjt = transpose_adj(T); deriv_wrt_A = 64 * d*d*d * adjt; deriv_wrt_A = deriv_wrt_A * transpose(Winv); set_scaled_outer_product( second_wrt_A, 192*d*d, adjt ); pluseq_scaled_2nd_deriv_of_det( second_wrt_A, 64*d*d*d ); second_deriv_wrt_product_factor( second_wrt_A, Winv ); } else { result = 0.0; second_wrt_A[0] = second_wrt_A[1] = second_wrt_A[2] = deriv_wrt_A = MsqMatrix<2,2>(0.0); } return true; }
bool TShapeSizeOrientB1::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 d = det(T); if (TMetric::invalid_determinant(d)) { // barrier MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } deriv_wrt_T = T; pluseq_scaled_I( deriv_wrt_T, -1.0 ); double inv_d = 1.0/d; result = 0.5 * sqr_Frobenius(deriv_wrt_T) * inv_d; MsqMatrix<2,2> adjt = transpose_adj(T); set_scaled_outer_product( second_wrt_T, 2*result*inv_d*inv_d, adjt ); pluseq_scaled_sum_outer_product( second_wrt_T, -inv_d*inv_d, deriv_wrt_T, adjt ); pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -result * inv_d, T ); pluseq_scaled_I( second_wrt_T, inv_d ); deriv_wrt_T -= result * adjt; deriv_wrt_T *= inv_d; return true; }
bool Target3DShapeSizeBarrierAlt1::evaluate_with_grad( const MsqMatrix<3,3>& A, const MsqMatrix<3,3>& W, double& result, MsqMatrix<3,3>& deriv_wrt_A, 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); deriv_wrt_A = -transpose(T) * T; deriv_wrt_A(0,0) += 1+f; deriv_wrt_A(1,1) += 1+f; deriv_wrt_A(2,2) += 1+f; deriv_wrt_A = T * deriv_wrt_A; deriv_wrt_A -= 3*result * transpose_adj(T); deriv_wrt_A *= 1.0/(3*tau); deriv_wrt_A = deriv_wrt_A * transpose(Winv); result -= 1.0; return true; }
bool TShapeSize2DB2::evaluate_with_hess( const MsqMatrix<2,2>& T, double& result, MsqMatrix<2,2>& deriv_wrt_T, MsqMatrix<2,2> second[3], MsqError& err ) { const double d = det(T); if (invalid_determinant(d)) { // barrier MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } const double frob_sqr = sqr_Frobenius(T); const double psi = sqrt( frob_sqr + 2.0*det(T) ); const double v = frob_sqr - 2.0 * psi + 2.0; result = v / (2*d); // deriv of V wrt T MsqMatrix<2,2> adjt = transpose_adj(T); MsqMatrix<2,2> v_wrt_T(T); if (psi > 1e-50) { v_wrt_T *= (1.0 - 1.0/psi); v_wrt_T -= 1.0/psi * adjt; v_wrt_T *= 2; } else { std::cout << "Warning: Division by zero avoided in TShapeSize2DB2::evaluate_with_hess()" << std::endl; } // deriv of mu wrt T deriv_wrt_T = v_wrt_T; deriv_wrt_T *= 0.5/d; deriv_wrt_T -= v / (2*d*d) * adjt; // second of V wrt T const double s = T(0,1) - T(1,0); const double tr = trace(T); const double f = -2.0/(psi*psi*psi); second[0](0,0) = second[1](0,1) = second[2](1,1) = f*s*s; second[0](0,1) = second[0](1,0) = second[1](1,1) = -f*s*tr; second[1](0,0) = second[2](0,1) = second[2](1,0) = f*s*tr; second[0](1,1) = second[2](0,0) = -(second[1](1,0) = -f*tr*tr); pluseq_scaled_I( second, 2 ); // second of mu wrt T const double x = 1.0/(2*d); second[0] *= x; second[1] *= x; second[2] *= x; pluseq_scaled_2nd_deriv_of_det( second, v/(-2*d*d) ); pluseq_scaled_outer_product( second, v/(d*d*d), adjt ); pluseq_scaled_sum_outer_product( second, -1/(2*d*d), v_wrt_T, adjt ); return true; }
template <unsigned DIM> static inline bool grad( const MsqMatrix<DIM,DIM>& T, double& result, MsqMatrix<DIM,DIM>& deriv ) { double d1 = det(T) - 1; result = d1*d1; deriv = 2 * d1 * transpose_adj(T); return true; }
bool InverseMeanRatio2D::evaluate_with_hess( const MsqMatrix<2,2>& A, const MsqMatrix<2,2>& W, double& result, MsqMatrix<2,2>& dA, MsqMatrix<2,2> d2A[3], MsqError& err ) { const MsqMatrix<2,2> Winv = inverse(W); const MsqMatrix<2,2> T = A * Winv; const double d = det( T ); if (invalid_determinant(d)) { result = 0.0; dA = d2A[0] = d2A[1] = d2A[2] = MsqMatrix<2,2>(0.0); return false; } else { const double inv_det = 1.0/d; result = sqr_Frobenius(T) * 0.5 * inv_det; const MsqMatrix<2,2> AT = transpose_adj(T); dA = AT; dA *= -result; dA += T; dA *= inv_det; dA = dA * transpose(Winv); const double p3 = -result * inv_det; const double p1 = -2.0 * p3 * inv_det; const double p2 = -inv_det * inv_det; const MsqMatrix<2,2> AT_T_op_00 = outer( AT.row(0), T.row(0)); const MsqMatrix<2,2> AT_T_op_11 = outer( AT.row(1), T.row(1)); d2A[0] = p1 * outer( AT.row(0), AT.row(0)) + p2 * (AT_T_op_00 + transpose(AT_T_op_00)); d2A[1] = p1 * outer( AT.row(0), AT.row(1)) + p2 * (outer( AT.row(0), T.row(1)) + outer( T.row(0), AT.row(1) )); d2A[2] = p1 * outer( AT.row(1), AT.row(1)) + p2 * (AT_T_op_11 + transpose(AT_T_op_11)); d2A[0](0,0) += inv_det; d2A[0](1,1) += inv_det; d2A[1](0,1) += p3; d2A[1](1,0) -= p3; d2A[2](0,0) += inv_det; d2A[2](1,1) += inv_det; d2A[0] = Winv * d2A[0] * transpose(Winv); d2A[1] = Winv * d2A[1] * transpose(Winv); d2A[2] = Winv * d2A[2] * transpose(Winv); result -= 1.0; return true; } }
bool InvTransBarrier::evaluate( const MsqMatrix<2,2>& T, double& result, MsqError& err ) { double tau = det(T); if (invalid_determinant(tau)) return false; MsqMatrix<2,2> Tp = transpose_adj(T); Tp *= 1.0/tau; bool rval = metricPtr->evaluate( Tp, result, err ); return !MSQ_CHKERR(err) && rval; }
template <unsigned DIM> static inline bool hess( const MsqMatrix<DIM,DIM>& T, double& result, MsqMatrix<DIM,DIM>& deriv, MsqMatrix<DIM,DIM>* second ) { double d1 = det(T) - 1; result = d1*d1; const MsqMatrix<DIM,DIM> adjt = transpose_adj(T); deriv = 2 * d1 * adjt; set_scaled_outer_product( second, 2, adjt ); pluseq_scaled_2nd_deriv_of_det( second, 2 * d1, T ); 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 TSizeB1::evaluate_with_grad( const MsqMatrix<2,2>& T, double& result, MsqMatrix<2,2>& deriv_wrt_T, MsqError& err ) { double d = det(T); if (TMetric::invalid_determinant(d)) { MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } result = d + 1.0/d - 2.0; deriv_wrt_T = (1 - 1/(d*d)) * transpose_adj(T); return true; }
bool TShapeSizeB1::evaluate( const MsqMatrix<3,3>& T, double& result, MsqError& ) { const double tau = det(T); if (invalid_determinant(tau)) { // barrier result = 0.0; return false; } const double nT = sqr_Frobenius(T); const double nadj = sqr_Frobenius(transpose_adj(T)); const double f = 1/(tau*tau); result = nT + f*nadj - 6; 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 TShapeSizeB3::evaluate_with_grad( const MsqMatrix<2,2>& T, double& result, MsqMatrix<2,2>& deriv_wrt_T, MsqError& err ) { const double tau = det(T); if (invalid_determinant(tau)) { // barrier MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED ); return false; } result = sqr_Frobenius(T) - 2.0 * std::log(tau) - 2; deriv_wrt_T = T; deriv_wrt_T -= 1/tau * transpose_adj(T); deriv_wrt_T *= 2; return true; }