Build: Remove the demos and Qt4 support

libeigen/eigen!3413

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
diff --git a/AGENTS.md b/AGENTS.md
index 079bcfa..e3f8674 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -113,7 +113,7 @@
 ## Repository essentials
 
 Eigen is a header-only expression-template library. Consumers include module headers under `Eigen/` or
-`contrib/Eigen/`. The top-level CMake project builds tests, documentation, demos, and BLAS/LAPACK shims rather than
+`contrib/Eigen/`. The top-level CMake project builds tests, documentation, and BLAS/LAPACK shims rather than
 a core Eigen library; benchmarks use separate CMake projects. `Eigen/Dense` aggregates the dense modules, while
 `Eigen/Eigen` includes `Dense` and `Sparse`. External backend support modules and `Eigen/ThreadPool` remain separate
 includes. The upstream project is on GitLab; its GitHub repository is a read-only mirror.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 972e692..ea3c0aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,9 +24,11 @@
 
 Breaking changes:
 - The default `epsfcn` for central mode differences was changed to `cbrt(NumTraits<Scalar>::epsilon())` (used to be `sqrt(NumTraits<Scalar>::epsilon())`). The new default should reduce numerical error in most cases.
+- Removed `Eigen/QtAlignedMalloc`, which replaced Qt 4's `qMalloc`, `qFree` and `qRealloc` with aligned versions on platforms whose `malloc` is not already sufficiently aligned. Remove the include. [!3413]
 
 Deprecations:
 - `ArrayBase::shiftRight<N>()` and `ArrayBase::shiftLeft<N>()`, in favour of `arithmeticShiftRight<N>()` and `logicalShiftLeft<N>()` [!2816]
+- The `Transform` conversions from and to Qt's `QMatrix` and `QTransform`, which `EIGEN_QT_SUPPORT` enables, in favor of copying the coefficients explicitly [!3413]
 
 Other changes:
 - The top-level `unsupported/` directory was renamed to `contrib/`. Existing
@@ -34,6 +36,7 @@
   unchanged via forwarding header shims. The CMake subproject label and
   build-group target were renamed accordingly: `Unsupported` → `Contrib`,
   `BuildUnsupported` → `BuildContrib`.
+- Removed the `demos/` directory, including its two Qt GUI demos, and the `EIGEN_BUILD_DEMOS` and `EIGEN_TEST_NOQT` CMake options. The sparse tutorial example no longer needs Qt; it writes a PGM image. [!3413]
 
 ## [5.0.1] - 2025-11-11
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 69ba5e7..8635e0a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -139,8 +139,6 @@
 endif()
 option(EIGEN_BUILD_DOC "Enable creation of Eigen documentation" ${EIGEN_BUILD_DOC_DEFAULT})
 
-option(EIGEN_BUILD_DEMOS "Toggles the building of the Eigen demos" ${PROJECT_IS_TOP_LEVEL})
-
 # Disable pkgconfig only for native Windows builds
 if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
   option(EIGEN_BUILD_PKGCONFIG "Build pkg-config .pc file for Eigen" ${PROJECT_IS_TOP_LEVEL})
@@ -151,7 +149,7 @@
 # headers, eigen3.pc, the CMake package files, and the BLAS/LAPACK libraries.
 option(EIGEN_INSTALL "Enable Eigen's install rules" ON)
 
-if (EIGEN_BUILD_TESTING OR EIGEN_BUILD_BLAS OR EIGEN_BUILD_LAPACK OR EIGEN_BUILD_DOC OR EIGEN_BUILD_DEMOS)
+if (EIGEN_BUILD_TESTING OR EIGEN_BUILD_BLAS OR EIGEN_BUILD_LAPACK OR EIGEN_BUILD_DOC)
   set(EIGEN_IS_BUILDING_ ON)
 endif()
 
@@ -826,10 +824,6 @@
   add_subdirectory(doc EXCLUDE_FROM_ALL)
 endif()
 
-if (EIGEN_BUILD_DEMOS)
-  add_subdirectory(demos EXCLUDE_FROM_ALL)
-endif()
-
 if (PROJECT_IS_TOP_LEVEL)
   # must be after test and contrib, for configuring buildtests.in
   add_subdirectory(scripts EXCLUDE_FROM_ALL)
diff --git a/Eigen/QtAlignedMalloc b/Eigen/QtAlignedMalloc
deleted file mode 100644
index cb34bfa..0000000
--- a/Eigen/QtAlignedMalloc
+++ /dev/null
@@ -1,34 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-FileCopyrightText: The Eigen Authors
-// SPDX-License-Identifier: MPL-2.0
-
-#ifndef EIGEN_QTMALLOC_MODULE_H
-#define EIGEN_QTMALLOC_MODULE_H
-
-#include "Core"
-
-#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-inline void *qMalloc(std::size_t size) { return Eigen::internal::aligned_malloc(size); }
-
-inline void qFree(void *ptr) { Eigen::internal::aligned_free(ptr); }
-
-inline void *qRealloc(void *ptr, std::size_t size) {
-  void *newPtr = Eigen::internal::aligned_malloc(size);
-  std::memcpy(newPtr, ptr, size);
-  Eigen::internal::aligned_free(ptr);
-  return newPtr;
-}
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif
-
-#endif  // EIGEN_QTMALLOC_MODULE_H
diff --git a/Eigen/src/Core/util/DisableStupidWarnings.h b/Eigen/src/Core/util/DisableStupidWarnings.h
index 8091ad4..b993f2d 100644
--- a/Eigen/src/Core/util/DisableStupidWarnings.h
+++ b/Eigen/src/Core/util/DisableStupidWarnings.h
@@ -11,7 +11,6 @@
 // 4181 - qualifier applied to reference type ignored
 // 4211 - nonstandard extension used : redefined extern to static
 // 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data
-// 4273 - QtAlignedMalloc, inconsistent DLL linkage
 // 4324 - structure was padded due to declspec(align())
 // 4503 - decorated name length exceeded, name was truncated
 // 4512 - assignment operator could not be generated
@@ -21,7 +20,7 @@
 // 4717 - 'function' : recursive on all control paths, function will cause runtime stack overflow
 // 4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning)
 #pragma warning(push)
-#pragma warning(disable : 4100 4101 4127 4181 4211 4244 4273 4324 4503 4512 4522 4700 4714 4717 4800)
+#pragma warning(disable : 4100 4101 4127 4181 4211 4244 4324 4503 4512 4522 4700 4714 4717 4800)
 // We currently rely on has_denorm in tests, and need it defined correctly for half/bfloat16.
 #ifndef _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
 #define EIGEN_REENABLE_CXX23_DENORM_DEPRECATION_WARNING 1
diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h
index 2a2150f..1896f20 100644
--- a/Eigen/src/Geometry/Transform.h
+++ b/Eigen/src/Geometry/Transform.h
@@ -211,7 +211,7 @@
  * Note that there is zero overhead.
  *
  * Conversion methods from/to Qt's QMatrix and QTransform are available if the
- * preprocessor token EIGEN_QT_SUPPORT is defined.
+ * preprocessor token EIGEN_QT_SUPPORT is defined. They are deprecated and will be removed.
  *
  * This class can be extended with the help of the plugin mechanism described on the page
  * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_TRANSFORM_PLUGIN.
@@ -376,13 +376,14 @@
 
 #ifdef EIGEN_QT_SUPPORT
 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
-  inline Transform(const QMatrix& other);
-  inline Transform& operator=(const QMatrix& other);
-  inline QMatrix toQMatrix(void) const;
+  EIGEN_DEPRECATED_WITH_REASON("Copy the coefficients explicitly.") inline Transform(const QMatrix& other);
+  EIGEN_DEPRECATED_WITH_REASON("Copy the coefficients explicitly.") inline Transform& operator=(const QMatrix& other);
+  EIGEN_DEPRECATED_WITH_REASON("Copy the coefficients explicitly.") inline QMatrix toQMatrix(void) const;
 #endif
-  inline Transform(const QTransform& other);
+  EIGEN_DEPRECATED_WITH_REASON("Copy the coefficients explicitly.") inline Transform(const QTransform& other);
+  EIGEN_DEPRECATED_WITH_REASON("Copy the coefficients explicitly.")
   inline Transform& operator=(const QTransform& other);
