Skip to content
Snippets Groups Projects
Commit 6c2eda51 authored by Sander, Oliver's avatar Sander, Oliver
Browse files

harmonicenergytest.cc: Only test with points that are mutually close

Previously, this test used a situation with geodesic interpolation
between two points on the sphere that are almost antipodal.
This made the TargetSpaceRiemannianTRSolver crash, because the
weighted sum of squared distances can have indefinite second
derivatives in such a situation.  In principle, the
TargetSpaceRiemannianTRSolver should handle this, but nowadays
it is not actually a TR solver anymore, but a plain local
Newton method.  Maybe I should revert back to trust-region.

I added a comment to targetspacetrsolver.cc that explains the
situation a little.
parent 2ea31ce8
Branches
No related tags found
No related merge requests found
...@@ -55,6 +55,15 @@ void TargetSpaceRiemannianTRSolver<TargetSpace>::solve() ...@@ -55,6 +55,15 @@ void TargetSpaceRiemannianTRSolver<TargetSpace>::solve()
// ///////////////////////////// // /////////////////////////////
// Solve ! // Solve !
// ///////////////////////////// // /////////////////////////////
// TODO: The GramSchmidtSolver may not be the smartest choice here, because it needs
// a matrix that is positive definite on the complement of its kernel. This can limit
// the radius of convergence of the Newton solver. As an example consider interpolation
// between two points on the unit sphere that are more than pi/2 apart. There is a
// well-defined unique shortest geodesic between two such points, but depending on the
// weights, the weighted sum of squared distances does not everywhere have a positive definite
// second derivative.
// Maybe the Newton solver has to be replaced by a trust-region or line-search solver
// for such situations.
Dune::FieldMatrix<field_type,blocksize,embeddedBlocksize> basis = x_.orthonormalFrame(); Dune::FieldMatrix<field_type,blocksize,embeddedBlocksize> basis = x_.orthonormalFrame();
GramSchmidtSolver<field_type, blocksize, embeddedBlocksize>::solve(hesseMatrix, corr, rhs, basis); GramSchmidtSolver<field_type, blocksize, embeddedBlocksize>::solve(hesseMatrix, corr, rhs, basis);
......
...@@ -17,6 +17,17 @@ typedef UnitVector<double,3> TargetSpace; ...@@ -17,6 +17,17 @@ typedef UnitVector<double,3> TargetSpace;
using namespace Dune; using namespace Dune;
/** \brief Computes the diameter of a set */
template <class TargetSpace>
double diameter(const std::vector<TargetSpace>& v)
{
double d = 0;
for (size_t i=0; i<v.size(); i++)
for (size_t j=0; j<v.size(); j++)
d = std::max(d, TargetSpace::distance(v[i],v[j]));
return d;
}
template <class Basis> template <class Basis>
void testEnergy(const Basis& basis, const std::vector<TargetSpace>& coefficients) void testEnergy(const Basis& basis, const std::vector<TargetSpace>& coefficients)
{ {
...@@ -102,6 +113,10 @@ void testUnitVector3d() ...@@ -102,6 +113,10 @@ void testUnitVector3d()
for (int j=0; j<dim+1; j++) for (int j=0; j<dim+1; j++)
coefficients[j] = testPoints[index[j]]; coefficients[j] = testPoints[index[j]];
// This may be overly restrictive, but see the TODO in targetspacetrsolver.cc
if (diameter(coefficients) > TargetSpace::convexityRadius)
continue;
testEnergy<Basis>(basis, coefficients); testEnergy<Basis>(basis, coefficients);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment