// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
// 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

#ifndef SVD_DEFAULT
#error a macro SVD_DEFAULT(MatrixType) must be defined prior to including svd_common.h
#endif

#ifndef SVD_FOR_MIN_NORM
#error a macro SVD_FOR_MIN_NORM(MatrixType) must be defined prior to including svd_common.h
#endif

#ifndef SVD_STATIC_OPTIONS
#error a macro SVD_STATIC_OPTIONS(MatrixType, Options) must be defined prior to including svd_common.h
#endif

#include "svd_fill.h"
#include "solverbase.h"

// Check that the matrix m is properly reconstructed and that the U and V factors are unitary
// The SVD must have already been computed.
template <typename SvdType, typename MatrixType>
void svd_check_full(const MatrixType& m, const SvdType& svd) {
  Index rows = m.rows();
  Index cols = m.cols();

  enum { RowsAtCompileTime = MatrixType::RowsAtCompileTime, ColsAtCompileTime = MatrixType::ColsAtCompileTime };

  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixUType;
  typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime> MatrixVType;

  MatrixType sigma = MatrixType::Zero(rows, cols);
  sigma.diagonal() = svd.singularValues().template cast<Scalar>();
  MatrixUType u = svd.matrixU();
  MatrixVType v = svd.matrixV();
  RealScalar scaling = m.cwiseAbs().maxCoeff();
  if (scaling < (std::numeric_limits<RealScalar>::min)()) {
    VERIFY(sigma.cwiseAbs().maxCoeff() <= (std::numeric_limits<RealScalar>::min)());
  } else {
    VERIFY_IS_APPROX(m / scaling, u * (sigma / scaling) * v.adjoint());
  }
  VERIFY_IS_UNITARY(u);
  VERIFY_IS_UNITARY(v);
}

template <typename MatrixType, typename SvdType>
void svd_least_square(const MatrixType& m, SvdType& svd) {
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  Index rows = m.rows();
  Index cols = m.cols();

  enum { RowsAtCompileTime = MatrixType::RowsAtCompileTime, ColsAtCompileTime = MatrixType::ColsAtCompileTime };

  typedef Matrix<Scalar, RowsAtCompileTime, Dynamic> RhsType;
  typedef Matrix<Scalar, ColsAtCompileTime, Dynamic> SolutionType;

  RhsType rhs = RhsType::Random(rows, internal::random<Index>(1, cols));

  if (std::is_same<RealScalar, double>::value)
    svd.setThreshold(RealScalar(1e-8));
  else if (std::is_same<RealScalar, float>::value)
    svd.setThreshold(RealScalar(2e-4));

  SolutionType x = svd.solve(rhs);

  RealScalar residual = (m * x - rhs).norm();
  RealScalar rhs_norm = rhs.norm();
  if (!test_isMuchSmallerThan(residual, rhs.norm())) {
    // ^^^ If the residual is very small, then we have an exact solution, so we are already good.

    // evaluate normal equation which works also for least-squares solutions
    if (std::is_same<RealScalar, double>::value || svd.rank() == m.diagonal().size()) {
      using std::sqrt;
      // This test is not stable with single precision.
      // This is likely because squaring m significantly affects the precision.
      if (std::is_same<RealScalar, float>::value) ++g_test_level;

      VERIFY_IS_APPROX(m.adjoint() * (m * x), m.adjoint() * rhs);

      if (std::is_same<RealScalar, float>::value) --g_test_level;
    }

    // Check that there is no significantly better solution in the neighborhood of x
    for (Index k = 0; k < x.rows(); ++k) {
      using std::abs;

      SolutionType y(x);
      y.row(k) = (RealScalar(1) + 2 * NumTraits<RealScalar>::epsilon()) * x.row(k);
      RealScalar residual_y = (m * y - rhs).norm();
      VERIFY(test_isMuchSmallerThan(abs(residual_y - residual), rhs_norm) || residual < residual_y);
      if (std::is_same<RealScalar, float>::value) ++g_test_level;
      VERIFY(test_isApprox(residual_y, residual) || residual < residual_y);
      if (std::is_same<RealScalar, float>::value) --g_test_level;

      y.row(k) = (RealScalar(1) - 2 * NumTraits<RealScalar>::epsilon()) * x.row(k);
      residual_y = (m * y - rhs).norm();
      VERIFY(test_isMuchSmallerThan(abs(residual_y - residual), rhs_norm) || residual < residual_y);
      if (std::is_same<RealScalar, float>::value) ++g_test_level;
      VERIFY(test_isApprox(residual_y, residual) || residual < residual_y);
      if (std::is_same<RealScalar, float>::value) --g_test_level;
    }
  }
  svd.setThreshold(Default);
}