-  inline QTransform toQTransform(void) const;
+  EIGEN_DEPRECATED_WITH_REASON("Copy the coefficients explicitly.") inline QTransform toQTransform(void) const;
 #endif
 
   EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept {
@@ -723,10 +724,16 @@
 
 #ifdef EIGEN_QT_SUPPORT
 
+// The deprecated constructors call the deprecated assignment operators.
+EIGEN_DIAGNOSTICS(push)
+EIGEN_DIAGNOSTICS_OFF(disable : 4996, ignored "-Wdeprecated-declarations")
+
 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
 /** Initializes \c *this from a QMatrix assuming the dimension is 2.
  *
  * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ *
+ * \deprecated Copy the coefficients explicitly.
  */
 template <typename Scalar, int Dim, int Mode, int Options>
 Transform<Scalar, Dim, Mode, Options>::Transform(const QMatrix& other) {
@@ -737,6 +744,8 @@
 /** Set \c *this from a QMatrix assuming the dimension is 2.
  *
  * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ *
+ * \deprecated Copy the coefficients explicitly.
  */
 template <typename Scalar, int Dim, int Mode, int Options>
 Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::operator=(const QMatrix& other) {
@@ -753,6 +762,8 @@
  * \warning this conversion might lose data if \c *this is not affine
  *
  * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ *
+ * \deprecated Copy the coefficients explicitly.
  */
 template <typename Scalar, int Dim, int Mode, int Options>
 QMatrix Transform<Scalar, Dim, Mode, Options>::toQMatrix(void) const {
@@ -766,6 +777,8 @@
 /** Initializes \c *this from a QTransform assuming the dimension is 2.
  *
  * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ *
+ * \deprecated Copy the coefficients explicitly.
  */
 template <typename Scalar, int Dim, int Mode, int Options>
 Transform<Scalar, Dim, Mode, Options>::Transform(const QTransform& other) {
@@ -776,6 +789,8 @@
 /** Set \c *this from a QTransform assuming the dimension is 2.
  *
  * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ *
+ * \deprecated Copy the coefficients explicitly.
  */
 template <typename Scalar, int Dim, int Mode, int Options>
 Transform<Scalar, Dim, Mode, Options>& Transform<Scalar, Dim, Mode, Options>::operator=(const QTransform& other) {
@@ -792,6 +807,8 @@
 /** \returns a QTransform from \c *this assuming the dimension is 2.
  *
  * This function is available only if the token EIGEN_QT_SUPPORT is defined.
+ *
+ * \deprecated Copy the coefficients explicitly.
  */
 template <typename Scalar, int Dim, int Mode, int Options>
 QTransform Transform<Scalar, Dim, Mode, Options>::toQTransform(void) const {
@@ -804,6 +821,8 @@
                       m_matrix.coeff(1, 1), m_matrix.coeff(2, 1), m_matrix.coeff(0, 2), m_matrix.coeff(1, 2),
                       m_matrix.coeff(2, 2));
 }
+
+EIGEN_DIAGNOSTICS(pop)
 #endif
 
 /*********************
diff --git a/ci/scripts/test.buildsystem.script.sh b/ci/scripts/test.buildsystem.script.sh
index dfcba1d..4aac9bc 100755
--- a/ci/scripts/test.buildsystem.script.sh
+++ b/ci/scripts/test.buildsystem.script.sh
@@ -30,7 +30,6 @@
   "-DCMAKE_CXX_COMPILER=${EIGEN_CI_CXX_COMPILER}" \
   -DEIGEN_BUILD_TESTING=ON                        \
   -DEIGEN_BUILD_DOC=OFF                           \
-  -DEIGEN_BUILD_DEMOS=OFF                         \
   -DEIGEN_BUILD_BLAS=OFF                          \
   -DEIGEN_BUILD_LAPACK=OFF                        \
   ${EIGEN_CI_ADDITIONAL_ARGS} "${rootdir}"
diff --git a/contrib/README.txt b/contrib/README.txt
index f19488a..bb23648 100644
--- a/contrib/README.txt
+++ b/contrib/README.txt
@@ -29,9 +29,7 @@
  - should have some general purpose in the sense that it could
    potentially become a core Eigen module (or be merged into another one).
 
-In doubt feel free to contact us. For instance, if your addon is very
-specific but shows an interesting way of using Eigen, it could make for a
-nice demo.
+In doubt feel free to contact us.
 
 
 This directory is organized as follow:
diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt
deleted file mode 100644
index a27f047..0000000
--- a/demos/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-FileCopyrightText: The Eigen Authors
-# SPDX-License-Identifier: MPL-2.0
-
-project(EigenDemos)
-
-add_custom_target(demos)
-
-if(NOT EIGEN_TEST_NOQT)
-  find_package(Qt4)
-  if(QT4_FOUND)
-    add_subdirectory(mandelbrot)
-    add_subdirectory(opengl)
-  else()
-    message(STATUS "Qt4 not found, so disabling the mandelbrot and opengl demos")
-  endif()
-endif()
diff --git a/demos/mandelbrot/CMakeLists.txt b/demos/mandelbrot/CMakeLists.txt
deleted file mode 100644
index 66dd13f..0000000
--- a/demos/mandelbrot/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-# SPDX-FileCopyrightText: The Eigen Authors
-# SPDX-License-Identifier: MPL-2.0
-
-find_package(Qt4 REQUIRED)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-if (CMAKE_COMPILER_IS_GNUCXX)
-   set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
-   add_definitions ( "-DNDEBUG" )
-endif ()
-
-include_directories( ${QT_INCLUDE_DIR} )
-
-set(mandelbrot_SRCS
-    mandelbrot.cpp
-)
-
-qt4_automoc(${mandelbrot_SRCS})
-
-add_executable(mandelbrot ${mandelbrot_SRCS})
-add_dependencies(demos mandelbrot)
-
-target_link_libraries(mandelbrot ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
diff --git a/demos/mandelbrot/README b/demos/mandelbrot/README
deleted file mode 100644
index a451d65..0000000
--- a/demos/mandelbrot/README
+++ /dev/null
@@ -1,10 +0,0 @@
-*** Mandelbrot demo ***
-
-Controls:
-* Left mouse button to center view at a point.
-* Drag vertically with left mouse button to zoom in and out.
-
-Be sure to enable SSE2 or AltiVec to improve performance.
-
-The number of iterations, and the choice between single and double precision, are
-determined at runtime depending on the zoom level.
diff --git a/demos/mandelbrot/mandelbrot.cpp b/demos/mandelbrot/mandelbrot.cpp
deleted file mode 100644
index 9c192fe..0000000
--- a/demos/mandelbrot/mandelbrot.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "mandelbrot.h"
-#include <iostream>
-#include <QtGui/QPainter>
-#include <QtGui/QImage>
-#include <QtGui/QMouseEvent>
-#include <QtCore/QTime>
-
-void MandelbrotWidget::resizeEvent(QResizeEvent *) {
-  if (size < width() * height()) {
-    std::cout << "reallocate buffer" << std::endl;
-    size = width() * height();
-    if (buffer) delete[] buffer;
-    buffer = new unsigned char[4 * size];
-  }
-}
-
-template <typename T>
-struct iters_before_test {
-  enum { ret = 8 };
-};
-template <>
-struct iters_before_test<double> {
-  enum { ret = 16 };
-};
-
-template <typename Real>
-void MandelbrotThread::render(int img_width, int img_height) {
-  enum { packetSize = Eigen::internal::packet_traits<Real>::size };  // number of reals in a Packet
-  typedef Eigen::Array<Real, packetSize, 1> Packet;                  // wrap a Packet as a vector
-
-  enum { iters_before_test = iters_before_test<Real>::ret };
-  max_iter = (max_iter / iters_before_test) * iters_before_test;
-  const int alignedWidth = (img_width / packetSize) * packetSize;
-  unsigned char *const buffer = widget->buffer;
-  const double xradius = widget->xradius;
-  const double yradius = xradius * img_height / img_width;
-  const int threadcount = widget->threadcount;
-  typedef Eigen::Array<Real, 2, 1> Vector2;
-  Vector2 start(widget->center.x() - widget->xradius, widget->center.y() - yradius);
-  Vector2 step(2 * widget->xradius / img_width, 2 * yradius / img_height);
-  total_iter = 0;
-
-  for (int y = id; y < img_height; y += threadcount) {
-    int pix = y * img_width;
-
-    // for each pixel, we're going to do the iteration z := z^2 + c where z and c are complex numbers,
-    // starting with z = c = complex coord of the pixel. pzi and pzr denote the real and imaginary parts of z.
-    // pci and pcr denote the real and imaginary parts of c.
-
-    Packet pzi_start, pci_start;
-    for (int i = 0; i < packetSize; i++) pzi_start[i] = pci_start[i] = start.y() + y * step.y();
-
-    for (int x = 0; x < alignedWidth; x += packetSize, pix += packetSize) {
-      Packet pcr, pci = pci_start, pzr, pzi = pzi_start, pzr_buf;
-      for (int i = 0; i < packetSize; i++) pzr[i] = pcr[i] = start.x() + (x + i) * step.x();
-
-      // do the iterations. Every iters_before_test iterations we check for divergence,
-      // in which case we can stop iterating.
-      int j = 0;
-      typedef Eigen::Matrix<int, packetSize, 1> Packeti;
-      Packeti pix_iter = Packeti::Zero(),  // number of iteration per pixel in the packet
-          pix_dont_diverge;                // whether or not each pixel has already diverged
-      do {
-        for (int i = 0; i < iters_before_test / 4; i++)  // peel the inner loop by 4
-        {
-#define ITERATE              \
-  pzr_buf = pzr;             \
-  pzr = pzr.square();        \
-  pzr -= pzi.square();       \
-  pzr += pcr;                \
-  pzi = (2 * pzr_buf) * pzi; \
-  pzi += pci;
-          ITERATE ITERATE ITERATE ITERATE
-        }
-        pix_dont_diverge =
-            ((pzr.square() + pzi.square()).eval()  // temporary fix as what follows is not yet vectorized by Eigen
-             <= Packet::Constant(4))
-                // the 4 here is not a magic value, it's a math fact that if
-                // the square modulus is >4 then divergence is inevitable.
-                .template cast<int>();
-        pix_iter += iters_before_test * pix_dont_diverge;
-        j++;
-        total_iter += iters_before_test * packetSize;
-      } while (j < max_iter / iters_before_test && pix_dont_diverge.any());  // any() is not yet vectorized by Eigen
-
-      // compute pixel colors
-      for (int i = 0; i < packetSize; i++) {
-        buffer[4 * (pix + i)] = 255 * pix_iter[i] / max_iter;
-        buffer[4 * (pix + i) + 1] = 0;
-        buffer[4 * (pix + i) + 2] = 0;
-      }
-    }
-
-    // if the width is not a multiple of packetSize, fill the remainder in black
-    for (int x = alignedWidth; x < img_width; x++, pix++)
-      buffer[4 * pix] = buffer[4 * pix + 1] = buffer[4 * pix + 2] = 0;
-  }
-  return;
-}
-
-void MandelbrotThread::run() {
-  setTerminationEnabled(true);
-  double resolution = widget->xradius * 2 / widget->width();
-  max_iter = 128;
-  if (resolution < 1e-4f) max_iter += 128 * (-4 - std::log10(resolution));
-  int img_width = widget->width() / widget->draft;
-  int img_height = widget->height() / widget->draft;
-  single_precision = resolution > 1e-7f;
-
-  if (single_precision)
-    render<float>(img_width, img_height);
-  else
-    render<double>(img_width, img_height);
-}
-
-void MandelbrotWidget::paintEvent(QPaintEvent *) {
-  static float max_speed = 0;
-  long long total_iter = 0;
-
-  QTime time;
-  time.start();
-  for (int th = 0; th < threadcount; th++) threads[th]->start(QThread::LowPriority);
-  for (int th = 0; th < threadcount; th++) {
-    threads[th]->wait();
-    total_iter += threads[th]->total_iter;
-  }
-  int elapsed = time.elapsed();
-
-  if (draft == 1) {
-    float speed = elapsed ? float(total_iter) * 1000 / elapsed : 0;
-    max_speed = std::max(max_speed, speed);
-    std::cout << threadcount << " threads, " << elapsed << " ms, " << speed << " iters/s (max " << max_speed << ")"
-              << std::endl;
-    int packetSize = threads[0]->single_precision ? int(Eigen::internal::packet_traits<float>::size)
-                                                  : int(Eigen::internal::packet_traits<double>::size);
-    setWindowTitle(
-        QString("resolution ") + QString::number(xradius * 2 / width(), 'e', 2) +
-        QString(", %1 iterations per pixel, ").arg(threads[0]->max_iter) +
-        (threads[0]->single_precision ? QString("single ") : QString("double ")) + QString("precision, ") +
-        (packetSize == 1 ? QString("no vectorization") : QString("vectorized (%1 per packet)").arg(packetSize)));
-  }
-
-  QImage image(buffer, width() / draft, height() / draft, QImage::Format_RGB32);
-  QPainter painter(this);
-  painter.drawImage(QPoint(0, 0), image.scaled(width(), height()));
-
-  if (draft > 1) {
-    draft /= 2;
-    setWindowTitle(QString("recomputing at 1/%1 resolution...").arg(draft));
-    update();
-  }
-}
-
-void MandelbrotWidget::mousePressEvent(QMouseEvent *event) {
-  if (event->buttons() & Qt::LeftButton) {
-    lastpos = event->pos();
-    double yradius = xradius * height() / width();
-    center = Eigen::Vector2d(center.x() + (event->pos().x() - width() / 2) * xradius * 2 / width(),
-                             center.y() + (event->pos().y() - height() / 2) * yradius * 2 / height());
-    draft = 16;
-    for (int th = 0; th < threadcount; th++) threads[th]->terminate();
-    update();
-  }
-}
-
-void MandelbrotWidget::mouseMoveEvent(QMouseEvent *event) {
-  QPoint delta = event->pos() - lastpos;
-  lastpos = event->pos();
-  if (event->buttons() & Qt::LeftButton) {
-    double t = 1 + 5 * double(delta.y()) / height();
-    if (t < 0.5) t = 0.5;
-    if (t > 2) t = 2;
-    xradius *= t;
-    draft = 16;
-    for (int th = 0; th < threadcount; th++) threads[th]->terminate();
-    update();
-  }
-}
-
-int main(int argc, char *argv[]) {
-  QApplication app(argc, argv);
-  MandelbrotWidget w;
-  w.show();
-  return app.exec();
-}
-
-#include "mandelbrot.moc"
diff --git a/demos/mandelbrot/mandelbrot.h b/demos/mandelbrot/mandelbrot.h
deleted file mode 100644
index 0b7d9a6..0000000
--- a/demos/mandelbrot/mandelbrot.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#ifndef MANDELBROT_H
-#define MANDELBROT_H
-
-#include <Eigen/Core>
-#include <QtGui/QApplication>
-#include <QtGui/QWidget>
-#include <QtCore/QThread>
-
-class MandelbrotWidget;
-
-class MandelbrotThread : public QThread {
-  friend class MandelbrotWidget;
-  MandelbrotWidget *widget;
-  long long total_iter;
-  int id, max_iter;
-  bool single_precision;
-
- public:
-  MandelbrotThread(MandelbrotWidget *w, int i) : widget(w), id(i) {}
-  void run();
-  template <typename Real>
-  void render(int img_width, int img_height);
-};
-
-class MandelbrotWidget : public QWidget {
-  Q_OBJECT
-
-  friend class MandelbrotThread;
-  Eigen::Vector2d center;
-  double xradius;
-  int size;
-  unsigned char *buffer;
-  QPoint lastpos;
-  int draft;
-  MandelbrotThread **threads;
-  int threadcount;
-
- protected:
-  void resizeEvent(QResizeEvent *);
-  void paintEvent(QPaintEvent *);
-  void mousePressEvent(QMouseEvent *event);
-  void mouseMoveEvent(QMouseEvent *event);
-
- public:
-  MandelbrotWidget() : QWidget(), center(0, 0), xradius(2), size(0), buffer(0), draft(16) {
-    setAutoFillBackground(false);
-    threadcount = QThread::idealThreadCount();
-    threads = new MandelbrotThread *[threadcount];
-    for (int th = 0; th < threadcount; th++) threads[th] = new MandelbrotThread(this, th);
-  }
-  ~MandelbrotWidget() {
-    if (buffer) delete[] buffer;
-    for (int th = 0; th < threadcount; th++) delete threads[th];
-    delete[] threads;
-  }
-};
-
-#endif  // MANDELBROT_H
diff --git a/demos/mix_eigen_and_c/README b/demos/mix_eigen_and_c/README
deleted file mode 100644
index d9cc927..0000000
--- a/demos/mix_eigen_and_c/README
+++ /dev/null
@@ -1,9 +0,0 @@
-This is an example of how one can wrap some of Eigen into a C library.
-
-To try this with GCC, do:
-
-  g++ -c binary_library.cpp -O2 -msse2 -I ../..
-  gcc example.c binary_library.o -o example -lstdc++
-  ./example
-
-TODO: add CMakeLists, add more explanations here
diff --git a/demos/mix_eigen_and_c/binary_library.cpp b/demos/mix_eigen_and_c/binary_library.cpp
deleted file mode 100644
index 4da74b6..0000000
--- a/demos/mix_eigen_and_c/binary_library.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-// This C++ file compiles to binary code that can be linked to by your C program,
-// thanks to the extern "C" syntax used in the declarations in binary_library.h.
-
-#include "binary_library.h"
-
-#include <Eigen/Core>
-
-using namespace Eigen;
-
-/************************* pointer conversion methods **********************************************/
-
-////// class MatrixXd //////
-
-inline MatrixXd &c_to_eigen(C_MatrixXd *ptr) { return *reinterpret_cast<MatrixXd *>(ptr); }
-
-inline const MatrixXd &c_to_eigen(const C_MatrixXd *ptr) { return *reinterpret_cast<const MatrixXd *>(ptr); }
-
-inline C_MatrixXd *eigen_to_c(MatrixXd &ref) { return reinterpret_cast<C_MatrixXd *>(&ref); }
-
-inline const C_MatrixXd *eigen_to_c(const MatrixXd &ref) { return reinterpret_cast<const C_MatrixXd *>(&ref); }
-
-////// class Map<MatrixXd> //////
-
-inline Map<MatrixXd> &c_to_eigen(C_Map_MatrixXd *ptr) { return *reinterpret_cast<Map<MatrixXd> *>(ptr); }
-
-inline const Map<MatrixXd> &c_to_eigen(const C_Map_MatrixXd *ptr) {
-  return *reinterpret_cast<const Map<MatrixXd> *>(ptr);
-}
-
-inline C_Map_MatrixXd *eigen_to_c(Map<MatrixXd> &ref) { return reinterpret_cast<C_Map_MatrixXd *>(&ref); }
-
-inline const C_Map_MatrixXd *eigen_to_c(const Map<MatrixXd> &ref) {
-  return reinterpret_cast<const C_Map_MatrixXd *>(&ref);
-}
-
-/************************* implementation of classes **********************************************/
-
-////// class MatrixXd //////
-
-C_MatrixXd *MatrixXd_new(int rows, int cols) { return eigen_to_c(*new MatrixXd(rows, cols)); }
-
-void MatrixXd_delete(C_MatrixXd *m) { delete &c_to_eigen(m); }
-
-double *MatrixXd_data(C_MatrixXd *m) { return c_to_eigen(m).data(); }
-
-void MatrixXd_set_zero(C_MatrixXd *m) { c_to_eigen(m).setZero(); }
-
-void MatrixXd_resize(C_MatrixXd *m, int rows, int cols) { c_to_eigen(m).resize(rows, cols); }
-
-void MatrixXd_copy(C_MatrixXd *dst, const C_MatrixXd *src) { c_to_eigen(dst) = c_to_eigen(src); }
-
-void MatrixXd_copy_map(C_MatrixXd *dst, const C_Map_MatrixXd *src) { c_to_eigen(dst) = c_to_eigen(src); }
-
-void MatrixXd_set_coeff(C_MatrixXd *m, int i, int j, double coeff) { c_to_eigen(m)(i, j) = coeff; }
-
-double MatrixXd_get_coeff(const C_MatrixXd *m, int i, int j) { return c_to_eigen(m)(i, j); }
-
-void MatrixXd_print(const C_MatrixXd *m) { std::cout << c_to_eigen(m) << std::endl; }
-
-void MatrixXd_multiply(const C_MatrixXd *m1, const C_MatrixXd *m2, C_MatrixXd *result) {
-  c_to_eigen(result) = c_to_eigen(m1) * c_to_eigen(m2);
-}
-
-void MatrixXd_add(const C_MatrixXd *m1, const C_MatrixXd *m2, C_MatrixXd *result) {
-  c_to_eigen(result) = c_to_eigen(m1) + c_to_eigen(m2);
-}
-
-////// class Map_MatrixXd //////
-
-C_Map_MatrixXd *Map_MatrixXd_new(double *array, int rows, int cols) {
-  return eigen_to_c(*new Map<MatrixXd>(array, rows, cols));
-}
-
-void Map_MatrixXd_delete(C_Map_MatrixXd *m) { delete &c_to_eigen(m); }
-
-void Map_MatrixXd_set_zero(C_Map_MatrixXd *m) { c_to_eigen(m).setZero(); }
-
-void Map_MatrixXd_copy(C_Map_MatrixXd *dst, const C_Map_MatrixXd *src) { c_to_eigen(dst) = c_to_eigen(src); }
-
-void Map_MatrixXd_copy_matrix(C_Map_MatrixXd *dst, const C_MatrixXd *src) { c_to_eigen(dst) = c_to_eigen(src); }
-
-void Map_MatrixXd_set_coeff(C_Map_MatrixXd *m, int i, int j, double coeff) { c_to_eigen(m)(i, j) = coeff; }
-
-double Map_MatrixXd_get_coeff(const C_Map_MatrixXd *m, int i, int j) { return c_to_eigen(m)(i, j); }
-
-void Map_MatrixXd_print(const C_Map_MatrixXd *m) { std::cout << c_to_eigen(m) << std::endl; }
-
-void Map_MatrixXd_multiply(const C_Map_MatrixXd *m1, const C_Map_MatrixXd *m2, C_Map_MatrixXd *result) {
-  c_to_eigen(result) = c_to_eigen(m1) * c_to_eigen(m2);
-}
-
-void Map_MatrixXd_add(const C_Map_MatrixXd *m1, const C_Map_MatrixXd *m2, C_Map_MatrixXd *result) {
-  c_to_eigen(result) = c_to_eigen(m1) + c_to_eigen(m2);
-}
diff --git a/demos/mix_eigen_and_c/binary_library.h b/demos/mix_eigen_and_c/binary_library.h
deleted file mode 100644
index 8cb1a8f..0000000
--- a/demos/mix_eigen_and_c/binary_library.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-// This is a pure C header, no C++ here.
-// The functions declared here will be implemented in C++ but
-// we don't have to know, because thanks to the extern "C" syntax,
-// they will be compiled to C object code.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// just dummy empty structs to give different pointer types,
-// instead of using void* which would be type unsafe
-struct C_MatrixXd {};
-struct C_Map_MatrixXd {};
-
-// the C_MatrixXd class, wraps some of the functionality
-// of Eigen::MatrixXd.
-struct C_MatrixXd *MatrixXd_new(int rows, int cols);
-void MatrixXd_delete(struct C_MatrixXd *m);
-double *MatrixXd_data(struct C_MatrixXd *m);
-void MatrixXd_set_zero(struct C_MatrixXd *m);
-void MatrixXd_resize(struct C_MatrixXd *m, int rows, int cols);
-void MatrixXd_copy(struct C_MatrixXd *dst, const struct C_MatrixXd *src);
-void MatrixXd_copy_map(struct C_MatrixXd *dst, const struct C_Map_MatrixXd *src);
-void MatrixXd_set_coeff(struct C_MatrixXd *m, int i, int j, double coeff);
-double MatrixXd_get_coeff(const struct C_MatrixXd *m, int i, int j);
-void MatrixXd_print(const struct C_MatrixXd *m);
-void MatrixXd_add(const struct C_MatrixXd *m1, const struct C_MatrixXd *m2, struct C_MatrixXd *result);
-void MatrixXd_multiply(const struct C_MatrixXd *m1, const struct C_MatrixXd *m2, struct C_MatrixXd *result);
-
-// the C_Map_MatrixXd class, wraps some of the functionality
-// of Eigen::Map<MatrixXd>
-struct C_Map_MatrixXd *Map_MatrixXd_new(double *array, int rows, int cols);
-void Map_MatrixXd_delete(struct C_Map_MatrixXd *m);
-void Map_MatrixXd_set_zero(struct C_Map_MatrixXd *m);
-void Map_MatrixXd_copy(struct C_Map_MatrixXd *dst, const struct C_Map_MatrixXd *src);
-void Map_MatrixXd_copy_matrix(struct C_Map_MatrixXd *dst, const struct C_MatrixXd *src);
-void Map_MatrixXd_set_coeff(struct C_Map_MatrixXd *m, int i, int j, double coeff);
-double Map_MatrixXd_get_coeff(const struct C_Map_MatrixXd *m, int i, int j);
-void Map_MatrixXd_print(const struct C_Map_MatrixXd *m);
-void Map_MatrixXd_add(const struct C_Map_MatrixXd *m1, const struct C_Map_MatrixXd *m2, struct C_Map_MatrixXd *result);
-void Map_MatrixXd_multiply(const struct C_Map_MatrixXd *m1, const struct C_Map_MatrixXd *m2,
-                           struct C_Map_MatrixXd *result);
-
-#ifdef __cplusplus
-}  // end extern "C"
-#endif
diff --git a/demos/mix_eigen_and_c/example.c b/demos/mix_eigen_and_c/example.c
deleted file mode 100644
index a8e2e60..0000000
--- a/demos/mix_eigen_and_c/example.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "binary_library.h"
-#include "stdio.h"
-
-void demo_MatrixXd() {
-  struct C_MatrixXd *matrix1, *matrix2, *result;
-  printf("*** demo_MatrixXd ***\n");
-
-  matrix1 = MatrixXd_new(3, 3);
-  MatrixXd_set_zero(matrix1);
-  MatrixXd_set_coeff(matrix1, 0, 1, 2.5);
-  MatrixXd_set_coeff(matrix1, 1, 0, 1.4);
-  printf("Here is matrix1:\n");
-  MatrixXd_print(matrix1);
-
-  matrix2 = MatrixXd_new(3, 3);
-  MatrixXd_multiply(matrix1, matrix1, matrix2);
-  printf("Here is matrix1*matrix1:\n");
-  MatrixXd_print(matrix2);
-
-  MatrixXd_delete(matrix1);
-  MatrixXd_delete(matrix2);
-}
-
-// this helper function takes a plain C array and prints it in one line
-void print_array(double *array, int n) {
-  struct C_Map_MatrixXd *m = Map_MatrixXd_new(array, 1, n);
-  Map_MatrixXd_print(m);
-  Map_MatrixXd_delete(m);
-}
-
-void demo_Map_MatrixXd() {
-  struct C_Map_MatrixXd *map;
-  double array[5];
-  int i;
-  printf("*** demo_Map_MatrixXd ***\n");
-
-  for (i = 0; i < 5; ++i) array[i] = i;
-  printf("Initially, the array is:\n");
-  print_array(array, 5);
-
-  map = Map_MatrixXd_new(array, 5, 1);
-  Map_MatrixXd_add(map, map, map);
-  Map_MatrixXd_delete(map);
-
-  printf("Now the array is:\n");
-  print_array(array, 5);
-}
-
-int main() {
-  demo_MatrixXd();
-  demo_Map_MatrixXd();
-}
diff --git a/demos/opengl/CMakeLists.txt b/demos/opengl/CMakeLists.txt
deleted file mode 100644
index 38bc5ad..0000000
--- a/demos/opengl/CMakeLists.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-# SPDX-FileCopyrightText: The Eigen Authors
-# SPDX-License-Identifier: MPL-2.0
-
-find_package(Qt4)
-find_package(OpenGL)
-
-if(QT4_FOUND AND OPENGL_FOUND)
-
-  set(QT_USE_QTOPENGL TRUE)
-  include(${QT_USE_FILE})
-
-  set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-  include_directories( ${QT_INCLUDE_DIR} )
-
-  set(quaternion_demo_SRCS  gpuhelper.cpp icosphere.cpp camera.cpp trackball.cpp quaternion_demo.cpp)
-
-  qt4_automoc(${quaternion_demo_SRCS})
-
-  add_executable(quaternion_demo ${quaternion_demo_SRCS})
-  add_dependencies(demos quaternion_demo)
-
-  target_link_libraries(quaternion_demo
-    ${QT_QTCORE_LIBRARY}    ${QT_QTGUI_LIBRARY}
-    ${QT_QTOPENGL_LIBRARY}  ${OPENGL_LIBRARIES} )
-
-else()
-
-  message(STATUS "OpenGL demo disabled because Qt4 and/or OpenGL have not been found.")
-
-endif()
\ No newline at end of file
diff --git a/demos/opengl/README b/demos/opengl/README
deleted file mode 100644
index 8fb1649..0000000
--- a/demos/opengl/README
+++ /dev/null
@@ -1,13 +0,0 @@
-
-Navigation:
- left button:           rotate around the target
- middle button:         zoom
- left button + ctrl     quake rotate (rotate around camera position)
- middle button + ctrl   walk (progress along camera's z direction)
- left button:           pan (translate in the XY camera's plane)
-
-R : move the camera to initial position
-A : start/stop animation
-C : clear the animation
-G : add a key frame
-
diff --git a/demos/opengl/camera.cpp b/demos/opengl/camera.cpp
deleted file mode 100644
index 20f2242..0000000
--- a/demos/opengl/camera.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "camera.h"
-
-#include "gpuhelper.h"
-#include <GL/glu.h>
-
-#include "Eigen/LU"
-using namespace Eigen;
-
-Camera::Camera() : mViewIsUptodate(false), mProjIsUptodate(false) {
-  mViewMatrix.setIdentity();
-
-  mFovY = EIGEN_PI / 3.;
-  mNearDist = 1.;
-  mFarDist = 50000.;
-
-  mVpX = 0;
-  mVpY = 0;
-
-  setPosition(Vector3f::Constant(100.));
-  setTarget(Vector3f::Zero());
-}
-
-Camera& Camera::operator=(const Camera& other) {
-  mViewIsUptodate = false;
-  mProjIsUptodate = false;
-
-  mVpX = other.mVpX;
-  mVpY = other.mVpY;
-  mVpWidth = other.mVpWidth;
-  mVpHeight = other.mVpHeight;
-
-  mTarget = other.mTarget;
-  mFovY = other.mFovY;
-  mNearDist = other.mNearDist;
-  mFarDist = other.mFarDist;
-
-  mViewMatrix = other.mViewMatrix;
-  mProjectionMatrix = other.mProjectionMatrix;
-
-  return *this;
-}
-
-Camera::Camera(const Camera& other) { *this = other; }
-
-Camera::~Camera() {}
-
-void Camera::setViewport(uint offsetx, uint offsety, uint width, uint height) {
-  mVpX = offsetx;
-  mVpY = offsety;
-  mVpWidth = width;
-  mVpHeight = height;
-
-  mProjIsUptodate = false;
-}
-
-void Camera::setViewport(uint width, uint height) {
-  mVpWidth = width;
-  mVpHeight = height;
-
-  mProjIsUptodate = false;
-}
-
-void Camera::setFovY(float value) {
-  mFovY = value;
-  mProjIsUptodate = false;
-}
-
-Vector3f Camera::direction(void) const { return -(orientation() * Vector3f::UnitZ()); }
-Vector3f Camera::up(void) const { return orientation() * Vector3f::UnitY(); }
-Vector3f Camera::right(void) const { return orientation() * Vector3f::UnitX(); }
-
-void Camera::setDirection(const Vector3f& newDirection) {
-  // TODO implement it computing the rotation between newDirection and current dir ?
-  Vector3f up = this->up();
-
-  Matrix3f camAxes;
-
-  camAxes.col(2) = (-newDirection).normalized();
-  camAxes.col(0) = up.cross(camAxes.col(2)).normalized();
-  camAxes.col(1) = camAxes.col(2).cross(camAxes.col(0)).normalized();
-  setOrientation(Quaternionf(camAxes));
-
-  mViewIsUptodate = false;
-}
-
-void Camera::setTarget(const Vector3f& target) {
-  mTarget = target;
-  if (!mTarget.isApprox(position())) {
-    Vector3f newDirection = mTarget - position();
-    setDirection(newDirection.normalized());
-  }
-}
-
-void Camera::setPosition(const Vector3f& p) {
-  mFrame.position = p;
-  mViewIsUptodate = false;
-}
-
-void Camera::setOrientation(const Quaternionf& q) {
-  mFrame.orientation = q;
-  mViewIsUptodate = false;
-}
-
-void Camera::setFrame(const Frame& f) {
-  mFrame = f;
-  mViewIsUptodate = false;
-}
-
-void Camera::rotateAroundTarget(const Quaternionf& q) {
-  Matrix4f mrot, mt, mtm;
-
-  // update the transform matrix
-  updateViewMatrix();
-  Vector3f t = mViewMatrix * mTarget;
-
-  mViewMatrix = Translation3f(t) * q * Translation3f(-t) * mViewMatrix;
-
-  Quaternionf qa(mViewMatrix.linear());
-  qa = qa.conjugate();
-  setOrientation(qa);
-  setPosition(-(qa * mViewMatrix.translation()));
-
-  mViewIsUptodate = true;
-}
-
-void Camera::localRotate(const Quaternionf& q) {
-  float dist = (position() - mTarget).norm();
-  setOrientation(orientation() * q);
-  mTarget = position() + dist * direction();
-  mViewIsUptodate = false;
-}
-
-void Camera::zoom(float d) {
-  float dist = (position() - mTarget).norm();
-  if (dist > d) {
-    setPosition(position() + direction() * d);
-    mViewIsUptodate = false;
-  }
-}
-
-void Camera::localTranslate(const Vector3f& t) {
-  Vector3f trans = orientation() * t;
-  setPosition(position() + trans);
-  setTarget(mTarget + trans);
-
-  mViewIsUptodate = false;
-}
-
-void Camera::updateViewMatrix(void) const {
-  if (!mViewIsUptodate) {
-    Quaternionf q = orientation().conjugate();
-    mViewMatrix.linear() = q.toRotationMatrix();
-    mViewMatrix.translation() = -(mViewMatrix.linear() * position());
-
-    mViewIsUptodate = true;
-  }
-}
-
-const Affine3f& Camera::viewMatrix(void) const {
-  updateViewMatrix();
-  return mViewMatrix;
-}
-
-void Camera::updateProjectionMatrix(void) const {
-  if (!mProjIsUptodate) {
-    mProjectionMatrix.setIdentity();
-    float aspect = float(mVpWidth) / float(mVpHeight);
-    float theta = mFovY * 0.5;
-    float range = mFarDist - mNearDist;
-    float invtan = 1. / tan(theta);
-
-    mProjectionMatrix(0, 0) = invtan / aspect;
-    mProjectionMatrix(1, 1) = invtan;
-    mProjectionMatrix(2, 2) = -(mNearDist + mFarDist) / range;
-    mProjectionMatrix(3, 2) = -1;
-    mProjectionMatrix(2, 3) = -2 * mNearDist * mFarDist / range;
-    mProjectionMatrix(3, 3) = 0;
-
-    mProjIsUptodate = true;
-  }
-}
-
-const Matrix4f& Camera::projectionMatrix(void) const {
-  updateProjectionMatrix();
-  return mProjectionMatrix;
-}
-
-void Camera::activateGL(void) {
-  glViewport(vpX(), vpY(), vpWidth(), vpHeight());
-  gpu.loadMatrix(projectionMatrix(), GL_PROJECTION);
-  gpu.loadMatrix(viewMatrix().matrix(), GL_MODELVIEW);
-}
-
-Vector3f Camera::unProject(const Vector2f& uv, float depth) const {
-  Matrix4f inv = mViewMatrix.inverse().matrix();
-  return unProject(uv, depth, inv);
-}
-
-Vector3f Camera::unProject(const Vector2f& uv, float depth, const Matrix4f& invModelview) const {
-  updateViewMatrix();
-  updateProjectionMatrix();
-
-  Vector3f a(2. * uv.x() / float(mVpWidth) - 1., 2. * uv.y() / float(mVpHeight) - 1., 1.);
-  a.x() *= depth / mProjectionMatrix(0, 0);
-  a.y() *= depth / mProjectionMatrix(1, 1);
-  a.z() = -depth;
-  // FIXME: verify this transformation.
-  Vector4f b = invModelview * Vector4f(a.x(), a.y(), a.z(), 1.);
-  return Vector3f(b.x(), b.y(), b.z());
-}
diff --git a/demos/opengl/camera.h b/demos/opengl/camera.h
deleted file mode 100644
index a8f99ca..0000000
--- a/demos/opengl/camera.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#ifndef EIGEN_CAMERA_H
-#define EIGEN_CAMERA_H
-
-#include <Eigen/Geometry>
-#include <QObject>
-// #include <frame.h>
-
-class Frame {
- public:
-  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
-
-  inline Frame(const Eigen::Vector3f& pos = Eigen::Vector3f::Zero(), const Eigen::Quaternionf& o = Eigen::Quaternionf())
-      : orientation(o), position(pos) {}
-  Frame lerp(float alpha, const Frame& other) const {
-    return Frame((1.f - alpha) * position + alpha * other.position, orientation.slerp(alpha, other.orientation));
-  }
-
-  Eigen::Quaternionf orientation;
-  Eigen::Vector3f position;
-};
-
-class Camera {
- public:
-  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
-
-  Camera(void);
-
-  Camera(const Camera& other);
-
-  virtual ~Camera();
-
-  Camera& operator=(const Camera& other);
-
-  void setViewport(uint offsetx, uint offsety, uint width, uint height);
-  void setViewport(uint width, uint height);
-
-  inline uint vpX(void) const { return mVpX; }
-  inline uint vpY(void) const { return mVpY; }
-  inline uint vpWidth(void) const { return mVpWidth; }
-  inline uint vpHeight(void) const { return mVpHeight; }
-
-  inline float fovY(void) const { return mFovY; }
-  void setFovY(float value);
-
-  void setPosition(const Eigen::Vector3f& pos);
-  inline const Eigen::Vector3f& position(void) const { return mFrame.position; }
-
-  void setOrientation(const Eigen::Quaternionf& q);
-  inline const Eigen::Quaternionf& orientation(void) const { return mFrame.orientation; }
-
-  void setFrame(const Frame& f);
-  const Frame& frame(void) const { return mFrame; }
-
-  void setDirection(const Eigen::Vector3f& newDirection);
-  Eigen::Vector3f direction(void) const;
-  void setUp(const Eigen::Vector3f& vectorUp);
-  Eigen::Vector3f up(void) const;
-  Eigen::Vector3f right(void) const;
-
-  void setTarget(const Eigen::Vector3f& target);
-  inline const Eigen::Vector3f& target(void) { return mTarget; }
-
-  const Eigen::Affine3f& viewMatrix(void) const;
-  const Eigen::Matrix4f& projectionMatrix(void) const;
-
-  void rotateAroundTarget(const Eigen::Quaternionf& q);
-  void localRotate(const Eigen::Quaternionf& q);
-  void zoom(float d);
-
-  void localTranslate(const Eigen::Vector3f& t);
-
-  /** Setup OpenGL matrices and viewport */
-  void activateGL(void);
-
-  Eigen::Vector3f unProject(const Eigen::Vector2f& uv, float depth, const Eigen::Matrix4f& invModelview) const;
-  Eigen::Vector3f unProject(const Eigen::Vector2f& uv, float depth) const;
-
- protected:
-  void updateViewMatrix(void) const;
-  void updateProjectionMatrix(void) const;
-
- protected:
-  uint mVpX, mVpY;
-  uint mVpWidth, mVpHeight;
-
-  Frame mFrame;
-
-  mutable Eigen::Affine3f mViewMatrix;
-  mutable Eigen::Matrix4f mProjectionMatrix;
-
-  mutable bool mViewIsUptodate;
-  mutable bool mProjIsUptodate;
-
-  // used by rotateAroundTarget
-  Eigen::Vector3f mTarget;
-
-  float mFovY;
-  float mNearDist;
-  float mFarDist;
-};
-
-#endif  // EIGEN_CAMERA_H
diff --git a/demos/opengl/gpuhelper.cpp b/demos/opengl/gpuhelper.cpp
deleted file mode 100644
index 1e4086d..0000000
--- a/demos/opengl/gpuhelper.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "gpuhelper.h"
-#include "icosphere.h"
-#include <GL/glu.h>
-// PLEASE don't look at this old code... ;)
-
-#include <fstream>
-#include <algorithm>
-
-GpuHelper gpu;
-
-GpuHelper::GpuHelper() {
-  mVpWidth = mVpHeight = 0;
-  mCurrentMatrixTarget = 0;
-  mInitialized = false;
-}
-
-GpuHelper::~GpuHelper() {}
-
-void GpuHelper::pushProjectionMode2D(ProjectionMode2D pm) {
-  // switch to 2D projection
-  pushMatrix(Matrix4f::Identity(), GL_PROJECTION);
-
-  if (pm == PM_Normalized) {
-    // glOrtho(-1., 1., -1., 1., 0., 1.);
-  } else if (pm == PM_Viewport) {
-    GLint vp[4];
-    glGetIntegerv(GL_VIEWPORT, vp);
-    glOrtho(0., vp[2], 0., vp[3], -1., 1.);
-  }
-
-  pushMatrix(Matrix4f::Identity(), GL_MODELVIEW);
-}
-
-void GpuHelper::popProjectionMode2D(void) {
-  popMatrix(GL_PROJECTION);
-  popMatrix(GL_MODELVIEW);
-}
-
-void GpuHelper::drawVector(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect /* = 50.*/) {
-  static GLUquadricObj* cylinder = gluNewQuadric();
-  glColor4fv(color.data());
-  float length = vec.norm();
-  pushMatrix(GL_MODELVIEW);
-  glTranslatef(position.x(), position.y(), position.z());
-  Vector3f ax = Matrix3f::Identity().col(2).cross(vec);
-  ax.normalize();
-  Vector3f tmp = vec;
-  tmp.normalize();
-  float angle = 180.f / EIGEN_PI * acos(tmp.z());
-  if (angle > 1e-3) glRotatef(angle, ax.x(), ax.y(), ax.z());
-  gluCylinder(cylinder, length / aspect, length / aspect, 0.8 * length, 10, 10);
-  glTranslatef(0.0, 0.0, 0.8 * length);
-  gluCylinder(cylinder, 2.0 * length / aspect, 0.0, 0.2 * length, 10, 10);
-
-  popMatrix(GL_MODELVIEW);
-}
-
-void GpuHelper::drawVectorBox(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect) {
-  static GLUquadricObj* cylinder = gluNewQuadric();
-  glColor4fv(color.data());
-  float length = vec.norm();
-  pushMatrix(GL_MODELVIEW);
-  glTranslatef(position.x(), position.y(), position.z());
-  Vector3f ax = Matrix3f::Identity().col(2).cross(vec);
-  ax.normalize();
-  Vector3f tmp = vec;
-  tmp.normalize();
-  float angle = 180.f / EIGEN_PI * acos(tmp.z());
-  if (angle > 1e-3) glRotatef(angle, ax.x(), ax.y(), ax.z());
-  gluCylinder(cylinder, length / aspect, length / aspect, 0.8 * length, 10, 10);
-  glTranslatef(0.0, 0.0, 0.8 * length);
-  glScalef(4.0 * length / aspect, 4.0 * length / aspect, 4.0 * length / aspect);
-  drawUnitCube();
-  popMatrix(GL_MODELVIEW);
-}
-
-void GpuHelper::drawUnitCube(void) {
-  static float vertices[][3] = {{-0.5, -0.5, -0.5}, {0.5, -0.5, -0.5}, {-0.5, 0.5, -0.5}, {0.5, 0.5, -0.5},
-                                {-0.5, -0.5, 0.5},  {0.5, -0.5, 0.5},  {-0.5, 0.5, 0.5},  {0.5, 0.5, 0.5}};
-
-  glBegin(GL_QUADS);
-  glNormal3f(0, 0, -1);
-  glVertex3fv(vertices[0]);
-  glVertex3fv(vertices[2]);
-  glVertex3fv(vertices[3]);
-  glVertex3fv(vertices[1]);
-  glNormal3f(0, 0, 1);
-  glVertex3fv(vertices[4]);
-  glVertex3fv(vertices[5]);
-  glVertex3fv(vertices[7]);
-  glVertex3fv(vertices[6]);
-  glNormal3f(0, -1, 0);
-  glVertex3fv(vertices[0]);
-  glVertex3fv(vertices[1]);
-  glVertex3fv(vertices[5]);
-  glVertex3fv(vertices[4]);
-  glNormal3f(0, 1, 0);
-  glVertex3fv(vertices[2]);
-  glVertex3fv(vertices[6]);
-  glVertex3fv(vertices[7]);
-  glVertex3fv(vertices[3]);
-  glNormal3f(-1, 0, 0);
-  glVertex3fv(vertices[0]);
-  glVertex3fv(vertices[4]);
-  glVertex3fv(vertices[6]);
-  glVertex3fv(vertices[2]);
-  glNormal3f(1, 0, 0);
-  glVertex3fv(vertices[1]);
-  glVertex3fv(vertices[3]);
-  glVertex3fv(vertices[7]);
-  glVertex3fv(vertices[5]);
-  glEnd();
-}
-
-void GpuHelper::drawUnitSphere(int level) {
-  static IcoSphere sphere;
-  sphere.draw(level);
-}
diff --git a/demos/opengl/gpuhelper.h b/demos/opengl/gpuhelper.h
deleted file mode 100644
index e31ffb6..0000000
--- a/demos/opengl/gpuhelper.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#ifndef EIGEN_GPUHELPER_H
-#define EIGEN_GPUHELPER_H
-
-#include <Eigen/Geometry>
-#include <GL/gl.h>
-#include <vector>
-
-using namespace Eigen;
-
-typedef Vector4f Color;
-
-class GpuHelper {
- public:
-  GpuHelper();
-
-  ~GpuHelper();
-
-  enum ProjectionMode2D { PM_Normalized = 1, PM_Viewport = 2 };
-  void pushProjectionMode2D(ProjectionMode2D pm);
-  void popProjectionMode2D();
-
-  /** Multiply the OpenGL matrix \a matrixTarget by the matrix \a mat.
-      Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required
-      and does a proper call to the right glMultMatrix*() function according to the scalar type
-      and storage order.
-      \warning glMatrixMode() must never be called directly. If you are unsure, use forceMatrixMode().
-      \sa Matrix, loadMatrix(), forceMatrixMode()
-  */
-  template <typename Scalar, int Flags_>
-  void multMatrix(const Matrix<Scalar, 4, 4, Flags_, 4, 4>& mat, GLenum matrixTarget);
-
-  /** Load the matrix \a mat to the OpenGL matrix \a matrixTarget.
-      Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required
-      and does a proper call to the right glLoadMatrix*() or glLoadIdentity() function according to the scalar type
-      and storage order.
-      \warning glMatrixMode() must never be called directly. If you are unsure, use forceMatrixMode().
-      \sa Matrix, multMatrix(), forceMatrixMode()
-  */
-  template <typename Scalar, int Flags_>
-  void loadMatrix(const Eigen::Matrix<Scalar, 4, 4, Flags_, 4, 4>& mat, GLenum matrixTarget);
-
-  template <typename Scalar, typename Derived>
-  void loadMatrix(const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>, Derived>&,
-                  GLenum matrixTarget);
-
-  /** Make the matrix \a matrixTarget the current OpenGL matrix target.
-      Call this function before loadMatrix() or multMatrix() if you cannot guarantee that glMatrixMode()
-      has never been called after the last loadMatrix() or multMatrix() calls.
-      \todo provides a debug mode checking the sanity of the cached matrix mode.
-  */
-  inline void forceMatrixTarget(GLenum matrixTarget) { glMatrixMode(mCurrentMatrixTarget = matrixTarget); }
-
-  inline void setMatrixTarget(GLenum matrixTarget);
-
-  /** Push the OpenGL matrix \a matrixTarget and load \a mat.
-   */
-  template <typename Scalar, int Flags_>
-  inline void pushMatrix(const Matrix<Scalar, 4, 4, Flags_, 4, 4>& mat, GLenum matrixTarget);
-
-  template <typename Scalar, typename Derived>
-  void pushMatrix(const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>, Derived>&,
-                  GLenum matrixTarget);
-
-  /** Push and clone the OpenGL matrix \a matrixTarget
-   */
-  inline void pushMatrix(GLenum matrixTarget);
-
-  /** Pop the OpenGL matrix \a matrixTarget
-   */
-  inline void popMatrix(GLenum matrixTarget);
-
-  void drawVector(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.);
-  void drawVectorBox(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.);
-  void drawUnitCube(void);
-  void drawUnitSphere(int level = 0);
-
-  /// draw the \a nofElement first elements
-  inline void draw(GLenum mode, uint nofElement);
-
-  /// draw a range of elements
-  inline void draw(GLenum mode, uint start, uint end);
-
-  /// draw an indexed subset
-  inline void draw(GLenum mode, const std::vector<uint>* pIndexes);
-
- protected:
-  void update(void);
-
-  GLuint mColorBufferId;
-  int mVpWidth, mVpHeight;
-  GLenum mCurrentMatrixTarget;
-  bool mInitialized;
-};
-
-/** Singleton shortcut
- */
-extern GpuHelper gpu;
-
-/** \internal
- */
-template <bool RowMajor, int Flags_>
-struct GlMatrixHelper;
-
-template <int Flags_>
-struct GlMatrixHelper<false, Flags_> {
-  static void loadMatrix(const Matrix<float, 4, 4, Flags_, 4, 4>& mat) { glLoadMatrixf(mat.data()); }
-  static void loadMatrix(const Matrix<double, 4, 4, Flags_, 4, 4>& mat) { glLoadMatrixd(mat.data()); }
-  static void multMatrix(const Matrix<float, 4, 4, Flags_, 4, 4>& mat) { glMultMatrixf(mat.data()); }
-  static void multMatrix(const Matrix<double, 4, 4, Flags_, 4, 4>& mat) { glMultMatrixd(mat.data()); }
-};
-
-template <int Flags_>
-struct GlMatrixHelper<true, Flags_> {
-  static void loadMatrix(const Matrix<float, 4, 4, Flags_, 4, 4>& mat) { glLoadMatrixf(mat.transpose().eval().data()); }
-  static void loadMatrix(const Matrix<double, 4, 4, Flags_, 4, 4>& mat) {
-    glLoadMatrixd(mat.transpose().eval().data());
-  }
-  static void multMatrix(const Matrix<float, 4, 4, Flags_, 4, 4>& mat) { glMultMatrixf(mat.transpose().eval().data()); }
-  static void multMatrix(const Matrix<double, 4, 4, Flags_, 4, 4>& mat) {
-    glMultMatrixd(mat.transpose().eval().data());
-  }
-};
-
-inline void GpuHelper::setMatrixTarget(GLenum matrixTarget) {
-  if (matrixTarget != mCurrentMatrixTarget) glMatrixMode(mCurrentMatrixTarget = matrixTarget);
-}
-
-template <typename Scalar, int Flags_>
-void GpuHelper::multMatrix(const Matrix<Scalar, 4, 4, Flags_, 4, 4>& mat, GLenum matrixTarget) {
-  setMatrixTarget(matrixTarget);
-  GlMatrixHelper<Flags_ & Eigen::RowMajorBit, Flags_>::multMatrix(mat);
-}
-
-template <typename Scalar, typename Derived>
-void GpuHelper::loadMatrix(const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>, Derived>&,
-                           GLenum matrixTarget) {
-  setMatrixTarget(matrixTarget);
-  glLoadIdentity();
-}
-
-template <typename Scalar, int Flags_>
-void GpuHelper::loadMatrix(const Eigen::Matrix<Scalar, 4, 4, Flags_, 4, 4>& mat, GLenum matrixTarget) {
-  setMatrixTarget(matrixTarget);
-  GlMatrixHelper<(Flags_ & Eigen::RowMajorBit) != 0, Flags_>::loadMatrix(mat);
-}
-
-inline void GpuHelper::pushMatrix(GLenum matrixTarget) {
-  setMatrixTarget(matrixTarget);
-  glPushMatrix();
-}
-
-template <typename Scalar, int Flags_>
-inline void GpuHelper::pushMatrix(const Matrix<Scalar, 4, 4, Flags_, 4, 4>& mat, GLenum matrixTarget) {
-  pushMatrix(matrixTarget);
-  GlMatrixHelper<Flags_ & Eigen::RowMajorBit, Flags_>::loadMatrix(mat);
-}
-
-template <typename Scalar, typename Derived>
-void GpuHelper::pushMatrix(const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>, Derived>&,
-                           GLenum matrixTarget) {
-  pushMatrix(matrixTarget);
-  glLoadIdentity();
-}
-
-inline void GpuHelper::popMatrix(GLenum matrixTarget) {
-  setMatrixTarget(matrixTarget);
-  glPopMatrix();
-}
-
-inline void GpuHelper::draw(GLenum mode, uint nofElement) { glDrawArrays(mode, 0, nofElement); }
-
-inline void GpuHelper::draw(GLenum mode, const std::vector<uint>* pIndexes) {
-  glDrawElements(mode, pIndexes->size(), GL_UNSIGNED_INT, &(pIndexes->front()));
-}
-
-inline void GpuHelper::draw(GLenum mode, uint start, uint end) { glDrawArrays(mode, start, end - start); }
-
-#endif  // EIGEN_GPUHELPER_H
diff --git a/demos/opengl/icosphere.cpp b/demos/opengl/icosphere.cpp
deleted file mode 100644
index e5abdea..0000000
--- a/demos/opengl/icosphere.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "icosphere.h"
-
-#include <GL/gl.h>
-#include <map>
-
-using namespace Eigen;
-
-//--------------------------------------------------------------------------------
-// icosahedron data
-//--------------------------------------------------------------------------------
-#define X .525731112119133606
-#define Z .850650808352039932
-
-static GLfloat vdata[12][3] = {{-X, 0.0, Z}, {X, 0.0, Z},   {-X, 0.0, -Z}, {X, 0.0, -Z}, {0.0, Z, X},  {0.0, Z, -X},
-                               {0.0, -Z, X}, {0.0, -Z, -X}, {Z, X, 0.0},   {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}};
-
-static GLint tindices[20][3] = {{0, 4, 1}, {0, 9, 4},  {9, 5, 4},  {4, 5, 8},  {4, 8, 1},  {8, 10, 1}, {8, 3, 10},
-                                {5, 3, 8}, {5, 2, 3},  {2, 7, 3},  {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6},
-                                {0, 1, 6}, {6, 1, 10}, {9, 0, 11}, {9, 11, 2}, {9, 2, 5},  {7, 2, 11}};
-//--------------------------------------------------------------------------------
-
-IcoSphere::IcoSphere(unsigned int levels) {
-  // init with an icosahedron
-  for (int i = 0; i < 12; i++) mVertices.push_back(Map<Vector3f>(vdata[i]));
-  mIndices.push_back(new std::vector<int>);
-  std::vector<int>& indices = *mIndices.back();
-  for (int i = 0; i < 20; i++) {
-    for (int k = 0; k < 3; k++) indices.push_back(tindices[i][k]);
-  }
-  mListIds.push_back(0);
-
-  while (mIndices.size() < levels) _subdivide();
-}
-
-const std::vector<int>& IcoSphere::indices(int level) const {
-  while (level >= int(mIndices.size())) const_cast<IcoSphere*>(this)->_subdivide();
-  return *mIndices[level];
-}
-
-void IcoSphere::_subdivide(void) {
-  typedef unsigned long long Key;
-  std::map<Key, int> edgeMap;
-  const std::vector<int>& indices = *mIndices.back();
-  mIndices.push_back(new std::vector<int>);
-  std::vector<int>& refinedIndices = *mIndices.back();
-  int end = indices.size();
-  for (int i = 0; i < end; i += 3) {
-    int ids0[3],  // indices of outer vertices
-        ids1[3];  // indices of edge vertices
-    for (int k = 0; k < 3; ++k) {
-      int k1 = (k + 1) % 3;
-      int e0 = indices[i + k];
-      int e1 = indices[i + k1];
-      ids0[k] = e0;
-      if (e1 > e0) std::swap(e0, e1);
-      Key edgeKey = Key(e0) | (Key(e1) << 32);
-      std::map<Key, int>::iterator it = edgeMap.find(edgeKey);
-      if (it == edgeMap.end()) {
-        ids1[k] = mVertices.size();
-        edgeMap[edgeKey] = ids1[k];
-        mVertices.push_back((mVertices[e0] + mVertices[e1]).normalized());
-      } else
-        ids1[k] = it->second;
-    }
-    refinedIndices.push_back(ids0[0]);
-    refinedIndices.push_back(ids1[0]);
-    refinedIndices.push_back(ids1[2]);
-    refinedIndices.push_back(ids0[1]);
-    refinedIndices.push_back(ids1[1]);
-    refinedIndices.push_back(ids1[0]);
-    refinedIndices.push_back(ids0[2]);
-    refinedIndices.push_back(ids1[2]);
-    refinedIndices.push_back(ids1[1]);
-    refinedIndices.push_back(ids1[0]);
-    refinedIndices.push_back(ids1[1]);
-    refinedIndices.push_back(ids1[2]);
-  }
-  mListIds.push_back(0);
-}
-
-void IcoSphere::draw(int level) {
-  while (level >= int(mIndices.size())) const_cast<IcoSphere*>(this)->_subdivide();
-  if (mListIds[level] == 0) {
-    mListIds[level] = glGenLists(1);
-    glNewList(mListIds[level], GL_COMPILE);
-    glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data());
-    glNormalPointer(GL_FLOAT, 0, mVertices[0].data());
-    glEnableClientState(GL_VERTEX_ARRAY);
-    glEnableClientState(GL_NORMAL_ARRAY);
-    glDrawElements(GL_TRIANGLES, mIndices[level]->size(), GL_UNSIGNED_INT, &(mIndices[level]->at(0)));
-    glDisableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_NORMAL_ARRAY);
-    glEndList();
-  }
-  glCallList(mListIds[level]);
-}
diff --git a/demos/opengl/icosphere.h b/demos/opengl/icosphere.h
deleted file mode 100644
index 909710f..0000000
--- a/demos/opengl/icosphere.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#ifndef EIGEN_ICOSPHERE_H
-#define EIGEN_ICOSPHERE_H
-
-#include <Eigen/Core>
-#include <vector>
-
-class IcoSphere {
- public:
-  IcoSphere(unsigned int levels = 1);
-  const std::vector<Eigen::Vector3f>& vertices() const { return mVertices; }
-  const std::vector<int>& indices(int level) const;
-  void draw(int level);
-
- protected:
-  void _subdivide();
-  std::vector<Eigen::Vector3f> mVertices;
-  std::vector<std::vector<int>*> mIndices;
-  std::vector<int> mListIds;
-};
-
-#endif  // EIGEN_ICOSPHERE_H
diff --git a/demos/opengl/quaternion_demo.cpp b/demos/opengl/quaternion_demo.cpp
deleted file mode 100644
index 74f8f59..0000000
--- a/demos/opengl/quaternion_demo.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "quaternion_demo.h"
-#include "icosphere.h"
-
-#include <Eigen/Geometry>
-#include <Eigen/QR>
-#include <Eigen/LU>
-
-#include <iostream>
-#include <QEvent>
-#include <QMouseEvent>
-#include <QInputDialog>
-#include <QGridLayout>
-#include <QButtonGroup>
-#include <QRadioButton>
-#include <QDockWidget>
-#include <QPushButton>
-#include <QGroupBox>
-
-using namespace Eigen;
-
-class FancySpheres {
- public:
-  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
-
-  FancySpheres() {
-    const int levels = 4;
-    const float scale = 0.33;
-    float radius = 100;
-    std::vector<int> parents;
-
-    // leval 0
-    mCenters.push_back(Vector3f::Zero());
-    parents.push_back(-1);
-    mRadii.push_back(radius);
-
-    // generate level 1 using icosphere vertices
-    radius *= 0.45;
-    {
-      float dist = mRadii[0] * 0.9;
-      for (int i = 0; i < 12; ++i) {
-        mCenters.push_back(mIcoSphere.vertices()[i] * dist);
-        mRadii.push_back(radius);
-        parents.push_back(0);
-      }
-    }
-
-    static const float angles[10] = {
-        0, 0, EIGEN_PI, 0. * EIGEN_PI, EIGEN_PI, 0.5 * EIGEN_PI, EIGEN_PI, 1. * EIGEN_PI, EIGEN_PI, 1.5 * EIGEN_PI};
-
-    // generate other levels
-    int start = 1;
-    for (int l = 1; l < levels; l++) {
-      radius *= scale;
-      int end = mCenters.size();
-      for (int i = start; i < end; ++i) {
-        Vector3f c = mCenters[i];
-        Vector3f ax0 = (c - mCenters[parents[i]]).normalized();
-        Vector3f ax1 = ax0.unitOrthogonal();
-        Quaternionf q;
-        q.setFromTwoVectors(Vector3f::UnitZ(), ax0);
-        Affine3f t = Translation3f(c) * q * Scaling(mRadii[i] + radius);
-        for (int j = 0; j < 5; ++j) {
-          Vector3f newC =
-              c + ((AngleAxisf(angles[j * 2 + 1], ax0) * AngleAxisf(angles[j * 2 + 0] * (l == 1 ? 0.35 : 0.5), ax1)) *
-                   ax0) *
-                      (mRadii[i] + radius * 0.8);
-          mCenters.push_back(newC);
-          mRadii.push_back(radius);
-          parents.push_back(i);
-        }
-      }
-      start = end;
-    }
-  }
-
-  void draw() {
-    int end = mCenters.size();
-    glEnable(GL_NORMALIZE);
-    for (int i = 0; i < end; ++i) {
-      Affine3f t = Translation3f(mCenters[i]) * Scaling(mRadii[i]);
-      gpu.pushMatrix(GL_MODELVIEW);
-      gpu.multMatrix(t.matrix(), GL_MODELVIEW);
-      mIcoSphere.draw(2);
-      gpu.popMatrix(GL_MODELVIEW);
-    }
-    glDisable(GL_NORMALIZE);
-  }
-
- protected:
-  std::vector<Vector3f> mCenters;
-  std::vector<float> mRadii;
-  IcoSphere mIcoSphere;
-};
-
-// generic linear interpolation method
-template <typename T>
-T lerp(float t, const T& a, const T& b) {
-  return a * (1 - t) + b * t;
-}
-
-// quaternion slerp
-template <>
-Quaternionf lerp(float t, const Quaternionf& a, const Quaternionf& b) {
-  return a.slerp(t, b);
-}
-
-// linear interpolation of a frame using the type OrientationType
-// to perform the interpolation of the orientations
-template <typename OrientationType>
-inline static Frame lerpFrame(float alpha, const Frame& a, const Frame& b) {
-  return Frame(lerp(alpha, a.position, b.position),
-               Quaternionf(lerp(alpha, OrientationType(a.orientation), OrientationType(b.orientation))));
-}
-
-template <typename Scalar_>
-class EulerAngles {
- public:
-  enum { Dim = 3 };
-  typedef Scalar_ Scalar;
-  typedef Matrix<Scalar, 3, 3> Matrix3;
-  typedef Matrix<Scalar, 3, 1> Vector3;
-  typedef Quaternion<Scalar> QuaternionType;
-
- protected:
-  Vector3 m_angles;
-
- public:
-  EulerAngles() {}
-  inline EulerAngles(Scalar a0, Scalar a1, Scalar a2) : m_angles(a0, a1, a2) {}
-  inline EulerAngles(const QuaternionType& q) { *this = q; }
-
-  const Vector3& coeffs() const { return m_angles; }
-  Vector3& coeffs() { return m_angles; }
-
-  EulerAngles& operator=(const QuaternionType& q) {
-    Matrix3 m = q.toRotationMatrix();
-    return *this = m;
-  }
-
-  EulerAngles& operator=(const Matrix3& m) {
-    // mat =  cy*cz          -cy*sz           sy
-    //        cz*sx*sy+cx*sz  cx*cz-sx*sy*sz -cy*sx
-    //       -cx*cz*sy+sx*sz  cz*sx+cx*sy*sz  cx*cy
-    m_angles.coeffRef(1) = std::asin(m.coeff(0, 2));
-    m_angles.coeffRef(0) = std::atan2(-m.coeff(1, 2), m.coeff(2, 2));
-    m_angles.coeffRef(2) = std::atan2(-m.coeff(0, 1), m.coeff(0, 0));
-    return *this;
-  }
-
-  Matrix3 toRotationMatrix(void) const {
-    Vector3 c = m_angles.array().cos();
-    Vector3 s = m_angles.array().sin();
-    Matrix3 res;
-    res << c.y() * c.z(), -c.y() * s.z(), s.y(), c.z() * s.x() * s.y() + c.x() * s.z(),
-        c.x() * c.z() - s.x() * s.y() * s.z(), -c.y() * s.x(), -c.x() * c.z() * s.y() + s.x() * s.z(),
-        c.z() * s.x() + c.x() * s.y() * s.z(), c.x() * c.y();
-    return res;
-  }
-
-  operator QuaternionType() { return QuaternionType(toRotationMatrix()); }
-};
-
-// Euler angles slerp
-template <>
-EulerAngles<float> lerp(float t, const EulerAngles<float>& a, const EulerAngles<float>& b) {
-  EulerAngles<float> res;
-  res.coeffs() = lerp(t, a.coeffs(), b.coeffs());
-  return res;
-}
-
-RenderingWidget::RenderingWidget() {
-  mAnimate = false;
-  mCurrentTrackingMode = TM_NO_TRACK;
-  mNavMode = NavTurnAround;
-  mLerpMode = LerpQuaternion;
-  mRotationMode = RotationStable;
-  mTrackball.setCamera(&mCamera);
-
-  // required to capture key press events
-  setFocusPolicy(Qt::ClickFocus);
-}
-
-void RenderingWidget::grabFrame(void) {
-  // ask user for a time
-  bool ok = false;
-  double t = 0;
-  if (!m_timeline.empty()) t = (--m_timeline.end())->first + 1.;
-  t = QInputDialog::getDouble(this, "Eigen's RenderingWidget", "time value: ", t, 0, 1e3, 1, &ok);
-  if (ok) {
-    Frame aux;
-    aux.orientation = mCamera.viewMatrix().linear();
-    aux.position = mCamera.viewMatrix().translation();
-    m_timeline[t] = aux;
-  }
-}
-
-void RenderingWidget::drawScene() {
-  static FancySpheres sFancySpheres;
-  float length = 50;
-  gpu.drawVector(Vector3f::Zero(), length * Vector3f::UnitX(), Color(1, 0, 0, 1));
-  gpu.drawVector(Vector3f::Zero(), length * Vector3f::UnitY(), Color(0, 1, 0, 1));
-  gpu.drawVector(Vector3f::Zero(), length * Vector3f::UnitZ(), Color(0, 0, 1, 1));
-
-  // draw the fractal object
-  float sqrt3 = std::sqrt(3.);
-  glLightfv(GL_LIGHT0, GL_AMBIENT, Vector4f(0.5, 0.5, 0.5, 1).data());
-  glLightfv(GL_LIGHT0, GL_DIFFUSE, Vector4f(0.5, 1, 0.5, 1).data());
-  glLightfv(GL_LIGHT0, GL_SPECULAR, Vector4f(1, 1, 1, 1).data());
-  glLightfv(GL_LIGHT0, GL_POSITION, Vector4f(-sqrt3, -sqrt3, sqrt3, 0).data());
-
-  glLightfv(GL_LIGHT1, GL_AMBIENT, Vector4f(0, 0, 0, 1).data());
-  glLightfv(GL_LIGHT1, GL_DIFFUSE, Vector4f(1, 0.5, 0.5, 1).data());
-  glLightfv(GL_LIGHT1, GL_SPECULAR, Vector4f(1, 1, 1, 1).data());
-  glLightfv(GL_LIGHT1, GL_POSITION, Vector4f(-sqrt3, sqrt3, -sqrt3, 0).data());
-
-  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Vector4f(0.7, 0.7, 0.7, 1).data());
-  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Vector4f(0.8, 0.75, 0.6, 1).data());
-  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Vector4f(1, 1, 1, 1).data());
-  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64);
-
-  glEnable(GL_LIGHTING);
-  glEnable(GL_LIGHT0);
-  glEnable(GL_LIGHT1);
-
-  sFancySpheres.draw();
-  glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data());
-  glNormalPointer(GL_FLOAT, 0, mNormals[0].data());
-  glEnableClientState(GL_VERTEX_ARRAY);
-  glEnableClientState(GL_NORMAL_ARRAY);
-  glDrawArrays(GL_TRIANGLES, 0, mVertices.size());
-  glDisableClientState(GL_VERTEX_ARRAY);
-  glDisableClientState(GL_NORMAL_ARRAY);
-
-  glDisable(GL_LIGHTING);
-}
-
-void RenderingWidget::animate() {
-  m_alpha += double(m_timer.interval()) * 1e-3;
-
-  TimeLine::const_iterator hi = m_timeline.upper_bound(m_alpha);
-  TimeLine::const_iterator lo = hi;
-  --lo;
-
-  Frame currentFrame;
-
-  if (hi == m_timeline.end()) {
-    // end
-    currentFrame = lo->second;
-    stopAnimation();
-  } else if (hi == m_timeline.begin()) {
-    // start
-    currentFrame = hi->second;
-  } else {
-    float s = (m_alpha - lo->first) / (hi->first - lo->first);
-    if (mLerpMode == LerpEulerAngles)
-      currentFrame = ::lerpFrame<EulerAngles<float> >(s, lo->second, hi->second);
-    else if (mLerpMode == LerpQuaternion)
-      currentFrame = ::lerpFrame<Eigen::Quaternionf>(s, lo->second, hi->second);
-    else {
-      std::cerr << "Invalid rotation interpolation mode (abort)\n";
-      exit(2);
-    }
-    currentFrame.orientation.coeffs().normalize();
-  }
-
-  currentFrame.orientation = currentFrame.orientation.inverse();
-  currentFrame.position = -(currentFrame.orientation * currentFrame.position);
-  mCamera.setFrame(currentFrame);
-
-  updateGL();
-}
-
-void RenderingWidget::keyPressEvent(QKeyEvent* e) {
-  switch (e->key()) {
-    case Qt::Key_Up:
-      mCamera.zoom(2);
-      break;
-    case Qt::Key_Down:
-      mCamera.zoom(-2);
-      break;
-    // add a frame
-    case Qt::Key_G:
-      grabFrame();
-      break;
-    // clear the time line
-    case Qt::Key_C:
-      m_timeline.clear();
-      break;
-    // move the camera to initial pos
-    case Qt::Key_R:
-      resetCamera();
-      break;
-    // start/stop the animation
-    case Qt::Key_A:
-      if (mAnimate) {
-        stopAnimation();
-      } else {
-        m_alpha = 0;
-        connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));
-        m_timer.start(1000 / 30);
-        mAnimate = true;
-      }
-      break;
-    default:
-      break;
-  }
-
-  updateGL();
-}
-
-void RenderingWidget::stopAnimation() {
-  disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));
-  m_timer.stop();
-  mAnimate = false;
-  m_alpha = 0;
-}
-
-void RenderingWidget::mousePressEvent(QMouseEvent* e) {
-  mMouseCoords = Vector2i(e->pos().x(), e->pos().y());
-  bool fly = (mNavMode == NavFly) || (e->modifiers() & Qt::ControlModifier);
-  switch (e->button()) {
-    case Qt::LeftButton:
-      if (fly) {
-        mCurrentTrackingMode = TM_LOCAL_ROTATE;
-        mTrackball.start(Trackball::Local);
-      } else {
-        mCurrentTrackingMode = TM_ROTATE_AROUND;
-        mTrackball.start(Trackball::Around);
-      }
-      mTrackball.track(mMouseCoords);
-      break;
-    case Qt::MidButton:
-      if (fly)
-        mCurrentTrackingMode = TM_FLY_Z;
-      else
-        mCurrentTrackingMode = TM_ZOOM;
-      break;
-    case Qt::RightButton:
-      mCurrentTrackingMode = TM_FLY_PAN;
-      break;
-    default:
-      break;
-  }
-}
-void RenderingWidget::mouseReleaseEvent(QMouseEvent*) {
-  mCurrentTrackingMode = TM_NO_TRACK;
-  updateGL();
-}
-
-void RenderingWidget::mouseMoveEvent(QMouseEvent* e) {
-  // tracking
-  if (mCurrentTrackingMode != TM_NO_TRACK) {
-    float dx = float(e->x() - mMouseCoords.x()) / float(mCamera.vpWidth());
-    float dy = -float(e->y() - mMouseCoords.y()) / float(mCamera.vpHeight());
-
-    // speedup the transformations
-    if (e->modifiers() & Qt::ShiftModifier) {
-      dx *= 10.;
-      dy *= 10.;
-    }
-
-    switch (mCurrentTrackingMode) {
-      case TM_ROTATE_AROUND:
-      case TM_LOCAL_ROTATE:
-        if (mRotationMode == RotationStable) {
-          // use the stable trackball implementation mapping
-          // the 2D coordinates to 3D points on a sphere.
-          mTrackball.track(Vector2i(e->pos().x(), e->pos().y()));
-        } else {
-          // standard approach mapping the x and y displacements as rotations
-          // around the camera's X and Y axes.
-          Quaternionf q = AngleAxisf(dx * EIGEN_PI, Vector3f::UnitY()) * AngleAxisf(-dy * EIGEN_PI, Vector3f::UnitX());
-          if (mCurrentTrackingMode == TM_LOCAL_ROTATE)
-            mCamera.localRotate(q);
-          else
-            mCamera.rotateAroundTarget(q);
-        }
-        break;
-      case TM_ZOOM:
-        mCamera.zoom(dy * 100);
-        break;
-      case TM_FLY_Z:
-        mCamera.localTranslate(Vector3f(0, 0, -dy * 200));
-        break;
-      case TM_FLY_PAN:
-        mCamera.localTranslate(Vector3f(dx * 200, dy * 200, 0));
-        break;
-      default:
-        break;
-    }
-
-    updateGL();
-  }
-
-  mMouseCoords = Vector2i(e->pos().x(), e->pos().y());
-}
-
-void RenderingWidget::paintGL() {
-  glEnable(GL_DEPTH_TEST);
-  glDisable(GL_CULL_FACE);
-  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-  glDisable(GL_COLOR_MATERIAL);
-  glDisable(GL_BLEND);
-  glDisable(GL_ALPHA_TEST);
-  glDisable(GL_TEXTURE_1D);
-  glDisable(GL_TEXTURE_2D);
-  glDisable(GL_TEXTURE_3D);
-
-  // Clear buffers
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-  mCamera.activateGL();
-
-  drawScene();
-}
-
-void RenderingWidget::initializeGL() {
-  glClearColor(1., 1., 1., 0.);
-  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
-  glDepthMask(GL_TRUE);
-  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
-  mCamera.setPosition(Vector3f(-200, -200, -200));
-  mCamera.setTarget(Vector3f(0, 0, 0));
-  mInitFrame.orientation = mCamera.orientation().inverse();
-  mInitFrame.position = mCamera.viewMatrix().translation();
-}
-
-void RenderingWidget::resizeGL(int width, int height) { mCamera.setViewport(width, height); }
-
-void RenderingWidget::setNavMode(int m) { mNavMode = NavMode(m); }
-
-void RenderingWidget::setLerpMode(int m) { mLerpMode = LerpMode(m); }
-
-void RenderingWidget::setRotationMode(int m) { mRotationMode = RotationMode(m); }
-
-void RenderingWidget::resetCamera() {
-  if (mAnimate) stopAnimation();
-  m_timeline.clear();
-  Frame aux0 = mCamera.frame();
-  aux0.orientation = aux0.orientation.inverse();
-  aux0.position = mCamera.viewMatrix().translation();
-  m_timeline[0] = aux0;
-
-  Vector3f currentTarget = mCamera.target();
-  mCamera.setTarget(Vector3f::Zero());
-
-  // compute the rotation duration to move the camera to the target
-  Frame aux1 = mCamera.frame();
-  aux1.orientation = aux1.orientation.inverse();
-  aux1.position = mCamera.viewMatrix().translation();
-  float duration = aux0.orientation.angularDistance(aux1.orientation) * 0.9;
-  if (duration < 0.1) duration = 0.1;
-
-  // put the camera at that time step:
-  aux1 = aux0.lerp(duration / 2, mInitFrame);
-  // and make it look at the target again
-  aux1.orientation = aux1.orientation.inverse();
-  aux1.position = -(aux1.orientation * aux1.position);
-  mCamera.setFrame(aux1);
-  mCamera.setTarget(Vector3f::Zero());
-
-  // add this camera keyframe
-  aux1.orientation = aux1.orientation.inverse();
-  aux1.position = mCamera.viewMatrix().translation();
-  m_timeline[duration] = aux1;
-
-  m_timeline[2] = mInitFrame;
-  m_alpha = 0;
-  animate();
-  connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));
-  m_timer.start(1000 / 30);
-  mAnimate = true;
-}
-
-QWidget* RenderingWidget::createNavigationControlWidget() {
-  QWidget* panel = new QWidget();
-  QVBoxLayout* layout = new QVBoxLayout();
-
-  {
-    QPushButton* but = new QPushButton("reset");
-    but->setToolTip("move the camera to initial position (with animation)");
-    layout->addWidget(but);
-    connect(but, SIGNAL(clicked()), this, SLOT(resetCamera()));
-  }
-  {
-    // navigation mode
-    QGroupBox* box = new QGroupBox("navigation mode");
-    QVBoxLayout* boxLayout = new QVBoxLayout;
-    QButtonGroup* group = new QButtonGroup(panel);
-    QRadioButton* but;
-    but = new QRadioButton("turn around");
-    but->setToolTip("look around an object");
-    group->addButton(but, NavTurnAround);
-    boxLayout->addWidget(but);
-    but = new QRadioButton("fly");
-    but->setToolTip("free navigation like a spaceship\n(this mode can also be enabled pressing the \"shift\" key)");
-    group->addButton(but, NavFly);
-    boxLayout->addWidget(but);
-    group->button(mNavMode)->setChecked(true);
-    connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setNavMode(int)));
-    box->setLayout(boxLayout);
-    layout->addWidget(box);
-  }
-  {
-    // track ball, rotation mode
-    QGroupBox* box = new QGroupBox("rotation mode");
-    QVBoxLayout* boxLayout = new QVBoxLayout;
-    QButtonGroup* group = new QButtonGroup(panel);
-    QRadioButton* but;
-    but = new QRadioButton("stable trackball");
-    group->addButton(but, RotationStable);
-    boxLayout->addWidget(but);
-    but->setToolTip("use the stable trackball implementation mapping\nthe 2D coordinates to 3D points on a sphere");
-    but = new QRadioButton("standard rotation");
-    group->addButton(but, RotationStandard);
-    boxLayout->addWidget(but);
-    but->setToolTip(
-        "standard approach mapping the x and y displacements\nas rotations around the camera's X and Y axes");
-    group->button(mRotationMode)->setChecked(true);
-    connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setRotationMode(int)));
-    box->setLayout(boxLayout);
-    layout->addWidget(box);
-  }
-  {
-    // interpolation mode
-    QGroupBox* box = new QGroupBox("spherical interpolation");
-    QVBoxLayout* boxLayout = new QVBoxLayout;
-    QButtonGroup* group = new QButtonGroup(panel);
-    QRadioButton* but;
-    but = new QRadioButton("quaternion slerp");
-    group->addButton(but, LerpQuaternion);
-    boxLayout->addWidget(but);
-    but->setToolTip("use quaternion spherical interpolation\nto interpolate orientations");
-    but = new QRadioButton("euler angles");
-    group->addButton(but, LerpEulerAngles);
-    boxLayout->addWidget(but);
-    but->setToolTip("use Euler angles to interpolate orientations");
-    group->button(mNavMode)->setChecked(true);
-    connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setLerpMode(int)));
-    box->setLayout(boxLayout);
-    layout->addWidget(box);
-  }
-  layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
-  panel->setLayout(layout);
-  return panel;
-}
-
-QuaternionDemo::QuaternionDemo() {
-  mRenderingWidget = new RenderingWidget();
-  setCentralWidget(mRenderingWidget);
-
-  QDockWidget* panel = new QDockWidget("navigation", this);
-  panel->setAllowedAreas((QFlags<Qt::DockWidgetArea>)(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea));
-  addDockWidget(Qt::RightDockWidgetArea, panel);
-  panel->setWidget(mRenderingWidget->createNavigationControlWidget());
-}
-
-int main(int argc, char* argv[]) {
-  std::cout << "Navigation:\n";
-  std::cout << "  left button:           rotate around the target\n";
-  std::cout << "  middle button:         zoom\n";
-  std::cout << "  left button + ctrl     quake rotate (rotate around camera position)\n";
-  std::cout << "  middle button + ctrl   walk (progress along camera's z direction)\n";
-  std::cout << "  left button:           pan (translate in the XY camera's plane)\n\n";
-  std::cout << "R : move the camera to initial position\n";
-  std::cout << "A : start/stop animation\n";
-  std::cout << "C : clear the animation\n";
-  std::cout << "G : add a key frame\n";
-
-  QApplication app(argc, argv);
-  QuaternionDemo demo;
-  demo.resize(600, 500);
-  demo.show();
-  return app.exec();
-}
-
-#include "quaternion_demo.moc"
diff --git a/demos/opengl/quaternion_demo.h b/demos/opengl/quaternion_demo.h
deleted file mode 100644
index 4c8f351..0000000
--- a/demos/opengl/quaternion_demo.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#ifndef EIGEN_QUATERNION_DEMO_H
-#define EIGEN_QUATERNION_DEMO_H
-
-#include "gpuhelper.h"
-#include "camera.h"
-#include "trackball.h"
-#include <map>
-#include <QTimer>
-#include <QtGui/QApplication>
-#include <QtOpenGL/QGLWidget>
-#include <QtGui/QMainWindow>
-
-class RenderingWidget : public QGLWidget {
-  Q_OBJECT
-
-  typedef std::map<float, Frame> TimeLine;
-  TimeLine m_timeline;
-  Frame lerpFrame(float t);
-
-  Frame mInitFrame;
-  bool mAnimate;
-  float m_alpha;
-
-  enum TrackMode { TM_NO_TRACK = 0, TM_ROTATE_AROUND, TM_ZOOM, TM_LOCAL_ROTATE, TM_FLY_Z, TM_FLY_PAN };
-
-  enum NavMode { NavTurnAround, NavFly };
-
-  enum LerpMode { LerpQuaternion, LerpEulerAngles };
-
-  enum RotationMode { RotationStable, RotationStandard };
-
-  Camera mCamera;
-  TrackMode mCurrentTrackingMode;
-  NavMode mNavMode;
-  LerpMode mLerpMode;
-  RotationMode mRotationMode;
-  Vector2i mMouseCoords;
-  Trackball mTrackball;
-
-  QTimer m_timer;
-
-  void setupCamera();
-
-  std::vector<Vector3f> mVertices;
-  std::vector<Vector3f> mNormals;
-  std::vector<int> mIndices;
-
- protected slots:
-
-  virtual void animate(void);
-  virtual void drawScene(void);
-
-  virtual void grabFrame(void);
-  virtual void stopAnimation();
-
-  virtual void setNavMode(int);
-  virtual void setLerpMode(int);
-  virtual void setRotationMode(int);
-  virtual void resetCamera();
-
- protected:
-  virtual void initializeGL();
-  virtual void resizeGL(int width, int height);
-  virtual void paintGL();
-
-  //--------------------------------------------------------------------------------
-  virtual void mousePressEvent(QMouseEvent* e);
-  virtual void mouseReleaseEvent(QMouseEvent* e);
-  virtual void mouseMoveEvent(QMouseEvent* e);
-  virtual void keyPressEvent(QKeyEvent* e);
-  //--------------------------------------------------------------------------------
-
- public:
-  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
-
-  RenderingWidget();
-  ~RenderingWidget() {}
-
-  QWidget* createNavigationControlWidget();
-};
-
-class QuaternionDemo : public QMainWindow {
-  Q_OBJECT
- public:
-  QuaternionDemo();
-
- protected:
-  RenderingWidget* mRenderingWidget;
-};
-
-#endif  // EIGEN_QUATERNION_DEMO_H
diff --git a/demos/opengl/trackball.cpp b/demos/opengl/trackball.cpp
deleted file mode 100644
index dfa22a5..0000000
--- a/demos/opengl/trackball.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "trackball.h"
-#include "camera.h"
-
-using namespace Eigen;
-
-void Trackball::track(const Vector2i& point2D) {
-  if (mpCamera == 0) return;
-  Vector3f newPoint3D;
-  bool newPointOk = mapToSphere(point2D, newPoint3D);
-
-  if (mLastPointOk && newPointOk) {
-    Vector3f axis = mLastPoint3D.cross(newPoint3D).normalized();
-    float cos_angle = mLastPoint3D.dot(newPoint3D);
-    if (std::abs(cos_angle) < 1.0) {
-      float angle = 2. * acos(cos_angle);
-      if (mMode == Around)
-        mpCamera->rotateAroundTarget(Quaternionf(AngleAxisf(angle, axis)));
-      else
-        mpCamera->localRotate(Quaternionf(AngleAxisf(-angle, axis)));
-    }
-  }
-
-  mLastPoint3D = newPoint3D;
-  mLastPointOk = newPointOk;
-}
-
-bool Trackball::mapToSphere(const Vector2i& p2, Vector3f& v3) {
-  if ((p2.x() >= 0) && (p2.x() <= int(mpCamera->vpWidth())) && (p2.y() >= 0) && (p2.y() <= int(mpCamera->vpHeight()))) {
-    double x = (double)(p2.x() - 0.5 * mpCamera->vpWidth()) / (double)mpCamera->vpWidth();
-    double y = (double)(0.5 * mpCamera->vpHeight() - p2.y()) / (double)mpCamera->vpHeight();
-    double sinx = sin(EIGEN_PI * x * 0.5);
-    double siny = sin(EIGEN_PI * y * 0.5);
-    double sinx2siny2 = sinx * sinx + siny * siny;
-
-    v3.x() = sinx;
-    v3.y() = siny;
-    v3.z() = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
-
-    return true;
-  } else
-    return false;
-}
diff --git a/demos/opengl/trackball.h b/demos/opengl/trackball.h
deleted file mode 100644
index a0026ba..0000000
--- a/demos/opengl/trackball.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#ifndef EIGEN_TRACKBALL_H
-#define EIGEN_TRACKBALL_H
-
-#include <Eigen/Geometry>
-
-class Camera;
-
-class Trackball {
- public:
-  enum Mode { Around, Local };
-
-  Trackball() : mpCamera(0) {}
-
-  void start(Mode m = Around) {
-    mMode = m;
-    mLastPointOk = false;
-  }
-
-  void setCamera(Camera* pCam) { mpCamera = pCam; }
-
-  void track(const Eigen::Vector2i& newPoint2D);
-
- protected:
-  bool mapToSphere(const Eigen::Vector2i& p2, Eigen::Vector3f& v3);
-
-  Camera* mpCamera;
-  Eigen::Vector3f mLastPoint3D;
-  Mode mMode;
-  bool mLastPointOk;
-};
-
-#endif  // EIGEN_TRACKBALL_H
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 26f0067..cd7600b 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -129,6 +129,7 @@
                          EIGEN_QT_SUPPORT \
                          EIGEN_STRONG_INLINE=inline \
                          EIGEN_DEVICE_FUNC= \
