// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2016 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 "main.h"
#include <Eigen/LU>
#include <Eigen/Cholesky>
#include <Eigen/QR>
#include <Eigen/Eigenvalues>

// This file test inplace decomposition through Ref<>, as supported by the Cholesky, LU, and QR decompositions, the
// Hessenberg, tridiagonal, Schur and QZ reductions, and the dense eigensolvers.

template <typename DecType, typename MatrixType>
void inplace(bool square = false, bool SPD = false) {
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> RhsType;
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> ResType;

  Index rows = MatrixType::RowsAtCompileTime == Dynamic ? internal::random<Index>(2, EIGEN_TEST_MAX_SIZE / 2)
                                                        : Index(MatrixType::RowsAtCompileTime);
  Index cols = MatrixType::ColsAtCompileTime == Dynamic ? (square ? rows : internal::random<Index>(2, rows))
                                                        : Index(MatrixType::ColsAtCompileTime);

  MatrixType A = MatrixType::Random(rows, cols);
  RhsType b = RhsType::Random(rows);
  ResType x(cols);

  if (SPD) {
    assert(square);
    A.topRows(cols) = A.topRows(cols).adjoint() * A.topRows(cols);
    A.diagonal().array() += 1e-3;
  }

  MatrixType A0 = A;
  MatrixType A1 = A;

  DecType dec(A);

  // Check that the content of A has been modified
  VERIFY_IS_NOT_APPROX(A, A0);

  // Check that the decomposition is correct:
  if (rows == cols) {
    VERIFY_IS_APPROX(A0 * (x = dec.solve(b)), b);
  } else {
    VERIFY_IS_APPROX(A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b);
  }

  // Check that modifying A breaks the current dec:
  A.setRandom();
  if (rows == cols) {
    VERIFY_IS_NOT_APPROX(A0 * (x = dec.solve(b)), b);
  } else {
    VERIFY_IS_NOT_APPROX(A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b);
  }

  // Check that calling compute(A1) does not modify A1:
  A = A0;
  dec.compute(A1);
  VERIFY_IS_EQUAL(A0, A1);
  VERIFY_IS_NOT_APPROX(A, A0);
  if (rows == cols) {
    VERIFY_IS_APPROX(A0 * (x = dec.solve(b)), b);
  } else {
    VERIFY_IS_APPROX(A0.transpose() * A0 * (x = dec.solve(b)), A0.transpose() * b);
  }
}

template <typename MatrixType>
void inplace_fullpivlu_subspaces() {
  using RealScalar = typename MatrixType::RealScalar;
  MatrixType input(3, 3);
  input << 1, 0, 1, 0, 1, 1, 0, 0, 0;
  MatrixType working = input;
  FullPivLU<Ref<MatrixType>> lu(working);
  Ref<MatrixType> original(input);
  const auto kernel = lu.kernel().eval();
  const auto image = lu.image(original).eval();
  STATIC_CHECK((int(decltype(kernel)::IsRowMajor) == int(MatrixType::IsRowMajor)));
  STATIC_CHECK((int(decltype(image)::IsRowMajor) == int(MatrixType::IsRowMajor)));
  VERIFY_IS_EQUAL(kernel.cols(), 1);
  VERIFY_IS_EQUAL(image.cols(), 2);
  const RealScalar tolerance = RealScalar(128 * input.rows()) * NumTraits<RealScalar>::epsilon();
  VERIFY((input * kernel).norm() <= tolerance * input.norm() * kernel.norm());
  VERIFY_IS_EQUAL(kernel.fullPivLu().rank(), kernel.cols());
  VERIFY_IS_EQUAL(image.fullPivLu().rank(), image.cols());
  VERIFY((image * image.fullPivLu().solve(input) - input).norm() <= tolerance * input.norm());
}

template <typename MatrixType>
MatrixType random_selfadjoint(Index n) {
  MatrixType a = MatrixType::Random(n, n);
  return a + a.adjoint();
}