// check minimal norm solutions, the input matrix m is only used to recover problem size
template <typename MatrixType, int Options>
void svd_min_norm(const MatrixType& m) {
  typedef typename MatrixType::Scalar Scalar;
  Index cols = m.cols();

  enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime };

  typedef Matrix<Scalar, ColsAtCompileTime, Dynamic> SolutionType;

  // Generate a full-rank m x n problem with m<n. Keep fixed columns from the
  // caller, but do not encode generated row counts into the helper matrix types.
  // Otherwise fixed-column callers instantiate extra fully fixed SVD shapes.
  constexpr int RankAtCompileTime2 = Dynamic;
  constexpr int RowsAtCompileTime3 = Dynamic;
  typedef Matrix<Scalar, RankAtCompileTime2, ColsAtCompileTime> MatrixType2;
  typedef Matrix<Scalar, RankAtCompileTime2, 1> RhsType2;
  typedef Matrix<Scalar, ColsAtCompileTime, RankAtCompileTime2> MatrixType2T;
  Index rank = ColsAtCompileTime == Dynamic ? internal::random<Index>(1, cols) : Index(ColsAtCompileTime / 2 + 1);
  MatrixType2 m2(rank, cols);
  m2.setRandom();
  if (SVD_FOR_MIN_NORM(MatrixType2)(m2).setThreshold(test_precision<Scalar>()).rank() != rank) {
    // Ensure full row rank by making the leading square block diagonally dominant.
    for (Index i = 0; i < rank; ++i) m2(i, i) += Scalar(1);
  }

  RhsType2 rhs2 = RhsType2::Random(rank);
  // use QR to find a reference minimal norm solution
  HouseholderQR<MatrixType2T> qr(m2.adjoint());
  Matrix<Scalar, Dynamic, 1> tmp =
      qr.matrixQR().topLeftCorner(rank, rank).template triangularView<Upper>().adjoint().solve(rhs2);
  tmp.conservativeResize(cols);
  tmp.tail(cols - rank).setZero();
  SolutionType x21 = qr.householderQ() * tmp;
  // now check with SVD
  SVD_STATIC_OPTIONS(MatrixType2, Options) svd2(m2);
  SolutionType x22 = svd2.solve(rhs2);
  VERIFY_IS_APPROX(m2 * x21, rhs2);
  VERIFY_IS_APPROX(m2 * x22, rhs2);
  VERIFY_IS_APPROX(x21, x22);

  // Now check with a rank deficient matrix
  typedef Matrix<Scalar, RowsAtCompileTime3, ColsAtCompileTime> MatrixType3;
  typedef Matrix<Scalar, RowsAtCompileTime3, 1> RhsType3;
  Index rows3 =
      ColsAtCompileTime == Dynamic ? internal::random<Index>(rank + 1, 2 * cols) : Index(ColsAtCompileTime + 1);
  Matrix<Scalar, RowsAtCompileTime3, Dynamic> C = Matrix<Scalar, RowsAtCompileTime3, Dynamic>::Random(rows3, rank);
  MatrixType3 m3 = C * m2;
  RhsType3 rhs3 = C * rhs2;
  SVD_STATIC_OPTIONS(MatrixType3, Options) svd3(m3);
  SolutionType x3 = svd3.solve(rhs3);
  VERIFY_IS_APPROX(m3 * x3, rhs3);
  VERIFY_IS_APPROX(m3 * x21, rhs3);
  VERIFY_IS_APPROX(m2 * x3, rhs2);
  VERIFY_IS_APPROX(x21, x3);
}