+                         "EIGEN_DEPRECATED_WITH_REASON(message)=" \
                          "EIGEN_MAKE_CWISE_UNARY_OP(METHOD,FUNCTOR,RETURN_TYPE)=const CwiseUnaryOp<FUNCTOR<Scalar>,const Derived> METHOD() const; using RETURN_TYPE=CwiseUnaryOp<FUNCTOR<Scalar>,const Derived>;" \
                          "EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR)=template<typename OtherDerived> const CwiseBinaryOp<FUNCTOR<Scalar,typename OtherDerived::Scalar>, const Derived, const OtherDerived> METHOD(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const;" \
                          "EIGEN_CWISE_PRODUCT_RETURN_TYPE(LHS,RHS)=CwiseBinaryOp<internal::scalar_product_op<LHS::Scalar,RHS::Scalar>, const LHS, const RHS>" \
diff --git a/doc/TutorialSparse.dox b/doc/TutorialSparse.dox
index 2f750a4..6e25ace 100644
--- a/doc/TutorialSparse.dox
+++ b/doc/TutorialSparse.dox
@@ -101,7 +101,7 @@
 The last step consists of effectively solving the assembled problem.
 Since the resulting matrix \c A is symmetric by construction, we can perform a direct Cholesky factorization via the SimplicialLDLT class which behaves like its LDLT counterpart for dense objects.
 
