diff --git a/dune/gfe/localprojectedfefunction.hh b/dune/gfe/localprojectedfefunction.hh
index 189deb1f99a063290710eef5c123e0593cd8416e..846264b78c9319a420f1041d6be6e939ac6c5ba3 100644
--- a/dune/gfe/localprojectedfefunction.hh
+++ b/dune/gfe/localprojectedfefunction.hh
@@ -8,7 +8,7 @@
 #include <dune/geometry/type.hh>
 
 #include <dune/gfe/rotation.hh>
-#include <dune/gfe/svd.hh>
+#include <dune/gfe/rigidbodymotion.hh>
 #include <dune/gfe/linearalgebra.hh>
 
 namespace Dune {
@@ -206,19 +206,17 @@ Dune::FieldMatrix< K, m, p > operator* ( const Dune::FieldMatrix< K, m, n > &A,
 
       static FieldMatrix<field_type,3,3> polarFactor(const FieldMatrix<field_type,3,3>& matrix)
       {
-        FieldVector<field_type,3> W;
-        FieldMatrix<field_type,3,3> V, VT;
+        // Use Higham's method
         auto polar = matrix;
+        for (size_t i=0; i<3; i++)
+        {
+          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]);
+        }
 
-        // returns a decomposition U W VT, where U is returned in the first argument
-        svdcmp<field_type,3,3>(polar, W, V);
-
-        // \todo Merge this transposition with the following multiplication
-        for (int i=0; i<3; i++)
-          for (int j=0; j<3; j++)
-            VT[i][j] = V[j][i];
-
-        polar.rightmultiply(VT);
         return polar;
       }
 
@@ -231,61 +229,52 @@ Dune::FieldMatrix< K, m, p > operator* ( const Dune::FieldMatrix< K, m, n > &A,
       {
         std::array<std::array<FieldMatrix<field_type,3,3>, 3>, 3> result;
 
-        /////////////////////////////////////////////////////////////////////////////////
-        //  Step I: Compute the singular value decomposition of A
-        /////////////////////////////////////////////////////////////////////////////////
-
-        FieldVector<field_type,3> sigma;
-        FieldMatrix<field_type,3,3> V, VT;
-        FieldMatrix<field_type,3,3> U = A;
-
-        // returns a decomposition U diag(sigma) VT, where U is returned in the first argument
-        svdcmp<field_type,3,3>(U, sigma, V);
-
-        // Compute VT from V (svdcmp returns the latter)
         for (int i=0; i<3; i++)
           for (int j=0; j<3; j++)
-            VT[i][j] = V[j][i];
+            for (int k=0; k<3; k++)
+              for (int l=0; l<3; l++)
+                result[i][j][k][l] = (i==k) and (j==l);
 
-        /////////////////////////////////////////////////////////////////////////////////
-        //  Step II: Compute the derivative direction X
-        /////////////////////////////////////////////////////////////////////////////////
+        auto polar = A;
 
-        for (int dir0=0; dir0<3; dir0++)
+        // Use Heron's method
+        const size_t maxIterations = 3;
+        for (size_t iteration=0; iteration<maxIterations; iteration++)
         {
-          for (int dir1=0; dir1<3; dir1++)
-          {
-            FieldMatrix<field_type,3,3> X(0);
-            X[dir0][dir1] = 1.0;
-
-            /////////////////////////////////////////////////////////////////////////////////
-            //  Step ???: Markus' magic formula
-            /////////////////////////////////////////////////////////////////////////////////
-
-            FieldMatrix<field_type,3,3> UTXV = transpose(U)*X*V;
-
-            FieldMatrix<field_type,3,3> center;
-            center[0][0] = 0.0;
-            center[0][1] = (UTXV[0][1] - UTXV[1][0]) / (sigma[0] + sigma[1]);
-            center[0][2] = (UTXV[0][2] - UTXV[2][0]) / (sigma[0] + sigma[2]);
-
-            center[1][0] = (UTXV[1][0] - UTXV[0][1]) / (sigma[1] + sigma[0]);
-            center[1][1] = 0.0;
-            center[1][2] = (UTXV[1][2] - UTXV[2][1]) / (sigma[1] + sigma[2]);
-
-            center[2][0] = (UTXV[2][0] - UTXV[0][2]) / (sigma[2] + sigma[0]);
-            center[2][1] = (UTXV[2][1] - UTXV[1][2]) / (sigma[2] + sigma[1]);
-            center[2][2] = 0.0;
-
-            // Compute U center VT
-            FieldMatrix<field_type,3,3> PAX = U*center*VT;
-
-            // Copy into result array
-            for (int i=0; i<3; i++)
-              for (int j=0; j<3; j++)
-                result[i][j][dir0][dir1] = PAX[i][j];
-
-          }
+          auto polarInvert = polar;
+          polarInvert.invert();
+          for (size_t i=0; i<polar.N(); i++)
+            for (size_t j=0; j<polar.M(); j++)
+              polar[i][j] = 0.5 * (polar[i][j] + polarInvert[j][i]);
+
+          decltype(result) dQT;
+          for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++)
+              for (int k=0; k<3; k++)
+                for (int l=0; l<3; l++)
+                  dQT[i][j][k][l] = result[i][j][k][l];
+
+          // Multiply from the right with Q^{-T}
+          decltype(result) tmp1, tmp2;
+          for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++)
+              for (int k=0; k<3; k++)
+                for (int l=0; l<3; l++)
+                  tmp1[i][j][k][l] = tmp2[i][j][k][l] = 0.0;
+
+          for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++)
+              for (int k=0; k<3; k++)
+                for (int l=0; l<3; l++)
+                  for (int m=0; m<3; m++)
+                    for (int o=0; o<3; o++)
+                      tmp2[i][j][k][l] += polarInvert[m][i] * dQT[o][m][k][l] * polarInvert[j][o];
+
+          for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++)
+              for (int k=0; k<3; k++)
+                for (int l=0; l<3; l++)
+                  result[i][j][k][l] = 0.5 * (result[i][j][k][l] - tmp2[i][j][k][l]);
         }
 
         return result;
