diff --git a/dune/xt/la/eigen-solver/internal/shifted-qr.hh b/dune/xt/la/eigen-solver/internal/shifted-qr.hh
index 374a47d47c218225225c3c7ba7ea282c89b1b1ec..485c0d97b59f71363f3ab5f0a00e981998180f00 100644
--- a/dune/xt/la/eigen-solver/internal/shifted-qr.hh
+++ b/dune/xt/la/eigen-solver/internal/shifted-qr.hh
@@ -113,9 +113,13 @@ struct RealQrEigenSolver
     return eigenvalues;
   } // .. calculate_eigenvalues_by_shifted_qr(...)
 
-  static void reduced_row_echelon_form(MatrixType& A, std::vector<size_t>& pivot_variables)
+  static void reduced_row_echelon_form(MatrixType& A,
+                                       std::vector<std::pair<size_t, size_t>>& pivot_variables,
+                                       std::vector<size_t>& free_variables,
+                                       double tol)
   {
     pivot_variables.clear();
+    free_variables.clear();
     size_t col = 0;
     for (size_t row = 0; row < A.rows(); ++row) {
       while (col < A.cols()) {
@@ -125,7 +129,8 @@ struct RealQrEigenSolver
           if (std::abs(A[rr][col]) > std::abs(A[pivot][col]))
             pivot = rr;
         // if all entries in column are zero, continue with next column
-        if (XT::Common::FloatCmp::eq(A[pivot][col], 0.)) {
+        if (XT::Common::FloatCmp::eq<XT::Common::FloatCmp::Style::absolute>(A[pivot][col], 0., tol)) {
+          free_variables.push_back(col);
           ++col;
           continue;
         } else {
@@ -139,14 +144,14 @@ struct RealQrEigenSolver
           // add row to all other rows to zero out other entries in column
           for (size_t rr = 0; rr < A.rows(); ++rr) {
             auto factor = A[rr][col];
-            if (rr != row && XT::Common::FloatCmp::ne(factor, 0.)) {
+            if (rr != row) {
               for (size_t cc = col + 1; cc < A.cols(); ++cc)
                 A[rr][cc] -= A[row][cc] * factor;
               A[rr][col] = 0.;
             }
           } // rr
-          // store column as pivot variable
-          pivot_variables.push_back(col);
+          // store (col, row) as pivot variable
+          pivot_variables.push_back(std::make_pair(col, row));
           // continue with next row and col
           ++col;
           break;
@@ -155,27 +160,34 @@ struct RealQrEigenSolver
     } // row
   } // void reduced_row_echelon_form(...)
 
-  static std::vector<double> get_eigenvalues(const MatrixType& A_in)
+  static std::vector<double> get_eigenvalues(const MatrixType& A_in, MatrixType* Q = nullptr)
   {
     auto A_ptr = std::make_unique<MatrixType>(A_in);
     auto& A = *A_ptr;
-    hessenberg_transformation(A);
-    auto eigenvalues = calculate_eigenvalues_by_shifted_qr(A);
+    hessenberg_transformation(A, Q);
+    auto eigenvalues = calculate_eigenvalues_by_shifted_qr(A, Q);
     std::sort(eigenvalues.begin(), eigenvalues.end());
     return eigenvalues;
   } // ... get_eigenvalues(...)
 
-  static std::unique_ptr<MatrixType> get_eigenvectors(const MatrixType& A_in, const std::vector<double>& eigenvalues)
+  static std::unique_ptr<MatrixType>
+  get_eigenvectors(const MatrixType& A_in, const std::vector<double>& eigenvalues, const MatrixType& Q)
   {
+    std::cout << "A = " << XT::Common::to_string(A_in, 17) << std::endl;
+    std::cout << "eigenvalues = " << XT::Common::to_string(eigenvalues, 15) << std::endl;
     auto A_ptr = std::make_unique<MatrixType>(A_in);
     auto& A = *A_ptr;
+    // use the same tolerance max(size(A)) * eps * norm(A,inf) as matlab for rref
+    double tol = std::numeric_limits<double>::epsilon() * std::max(A.rows(), A.cols()) * A.infinity_norm();
     auto ret = std::make_unique<MatrixType>(A_in);
+    *ret *= 0.;
     // Calculate eigenvectors by solving (A - \lambda I) x = 0.
     for (size_t ii = 0; ii < eigenvalues.size(); ++ii) {
       // get eigenvalue, calculate multiplicity
       double lambda = eigenvalues[ii];
       size_t multiplicity = 1;
-      while (XT::Common::FloatCmp::eq(eigenvalues[ii], eigenvalues[ii + 1])) {
+      while (
+          XT::Common::FloatCmp::eq<XT::Common::FloatCmp::Style::absolute>(eigenvalues[ii], eigenvalues[ii + 1], tol)) {
         ++multiplicity;
         ++ii;
       }
@@ -185,25 +197,42 @@ struct RealQrEigenSolver
         A[rr][rr] -= lambda;
 
       // transform B to reduced row echelon form
-      // in the process, keep track of pivot variables
-      std::vector<size_t> pivot_variables;
-      reduced_row_echelon_form(A, pivot_variables);
+      // in the process, keep track of variables
+      // pivot_variables contains pairs of (col, row), where col is the pivot column and row is the row where the 1 is
+      // located
+      std::vector<std::pair<size_t, size_t>> pivot_variables;
+      // free_variables contains the columns of the free variables
+      std::vector<size_t> free_variables;
+      // This loop is a hack to avoid problems with the reduced row echelon form being wrong due to too small tolerances
+      // TODO: Do something more sophisticated/replace rref by a more stable algorithm to get eigenvectors?
+      size_t max_power = 4;
+      for (size_t jj = 0; jj <= max_power; ++jj) {
+        tol = std::numeric_limits<double>::epsilon() * std::max(A.rows(), A.cols()) * A.infinity_norm()
+              * std::pow(10., jj);
+        std::cout << "tol: " << XT::Common::to_string(tol, 15) << std::endl;
+        reduced_row_echelon_form(A, pivot_variables, free_variables, tol);
+        std::cout << "Arref = " << XT::Common::to_string(A, 15) << std::endl;
+        std::cout << "lambda = " << XT::Common::to_string(lambda, 15) << std::endl;
+        std::cout << "free_variables" << XT::Common::to_string(free_variables) << std::endl;
+        if (free_variables.size() == multiplicity)
+          break;
+        if (jj == max_power && free_variables.size() != multiplicity)
+          DUNE_THROW(Dune::MathError, "Failed to compute eigenvectors!");
+        A = A_in;
+        for (size_t rr = 0; rr < A.rows(); ++rr)
+          A[rr][rr] -= lambda;
+      } // jj
 
       // Now get the eigenvectors from the reduced row echelon form. To get an eigenvector, set one of the free
       // variables to 1 and the other free variables to 0 and calculate the pivot variables.
-      std::vector<size_t> free_variables;
-      for (size_t jj = 0; jj < A.cols(); ++jj)
-        if (std::find(pivot_variables.begin(), pivot_variables.end(), jj) == pivot_variables.end())
-          free_variables.push_back(jj);
-      if (free_variables.size() != multiplicity)
-        DUNE_THROW(Dune::MathError, "Failed to compute eigenvectors!");
       size_t eigenvector_index = ii - multiplicity + 1;
-      for (const auto& cc : free_variables) {
-        for (size_t rr = 0; rr < A.rows(); ++rr)
-          (*ret)[rr][eigenvector_index] = -A[rr][cc];
-        (*ret)[cc][eigenvector_index] = 1.;
+      for (const auto& free_var : free_variables) {
+        for (const auto& pivot_var : pivot_variables) {
+          (*ret)[pivot_var.first][eigenvector_index] = -A[pivot_var.second][free_var];
+        }
+        (*ret)[free_var][eigenvector_index] = 1.;
         ++eigenvector_index;
-      } // cc
+      } // free_var
     } // ii
     // normalize eigenvectors
     for (size_t col = 0; col < ret->cols(); ++col) {
@@ -214,6 +243,7 @@ struct RealQrEigenSolver
       for (size_t row = 0; row < ret->rows(); ++row)
         (*ret)[row][col] *= inv_norm;
     }
+    std::cout << "ret = " << XT::Common::to_string(*ret, 15) << std::endl;
     return ret;
   } // ... get_eigenvectors(...)
 
@@ -339,7 +369,7 @@ struct RealQrEigenSolver
 
   //! \brief Transform A to Hessenberg form by transformation P^T A P
   //! \see https://lp.uni-goettingen.de/get/text/2137
-  static void hessenberg_transformation(MatrixType& A)
+  static void hessenberg_transformation(MatrixType& A, MatrixType* Q)
   {
     assert(A.rows() == A.cols() && "Hessenberg transformation needs a square matrix!");
     VectorType u(A.rows(), 0.);
@@ -359,6 +389,8 @@ struct RealQrEigenSolver
         multiply_householder_from_left(A, beta, u, jj + 1, A.rows());
         // now calculate (PA) P  = PA - (PA u) (beta u^T)
         multiply_householder_from_right(A, beta, u, jj + 1, A.cols());
+        if (Q)
+          multiply_householder_from_right(*Q, beta, u, jj + 1, A.cols());
       } // if (gamma != 0)
     } // jj
   } // void hessenberg_transformation(...)