template <typename MatrixType, typename BasisType, typename FormType>
void verify_inplace_similarity(const MatrixType& input, const BasisType& basis, const FormType& form) {
  using RealScalar = typename MatrixType::RealScalar;
  const RealScalar tolerance = RealScalar(128 * input.rows()) * NumTraits<RealScalar>::epsilon();
  VERIFY((input - basis * form * basis.adjoint()).norm() <= tolerance * input.norm());
  VERIFY(basis.isUnitary(tolerance));
}

template <typename MatrixType, typename QZType>
void verify_inplace_qz(const MatrixType& a, const MatrixType& b, const QZType& qz) {
  using RealScalar = typename MatrixType::RealScalar;
  const RealScalar tolerance = RealScalar(128 * a.rows()) * NumTraits<RealScalar>::epsilon();
  VERIFY_IS_EQUAL(qz.info(), Success);
  VERIFY((a - qz.matrixQ() * qz.matrixS() * qz.matrixZ()).norm() <= tolerance * a.norm());
  VERIFY((b - qz.matrixQ() * qz.matrixT() * qz.matrixZ()).norm() <= tolerance * b.norm());
  VERIFY(qz.matrixQ().isUnitary(tolerance));
  VERIFY(qz.matrixZ().isUnitary(tolerance));
}

template <typename MatrixType>
void inplace_reductions(Index size) {
  using Scalar = typename MatrixType::Scalar;
  {
    MatrixType A = MatrixType::Random(size, size), A0 = A;
    HessenbergDecomposition<Ref<MatrixType>> hess(A);
    VERIFY(internal::is_same_dense(hess.packedMatrix(), A));
    MatrixType Q = hess.matrixQ(), H = hess.matrixH();
    verify_inplace_similarity(A0, Q, H);
    MatrixType twiceH = Scalar(2) * hess.matrixH();
    VERIFY_IS_EQUAL(twiceH, Scalar(2) * H);

    // NOLINTNEXTLINE(performance-unnecessary-copy-initialization): Snapshot verifies compute() preserves its input.
    MatrixType A1 = MatrixType::Random(size, size), A1c = A1;
    hess.compute(A1);
    VERIFY_IS_EQUAL(A1, A1c);
    VERIFY(internal::is_same_dense(hess.packedMatrix(), A));
    Q = hess.matrixQ();
    H = hess.matrixH();
    verify_inplace_similarity(A1, Q, H);
  }
  {
    MatrixType A = random_selfadjoint<MatrixType>(size), A0 = A;
    Tridiagonalization<Ref<MatrixType>> tri(A);
    VERIFY(internal::is_same_dense(tri.packedMatrix(), A));
    MatrixType Q = tri.matrixQ(), T = tri.matrixT().eval().template cast<Scalar>();
    verify_inplace_similarity(A0, Q, T);
  }
}

template <typename MatrixType, template <typename> class SchurType>
void inplace_schur(Index size) {
  using RealScalar = typename MatrixType::RealScalar;
  const RealScalar tolerance = RealScalar(128 * size) * NumTraits<RealScalar>::epsilon();
  MatrixType A = MatrixType::Random(size, size), A0 = A;
  SchurType<Ref<MatrixType>> schur(A);
  VERIFY_IS_EQUAL(schur.info(), Success);
  VERIFY(internal::is_same_dense(schur.matrixT(), A));
  verify_inplace_similarity(A0, schur.matrixU(), schur.matrixT());

  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization): Snapshot verifies compute() preserves its input.
  MatrixType A1 = MatrixType::Random(size, size), A1c = A1;
  schur.compute(A1);
  VERIFY_IS_EQUAL(schur.info(), Success);
  VERIFY_IS_EQUAL(A1, A1c);
  VERIFY(internal::is_same_dense(schur.matrixT(), A));
  verify_inplace_similarity(A1, schur.matrixU(), schur.matrixT());
  MatrixType T = schur.matrixT();
  schur.compute(A1, false);
  VERIFY_IS_EQUAL(schur.info(), Success);
  VERIFY_IS_EQUAL(A1, A1c);
  VERIFY((schur.matrixT() - T).norm() <= tolerance * A1.norm());
}