template <typename MatrixType, typename SolverType>
void svd_test_solvers(const MatrixType& m, const SolverType& solver) {
  Index rows, cols, cols2;

  rows = m.rows();
  cols = m.cols();

  if (MatrixType::ColsAtCompileTime == Dynamic) {
    cols2 = internal::random<int>(2, EIGEN_TEST_MAX_SIZE);
  } else {
    cols2 = cols;
  }
  typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> CMatrixType;
  check_solverbase<CMatrixType, MatrixType>(m, solver, rows, cols, cols2);
}

template <typename MatrixType, int Options,
          bool HasQrPreconditioner = (Options & internal::QRPreconditionerBits) != NoQRPreconditioner>
struct svd_min_norm_if {
  static void run(const MatrixType& m) { svd_min_norm<MatrixType, Options>(m); }
};

template <typename MatrixType, int Options>
struct svd_min_norm_if<MatrixType, Options, false> {
  static void run(const MatrixType&) {}
};

template <typename MatrixType, int Options, typename SVDType,
          bool ComputesBothUnitaries =
              (Options & (ComputeThinU | ComputeFullU)) != 0 && (Options & (ComputeThinV | ComputeFullV)) != 0>
struct svd_solver_checks_if {
  static void run(const MatrixType&, SVDType&) {}
};

template <typename MatrixType, int Options, typename SVDType>
struct svd_solver_checks_if<MatrixType, Options, SVDType, true> {
  static void run(const MatrixType& m, SVDType& staticSvd) {
    svd_test_solvers(m, staticSvd);
    svd_least_square(m, staticSvd);
    // svd_min_norm generates non-square matrices so it can't be used with NoQRPreconditioner.
    svd_min_norm_if<MatrixType, Options>::run(m);
  }
};

// This function verifies we don't iterate infinitely on nan/inf values,
// and that info() returns InvalidInput.
template <typename MatrixType>
void svd_inf_nan() {
  SVD_STATIC_OPTIONS(MatrixType, ComputeFullU | ComputeFullV) svd;
  typedef typename MatrixType::Scalar Scalar;
  const Scalar some_inf = (std::numeric_limits<Scalar>::infinity)();
  VERIFY((numext::isinf)(some_inf));
  svd.compute(MatrixType::Constant(10, 10, some_inf));
  VERIFY(svd.info() == InvalidInput);

  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
  VERIFY(nan != nan);
  svd.compute(MatrixType::Constant(10, 10, nan));
  VERIFY(svd.info() == InvalidInput);

  MatrixType m = MatrixType::Zero(10, 10);
  m(internal::random<int>(0, 9), internal::random<int>(0, 9)) = some_inf;
  svd.compute(m);
  VERIFY(svd.info() == InvalidInput);

  m = MatrixType::Zero(10, 10);
  m(internal::random<int>(0, 9), internal::random<int>(0, 9)) = nan;
  svd.compute(m);
  VERIFY(svd.info() == InvalidInput);

  // regression test for bug 791
  m.resize(3, 3);
  m << 0, 2 * NumTraits<Scalar>::epsilon(), 0.5, 0, -0.5, 0, nan, 0, 0;
  svd.compute(m);
  VERIFY(svd.info() == InvalidInput);

  Scalar min = (std::numeric_limits<Scalar>::min)();
  m.resize(4, 4);
  m << 1, 0, 0, 0, 0, 3, 1, min, 1, 0, 1, nan, 0, nan, nan, 0;
  svd.compute(m);
  VERIFY(svd.info() == InvalidInput);
}