-The resulting vector \c x contains the pixel values as a 1D array which is saved to a jpeg file shown on the right of the code above.
+The resulting vector \c x contains the pixel values as a 1D array which is saved to a grayscale PGM image file.
 
 Describing the \a buildProblem and \a save functions is out of the scope of this tutorial. They are given \ref TutorialSparse_example_details "here" for the curious and reproducibility purpose.
 
diff --git a/doc/special_examples/CMakeLists.txt b/doc/special_examples/CMakeLists.txt
index b0e90b0..0b77540 100644
--- a/doc/special_examples/CMakeLists.txt
+++ b/doc/special_examples/CMakeLists.txt
@@ -1,26 +1,16 @@
 # SPDX-FileCopyrightText: The Eigen Authors
 # SPDX-License-Identifier: MPL-2.0
 
-if(NOT EIGEN_TEST_NOQT)
-  find_package(Qt4)
-  if(QT4_FOUND)
-    include(${QT_USE_FILE})
-  endif()
-endif()
+add_executable(Tutorial_sparse_example Tutorial_sparse_example.cpp Tutorial_sparse_example_details.cpp)
+target_link_libraries(Tutorial_sparse_example ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} Eigen3::Eigen)
+add_dependencies(all_examples Tutorial_sparse_example)
 