template <typename MatrixType>
void inplace_selfadjoint_eigensolver(Index size) {
  using Scalar = typename MatrixType::Scalar;
  using RealScalar = typename MatrixType::RealScalar;
  const RealScalar tolerance = RealScalar(128 * size) * NumTraits<RealScalar>::epsilon();
  MatrixType A = random_selfadjoint<MatrixType>(size), A0 = A;
  A.template triangularView<StrictlyUpper>().setConstant(Scalar(std::numeric_limits<RealScalar>::quiet_NaN()));
  SelfAdjointEigenSolver<Ref<MatrixType>> es(A);
  VERIFY_IS_EQUAL(es.info(), Success);
  VERIFY(internal::is_same_dense(es.eigenvectors(), A));
  VERIFY((A0 * A - A * es.eigenvalues().asDiagonal()).norm() <= tolerance * A0.norm());
  VERIFY(A.isUnitary(tolerance));

  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization): Snapshot verifies compute() preserves its input.
  MatrixType A1 = random_selfadjoint<MatrixType>(size), A1c = A1;
  es.compute(A1, EigenvaluesOnly);
  VERIFY_IS_EQUAL(es.info(), Success);
  VERIFY_IS_EQUAL(A1, A1c);
  const auto values = es.eigenvalues().eval();
  es.compute(A1);
  VERIFY_IS_EQUAL(es.info(), Success);
  VERIFY_IS_EQUAL(A1, A1c);
  VERIFY(internal::is_same_dense(es.eigenvectors(), A));
  VERIFY((es.eigenvalues() - values).norm() <= tolerance * A1.norm());
  VERIFY((A1 * A - A * es.eigenvalues().asDiagonal()).norm() <= tolerance * A1.norm());
  VERIFY(A.isUnitary(tolerance));

  if (MatrixType::RowsAtCompileTime == Dynamic) {
    MatrixType big = MatrixType::Random(size + 3, size + 2);
    Ref<MatrixType> B = big.block(2, 1, size, size);
    B = random_selfadjoint<MatrixType>(size);
    MatrixType Bin = B;
    SelfAdjointEigenSolver<Ref<MatrixType>> esb(B);
    VERIFY_IS_EQUAL(esb.info(), Success);
    VERIFY(internal::is_same_dense(esb.eigenvectors(), B));
    VERIFY((Bin * B - B * esb.eigenvalues().asDiagonal()).norm() <= tolerance * Bin.norm());
    VERIFY(B.isUnitary(tolerance));
  }

  MatrixType Ag = random_selfadjoint<MatrixType>(size);
  MatrixType Bg = MatrixType::Random(size, size);
  Bg = Bg * Bg.adjoint() + RealScalar(size) * MatrixType::Identity(size, size);
  for (int type : {int(Ax_lBx), int(ABx_lx), int(BAx_lx)}) {
    MatrixType A2 = Ag, B2 = Bg;
    GeneralizedSelfAdjointEigenSolver<Ref<MatrixType>> ges(A2, B2, ComputeEigenvectors | type);
    VERIFY_IS_EQUAL(ges.info(), Success);
    VERIFY(internal::is_same_dense(ges.eigenvectors(), A2));
    const MatrixType& V = ges.eigenvectors();
    MatrixType VD = V * ges.eigenvalues().asDiagonal();
    if (type == Ax_lBx) {
      VERIFY((Ag * V - Bg * VD).norm() <= tolerance * (Ag.norm() * V.norm() + Bg.norm() * VD.norm()));
    } else if (type == ABx_lx) {
      VERIFY((Ag * (Bg * V) - VD).norm() <= tolerance * (Ag.norm() * Bg.norm() * V.norm() + VD.norm()));
    } else {
      VERIFY((Bg * (Ag * V) - VD).norm() <= tolerance * (Ag.norm() * Bg.norm() * V.norm() + VD.norm()));
    }
    MatrixType metric;
    if (type == BAx_lx) {
      metric = V.adjoint() * Bg.llt().solve(V);
    } else {
      metric = V.adjoint() * Bg * V;
    }
    VERIFY((metric - MatrixType::Identity(size, size)).norm() <= tolerance * RealScalar(size));

    MatrixType A3 = Ag, B3 = Bg;
    GeneralizedSelfAdjointEigenSolver<Ref<MatrixType>> gesv(A3, B3, EigenvaluesOnly | type);
    VERIFY_IS_EQUAL(gesv.info(), Success);
    VERIFY((gesv.eigenvalues() - ges.eigenvalues()).norm() <= tolerance * ges.eigenvalues().norm());
  }
}