// Regression test for bug 286: JacobiSVD loops indefinitely with some
// matrices containing denormal numbers.
template <typename>
void svd_underoverflow() {
#if defined __INTEL_COMPILER
// shut up warning #239: floating point underflow
#pragma warning push
#pragma warning disable 239
#endif
  Matrix2d M;
  M << -7.90884e-313, -4.94e-324, 0, 5.60844e-313;
  SVD_STATIC_OPTIONS(Matrix2d, ComputeFullU | ComputeFullV) svd;
  svd.compute(M);
  CALL_SUBTEST(svd_check_full(M, svd));

  // Check all 2x2 matrices made with the following coefficients:
  VectorXd value_set(9);
  value_set << 0, 1, -1, 5.60844e-313, -5.60844e-313, 4.94e-324, -4.94e-324, -4.94e-223, 4.94e-223;
  Array4i id(0, 0, 0, 0);
  int k = 0;
  do {
    M << value_set(id(0)), value_set(id(1)), value_set(id(2)), value_set(id(3));
    svd.compute(M);
    CALL_SUBTEST(svd_check_full(M, svd));

    id(k)++;
    if (id(k) >= value_set.size()) {
      while (k < 3 && id(k) >= value_set.size()) id(++k)++;
      id.head(k).setZero();
      k = 0;
    }

  } while ((id < int(value_set.size())).all());

#if defined __INTEL_COMPILER
#pragma warning pop
#endif

  // Check for overflow:
  Matrix3d M3;
  M3 << 4.4331978442502944e+307, -5.8585363752028680e+307, 6.4527017443412964e+307, 3.7841695601406358e+307,
      2.4331702789740617e+306, -3.5235707140272905e+307, -8.7190887618028355e+307, -7.3453213709232193e+307,
      -2.4367363684472105e+307;

  SVD_STATIC_OPTIONS(Matrix3d, ComputeFullU | ComputeFullV) svd3;
  svd3.compute(M3);  // just check we don't loop indefinitely
  CALL_SUBTEST(svd_check_full(M3, svd3));
}

template <typename>
void svd_preallocate() {
  Vector3f v(3.f, 2.f, 1.f);
  MatrixXf m = v.asDiagonal();

  internal::set_is_malloc_allowed(false);
  VERIFY_RAISES_ASSERT(VectorXf tmp(10);)
  SVD_DEFAULT(MatrixXf) svd;
  internal::set_is_malloc_allowed(true);
  svd.compute(m);
  VERIFY_IS_APPROX(svd.singularValues(), v);
  VERIFY_RAISES_ASSERT(svd.matrixU());
  VERIFY_RAISES_ASSERT(svd.matrixV());

  SVD_STATIC_OPTIONS(MatrixXf, ComputeFullU | ComputeFullV) svd2(3, 3);
  internal::set_is_malloc_allowed(false);
  svd2.compute(m);
  internal::set_is_malloc_allowed(true);
  VERIFY_IS_APPROX(svd2.singularValues(), v);
  VERIFY_IS_APPROX(svd2.matrixU(), Matrix3f::Identity());
  VERIFY_IS_APPROX(svd2.matrixV(), Matrix3f::Identity());
  internal::set_is_malloc_allowed(false);
  svd2.compute(m);
  internal::set_is_malloc_allowed(true);
}

template <typename MatrixType, int QRPreconditioner = 0>
void svd_verify_assert_full_only(const MatrixType& m) {
  enum { RowsAtCompileTime = MatrixType::RowsAtCompileTime };

  typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, 1> RhsType;
  RhsType rhs = RhsType::Zero(m.rows());
  EIGEN_UNUSED_VARIABLE(rhs);  // Only used if asserts are enabled.

  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner) svd0;
  VERIFY_RAISES_ASSERT((svd0.matrixU()));
  VERIFY_RAISES_ASSERT((svd0.singularValues()));
  VERIFY_RAISES_ASSERT((svd0.matrixV()));
  VERIFY_RAISES_ASSERT((svd0.solve(rhs)));
  VERIFY_RAISES_ASSERT((svd0.transpose().solve(rhs)));
  VERIFY_RAISES_ASSERT((svd0.adjoint().solve(rhs)));

  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner) svd1(m);
  VERIFY_RAISES_ASSERT((svd1.matrixU()));
  VERIFY_RAISES_ASSERT((svd1.matrixV()));
  VERIFY_RAISES_ASSERT((svd1.solve(rhs)));

  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeFullU) svdFullU(m);
  VERIFY_RAISES_ASSERT((svdFullU.matrixV()));
  VERIFY_RAISES_ASSERT((svdFullU.solve(rhs)));
  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeFullV) svdFullV(m);
  VERIFY_RAISES_ASSERT((svdFullV.matrixU()));
  VERIFY_RAISES_ASSERT((svdFullV.solve(rhs)));
}