-if(QT4_FOUND)
-  add_executable(Tutorial_sparse_example Tutorial_sparse_example.cpp Tutorial_sparse_example_details.cpp)
-  target_link_libraries(Tutorial_sparse_example ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} Eigen3::Eigen)
-
-  add_custom_command(
-    TARGET Tutorial_sparse_example
-    POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../html/
-    COMMAND Tutorial_sparse_example ARGS ${CMAKE_CURRENT_BINARY_DIR}/../html/Tutorial_sparse_example.jpeg
-  )
-
-  add_dependencies(all_examples Tutorial_sparse_example)
-endif()
+add_custom_command(
+  TARGET Tutorial_sparse_example
+  POST_BUILD
+  COMMAND Tutorial_sparse_example
+  ARGS ${CMAKE_CURRENT_BINARY_DIR}/Tutorial_sparse_example.pgm
+)
 
 add_executable(random_generators random_generators.cpp)
 target_link_libraries(random_generators ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} Eigen3::Eigen)
diff --git a/doc/special_examples/Tutorial_sparse_example_details.cpp b/doc/special_examples/Tutorial_sparse_example_details.cpp
index 81ef47a..833cb50 100644
--- a/doc/special_examples/Tutorial_sparse_example_details.cpp
+++ b/doc/special_examples/Tutorial_sparse_example_details.cpp
@@ -2,8 +2,8 @@
 // SPDX-License-Identifier: MPL-2.0
 
 #include <Eigen/Sparse>