template <typename MatrixType>
void inplace_special_values(Index size) {
  using RealScalar = typename MatrixType::RealScalar;
  for (Index kind = 0; kind <= 2 * size; ++kind) {
    MatrixType A0 = MatrixType::Zero(size, size);
    if (kind > 0) {
      const Index index = (kind - 1) % size;
      A0(index, index) =
          kind <= size ? std::numeric_limits<RealScalar>::quiet_NaN() : std::numeric_limits<RealScalar>::infinity();
    }
    MatrixType A = A0;
    RealSchur<Ref<MatrixType>> schur(A);
    RealSchur<MatrixType> schur0(A0);
    VERIFY_IS_EQUAL(schur.info(), schur0.info());
    VERIFY_IS_EQUAL(schur.info(), kind == 0 ? Success : NoConvergence);
    if (schur.info() == Success && kind == 0) verify_inplace_similarity(A0, schur.matrixU(), schur.matrixT());

    MatrixType B = A0;
    SelfAdjointEigenSolver<Ref<MatrixType>> saes(B);
    SelfAdjointEigenSolver<MatrixType> saes0(A0);
    VERIFY_IS_EQUAL(saes.info(), saes0.info());
    VERIFY_IS_EQUAL(saes.info(), kind == 0 ? Success : NoConvergence);
    if (saes.info() == Success && kind == 0) {
      VERIFY_IS_EQUAL(saes.eigenvalues(), saes0.eigenvalues());
      VERIFY(saes.eigenvectors().isUnitary(RealScalar(128 * size) * NumTraits<RealScalar>::epsilon()));
    }

    MatrixType C = A0;
    EigenSolver<Ref<MatrixType>> es(C);
    EigenSolver<MatrixType> es0(A0);
    VERIFY_IS_EQUAL(es.info(), es0.info());
    VERIFY_IS_EQUAL(es.info(), kind == 0 ? Success : NumericalIssue);
    if (es.info() == Success && kind == 0) {
      VERIFY_IS_EQUAL(es.eigenvalues(), es0.eigenvalues());
      VERIFY((es.eigenvectors().colwise().norm().array() > RealScalar(0)).all());
    }
  }
}

template <typename MatrixType, template <typename> class SolverType>
void inplace_eigensolver(Index size) {
  using RealScalar = typename MatrixType::RealScalar;
  using ComplexScalar = std::complex<RealScalar>;
  using ComplexMatrix = typename EigenSolver<MatrixType>::EigenvectorsType;
  const RealScalar tolerance = RealScalar(128 * size) * NumTraits<RealScalar>::epsilon();
  MatrixType A = MatrixType::Random(size, size), A0 = A;
  SolverType<Ref<MatrixType>> es(A);
  VERIFY_IS_EQUAL(es.info(), Success);
  ComplexMatrix V = es.eigenvectors();
  VERIFY((A0.template cast<ComplexScalar>() * V - V * es.eigenvalues().asDiagonal()).norm() <=
         tolerance * A0.norm() * V.norm());
  VERIFY((V.colwise().norm().array() - RealScalar(1)).abs().maxCoeff() <= tolerance);

  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization): Snapshot verifies compute() preserves its input.
  MatrixType A1 = MatrixType::Random(size, size), A1c = A1;
  es.compute(A1);
  VERIFY_IS_EQUAL(es.info(), Success);
  VERIFY_IS_EQUAL(A1, A1c);
  V = es.eigenvectors();
  VERIFY((A1.template cast<ComplexScalar>() * V - V * es.eigenvalues().asDiagonal()).norm() <=
         tolerance * A1.norm() * V.norm());
  const auto values = es.eigenvalues().eval();
  es.compute(A1, false);
  VERIFY_IS_EQUAL(es.info(), Success);
  VERIFY_IS_EQUAL(A1, A1c);
  VERIFY((es.eigenvalues() - values).norm() <= tolerance * A1.norm());
}