@@ -431,6 +420,138 @@ Dune::FieldMatrix< K, m, p > operator* ( const Dune::FieldMatrix< K, m, n > &A,
 
     };
 
+
+    /** \brief Interpolate in an embedding Euclidean space, and project back onto the Riemannian manifold -- specialization for R^3 x SO(3)
+     *
+     * \tparam dim Dimension of the reference element
+     * \tparam ctype Type used for coordinates on the reference element
+     * \tparam LocalFiniteElement A Lagrangian finite element whose shape functions define the interpolation weights
+     */
+    template <int dim, class ctype, class LocalFiniteElement, class field_type>
+    class LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,RigidBodyMotion<field_type,3> >
+    {
+    public:
+      typedef RigidBodyMotion<field_type,3> TargetSpace;
+    private:
+      typedef typename TargetSpace::ctype RT;
+
+      typedef typename TargetSpace::EmbeddedTangentVector EmbeddedTangentVector;
+      static const int embeddedDim = EmbeddedTangentVector::dimension;
+
+      static const int spaceDim = TargetSpace::TangentVector::dimension;
+
+    public:
+
+      /** \brief The type used for derivatives */
+      typedef Dune::FieldMatrix<RT, embeddedDim, dim> DerivativeType;
+
+      /** \brief Constructor
+       * \param localFiniteElement A Lagrangian finite element that provides the interpolation points
+       * \param coefficients Values of the function at the Lagrange points
+       */
+      LocalProjectedFEFunction(const LocalFiniteElement& localFiniteElement,
+                               const std::vector<TargetSpace>& coefficients)
+      : localFiniteElement_(localFiniteElement),
+        translationCoefficients_(coefficients.size())
+      {
+        assert(localFiniteElement.localBasis().size() == coefficients.size());
+
+        for (size_t i=0; i<coefficients.size(); i++)
+            translationCoefficients_[i] = coefficients[i].r;
+
+        std::vector<Rotation<field_type,3> > orientationCoefficients(coefficients.size());
+        for (size_t i=0; i<coefficients.size(); i++)
+            orientationCoefficients[i] = coefficients[i].q;
+
+        orientationFunction_ = std::make_unique<LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,Rotation<field_type,3> > > (localFiniteElement,orientationCoefficients);
+      }
+
+      /** \brief The number of Lagrange points */
+      unsigned int size() const
+      {
+        return localFiniteElement_.size();
+      }
+
+      /** \brief The type of the reference element */
+      Dune::GeometryType type() const
+      {
+        return localFiniteElement_.type();
+      }
+
+      /** \brief Evaluate the function */
+      TargetSpace evaluate(const Dune::FieldVector<ctype, dim>& local) const
+      {
+        RigidBodyMotion<field_type,3> result;
+
+        // Evaluate the weighting factors---these are the Lagrangian shape function values at 'local'
+        std::vector<Dune::FieldVector<ctype,1> > w;
+        localFiniteElement_.localBasis().evaluateFunction(local,w);
+
+        result.r = 0;
+        for (size_t i=0; i<w.size(); i++)
+            result.r.axpy(w[i][0], translationCoefficients_[i]);
+
+        result.q = orientationFunction_->evaluate(local);
+
+        return result;
+      }
+
+      /** \brief Evaluate the derivative of the function */
+      DerivativeType evaluateDerivative(const Dune::FieldVector<ctype, dim>& local) const
+      {
+        // the function value at the point where we are evaluating the derivative
+        TargetSpace q = evaluate(local);
+
+        // Actually compute the derivative
+        return evaluateDerivative(local,q);
+      }
+
+      /** \brief Evaluate the derivative of the function, if you happen to know the function value (much faster!)
+       *        \param local Local coordinates in the reference element where to evaluate the derivative
+       *        \param q Value of the local function at 'local'.  If you provide something wrong here the result will be wrong, too!
+       */
+      DerivativeType evaluateDerivative(const Dune::FieldVector<ctype, dim>& local,
+                                        const TargetSpace& q) const
+      {
+        DerivativeType result(0);
+
+        // get translation part
+        std::vector<Dune::FieldMatrix<ctype,1,dim> > sfDer(translationCoefficients_.size());
+        localFiniteElement_.localBasis().evaluateJacobian(local, sfDer);
+
+        for (size_t i=0; i<translationCoefficients_.size(); i++)
+            for (int j=0; j<3; j++)
+                result[j].axpy(translationCoefficients_[i][j], sfDer[i][0]);
+
+        // get orientation part
+        Dune::FieldMatrix<field_type,4,dim> qResult = orientationFunction_->evaluateDerivative(local,q.q);
+
+        for (int i=0; i<4; i++)
+            for (int j=0; j<dim; j++)
+                result[3+i][j] = qResult[i][j];
+
+        return result;
+      }
+
+      /** \brief Get the i'th base coefficient. */
+      TargetSpace coefficient(int i) const
+      {
+        return TargetSpace(translationCoefficients_[i],orientationFunction_->coefficient(i));
+      }
+    private:
+
+      /** \brief The scalar local finite element, which provides the weighting factors
+       *        \todo We really only need the local basis
+       */
+      const LocalFiniteElement& localFiniteElement_;
+
+      std::vector<Dune::FieldVector<field_type,3> > translationCoefficients_;
+
+      std::unique_ptr<LocalProjectedFEFunction<dim,ctype,LocalFiniteElement,Rotation<field_type, 3> > > orientationFunction_;
+
+
+    };
+
   }
 
 }