+#include <fstream>
 #include <vector>
-#include <QImage>
 
 typedef Eigen::SparseMatrix<double> SpMat;  // declares a column-major sparse matrix type of double
 typedef Eigen::Triplet<double> T;
@@ -36,10 +36,10 @@
   }
 }
 
+// Writes the n x n pixel values in x, which lie in [0,1], as a binary PGM (grayscale) image.
 void saveAsBitmap(const Eigen::VectorXd& x, int n, const char* filename) {
   Eigen::Array<unsigned char, Eigen::Dynamic, Eigen::Dynamic> bits = (x * 255).cast<unsigned char>();
-  QImage img(bits.data(), n, n, QImage::Format_Indexed8);
-  img.setColorCount(256);
-  for (int i = 0; i < 256; i++) img.setColor(i, qRgb(i, i, i));
-  img.save(filename);
+  std::ofstream file(filename, std::ios::binary);
+  file << "P5\n" << n << ' ' << n << "\n255\n";
+  file.write(reinterpret_cast<const char*>(bits.data()), bits.size());
 }
diff --git a/scripts/affected_tests.py b/scripts/affected_tests.py
index 1a99707..4319994 100644
--- a/scripts/affected_tests.py
+++ b/scripts/affected_tests.py
@@ -119,7 +119,6 @@
     "ci/tidy/*",
     "ci/lint/*",
     "debug/*",
