Skip to content
Snippets Groups Projects

Correct the iterative calculation of the polar decomposition and its derivative

Merged Nebel, Lisa Julia requested to merge lnebel/dune-gfe:fix/polardecomposition into master
4 files
+ 572
24
Compare changes
  • Side-by-side
  • Inline
Files
4
  • Move the polar decomposition to a separate file and add the algorithm by Higham and Noferini (from Robin Fraenzel)
    
    In the test for the Higham and Noferini algorithm, we see:
    Unfortunately, for matrices that are close to an orthogonal matrix, this algorithm is
    about 2x slower. One can benefit from the Higham and Noferini algorithm only if the
    matrix is quite far away from an orthogonal one.
@@ -10,6 +10,7 @@
#include <dune/gfe/rotation.hh>
#include <dune/gfe/rigidbodymotion.hh>
#include <dune/gfe/linearalgebra.hh>
#include <dune/gfe/polardecomposition.hh>
namespace Dune {
@@ -174,29 +175,6 @@ namespace Dune {
static const int spaceDim = TargetSpace::TangentVector::dimension;
static FieldMatrix<field_type,3,3> polarFactor(const FieldMatrix<field_type,3,3>& matrix)
{
int maxIterations = 100;
double tol = 0.001;
// Use Higham's method
auto polar = matrix;
for (size_t i=0; i<maxIterations; i++)
{
auto oldPolar = polar;
auto polarInvert = polar;
polarInvert.invert();
for (size_t j=0; j<polar.N(); j++)
for (size_t k=0; k<polar.M(); k++)
polar[j][k] = 0.5 * (polar[j][k] + polarInvert[k][j]);
oldPolar -= polar;
if (oldPolar.frobenius_norm() < tol) {
break;
}
}
return polar;
}
/**
* \param A The argument of the projection
* \param polar The image of the projection, i.e., the polar factor of A
@@ -309,7 +287,7 @@ namespace Dune {
}
// Project back onto SO(3)
result.set(polarFactor(interpolatedMatrix));
result.set(Dune::GFE::PolarDecomposition()(interpolatedMatrix));
return result;
}
Loading