template <typename MatrixType, template <typename> class QZType>
void inplace_qz(Index size) {
  MatrixType A = MatrixType::Random(size, size), B = MatrixType::Random(size, size), A0 = A, Bin = B;
  QZType<Ref<MatrixType>> qz(A, B);
  VERIFY(internal::is_same_dense(qz.matrixS(), A));
  VERIFY(internal::is_same_dense(qz.matrixT(), B));
  verify_inplace_qz(A0, Bin, qz);

  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization): Snapshots verify compute() preserves both inputs.
  MatrixType A1 = MatrixType::Random(size, size), B1 = MatrixType::Random(size, size), A1c = A1, B1c = B1;
  qz.compute(A1, B1);
  VERIFY_IS_EQUAL(A1, A1c);
  VERIFY_IS_EQUAL(B1, B1c);
  VERIFY(internal::is_same_dense(qz.matrixS(), A));
  VERIFY(internal::is_same_dense(qz.matrixT(), B));
  verify_inplace_qz(A1, B1, qz);
  const MatrixType S = qz.matrixS(), T = qz.matrixT();
  qz.compute(A1, B1, false);
  VERIFY_IS_EQUAL(qz.info(), Success);
  VERIFY_IS_EQUAL(A1, A1c);
  VERIFY_IS_EQUAL(B1, B1c);
  using RealScalar = typename MatrixType::RealScalar;
  const RealScalar tolerance = RealScalar(128 * size) * NumTraits<RealScalar>::epsilon();
  VERIFY((qz.matrixS() - S).norm() <= tolerance * A1.norm());
  VERIFY((qz.matrixT() - T).norm() <= tolerance * B1.norm());
}

template <typename MatrixType>
void inplace_generalized_eigensolver(Index size) {
  using RealScalar = typename MatrixType::RealScalar;
  using ComplexScalar = std::complex<RealScalar>;
  using EigenvectorsType = typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType;
  MatrixType A = MatrixType::Random(size, size), B = MatrixType::Random(size, size), A0 = A, Binput = B;
  GeneralizedEigenSolver<Ref<MatrixType>> ges(A, B);
  VERIFY_IS_EQUAL(ges.info(), Success);
  EigenvectorsType V = ges.eigenvectors();
  const EigenvectorsType lhs =
      A0.template cast<ComplexScalar>() * V * ges.betas().template cast<ComplexScalar>().asDiagonal();
  const EigenvectorsType rhs = Binput.template cast<ComplexScalar>() * V * ges.alphas().asDiagonal();
  const RealScalar tolerance = RealScalar(128 * size) * NumTraits<RealScalar>::epsilon();
  VERIFY((lhs - rhs).norm() <= tolerance * (lhs.norm() + rhs.norm()));
  VERIFY((V.colwise().norm().array() - RealScalar(1)).abs().maxCoeff() <= tolerance);
}

template <typename Scalar, template <typename> class QZType, int Options>
void inplace_qz_inner_stride() {
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic, Options>;
  using StridedRef = Ref<MatrixType, 0, Stride<Dynamic, Dynamic>>;
  for (Index inner : {Index(1), Index(2)}) {
    MatrixType storageA = MatrixType::Random(8, 5), storageB = MatrixType::Random(8, 5);
    const Stride<Dynamic, Dynamic> stride(8, inner);
    Map<MatrixType, 0, Stride<Dynamic, Dynamic>> a(storageA.data(), 4, 4, stride), b(storageB.data(), 4, 4, stride);
    const MatrixType A0 = a, Binput = b;
    const MatrixType savedA = storageA, savedB = storageB;
    StridedRef ar(a), br(b);
    QZType<StridedRef> qz(ar, br);
    VERIFY(internal::is_same_dense(qz.matrixS(), a));
    VERIFY(internal::is_same_dense(qz.matrixT(), b));
    verify_inplace_qz(A0, Binput, qz);
    // The Map's strides determine its footprint in either storage order.
    for (Index offset = 0; offset < storageA.size(); ++offset) {
      const Index outer = offset / stride.outer();
      const Index innerOffset = offset % stride.outer();
      if (outer < 4 && innerOffset % inner == 0 && innerOffset / inner < 4) continue;
      VERIFY_IS_EQUAL(storageA.data()[offset], savedA.data()[offset]);
      VERIFY_IS_EQUAL(storageB.data()[offset], savedB.data()[offset]);
    }
  }
}

