diff --git a/src/quaternion.hh b/src/quaternion.hh
index 211acbc688cfdcf3c9a95b31c62a1d32c8f84399..00fb41d0f2ef6b1f21e548385094ee25d2b6e37b 100644
--- a/src/quaternion.hh
+++ b/src/quaternion.hh
@@ -2,11 +2,18 @@
 #define QUATERNION_HH
 
 #include <dune/common/fvector.hh>
+#include <dune/common/fmatrix.hh>
 #include <dune/common/exceptions.hh>
 
 template <class T>
 class Quaternion : public Dune::FieldVector<T,4>
 {
+
+    /** \brief Computes sin(x/2) / x without getting unstable for small x */
+    static T sincHalf(const T& x) {
+        return (x < 1e-4) ? 0.5 + (x*x/48) : std::sin(x/2)/x;
+    }
+
 public:
 
     /** \brief Default constructor */
@@ -53,7 +60,7 @@ public:
         T normV = std::sqrt(v0*v0 + v1*v1 + v2*v2);
 
         // Stabilization for small |v| due to Grassia
-        T sin   = (normV < 1e-4) ? 0.5 + (normV*normV/48) : std::sin(normV/2)/normV;
+        T sin = sincHalf(normV);
 
         // if normV == 0 then q = (0,0,0,1)
         assert(!isnan(sin));
@@ -66,6 +73,27 @@ public:
         return q;
     }
 
+    static Dune::FieldMatrix<T,4,3> Dexp(const Dune::FieldVector<T,3>& v) {
+
+        Dune::FieldMatrix<T,4,3> result(0);
+        T norm = v.two_norm();
+
+        for (int i=0; i<3; i++) {
+
+            for (int m=0; m<3; m++) {
+                
+                result[m][i] = (norm==0) 
+                    ? (i==m) 
+                    : 0.5 * std::cos(norm/2) * v[i] * v[m] / (norm*norm) + sincHalf(norm) * ( (i==m) - v[i]*v[m]/(norm*norm));
+
+            }
+
+            result[3][i] = - 0.5 * sincHalf(norm) * v[i];
+
+        }
+        return result;
+    }
+
     /** \brief Right quaternion multiplication */
     Quaternion<T> mult(const Quaternion<T>& other) const {
         Quaternion<T> q;
@@ -147,11 +175,11 @@ public:
 
         Quaternion<T> diff = a;
         diff.invert();
-        diff.mult(b);
+        diff = diff.mult(b);
 
         T dist = 2*std::acos(diff[3]);
 
-        T invSinc = (dist < 1e-4) ? 1/(0.5+(dist*dist/48)) : dist / std::sin(dist/2);
+        T invSinc = 1/sincHalf(dist);
 
         // Compute difference on T_a SO(3)
         Dune::FieldVector<double,3> v;
@@ -169,12 +197,46 @@ public:
     /** \brief Interpolate between two rotations */
     static Quaternion<T> interpolateDerivative(const Quaternion<T>& a, const Quaternion<T>& b, 
                                                double omega, double intervallLength) {
-
         Quaternion<T> result;
+#if 0
 
         for (int i=0; i<4; i++)
             result[i] = a[i] / (-intervallLength) + b[i] / intervallLength;
 
+#else
+        // Interpolation on the geodesic in SO(3) from a to b
+
+        // diff = a^-1 b
+        Quaternion<T> diff = a;
+        diff.invert();
+        diff = diff.mult(b);
+
+        T dist = 2*std::acos(diff[3]);
+
+        T invSinc = 1/sincHalf(dist);
+
+        // Compute difference on T_a SO(3)
+        Dune::FieldVector<double,3> v;
+        v[0] = diff[0] * invSinc;
+        v[1] = diff[1] * invSinc;
+        v[2] = diff[2] * invSinc;
+
+        Dune::FieldVector<double,3> der = v;
+        der /= intervallLength;
+        
+        // //////////////////////////////////////////////////////////////
+        //   v now contains the derivative at 'a'.  The derivative at
+        //   the requested site is v pushed forward by Dexp.
+        // /////////////////////////////////////////////////////////////
+
+        v *= omega;
+
+        Dune::FieldMatrix<double,4,3> diffExp = Quaternion<double>::Dexp(v);
+
+        result[0] = result[1] = result[2] = result[3] = 0;
+        diffExp.umv(der,result);
+#endif
+        //std::cout << result << std::endl;
         return result;
     }