template <typename MatrixType, int QRPreconditioner = 0>
void svd_verify_assert(const MatrixType& m) {
  enum { RowsAtCompileTime = MatrixType::RowsAtCompileTime };
  typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, 1> RhsType;
  RhsType rhs = RhsType::Zero(m.rows());
  EIGEN_UNUSED_VARIABLE(rhs);  // Only used if asserts are enabled.

  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeThinU) svdThinU(m);
  VERIFY_RAISES_ASSERT((svdThinU.matrixV()));
  VERIFY_RAISES_ASSERT((svdThinU.solve(rhs)));
  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeThinV) svdThinV(m);
  VERIFY_RAISES_ASSERT((svdThinV.matrixU()));
  VERIFY_RAISES_ASSERT((svdThinV.solve(rhs)));

  svd_verify_assert_full_only<MatrixType, QRPreconditioner>(m);
}

template <typename MatrixType, int Options>
void svd_compute_checks(const MatrixType& m) {
  typedef SVD_STATIC_OPTIONS(MatrixType, Options) SVDType;

  enum {
    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
    DiagAtCompileTime = internal::min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
    MatrixURowsAtCompileTime = SVDType::MatrixUType::RowsAtCompileTime,
    MatrixUColsAtCompileTime = SVDType::MatrixUType::ColsAtCompileTime,
    MatrixVRowsAtCompileTime = SVDType::MatrixVType::RowsAtCompileTime,
    MatrixVColsAtCompileTime = SVDType::MatrixVType::ColsAtCompileTime
  };

  SVDType staticSvd(m);

  VERIFY(MatrixURowsAtCompileTime == RowsAtCompileTime);
  VERIFY(MatrixVRowsAtCompileTime == ColsAtCompileTime);
  if (Options & ComputeThinU) VERIFY(MatrixUColsAtCompileTime == DiagAtCompileTime);
  if (Options & ComputeFullU) VERIFY(MatrixUColsAtCompileTime == RowsAtCompileTime);
  if (Options & ComputeThinV) VERIFY(MatrixVColsAtCompileTime == DiagAtCompileTime);
  if (Options & ComputeFullV) VERIFY(MatrixVColsAtCompileTime == ColsAtCompileTime);

  if (Options & (ComputeThinU | ComputeFullU))
    VERIFY(staticSvd.computeU());
  else
    VERIFY(!staticSvd.computeU());
  if (Options & (ComputeThinV | ComputeFullV))
    VERIFY(staticSvd.computeV());
  else
    VERIFY(!staticSvd.computeV());

  if (staticSvd.computeU()) VERIFY(staticSvd.matrixU().isUnitary());
  if (staticSvd.computeV()) VERIFY(staticSvd.matrixV().isUnitary());

  svd_solver_checks_if<MatrixType, Options, SVDType>::run(m, staticSvd);
}

template <typename MatrixType, int QRPreconditioner = 0>
void svd_full_option_checks(const MatrixType& m) {
  svd_compute_checks<MatrixType, QRPreconditioner | ComputeFullU>(m);
  svd_compute_checks<MatrixType, QRPreconditioner | ComputeFullV>(m);
  svd_compute_checks<MatrixType, QRPreconditioner | ComputeFullU | ComputeFullV>(m);

  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeFullU | ComputeFullV) fullSvd(m);
  svd_check_full(m, fullSvd);
}

