From 72904b797d619016e6c8531ce3d53f351a65b9ae Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Sun, 7 Mar 2010 17:26:45 +0000 Subject: [PATCH] complete first implementation of secondDerivativeOfDistanceSquaredWRTSecondArgument [[Imported from SVN: r5670]] --- src/unitvector.hh | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/unitvector.hh b/src/unitvector.hh index c6c1d757..e4e63c08 100644 --- a/src/unitvector.hh +++ b/src/unitvector.hh @@ -29,7 +29,7 @@ public: /** \brief The exponential map */ static UnitVector exp(const UnitVector& p, const TangentVector& v) { - assert( std::abs(p.data_*v) < 1e-7 ); + assert( std::abs(p.data_*v) < 1e-5 ); const double norm = v.two_norm(); UnitVector result = p; @@ -74,7 +74,44 @@ public: result = b.projectOntoTangentSpace(result); // Gradient must be a tangent vector at b, in other words, orthogonal to it - assert( std::abs(b.data_ * result) < 1e-7); + assert( std::abs(b.data_ * result) < 1e-5); + + return result; + } + + /** \brief Compute the Hessian of the squared distance function keeping the first argument fixed + + Unlike the distance itself the squared distance is differentiable at zero + */ + static Dune::FieldMatrix<double,dim,dim> secondDerivativeOfDistanceSquaredWRTSecondArgument(const UnitVector& a, const UnitVector& b) { + + Dune::FieldMatrix<double,dim,dim> result; + + double sp = a.data_ * b.data_; + + // Compute vector A (see notes) + Dune::FieldMatrix<double,1,dim> row; + row[0] = a.globalCoordinates(); + row *= -1 / (1-sp*sp) * (1 + std::acos(sp)/std::sqrt(1-sp*sp) * sp); + + Dune::FieldMatrix<double,dim,1> column; + for (int i=0; i<dim; i++) + column[i] = a.globalCoordinates()[i] - b.globalCoordinates()[i]*sp; + + Dune::FieldMatrix<double,dim,dim> A; + // A = row * column + Dune::FMatrixHelp::multMatrix(column,row,A); + + // Compute matrix B (see notes) + Dune::FieldMatrix<double,dim,dim> B; + for (int i=0; i<dim; i++) + for (int j=0; j<dim; j++) + B[i][j] = (i==j)*sp + a.data_[j]*b.data_[i]; + + // Bring it all together + result = A; + result *= -2; + result.axpy(-2*std::acos(sp)/std::sqrt(1-sp*sp), B); return result; } @@ -98,7 +135,7 @@ public: } -private: + //private: Dune::FieldVector<double,dim> data_; }; -- GitLab