-    "demos/*",
     "doc/*",
     "contrib/benchmarks/*",
     "contrib/doc/*",
diff --git a/scripts/clang_tidy_hook.py b/scripts/clang_tidy_hook.py
index b4fe1de..5c75315 100644
--- a/scripts/clang_tidy_hook.py
+++ b/scripts/clang_tidy_hook.py
@@ -49,7 +49,7 @@
                           hook_post_image_and_added, is_cxx_path, line_filter_json)
 
 # Parsing an umbrella costs about a second, so keep the hook off trees whose
-# conventions these checks do not describe (bench/, demos/, doc/ examples).
+# conventions these checks do not describe (bench/, doc/ examples).
 # unsupported/Eigen/ is kept for the legacy umbrella shims that still live
 # there; the implementation tree itself is contrib/, which has no shims and
 # so needs the src-tree rules.
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 5683a7a..465bb3e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -236,17 +236,6 @@
   ei_add_property(EIGEN_MISSING_BACKENDS "Accelerate, ")
 endif()
 
-option(EIGEN_TEST_NOQT "Disable Qt support in unit tests" OFF)
-if(NOT EIGEN_TEST_NOQT)
-  find_package(Qt4)
-  if(QT4_FOUND)
-    include(${QT_USE_FILE})
-    ei_add_property(EIGEN_TESTED_BACKENDS  "Qt4 support, ")
-  else()
-    ei_add_property(EIGEN_MISSING_BACKENDS  "Qt4 support, ")
-  endif()
-endif()
-
 if(TEST_LIB)
   add_definitions("-DEIGEN_EXTERN_INSTANTIATIONS=1")
 endif()
