static inline bool do_numerical_gradient( AWMetric* mu, MsqMatrix<Dim, Dim> A, const MsqMatrix<Dim, Dim>& W, double& result, MsqMatrix<Dim,Dim>& wrt_A, MsqError& err ) { bool valid = mu->evaluate( A, W, result, err ); if (MSQ_CHKERR(err) || !valid) return valid; switch (Dim) { case 3: wrt_A(0,2) = do_finite_difference( 0, 2, mu, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(1,2) = do_finite_difference( 1, 2, mu, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(2,0) = do_finite_difference( 2, 0, mu, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(2,1) = do_finite_difference( 2, 1, mu, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(2,2) = do_finite_difference( 2, 2, mu, A, W, result, err ); MSQ_ERRZERO(err); case 2: wrt_A(0,1) = do_finite_difference( 0, 1, mu, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(1,0) = do_finite_difference( 1, 0, mu, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(1,1) = do_finite_difference( 1, 1, mu, A, W, result, err ); MSQ_ERRZERO(err); case 1: wrt_A(0,0) = do_finite_difference( 0, 0, mu, A, W, result, err ); MSQ_ERRZERO(err); break; default: assert(false); } return true; }
bool TargetMetric3D::evaluate_with_grad( const MsqMatrix<3,3>& A, const MsqMatrix<3,3>& W, double& result, MsqMatrix<3,3>& wrt_A, MsqError& err ) { bool valid = evaluate( A, W, result, err ); if (MSQ_CHKERR(err) || !valid) return valid; wrt_A(0,0) = do_finite_difference( 0, 0, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(0,1) = do_finite_difference( 0, 1, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(0,2) = do_finite_difference( 0, 2, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(1,0) = do_finite_difference( 1, 0, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(1,1) = do_finite_difference( 1, 1, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(1,2) = do_finite_difference( 1, 2, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(2,0) = do_finite_difference( 2, 0, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(2,1) = do_finite_difference( 2, 1, this, A, W, result, err ); MSQ_ERRZERO(err); wrt_A(2,2) = do_finite_difference( 2, 2, this, A, W, result, err ); MSQ_ERRZERO(err); return true; }