From 4e03c456bf664b77d26955301cea276c350a1a33 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Thu, 12 Jan 2012 09:08:42 +0000 Subject: [PATCH] Reimplement method derivativeOfDistanceSquaredWRTSecondArgument. Now it properly handles the situation that p and q may be on different sheets of the double cover. [[Imported from SVN: r8367]] --- dune/gfe/rotation.hh | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/dune/gfe/rotation.hh b/dune/gfe/rotation.hh index 6a52b7d7..e4f030a9 100644 --- a/dune/gfe/rotation.hh +++ b/dune/gfe/rotation.hh @@ -621,30 +621,26 @@ public: } + /** \brief Compute the derivative of the squared distance function with respect to the second argument + * + * The squared distance function is + * \f[ 4 \arccos^2 (|<p,q>|) \f] + * Deriving this with respect to the second coordinate gives + * \f[ 4 (\arccos^2)'(x)|_{x = |<p,q>|} * P_qp \f] + * The whole thing has to be multiplied by -1 if \f$ <p,q> \f$ is negative + */ static EmbeddedTangentVector derivativeOfDistanceSquaredWRTSecondArgument(const Rotation<T,3>& p, const Rotation<T,3>& q) { + T sp = p.globalCoordinates() * q.globalCoordinates(); - Rotation<T,3> pInv = p; - pInv.invert(); - - // the forth component of pInv times q - T pInvq_4 = - pInv[0]*q[0] - pInv[1]*q[1] - pInv[2]*q[2] + pInv[3]*q[3]; - - T arccosSquaredDer_pInvq_4 = derivativeOfArcCosSquared(pInvq_4); + // Compute the projection of p onto the tangent space of q + EmbeddedTangentVector result = p; + result.axpy(-1*(q*p), q); - EmbeddedTangentVector result; - result[0] = -4 * arccosSquaredDer_pInvq_4 * pInv[0]; - result[1] = -4 * arccosSquaredDer_pInvq_4 * pInv[1]; - result[2] = -4 * arccosSquaredDer_pInvq_4 * pInv[2]; - result[3] = 4 * arccosSquaredDer_pInvq_4 * pInv[3]; + // The ternary operator comes from the derivative of the absolute value function + result *= 4 * derivativeOfArcCosSquared(std::fabs(sp)) * ( (sp<0) ? -1 : 1 ); - // project onto the tangent space at q - EmbeddedTangentVector projectedResult = result; - projectedResult.axpy(-1*(q*result), q); - - assert(std::fabs(projectedResult * q) < 1e-7); - - return projectedResult; + return result; } /** \brief Compute the Hessian of the squared distance function keeping the first argument fixed -- GitLab