@@ -621,10 +610,6 @@
 ei_add_test(trig_reduction_fastmath "${EIGEN_FASTMATH_FLAGS}")
 ei_add_test(optimization_barrier "${EIGEN_FASTMATH_FLAGS}")
 
-if(QT4_FOUND)
-  ei_add_test(qtvector "" "${QT_QTCORE_LIBRARY}")
-endif()
-
 if(PARDISO_FOUND)
   ei_add_test(pardiso_support "" "${PARDISO_ALL_LIBS}")
 endif()
diff --git a/test/buildsystem/consumers/subproject/CMakeLists.txt b/test/buildsystem/consumers/subproject/CMakeLists.txt
index 10df8d6..2731ef7 100644
--- a/test/buildsystem/consumers/subproject/CMakeLists.txt
+++ b/test/buildsystem/consumers/subproject/CMakeLists.txt
@@ -21,7 +21,6 @@
 
 set(EIGEN_BUILD_TESTING OFF CACHE BOOL "" FORCE)
 set(EIGEN_BUILD_DOC OFF CACHE BOOL "" FORCE)
-set(EIGEN_BUILD_DEMOS OFF CACHE BOOL "" FORCE)
 set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
 
 if(EIGEN_USE_EXCLUDE_FROM_ALL)
diff --git a/test/buildsystem/run_scenario.cmake b/test/buildsystem/run_scenario.cmake
index feb98c1..57d0710 100644
--- a/test/buildsystem/run_scenario.cmake
+++ b/test/buildsystem/run_scenario.cmake
@@ -27,7 +27,6 @@
 set(BS_EIGEN_QUIET_OPTIONS
     -DEIGEN_BUILD_TESTING=OFF
     -DEIGEN_BUILD_DOC=OFF
-    -DEIGEN_BUILD_DEMOS=OFF
     -DEIGEN_BUILD_BLAS=OFF
     -DEIGEN_BUILD_LAPACK=OFF
     )
diff --git a/test/buildsystem/scenarios/install_off_all_options.cmake b/test/buildsystem/scenarios/install_off_all_options.cmake
index 6f9fb39..353163c 100644
--- a/test/buildsystem/scenarios/install_off_all_options.cmake
+++ b/test/buildsystem/scenarios/install_off_all_options.cmake
@@ -16,7 +16,6 @@
              "-DCMAKE_INSTALL_PREFIX=${BS_PREFIX}"
              -DEIGEN_BUILD_TESTING=OFF
              -DEIGEN_BUILD_DOC=OFF
-             -DEIGEN_BUILD_DEMOS=OFF
              -DEIGEN_BUILD_BLAS=ON
              -DEIGEN_BUILD_LAPACK=ON
              -DEIGEN_BUILD_CMAKE_PACKAGE=ON
@@ -45,7 +44,6 @@
              "-DCMAKE_INSTALL_PREFIX=${BS_PREFIX}"
              -DEIGEN_BUILD_TESTING=OFF
              -DEIGEN_BUILD_DOC=ON
-             -DEIGEN_BUILD_DEMOS=OFF
              -DEIGEN_BUILD_BLAS=OFF
              -DEIGEN_BUILD_LAPACK=OFF
              -DEIGEN_INSTALL=OFF)
diff --git a/test/qtvector.cpp b/test/qtvector.cpp
deleted file mode 100644
index f545a4e..0000000
--- a/test/qtvector.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-// SPDX-License-Identifier: MPL-2.0
-
-#include "main.h"
-#include <QtCore/QVector>
-#include <Eigen/Geometry>
-#include <Eigen/QtAlignedMalloc>
-
-template <typename MatrixType>
-void check_qtvector_matrix(const MatrixType& m) {
-  Index rows = m.rows();
-  Index cols = m.cols();
-  MatrixType x = MatrixType::Random(rows, cols), y = MatrixType::Random(rows, cols);
-  QVector<MatrixType> v(10, MatrixType(rows, cols)), w(20, y);
-  for (int i = 0; i < 20; i++) {
-    VERIFY_IS_APPROX(w[i], y);
-  }
-  v[5] = x;
-  w[6] = v[5];
-  VERIFY_IS_APPROX(w[6], v[5]);
-  v = w;
-  for (int i = 0; i < 20; i++) {
-    VERIFY_IS_APPROX(w[i], v[i]);
-  }
-
-  v.resize(21);
-  v[20] = x;
-  VERIFY_IS_APPROX(v[20], x);
-  v.fill(y, 22);
-  VERIFY_IS_APPROX(v[21], y);
-  v.push_back(x);
-  VERIFY_IS_APPROX(v[22], x);
-  VERIFY((size_t) & (v[22]) == (size_t) & (v[21]) + sizeof(MatrixType));
-
-  // do a lot of push_back such that the vector gets internally resized
-  // (with memory reallocation)
-  MatrixType* ref = &w[0];
-  for (int i = 0; i < 30 || ((ref == &w[0]) && i < 300); ++i) v.push_back(w[i % w.size()]);
-  for (int i = 23; i < v.size(); ++i) {
-    VERIFY(v[i] == w[(i - 23) % w.size()]);
-  }
-}
-
-template <typename TransformType>
-void check_qtvector_transform(const TransformType&) {
-  typedef typename TransformType::MatrixType MatrixType;
-  TransformType x(MatrixType::Random()), y(MatrixType::Random());
-  QVector<TransformType> v(10), w(20, y);
-  v[5] = x;
-  w[6] = v[5];
-  VERIFY_IS_APPROX(w[6], v[5]);
-  v = w;
-  for (int i = 0; i < 20; i++) {
-    VERIFY_IS_APPROX(w[i], v[i]);
-  }
-
-  v.resize(21);
-  v[20] = x;
-  VERIFY_IS_APPROX(v[20], x);
-  v.fill(y, 22);
-  VERIFY_IS_APPROX(v[21], y);
-  v.push_back(x);
-  VERIFY_IS_APPROX(v[22], x);
-  VERIFY((size_t) & (v[22]) == (size_t) & (v[21]) + sizeof(TransformType));
-
-  // do a lot of push_back such that the vector gets internally resized
-  // (with memory reallocation)
-  TransformType* ref = &w[0];
-  for (int i = 0; i < 30 || ((ref == &w[0]) && i < 300); ++i) v.push_back(w[i % w.size()]);
-  for (unsigned int i = 23; int(i) < v.size(); ++i) {
-    VERIFY(v[i].matrix() == w[(i - 23) % w.size()].matrix());
-  }
-}
-
-template <typename QuaternionType>
-void check_qtvector_quaternion(const QuaternionType&) {
-  typedef typename QuaternionType::Coefficients Coefficients;
-  QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
-  QVector<QuaternionType> v(10), w(20, y);
-  v[5] = x;
-  w[6] = v[5];
-  VERIFY_IS_APPROX(w[6], v[5]);
-  v = w;
-  for (int i = 0; i < 20; i++) {
-    VERIFY_IS_APPROX(w[i], v[i]);
-  }
-
-  v.resize(21);
-  v[20] = x;
-  VERIFY_IS_APPROX(v[20], x);
-  v.fill(y, 22);
-  VERIFY_IS_APPROX(v[21], y);
-  v.push_back(x);
-  VERIFY_IS_APPROX(v[22], x);
-  VERIFY((size_t) & (v[22]) == (size_t) & (v[21]) + sizeof(QuaternionType));
-
-  // do a lot of push_back such that the vector gets internally resized
-  // (with memory reallocation)
-  QuaternionType* ref = &w[0];
-  for (int i = 0; i < 30 || ((ref == &w[0]) && i < 300); ++i) v.push_back(w[i % w.size()]);
-  for (unsigned int i = 23; int(i) < v.size(); ++i) {
-    VERIFY(v[i].coeffs() == w[(i - 23) % w.size()].coeffs());
-  }
-}
-
-EIGEN_DECLARE_TEST(qtvector) {
-  // some non vectorizable fixed sizes
-  CALL_SUBTEST(check_qtvector_matrix(Vector2f()));
-  CALL_SUBTEST(check_qtvector_matrix(Matrix3f()));
-  CALL_SUBTEST(check_qtvector_matrix(Matrix3d()));
-
-  // some vectorizable fixed sizes
-  CALL_SUBTEST(check_qtvector_matrix(Matrix2f()));
-  CALL_SUBTEST(check_qtvector_matrix(Vector4f()));
-  CALL_SUBTEST(check_qtvector_matrix(Matrix4f()));
-  CALL_SUBTEST(check_qtvector_matrix(Matrix4d()));
-
-  // some dynamic sizes
-  CALL_SUBTEST(check_qtvector_matrix(MatrixXd(1, 1)));
-  CALL_SUBTEST(check_qtvector_matrix(VectorXd(20)));
-  CALL_SUBTEST(check_qtvector_matrix(RowVectorXf(20)));
-  CALL_SUBTEST(check_qtvector_matrix(MatrixXcf(10, 10)));
-
-  // some Transform
-  CALL_SUBTEST(check_qtvector_transform(Affine2f()));
-  CALL_SUBTEST(check_qtvector_transform(Affine3f()));
-  CALL_SUBTEST(check_qtvector_transform(Affine3d()));
-  // CALL_SUBTEST(check_qtvector_transform(Transform4d()));
-
-  // some Quaternion
-  CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));
-  CALL_SUBTEST(check_qtvector_quaternion(Quaterniond()));
-}