template <typename MatrixType, int QRPreconditioner = 0>
void svd_thin_full_option_checks(const MatrixType& input) {
  MatrixType m(input.rows(), input.cols());
  svd_fill_random(m);

  svd_verify_assert<MatrixType, QRPreconditioner>(m);

  svd_compute_checks<MatrixType, QRPreconditioner>(m);
  svd_compute_checks<MatrixType, QRPreconditioner | ComputeThinU>(m);
  svd_compute_checks<MatrixType, QRPreconditioner | ComputeThinV>(m);
  svd_compute_checks<MatrixType, QRPreconditioner | ComputeThinU | ComputeThinV>(m);

  svd_compute_checks<MatrixType, QRPreconditioner | ComputeThinU | ComputeFullV>(m);
  svd_compute_checks<MatrixType, QRPreconditioner | ComputeFullU | ComputeThinV>(m);

  svd_full_option_checks<MatrixType, QRPreconditioner>(m);
}

template <typename MatrixType, int QRPreconditioner = 0>
void svd_option_checks_full_only(const MatrixType& input) {
  MatrixType m(input.rows(), input.cols());
  svd_fill_random(m);
  svd_verify_assert_full_only<MatrixType, QRPreconditioner>(m);
  svd_full_option_checks<MatrixType, QRPreconditioner>(m);
}

template <typename MatrixType, int QRPreconditioner = 0>
void svd_check_max_size_matrix(int initialRows, int initialCols) {
  enum {
    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
  };

  int rows = MaxRowsAtCompileTime == Dynamic ? initialRows : (std::min)(initialRows, (int)MaxRowsAtCompileTime);
  int cols = MaxColsAtCompileTime == Dynamic ? initialCols : (std::min)(initialCols, (int)MaxColsAtCompileTime);

  MatrixType m(rows, cols);
  svd_fill_random(m);
  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeThinU | ComputeThinV) thinSvd(m);
  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeThinU | ComputeFullV) mixedSvd1(m);
  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeFullU | ComputeThinV) mixedSvd2(m);
  SVD_STATIC_OPTIONS(MatrixType, QRPreconditioner | ComputeFullU | ComputeFullV) fullSvd(m);

  MatrixType n(MaxRowsAtCompileTime, MaxColsAtCompileTime);
  svd_fill_random(n);
  thinSvd.compute(n);
  mixedSvd1.compute(n);
  mixedSvd2.compute(n);
  fullSvd.compute(n);

  MatrixX<typename MatrixType::Scalar> dynamicMatrix(MaxRowsAtCompileTime + 1, MaxColsAtCompileTime + 1);

  VERIFY_RAISES_ASSERT(thinSvd.compute(dynamicMatrix));
  VERIFY_RAISES_ASSERT(mixedSvd1.compute(dynamicMatrix));
  VERIFY_RAISES_ASSERT(mixedSvd2.compute(dynamicMatrix));
  VERIFY_RAISES_ASSERT(fullSvd.compute(dynamicMatrix));
}

template <typename SvdType, typename MatrixType>
void svd_verify_constructor_options_assert(const MatrixType& m) {
  typedef typename MatrixType::Scalar Scalar;
  Index rows = m.rows();

  enum { RowsAtCompileTime = MatrixType::RowsAtCompileTime, ColsAtCompileTime = MatrixType::ColsAtCompileTime };

  typedef Matrix<Scalar, RowsAtCompileTime, 1> RhsType;
  RhsType rhs(rows);
  svd_fill_random(rhs);
  SvdType svd;
  VERIFY_RAISES_ASSERT(svd.matrixU())
  VERIFY_RAISES_ASSERT(svd.singularValues())
  VERIFY_RAISES_ASSERT(svd.matrixV())
  VERIFY_RAISES_ASSERT(svd.solve(rhs))
  VERIFY_RAISES_ASSERT(svd.transpose().solve(rhs))
  VERIFY_RAISES_ASSERT(svd.adjoint().solve(rhs))
}

#undef SVD_DEFAULT
#undef SVD_FOR_MIN_NORM
#undef SVD_STATIC_OPTIONS