struct InplaceLowerOnly {
  double operator()(Index row, Index col) const {
    VERIFY(row >= col);
    return row == col ? 4.0 : 1.0;
  }
};

template <typename = void>
void inplace_plain_lower_triangle() {
  auto input = MatrixXd::NullaryExpr(3, 3, InplaceLowerOnly());
  SelfAdjointEigenSolver<MatrixXd> mutableSolver(input);
  const auto constInput = input;
  SelfAdjointEigenSolver<MatrixXd> constSolver(constInput);
  VERIFY_IS_EQUAL(mutableSolver.info(), Success);
  VERIFY_IS_EQUAL(mutableSolver.eigenvalues(), constSolver.eigenvalues());
}

EIGEN_DECLARE_TEST(inplace_decomposition) {
  CALL_SUBTEST_4((inplace_fullpivlu_subspaces<Matrix<double, Dynamic, Dynamic, ColMajor>>()));
  CALL_SUBTEST_4((inplace_fullpivlu_subspaces<Matrix<double, Dynamic, Dynamic, RowMajor>>()));
  CALL_SUBTEST_4((inplace_fullpivlu_subspaces<Matrix<double, 3, 3, RowMajor | DontAlign>>()));
  CALL_SUBTEST_10((inplace_special_values<MatrixXd>(2)));
  CALL_SUBTEST_10((inplace_special_values<MatrixXd>(1)));
  CALL_SUBTEST_11(inplace_plain_lower_triangle<>());
  CALL_SUBTEST_12((inplace_eigensolver<MatrixXd, EigenSolver>(128)));
  CALL_SUBTEST_12((inplace_eigensolver<MatrixXd, EigenSolver>(129)));
  CALL_SUBTEST_14((inplace_qz_inner_stride<double, RealQZ, ColMajor>()));
  CALL_SUBTEST_14((inplace_qz_inner_stride<double, RealQZ, RowMajor>()));
  CALL_SUBTEST_14((inplace_qz_inner_stride<std::complex<double>, ComplexQZ, ColMajor>()));
  CALL_SUBTEST_14((inplace_qz_inner_stride<std::complex<double>, ComplexQZ, RowMajor>()));
  EIGEN_UNUSED typedef Matrix<double, 4, 3> Matrix43d;
  for (int i = 0; i < g_repeat; i++) {
    EIGEN_UNUSED const Index size = internal::random<Index>(2, EIGEN_TEST_MAX_SIZE / 4);

    CALL_SUBTEST_1((inplace<LLT<Ref<MatrixXd> >, MatrixXd>(true, true)));
    CALL_SUBTEST_1((inplace<LLT<Ref<Matrix4d> >, Matrix4d>(true, true)));

    CALL_SUBTEST_2((inplace<LDLT<Ref<MatrixXd> >, MatrixXd>(true, true)));
    CALL_SUBTEST_2((inplace<LDLT<Ref<Matrix4d> >, Matrix4d>(true, true)));

    CALL_SUBTEST_3((inplace<PartialPivLU<Ref<MatrixXd> >, MatrixXd>(true, false)));
    CALL_SUBTEST_3((inplace<PartialPivLU<Ref<Matrix4d> >, Matrix4d>(true, false)));

    CALL_SUBTEST_4((inplace<FullPivLU<Ref<MatrixXd> >, MatrixXd>(true, false)));
    CALL_SUBTEST_4((inplace<FullPivLU<Ref<Matrix4d> >, Matrix4d>(true, false)));

    CALL_SUBTEST_5((inplace<HouseholderQR<Ref<MatrixXd> >, MatrixXd>(false, false)));
    CALL_SUBTEST_5((inplace<HouseholderQR<Ref<Matrix43d> >, Matrix43d>(false, false)));

    CALL_SUBTEST_6((inplace<ColPivHouseholderQR<Ref<MatrixXd> >, MatrixXd>(false, false)));
    CALL_SUBTEST_6((inplace<ColPivHouseholderQR<Ref<Matrix43d> >, Matrix43d>(false, false)));

    CALL_SUBTEST_7((inplace<FullPivHouseholderQR<Ref<MatrixXd> >, MatrixXd>(false, false)));
    CALL_SUBTEST_7((inplace<FullPivHouseholderQR<Ref<Matrix43d> >, Matrix43d>(false, false)));

    CALL_SUBTEST_8((inplace<CompleteOrthogonalDecomposition<Ref<MatrixXd> >, MatrixXd>(false, false)));
    CALL_SUBTEST_8((inplace<CompleteOrthogonalDecomposition<Ref<Matrix43d> >, Matrix43d>(false, false)));

    CALL_SUBTEST_2((inplace<BunchKaufman<Ref<MatrixXd>>, MatrixXd>(true, true)));
    CALL_SUBTEST_2((inplace<BunchKaufman<Ref<Matrix4d>>, Matrix4d>(true, true)));

    CALL_SUBTEST_9((inplace_reductions<MatrixXd>(size)));
    CALL_SUBTEST_9((inplace_reductions<MatrixXcd>(size)));
    CALL_SUBTEST_9((inplace_reductions<MatrixXd>(1)));
    CALL_SUBTEST_9((inplace_reductions<Matrix4f>(4)));

    CALL_SUBTEST_10((inplace_schur<MatrixXd, RealSchur>(size)));
    CALL_SUBTEST_10((inplace_schur<MatrixXd, RealSchur>(1)));
    CALL_SUBTEST_10((inplace_schur<Matrix4f, RealSchur>(4)));
    CALL_SUBTEST_10((inplace_schur<MatrixXcd, ComplexSchur>(size)));
    CALL_SUBTEST_10((inplace_schur<MatrixXcd, ComplexSchur>(1)));
    CALL_SUBTEST_10((inplace_schur<Matrix4cf, ComplexSchur>(4)));
    CALL_SUBTEST_10((inplace_special_values<MatrixXd>(size)));
    CALL_SUBTEST_10((inplace_special_values<Matrix4f>(4)));

    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<MatrixXd>(size)));
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<MatrixXcd>(size)));
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<MatrixXd>(1)));
    // Fixed sizes whose columns are packet-aligned take the vectorized rotation kernel.
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<Matrix2d>(2)));
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<Matrix3d>(3)));
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<Matrix4f>(4)));
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<Matrix4d>(4)));
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<Matrix<float, Dynamic, Dynamic, RowMajor>>(size)));
    // Large enough for the blocked tridiagonalization, on strided and row-major storage.
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<MatrixXd>(100)));
    CALL_SUBTEST_11((inplace_selfadjoint_eigensolver<Matrix<float, Dynamic, Dynamic, RowMajor>>(100)));

    CALL_SUBTEST_12((inplace_eigensolver<MatrixXd, EigenSolver>(size)));
    CALL_SUBTEST_12((inplace_eigensolver<MatrixXd, EigenSolver>(1)));
    CALL_SUBTEST_12((inplace_eigensolver<Matrix4f, EigenSolver>(4)));
    CALL_SUBTEST_12((inplace_eigensolver<MatrixXcd, ComplexEigenSolver>(size)));
    CALL_SUBTEST_12((inplace_eigensolver<MatrixXcd, ComplexEigenSolver>(1)));
    CALL_SUBTEST_12((inplace_eigensolver<Matrix4cf, ComplexEigenSolver>(4)));

    CALL_SUBTEST_13((inplace_qz<MatrixXd, RealQZ>(size)));
    CALL_SUBTEST_13((inplace_generalized_eigensolver<MatrixXd>(size)));
    CALL_SUBTEST_13((inplace_generalized_eigensolver<Matrix4d>(4)));
    CALL_SUBTEST_13((inplace_qz<MatrixXd, RealQZ>(1)));
    CALL_SUBTEST_13((inplace_qz<Matrix4d, RealQZ>(4)));
    CALL_SUBTEST_13((inplace_qz<MatrixXcd, ComplexQZ>(size)));
    CALL_SUBTEST_13((inplace_qz<MatrixXcd, ComplexQZ>(1)));
  }
}
