// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2026 Rasmus Munk Larsen <rmlarsen@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 "fp_control.h"
#include "tridiag_test_matrices.h"
#include <cfenv>
#include <limits>
#include <Eigen/Eigenvalues>

template <typename Packet>
EIGEN_DONT_INLINE Packet packet_product_runtime(const Packet& lhs, const Packet& rhs) {
  return internal::pmul(lhs, rhs);
}

// Some SIMD units flush subnormal operands and results to zero regardless of any library-side care
// (ARMv7 NEON is hard-wired FTZ while its scalar VFP unit honors subnormals). Sections that feed
// genuinely subnormal data through vectorized kernels cannot even observe their inputs on such
// hardware, so they are gated on this runtime probe of the packet path. The volatile load prevents
// constant folding, while the EIGEN_DONT_INLINE wrapper prevents Clang from scalarizing the packet
// product and applying scalar IEEE semantics.
template <typename RealScalar>
bool packet_path_flushes_subnormals() {
  typedef typename internal::packet_traits<RealScalar>::type Packet;
  volatile RealScalar vtiny = (std::numeric_limits<RealScalar>::min)();
  const RealScalar tiny = vtiny;
  const RealScalar half_tiny =
      internal::pfirst(packet_product_runtime(internal::pset1<Packet>(tiny), internal::pset1<Packet>(RealScalar(0.5))));
  return numext::is_exactly_zero(half_tiny);
}

// Dense (n x n) symmetric tridiagonal matrix from its diagonal d and sub-diagonal e, for
// residual / reconstruction checks against the solver output.
template <typename DiagType, typename SubType>
Matrix<typename DiagType::Scalar, Dynamic, Dynamic> dense_symmetric_tridiag(const DiagType& d, const SubType& e) {
  typedef typename DiagType::Scalar RealScalar;
  const Index n = d.size();
  Matrix<RealScalar, Dynamic, Dynamic> T = Matrix<RealScalar, Dynamic, Dynamic>::Zero(n, n);
  T.diagonal() = d;
  if (n > 1) {
    T.diagonal(-1) = e;
    T.diagonal(1) = e;
  }
  return T;
}

// Test TridiagonalEigenSolver (SIMD Sturm-sequence spectral bisection) on the full
// structured-tridiagonal catalog: compare against the implicit-QR path of
// SelfAdjointEigenSolver::computeFromTridiagonal(), exercise index/value range subset
// selection, and verify absolute accuracy against matrices with known spectra.
template <typename RealScalar>
void tridiagonal_eigensolver_bisection() {
  typedef Matrix<RealScalar, Dynamic, Dynamic> MatrixType;
  typedef Matrix<RealScalar, Dynamic, 1> VectorType;
  const RealScalar eps = NumTraits<RealScalar>::epsilon();
  const RealScalar tiny = (std::numeric_limits<RealScalar>::min)();

  // (a) Compare bisection against the QR path over every structured matrix, and exercise
  // index- and value-range subset selection.
  test::for_all_symmetric_tridiag_test_matrices<RealScalar>([&](const VectorType& diag, const VectorType& offdiag) {
    const Index n = diag.size();

    SelfAdjointEigenSolver<MatrixType> qr;
    qr.computeFromTridiagonal(diag, offdiag, EigenvaluesOnly);
    if (qr.info() != Success) return;  // skip pathological inputs the QR path itself rejects
    const VectorType w = qr.eigenvalues();

    TridiagonalEigenSolver<RealScalar> bz;
    bz.computeEigenvalues(diag, offdiag);
    VERIFY_IS_EQUAL(bz.info(), Success);
    VERIFY_IS_EQUAL(bz.eigenvalues().size(), n);
    for (Index i = 1; i < n; ++i) VERIFY(bz.eigenvalues()(i) >= bz.eigenvalues()(i - 1));

    // Bisection has an absolute accuracy floor of ~pivmin (the smallest safe pivot),
    // so the tolerance carries an absolute term in addition to the eps*||T|| term.
    const RealScalar radius = w.cwiseAbs().maxCoeff();
    const RealScalar tol = RealScalar(64) * RealScalar(n) * (eps * radius + tiny);
    VERIFY((bz.eigenvalues() - w).cwiseAbs().maxCoeff() <= tol);

    // Index-range subsets: the k smallest and the k largest.
    if (n >= 4) {
      const Index k = n / 3;
      TridiagonalEigenSolver<RealScalar> lo, hi;
      lo.computeEigenvalues(diag, offdiag, EigenvalueRange::indices(0, k));
      VERIFY_IS_EQUAL(lo.eigenvalues().size(), k);
      VERIFY((lo.eigenvalues() - w.head(k)).cwiseAbs().maxCoeff() <= tol);
      hi.computeEigenvalues(diag, offdiag, EigenvalueRange::indices(n - k, n));
      VERIFY_IS_EQUAL(hi.eigenvalues().size(), k);
      VERIFY((hi.eigenvalues() - w.tail(k)).cwiseAbs().maxCoeff() <= tol);
    }

    // Value-range subset [vl, vu) about the spectrum center. The count is compared strictly
    // only when no eigenvalue sits within tol of a boundary (otherwise it is legitimately
    // ambiguous which side the boundary eigenvalue falls on).
    if (n >= 2 && radius > tiny) {
      const RealScalar vl = -RealScalar(0.3) * radius, vu = RealScalar(0.3) * radius;
      TridiagonalEigenSolver<RealScalar> bv;
      bv.computeEigenvalues(diag, offdiag,
                            EigenvalueRange::values(static_cast<long double>(vl), static_cast<long double>(vu)));
      for (Index i = 0; i < bv.eigenvalues().size(); ++i)
        VERIFY(bv.eigenvalues()(i) >= vl - tol && bv.eigenvalues()(i) < vu + tol);
      const bool clean = (w.array() - vl).abs().minCoeff() > tol && (w.array() - vu).abs().minCoeff() > tol;
      if (clean) {
        const Index expected = (w.array() >= vl && w.array() < vu).count();
        VERIFY_IS_EQUAL(bv.eigenvalues().size(), expected);
        if (expected > 0) {
          Index first = 0;
          while (first < n && w(first) < vl) ++first;
          VERIFY((bv.eigenvalues() - w.segment(first, expected)).cwiseAbs().maxCoeff() <= tol);
        }
      }
    }
  });

  // (a2) Half-open value-range convention, fixed-size inputs, and input validation.
  {
    // values(vl, vu) selects the eigenvalues in the lower-closed, upper-open interval [vl, vu) (like
    // indices()): an eigenvalue exactly equal to vl is included, one exactly equal to vu is not. Use a
    // diagonal matrix (zero off-diagonal) with the exact integer spectrum {1, 2, 3} so the endpoints
    // land precisely on eigenvalues.
    VectorType d(3), e(2);
    d << RealScalar(1), RealScalar(2), RealScalar(3);
    e.setZero();
    TridiagonalEigenSolver<RealScalar> bmid;
    bmid.computeEigenvalues(d, e, EigenvalueRange::values(1.0L, 3.0L));
    VERIFY_IS_EQUAL(bmid.eigenvalues().size(), Index(2));  // [1, 3) = {1, 2}: lower end closed, upper end open
    VERIFY_IS_APPROX(bmid.eigenvalues()(0), RealScalar(1));
    VERIFY_IS_APPROX(bmid.eigenvalues()(1), RealScalar(2));
    TridiagonalEigenSolver<RealScalar> bopen;
    bopen.computeEigenvalues(d, e, EigenvalueRange::values(0.0L, 1.0L));
    VERIFY_IS_EQUAL(bopen.eigenvalues().size(), Index(0));  // [0, 1) excludes the eigenvalue at the open end 1
    TridiagonalEigenSolver<RealScalar> blow;
    blow.computeEigenvalues(d, e, EigenvalueRange::values(1.0L, 2.0L));
    VERIFY_IS_EQUAL(blow.eigenvalues().size(), Index(1));  // [1, 2) = {1}: includes the eigenvalue at the closed end 1
    VERIFY_IS_APPROX(blow.eigenvalues()(0), RealScalar(1));

    // The half-open endpoint semantics must survive rounding in the Sturm recurrence, not just the
    // exact-count diagonal case above: [[-3, 2], [2, -3]] has spectrum {-5, -1} exactly, but the
    // recurrence rounds through 2/3-type values, so counts taken exactly at an endpoint eigenvalue
    // are a coin flip (float used to drop -5 entirely, double used to keep -1). The endpoint
    // resolution against the converged eigenvalues must return exactly {-5}.
    VectorType dcross(2), ecross(1);
    dcross << RealScalar(-3), RealScalar(-3);
    ecross << RealScalar(2);
    TridiagonalEigenSolver<RealScalar> bcross;
    bcross.computeEigenvalues(dcross, ecross, EigenvalueRange::values(-5.0L, -1.0L));
    VERIFY_IS_EQUAL(bcross.eigenvalues().size(), Index(1));
    VERIFY_IS_APPROX(bcross.eigenvalues()(0), RealScalar(-5));

    // Infinite endpoints mean unbounded on that side; the endpoint-tolerance arithmetic must not
    // poison the result (inf - inf = NaN used to return an empty spectrum). A finite long double
    // endpoint that narrows to infinity in RealScalar (1e300 for float) behaves the same way.
    TridiagonalEigenSolver<RealScalar> binf;
    binf.computeEigenvalues(d, e,
                            EigenvalueRange::values(-std::numeric_limits<long double>::infinity(),
                                                    std::numeric_limits<long double>::infinity()));
    VERIFY_IS_EQUAL(binf.eigenvalues().size(), Index(3));
    binf.computeEigenvalues(d, e, EigenvalueRange::values(1.5L, std::numeric_limits<long double>::infinity()));
    VERIFY_IS_EQUAL(binf.eigenvalues().size(), Index(2));
    VERIFY_IS_APPROX(binf.eigenvalues()(0), RealScalar(2));
    binf.computeEigenvalues(d, e, EigenvalueRange::values(1.5L, 1e300L));
    VERIFY_IS_EQUAL(binf.eigenvalues().size(), Index(2));

    // Fixed-size input vectors work, including subset selection (the solver's own storage is
    // dynamic, so a subset shorter than the input is not a problem).
    Matrix<RealScalar, 3, 1> fd;
    fd << RealScalar(1), RealScalar(2), RealScalar(3);
    Matrix<RealScalar, 2, 1> fe;
    fe.setZero();
    TridiagonalEigenSolver<RealScalar> fz;
    fz.computeEigenvalues(fd, fe);
    VERIFY_IS_EQUAL(fz.eigenvalues().size(), Index(3));
    fz.computeEigenvalues(fd, fe, EigenvalueRange::indices(0, 1));
    VERIFY_IS_EQUAL(fz.eigenvalues().size(), Index(1));
    VERIFY_IS_APPROX(fz.eigenvalues()(0), RealScalar(1));

    // Querying an uninitialized solver is a usage error.
    TridiagonalEigenSolver<RealScalar> uninit;
    VERIFY_RAISES_ASSERT(uninit.eigenvalues());
    VERIFY_RAISES_ASSERT(uninit.info());

    // A non-finite input (NaN or Inf, diagonal or sub-diagonal) is rejected up front and
    // reported via info().
    VectorType dbad = d;
    dbad(1) = std::numeric_limits<RealScalar>::quiet_NaN();
    TridiagonalEigenSolver<RealScalar> bnan;
    bnan.computeEigenvalues(dbad, e);
    VERIFY_IS_EQUAL(bnan.info(), NoConvergence);
    dbad(1) = std::numeric_limits<RealScalar>::infinity();
    bnan.computeEigenvalues(dbad, e);
    VERIFY_IS_EQUAL(bnan.info(), NoConvergence);
    VectorType ebad = e;
    ebad(0) = std::numeric_limits<RealScalar>::quiet_NaN();
    bnan.computeEigenvalues(d, ebad);
    VERIFY_IS_EQUAL(bnan.info(), NoConvergence);
  }

  // (b) Absolute-accuracy checks against matrices with known spectra (independent of QR).
  // A subnormal-magnitude matrix exercises the normalization: dividing entries by the (subnormal) max
  // magnitude keeps the scaled matrix O(1), whereas multiplying by 1/scale would overflow to infinity
  // and return wrong eigenvalues. Compare against the same matrix in a normal range, scaled back down.
  // Skipped on flush-to-zero packet hardware, where the subnormal inputs read as zero (see the probe).
  if (!packet_path_flushes_subnormals<RealScalar>()) {
    const Index nn = 7;
    VectorType bd(nn), be(nn - 1);
    test::tridiag_1_2_1(bd, be);
    const RealScalar sub_scale = (std::numeric_limits<RealScalar>::min)() / RealScalar(64);  // subnormal
    TridiagonalEigenSolver<RealScalar> bref, bsub;
    bref.computeEigenvalues(bd, be);
    bsub.computeEigenvalues(VectorType(bd * sub_scale), VectorType(be * sub_scale));
    VERIFY_IS_EQUAL(bsub.info(), Success);
    // The subnormal eigenvalues, scaled back to O(1), agree with the reference to the subnormal
    // granularity at this magnitude (denorm_min / sub_scale) plus the usual bisection error.
    const RealScalar radius = bref.eigenvalues().cwiseAbs().maxCoeff();
    const RealScalar gran = (std::numeric_limits<RealScalar>::denorm_min)() / sub_scale;
    VERIFY((bsub.eigenvalues() / sub_scale - bref.eigenvalues()).cwiseAbs().maxCoeff() <=
           RealScalar(16) * (RealScalar(nn) * eps + gran) * radius);
  }
  const double pi = 3.14159265358979323846;
  for (Index n : {7, 16, 33, 64}) {
    VectorType d(n), e(n - 1), wexact(n);

    // 1-2-1 Toeplitz: lambda_k = 2 - 2 cos(k*pi/(n+1)), ascending for k = 1..n.
    test::tridiag_1_2_1(d, e);
    TridiagonalEigenSolver<RealScalar> b121;
    b121.computeEigenvalues(d, e);
    for (Index k = 0; k < n; ++k) wexact(k) = RealScalar(2.0 - 2.0 * std::cos(double(k + 1) * pi / double(n + 1)));
    VERIFY((b121.eigenvalues() - wexact).cwiseAbs().maxCoeff() <= RealScalar(64) * RealScalar(n) * eps * RealScalar(4));

    // Clement / Kac: integer spectrum -(n-1), -(n-3), ..., (n-1).
    test::tridiag_clement(d, e);
    TridiagonalEigenSolver<RealScalar> bcl;
    bcl.computeEigenvalues(d, e);
    for (Index k = 0; k < n; ++k) wexact(k) = RealScalar(-(n - 1) + 2 * k);
    VERIFY((bcl.eigenvalues() - wexact).cwiseAbs().maxCoeff() <= RealScalar(64) * RealScalar(n) * eps * RealScalar(n));

    // Spectra exactly symmetric about 0: signed Wilkinson, Hermite, Legendre, [1,0,1] Toeplitz.
    auto check_symmetric = [&](const VectorType& dd, const VectorType& ee) {
      TridiagonalEigenSolver<RealScalar> bs;
      bs.computeEigenvalues(dd, ee);
      const VectorType s = bs.eigenvalues();
      const RealScalar rad = s.cwiseAbs().maxCoeff();
      const RealScalar tol = RealScalar(64) * RealScalar(n) * (eps * rad + tiny);
      for (Index i = 0; i < n; ++i) VERIFY(numext::abs(s(i) + s(n - 1 - i)) <= tol);
    };
    test::tridiag_wilkinson_signed(d, e);
    check_symmetric(d, e);
    test::tridiag_hermite(d, e);
    check_symmetric(d, e);
    test::tridiag_legendre(d, e);
    check_symmetric(d, e);
    test::tridiag_toeplitz(d, e);  // default a = 1, b = 0
    check_symmetric(d, e);
  }
}

// Test the inverse-iteration eigenvector stage (LAPACK xSTEIN analog): staged
// (computeEigenvalues() followed by computeEigenvectors()), one-call compute(), and the direct
// computeEigenvectors(diag, subdiag, eigenvalues) API.
template <typename RealScalar>
void tridiagonal_eigensolver_eigenvectors() {
  typedef Matrix<RealScalar, Dynamic, Dynamic> MatrixType;
  typedef Matrix<RealScalar, Dynamic, 1> VectorType;
  const RealScalar eps = NumTraits<RealScalar>::epsilon();
  const RealScalar tiny = (std::numeric_limits<RealScalar>::min)();
  const double pi = 3.14159265358979323846;

  // (a) Eigenvectors over the structured catalog: staged and direct APIs.
  test::for_all_symmetric_tridiag_test_matrices<RealScalar>([&](const VectorType& diag, const VectorType& offdiag) {
    const Index n = diag.size();

    // Dense form of T for residual / reconstruction checks.
    const MatrixType T = dense_symmetric_tridiag(diag, offdiag);
    RealScalar scale = T.cwiseAbs().maxCoeff();
    if (!(numext::isfinite)(scale)) return;  // skip non-finite inputs, like the eigenvalue path
    if (numext::is_exactly_zero(scale)) scale = RealScalar(1);

    TridiagonalEigenSolver<RealScalar> es;
    es.computeEigenvalues(diag, offdiag);
    if (es.info() != Success) return;
    es.computeEigenvectors();  // staged inverse-iteration pass
    VERIFY_IS_EQUAL(es.info(), Success);
    const VectorType w = es.eigenvalues();
    const MatrixType V = es.eigenvectors();
    VERIFY_IS_EQUAL(V.rows(), n);
    VERIFY_IS_EQUAL(V.cols(), n);

    const RealScalar tol = RealScalar(128) * RealScalar(n) * (eps * scale + tiny);
    const RealScalar otol = RealScalar(128) * RealScalar(n) * eps;
    // Per-column residual; stableNorm() since the catalog includes near-overflow entries.
    for (Index i = 0; i < n; ++i) VERIFY((T * V.col(i) - w(i) * V.col(i)).stableNorm() <= tol);
    // Orthonormality and full-spectrum reconstruction (the latter in scaled coordinates so the
    // extreme-magnitude catalog entries cannot overflow the products).
    VERIFY((V.transpose() * V - MatrixType::Identity(n, n)).cwiseAbs().maxCoeff() <= otol);
    const RealScalar recon =
        ((V * (w / scale).asDiagonal() * V.transpose()) - (T / scale)).cwiseAbs().maxCoeff() * scale;
    VERIFY(recon <= tol);

    // The one-call compute() reproduces the staged result exactly.
    TridiagonalEigenSolver<RealScalar> onecall;
    onecall.compute(diag, offdiag);
    VERIFY_IS_EQUAL(onecall.info(), Success);
    VERIFY_IS_EQUAL((onecall.eigenvalues() - w).cwiseAbs().maxCoeff(), RealScalar(0));
    VERIFY_IS_EQUAL((onecall.eigenvectors() - V).cwiseAbs().maxCoeff(), RealScalar(0));

    // The direct API on the same eigenvalues reproduces the staged result exactly, unless T splits into
    // disconnected blocks (xSTEBZ's criterion, here with a 2x margin): the staged pass knows its eigenvalues
    // are only good to the bisection tolerance and may re-bisect a small block, while supplied eigenvalues
    // are taken as exact.
    TridiagonalEigenSolver<RealScalar> dir;
    dir.computeEigenvectors(diag, offdiag, w);
    VERIFY_IS_EQUAL(dir.eigenvectors().rows(), n);
    VERIFY_IS_EQUAL(dir.eigenvectors().cols(), n);
    const bool may_split =
        n > 1 && (offdiag.array().abs() <=
                  RealScalar(2) * eps * (diag.head(n - 1).array().abs().sqrt() * diag.tail(n - 1).array().abs().sqrt()))
                     .any();
    if (!may_split) VERIFY_IS_EQUAL((dir.eigenvectors() - V).cwiseAbs().maxCoeff(), RealScalar(0));
    VERIFY_IS_EQUAL(dir.info(), Success);
    VERIFY_IS_EQUAL(dir.eigenvalues(), w);
    const MatrixType& supplied_vectors = dir.eigenvectors();
    for (Index i = 0; i < n; ++i)
      VERIFY((T * supplied_vectors.col(i) - w(i) * supplied_vectors.col(i)).stableNorm() <= tol);
    VERIFY((supplied_vectors.transpose() * supplied_vectors - MatrixType::Identity(n, n)).cwiseAbs().maxCoeff() <=
           otol);

    // Index-subset eigenvectors: the bisection range selects a band, inverse iteration produces just
    // those columns; check residual and that they are orthonormal among themselves.
    if (n >= 4) {
      const Index il = n / 4, iu = n - n / 4;
      TridiagonalEigenSolver<RealScalar> sub;
      sub.compute(diag, offdiag, ComputeEigenvectors, EigenvalueRange::indices(il, iu));
      const MatrixType Vs = sub.eigenvectors();
      const VectorType ws = sub.eigenvalues();
      VERIFY_IS_EQUAL(Vs.rows(), n);
      VERIFY_IS_EQUAL(Vs.cols(), iu - il);
      for (Index k = 0; k < iu - il; ++k) VERIFY((T * Vs.col(k) - ws(k) * Vs.col(k)).stableNorm() <= tol);
      VERIFY((Vs.transpose() * Vs - MatrixType::Identity(iu - il, iu - il)).cwiseAbs().maxCoeff() <= otol);
    }
  });

  // (b) Closed-form 1-2-1 Toeplitz eigenvectors: v_k(j) = sin(j*(n-k)*pi/(n+1)) for the k-th
  // (ascending) eigenvalue. An analytic, solver-independent check of the inverse-iteration vectors.
  for (Index n : {5, 16, 33, 64}) {
    VectorType d(n), e(n - 1);
    test::tridiag_1_2_1(d, e);
    TridiagonalEigenSolver<RealScalar> es(d, e);
    const MatrixType V = es.eigenvectors();
    for (Index k = 0; k < n; ++k) {
      VectorType exact(n);
      for (Index j = 0; j < n; ++j) exact(j) = RealScalar(std::sin(double(j + 1) * double(n - k) * pi / double(n + 1)));
      exact.normalize();
      const RealScalar err = (std::min)((V.col(k) - exact).norm(), (V.col(k) + exact).norm());
      VERIFY(err <= RealScalar(256) * RealScalar(n) * eps);
    }
  }

  // (c) Edge cases: fixed-size inputs, eigenvalues-only requests, subnormal-magnitude matrices,
  // and convergence reporting.
  {
    // Fixed-size input vectors work for the full eigendecomposition and for subsets (the solver's
    // own storage is dynamic).
    Matrix<RealScalar, 4, 1> fdiag = Matrix<RealScalar, 4, 1>::Random();
    Matrix<RealScalar, 3, 1> fsub = Matrix<RealScalar, 3, 1>::Random();
    TridiagonalEigenSolver<RealScalar> fz;
    fz.compute(fdiag, fsub);
    VERIFY_IS_EQUAL(fz.info(), Success);
    VERIFY_IS_EQUAL(fz.eigenvectors().cols(), Index(4));
    {
      const MatrixType Tf = dense_symmetric_tridiag(fdiag, fsub);
      const MatrixType Vf = fz.eigenvectors();
      VERIFY((Vf.transpose() * Vf - MatrixType::Identity(4, 4)).cwiseAbs().maxCoeff() <= RealScalar(64) * eps);
      VERIFY((Tf * Vf - Vf * fz.eigenvalues().asDiagonal()).cwiseAbs().maxCoeff() <=
             RealScalar(64) * eps * Tf.cwiseAbs().maxCoeff());
    }

    // An EigenvaluesOnly compute() does not produce eigenvectors; querying them is a usage error,
    // and the staged computeEigenvectors() supplies them afterwards.
    TridiagonalEigenSolver<RealScalar> staged;
    staged.compute(fdiag, fsub, EigenvaluesOnly);
    VERIFY_IS_EQUAL(staged.info(), Success);
    VERIFY_RAISES_ASSERT(staged.eigenvectors());
    staged.computeEigenvectors();
    VERIFY_IS_EQUAL(staged.info(), Success);
    VERIFY_IS_EQUAL((staged.eigenvectors() - fz.eigenvectors()).cwiseAbs().maxCoeff(), RealScalar(0));

    // A matrix whose entries are all subnormal must still yield genuine unit-norm, orthonormal
    // eigenvectors rather than all-zero columns. Normalization must avoid forming 1/scale when
    // that reciprocal overflows; subnormal blocks require two finite scaling steps. The eigenvalues are
    // taken from the same matrix in a normal magnitude range (then scaled back down), so this exercises
    // the eigenvector normalization in isolation from the eigenvalue solver.
    // Skipped on flush-to-zero packet hardware, where the subnormal inputs read as zero (see the probe).
    if (!packet_path_flushes_subnormals<RealScalar>()) {
      const Index n = 6;
      VectorType base_d(n), base_e(n - 1);
      test::tridiag_1_2_1(base_d, base_e);
      // sub_scale is subnormal and small enough that 1/sub_scale overflows to infinity.
      const RealScalar sub_scale = (std::numeric_limits<RealScalar>::min)() / RealScalar(64);
      const VectorType d = base_d * sub_scale, e = base_e * sub_scale;

      TridiagonalEigenSolver<RealScalar> ref;
      ref.computeEigenvalues(base_d, base_e);
      const VectorType w_sub = ref.eigenvalues() * sub_scale;

      TridiagonalEigenSolver<RealScalar> se;
      se.computeEigenvectors(d, e, w_sub);
      VERIFY_IS_EQUAL(se.info(), Success);
      const MatrixType V = se.eigenvectors();
      for (Index i = 0; i < n; ++i)
        VERIFY(numext::abs(V.col(i).norm() - RealScalar(1)) <= RealScalar(64) * eps);  // unit norm, not all-zero
      VERIFY((V.transpose() * V - MatrixType::Identity(n, n)).cwiseAbs().maxCoeff() <=
             RealScalar(64) * RealScalar(n) * eps);
      // Residual in normal-range coordinates (the eigenvectors are invariant under the uniform scale).
      const MatrixType Tn = dense_symmetric_tridiag(base_d, base_e);
      for (Index i = 0; i < n; ++i)
        VERIFY((Tn * V.col(i) - ref.eigenvalues()(i) * V.col(i)).norm() <= RealScalar(256) * RealScalar(n) * eps);
    }

    // Numerically disconnected blocks at wildly different scales: each 1x1 block's eigenvector is
    // the corresponding unit vector, exactly (components outside the owning block are exact zeros).
    // Processing the blocks with one global perturbation floor (eps * ||T||) would swamp the pivots
    // of the small blocks and return arbitrary mixtures of the first four vectors instead.
    {
      VectorType d(5), e = VectorType::Zero(4);
      d << RealScalar(1), RealScalar(2), RealScalar(3), RealScalar(4), RealScalar(1e16);
      TridiagonalEigenSolver<RealScalar> blocks;
      blocks.computeEigenvectors(d, e, d);  // the diagonal is the exact (ascending) spectrum
      VERIFY_IS_EQUAL(blocks.info(), Success);
      VERIFY_IS_EQUAL((blocks.eigenvectors() - MatrixType::Identity(5, 5)).cwiseAbs().maxCoeff(), RealScalar(0));

      // Any single requested eigenvalue must select its own block. The localization windows are
      // expressed at each block's own scale; a window at the global scale (~ eps * 1e16 here) spans
      // all four small blocks at once and used to hand w = (3) to the first block.
      for (Index j = 0; j < 5; ++j) {
        VectorType wone(1);
        wone << d(j);
        TridiagonalEigenSolver<RealScalar> one;
        one.computeEigenvectors(d, e, wone);
        VERIFY_IS_EQUAL(one.info(), Success);
        VERIFY_IS_EQUAL((one.eigenvectors().col(0) - MatrixType::Identity(5, 5).col(j)).cwiseAbs().maxCoeff(),
                        RealScalar(0));
      }
    }

    // Small-block shifts need local accuracy even above the old global clustering cutoff.
    for (RealScalar c : {RealScalar(0.125), RealScalar(2), RealScalar(3.9), RealScalar(4), RealScalar(4.1),
                         RealScalar(5), RealScalar(10), RealScalar(100), RealScalar(1000)}) {
      VectorType d(3), e(2);
      d << RealScalar(1), RealScalar(0), RealScalar(0);
      e << RealScalar(0), c * eps;
      for (const auto& range : {EigenvalueRange::all(), EigenvalueRange::indices(0, 2), EigenvalueRange::indices(1, 2),
                                EigenvalueRange::values(-0.5, 0.5)}) {
        TridiagonalEigenSolver<RealScalar> blocks;
        blocks.computeEigenvalues(d, e, range);
        const VectorType values = blocks.eigenvalues();
        blocks.computeEigenvectors();
        VERIFY_IS_EQUAL(blocks.info(), Success);
        VERIFY_IS_EQUAL(blocks.eigenvalues(), values);
        const MatrixType V = blocks.eigenvectors();
        VERIFY(V.allFinite());
        VERIFY((V.transpose() * V - MatrixType::Identity(V.cols(), V.cols())).cwiseAbs().maxCoeff() <=
               RealScalar(32) * eps);
        VERIFY((dense_symmetric_tridiag(d, e) * V - V * values.asDiagonal()).cwiseAbs().maxCoeff() <=
               RealScalar(32) * eps);
        // Independent local eigenvectors are (1,+/-1)/sqrt(2), irrespective of global shift error.
        for (Index j = 0; j < V.cols(); ++j) {
          if (numext::abs(values(j)) < RealScalar(0.5))
            VERIFY(numext::abs(numext::abs(V(1, j)) - numext::abs(V(2, j))) <= RealScalar(32) * eps);
        }
      }
    }

    // Accurate supplied shifts must not inherit the unrelated block's scale, even after solver reuse.
    {
      const Index nb = 16;
      VectorType d = VectorType::Constant(nb + 1, RealScalar(2));
      VectorType e = VectorType::Ones(nb), w(nb);
      d(0) = numext::ldexp(RealScalar(1), 60);
      e(0) = RealScalar(0);
      for (Index k = 0; k < nb; ++k) {
        const RealScalar angle = RealScalar(EIGEN_PI) * RealScalar(k + 1) / RealScalar(2 * (nb + 1));
        w(k) = RealScalar(4) * numext::abs2(numext::sin(angle));
      }
      TridiagonalEigenSolver<RealScalar> supplied, local;
      supplied.computeEigenvalues(d, e);
      supplied.computeEigenvectors(d, e, w);
      local.computeEigenvectors(d.tail(nb).eval(), e.tail(nb - 1).eval(), w);
      VERIFY_IS_EQUAL(supplied.info(), Success);
      VERIFY_IS_EQUAL(local.info(), Success);
      VERIFY_IS_EQUAL(supplied.eigenvalues(), w);
      VERIFY_IS_EQUAL(supplied.eigenvectors().bottomRows(nb), local.eigenvectors());
      VERIFY_IS_EQUAL(supplied.eigenvectors().row(0).squaredNorm(), RealScalar(0));
    }

    // A zero block's normalization placeholder must not change clustering under power-of-two scaling.
    {
      VectorType d(4), e(3), w(4);
      d << RealScalar(0), RealScalar(2), RealScalar(2), RealScalar(2);
      e << RealScalar(0), RealScalar(1), RealScalar(1);
      const RealScalar root2 = numext::sqrt(RealScalar(2));
      w << RealScalar(0), RealScalar(2) - root2, RealScalar(2), RealScalar(2) + root2;
      TridiagonalEigenSolver<RealScalar> reference, scaled;
      reference.computeEigenvectors(d, e, w);
      const RealScalar scale = numext::ldexp(RealScalar(1), -60);
      scaled.computeEigenvectors((d * scale).eval(), (e * scale).eval(), (w * scale).eval());
      VERIFY_IS_EQUAL(reference.info(), Success);
      VERIFY_IS_EQUAL(scaled.info(), Success);
      VERIFY_IS_EQUAL((scaled.eigenvectors() - reference.eigenvectors()).cwiseAbs().maxCoeff(), RealScalar(0));
    }

    // A huge disconnected block must not force splitting of a strongly connected small block: a
    // splitting safety floor expressed at the global scale used to break the trailing 2x2 into
    // singletons, returning coordinate vectors with O(1) local residual.
    {
      const RealScalar big = (std::numeric_limits<RealScalar>::max)() / RealScalar(1e10);
      VectorType d(3), e(2), w(3);
      d << big, RealScalar(1), RealScalar(2);
      e << RealScalar(0), RealScalar(0.5);
      // Exact spectrum: big and (3 -+ sqrt(2))/2 from the trailing 2x2 block.
      w << RealScalar((3.0 - std::sqrt(2.0)) / 2.0), RealScalar((3.0 + std::sqrt(2.0)) / 2.0), big;
      TridiagonalEigenSolver<RealScalar> conn;
      conn.computeEigenvectors(d, e, w);
      VERIFY_IS_EQUAL(conn.info(), Success);
      const MatrixType Vc = conn.eigenvectors();
      const MatrixType Tc = dense_symmetric_tridiag(d, e);
      for (Index j = 0; j < 3; ++j)
        VERIFY((Tc * Vc.col(j) - w(j) * Vc.col(j)).stableNorm() <=
               RealScalar(64) * eps * numext::maxi(RealScalar(1), numext::abs(w(j))));
      // The small-block vectors have no support on the big block, exactly.
      VERIFY_IS_EQUAL(numext::abs(Vc(0, 0)), RealScalar(0));
      VERIFY_IS_EQUAL(numext::abs(Vc(0, 1)), RealScalar(0));
      VERIFY(numext::abs(Vc.col(0).dot(Vc.col(1))) <= RealScalar(8) * eps);
    }

    // Non-finite input to the direct eigenvector path is rejected up front and reported via info(),
    // mirroring computeEigenvalues(): NaN data or shifts must not produce NaN vectors with Success.
    {
      VectorType d = VectorType::Ones(3), e = VectorType::Zero(2), w = VectorType::Ones(3);
      TridiagonalEigenSolver<RealScalar> bad;
      VectorType dnan = d;
      dnan(1) = std::numeric_limits<RealScalar>::quiet_NaN();
      bad.computeEigenvectors(dnan, e, w);
      VERIFY_IS_EQUAL(bad.info(), NoConvergence);
      VectorType wnan = w;
      wnan(2) = std::numeric_limits<RealScalar>::quiet_NaN();
      bad.computeEigenvectors(d, e, wnan);
      VERIFY_IS_EQUAL(bad.info(), NoConvergence);
    }

    // Convergence is reported through info() rather than hard-coded to Success: inverse iteration
    // counts the eigenvectors that fail to converge within its step limit (cf. LAPACK xSTEIN), and a
    // well-conditioned spectrum converges fully, so that count is zero and info() is Success.
    {
      const Index n = 32;
      VectorType d = VectorType::Random(n), e = VectorType::Random(n - 1);
      TridiagonalEigenSolver<RealScalar> es2(d, e);
      VERIFY_IS_EQUAL(es2.info(), Success);
    }
  }
}

// Scalar types narrower than float (half, bfloat16) are computed internally in float (see
// TridiagonalEigenSolver::ComputeScalar): Sturm counts and bisection targets stay exact past the
// narrow type's ~1/eps integer ceiling, the start-vector RNG cannot overflow to infinity, and the
// coincident-shift perturbation (~0.08|x| at bfloat16 precision) cannot jump into a neighbouring
// eigenspace. Each block below used to fail in the corresponding way.
template <typename RealScalar>
void tridiagonal_eigensolver_narrow() {
  typedef Matrix<RealScalar, Dynamic, 1> VectorType;
  typedef Matrix<RealScalar, Dynamic, Dynamic> MatrixType;
  const RealScalar eps = NumTraits<RealScalar>::epsilon();

  // (a) 2x2 [2, 1; 1, 2]: exact eigenpairs (1, 3) with vectors (1, -1)/sqrt(2), (1, 1)/sqrt(2).
  // With the RNG overflow this returned an all-NaN eigenvector matrix with info() == Success.
  {
    VectorType d(2), e(1);
    d << RealScalar(2), RealScalar(2);
    e << RealScalar(1);
    TridiagonalEigenSolver<RealScalar> es(d, e);
    VERIFY_IS_EQUAL(es.info(), Success);
    VERIFY(es.eigenvectors().allFinite());
    VERIFY_IS_APPROX(es.eigenvalues()(0), RealScalar(1));
    VERIFY_IS_APPROX(es.eigenvalues()(1), RealScalar(3));
    const MatrixType V = es.eigenvectors();
    VERIFY((V.transpose() * V - MatrixType::Identity(2, 2)).cwiseAbs().maxCoeff() <= RealScalar(8) * eps);
    const MatrixType T = dense_symmetric_tridiag(d, e);
    VERIFY((T * V - V * es.eigenvalues().asDiagonal()).cwiseAbs().maxCoeff() <= RealScalar(16) * eps);
  }

  // (b) Identity of dimension 257 (> 1/eps for bfloat16): every eigenvalue is exactly 1. With the
  // Sturm counts held in the narrow type this returned eigenvalues as large as 5.19.
  {
    const Index n = 257;
    const VectorType d = VectorType::Constant(n, RealScalar(1));
    const VectorType e = VectorType::Zero(n - 1);
    TridiagonalEigenSolver<RealScalar> es;
    es.computeEigenvalues(d, e);
    VERIFY_IS_EQUAL(es.info(), Success);
    VERIFY_IS_EQUAL(es.eigenvalues().size(), n);
    for (Index i = 0; i < n; ++i) VERIFY_IS_EQUAL(es.eigenvalues()(i), RealScalar(1));
  }

  // (c) diag (1, 1, 1 + 2^-4), zero off-diagonal: the eigenvectors for the two eigenvalues at 1
  // must span exactly the first two coordinates. An un-capped shift perturbation at this precision
  // used to select the third eigenspace for the second vector.
  {
    VectorType d(3), e = VectorType::Zero(2), w(2);
    d << RealScalar(1), RealScalar(1), RealScalar(1.0625f);
    w << RealScalar(1), RealScalar(1);
    TridiagonalEigenSolver<RealScalar> es;
    es.computeEigenvectors(d, e, w);
    VERIFY_IS_EQUAL(es.info(), Success);
    const MatrixType V = es.eigenvectors();
    VERIFY_IS_EQUAL(numext::abs(V(2, 0)), RealScalar(0));
    VERIFY_IS_EQUAL(numext::abs(V(2, 1)), RealScalar(0));
    VERIFY((V.transpose() * V - MatrixType::Identity(2, 2)).cwiseAbs().maxCoeff() <= RealScalar(8) * eps);
  }

  // (d) 1-2-1 Toeplitz of dimension 64, staged full solve: the eigenvector pass must shift by the
  // retained unrounded float eigenvalues. Shifts rounded to RealScalar collapse neighbouring
  // eigenvalues and used to return near-parallel columns (Gram error ~0.4 in bfloat16).
  {
    const Index n = 64;
    const VectorType d = VectorType::Constant(n, RealScalar(2.0f));
    const VectorType e = VectorType::Constant(n - 1, RealScalar(1.0f));
    TridiagonalEigenSolver<RealScalar> es(d, e);
    VERIFY_IS_EQUAL(es.info(), Success);
    const MatrixType V = es.eigenvectors();
    VERIFY((V.transpose() * V - MatrixType::Identity(n, n)).cwiseAbs().maxCoeff() <= RealScalar(16) * eps);
  }
}

template <typename = void>
void tridiagonal_eigensolver_power_of_two_scaling() {
  // An input sensitive to normalization rounding; bisection promises normwise accuracy, not correct rounding.
  Vector3f diag;
  diag << numext::bit_cast<float>(numext::uint32_t(0xf055994f)), numext::bit_cast<float>(numext::uint32_t(0x6fb2331a)),
      numext::bit_cast<float>(numext::uint32_t(0x70d02374));
  Vector2f subdiag;
  subdiag << numext::bit_cast<float>(numext::uint32_t(0x70b84b8a)),
      numext::bit_cast<float>(numext::uint32_t(0x6fc495b1));
  Vector3f expected;
  expected << numext::bit_cast<float>(numext::uint32_t(0xf0e811b7)),
      numext::bit_cast<float>(numext::uint32_t(0x708f34f5)), numext::bit_cast<float>(numext::uint32_t(0x70eac055));

  TridiagonalEigenSolver<float> eigenvalues;
  eigenvalues.computeEigenvalues(diag, subdiag);
  VERIFY_IS_EQUAL(eigenvalues.info(), Success);
  VERIFY(eigenvalues.eigenvalues().allFinite());
  const Matrix3d bisectionMatrix = dense_symmetric_tridiag(diag, subdiag).cast<double>();
  const double bisectionNorm = bisectionMatrix.cwiseAbs().rowwise().sum().maxCoeff();
  // Allow O(n*eps*||T||_inf) Sturm-count displacement, the final bracket width and reference rounding.
  // Eight covers the 2.1*n*eps bracket expansion on both sides, with room for the latter two terms.
  const double eigenvalueTolerance = 8.0 * double(diag.size()) * double(NumTraits<float>::epsilon()) * bisectionNorm;
  VERIFY((eigenvalues.eigenvalues().cast<double>() - expected.cast<double>()).cwiseAbs().maxCoeff() <=
         eigenvalueTolerance);

  // Exercise normalization-sensitive inverse iteration with rounded supplied eigenvalues.
  diag << numext::bit_cast<float>(numext::uint32_t(0x44d75b8b)), numext::bit_cast<float>(numext::uint32_t(0x45b9403d)),
      numext::bit_cast<float>(numext::uint32_t(0x4554211f));
  subdiag << numext::bit_cast<float>(numext::uint32_t(0x45609c76)),
      numext::bit_cast<float>(numext::uint32_t(0xc590ed04));
  expected << numext::bit_cast<float>(numext::uint32_t(0xc4e47d7d)),
      numext::bit_cast<float>(numext::uint32_t(0x45173159)), numext::bit_cast<float>(numext::uint32_t(0x46235731));

  TridiagonalEigenSolver<float> eigenvectors;
  eigenvectors.computeEigenvectors(diag, subdiag, expected);
  VERIFY_IS_EQUAL(eigenvectors.info(), Success);
  const Matrix3d matrix = dense_symmetric_tridiag(diag, subdiag).cast<double>();
  const Matrix3d vectors = eigenvectors.eigenvectors().cast<double>();
  VERIFY(vectors.allFinite());
  const double residual = (matrix * vectors - vectors * expected.cast<double>().asDiagonal()).cwiseAbs().maxCoeff();
  // Match the inverse-iteration suite's 128*n*eps allowance for perturbed pivots, repeated solves and normalization.
  const double tolerance = 128.0 * double(diag.size()) * double(NumTraits<float>::epsilon());
  VERIFY(residual <= tolerance * matrix.cwiseAbs().maxCoeff());
  VERIFY((vectors.transpose() * vectors - Matrix3d::Identity()).cwiseAbs().maxCoeff() <= tolerance);
}

template <typename Scalar>
void tridiagonal_eigensolver_scaling_units() {
  using Vector = Matrix<Scalar, Dynamic, 1>;
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic>;
  Vector diag(4), subdiag(3);
  diag << Scalar(2), Scalar(2), Scalar(10), Scalar(10);
  subdiag << Scalar(1), Scalar(0), Scalar(2);
  Vector expected(4);
  expected << Scalar(1), Scalar(3), Scalar(8), Scalar(12);
  const MatrixType matrix = dense_symmetric_tridiag(diag, subdiag);
  const Scalar tolerance = Scalar(32) * NumTraits<Scalar>::epsilon();
  for (int exponent : {-60, 0, 60}) {
    const Scalar scale = numext::ldexp(Scalar(1), exponent);
    const Vector d = diag * scale, e = subdiag * scale;
    TridiagonalEigenSolver<Scalar> solver(d, e);
    VERIFY_IS_EQUAL(solver.info(), Success);
    const Vector values = solver.eigenvalues() / scale;
    VERIFY(values.allFinite());
    VERIFY((values - expected).cwiseAbs().maxCoeff() <= tolerance * Scalar(12));
    const MatrixType vectors = solver.eigenvectors();
    VERIFY(vectors.allFinite());
    VERIFY((matrix * vectors - vectors * values.asDiagonal()).norm() <= tolerance * matrix.norm());
    VERIFY((vectors.transpose() * vectors - MatrixType::Identity(4, 4)).norm() <= tolerance);
    solver.computeEigenvalues(
        d, e, EigenvalueRange::values(static_cast<long double>(scale) * 2, static_cast<long double>(scale) * 9));
    VERIFY_IS_EQUAL(solver.eigenvalues().size(), 2);
    VERIFY((solver.eigenvalues() / scale - expected.segment(1, 2)).cwiseAbs().maxCoeff() <= tolerance * Scalar(12));

    // The internal absolute tolerance is in input units, not normalized units.
    Vector approximate;
    const Scalar abs_tol = scale / Scalar(128);
    internal::tridiagonal_bisection(d, e, EigenvalueRange::all(), abs_tol, approximate);
    VERIFY((approximate / scale - expected).cwiseAbs().maxCoeff() <= Scalar(1) / Scalar(128) + tolerance);
  }
}

template <typename Scalar>
void tridiagonal_eigensolver_subnormal_staged() {
  if (packet_path_flushes_subnormals<Scalar>()) return;
  using Vector = Matrix<Scalar, 4, 1>;
  using Subdiag = Matrix<Scalar, 3, 1>;
  using MatrixType = Matrix<Scalar, 4, 4>;
  const Vector diag = Vector::Constant(Scalar(2));
  const Subdiag subdiag = Subdiag::Ones();
  const MatrixType matrix = dense_symmetric_tridiag(diag, subdiag);
  for (int divisor : {64, 1024, 4096}) {
    const Scalar scale = (std::numeric_limits<Scalar>::min)() / Scalar(divisor);
    const Vector d = diag * scale;
    const Subdiag e = subdiag * scale;
    TridiagonalEigenSolver<Scalar> solver;
    solver.computeEigenvalues(d, e);
    VERIFY_IS_EQUAL(solver.info(), Success);
    solver.computeEigenvectors();
    VERIFY_IS_EQUAL(solver.info(), Success);
    const Vector values = solver.eigenvalues() / scale;
    const MatrixType vectors = solver.eigenvectors();
    VERIFY(values.allFinite());
    VERIFY(vectors.allFinite());
    // Restored eigenvalues have absolute quantization denorm_min/scale. This matrix has
    // norm <= 4 and minimum eigenvalue gap 1, so both residual and orthogonality see this error.
    const Scalar quantization = std::numeric_limits<Scalar>::denorm_min() / scale;
    const Scalar tolerance = Scalar(128 * 4) * NumTraits<Scalar>::epsilon() + Scalar(8 * 4) * quantization;
    VERIFY((matrix * vectors - vectors * values.asDiagonal()).norm() <= tolerance);
    VERIFY((vectors.transpose() * vectors - MatrixType::Identity()).norm() <= tolerance);
  }
}

// diag(big, tridiag(1, 2, 1)) in float: the staged eigenvalues are accurate to eps * big, which passes the small
// block's Sturm check yet left inverse iteration with |v_i' v_j| ~ (eps * big / gap)^3, O(1) for big ~ 1e4 and
// nb = 1000. The staged pass re-bisects the block at its own scale, so its vectors are those of the block solved alone.
// (Double needs ||T|| / ||T_b|| ~ 1e7 before the shift error matters, past where the Sturm check already refines.)
template <typename Scalar>
void tridiagonal_eigensolver_staged_small_block() {
  using VectorType = Matrix<Scalar, Dynamic, 1>;
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic>;
  const Index nb = 1000;
  VectorType d = VectorType::Constant(nb + 1, Scalar(2)), e = VectorType::Ones(nb);
  d(0) = Scalar(1e4);
  e(0) = Scalar(0);
  TridiagonalEigenSolver<Scalar> local, staged;
  local.computeEigenvalues(d.tail(nb).eval(), e.tail(nb - 1).eval());
  local.computeEigenvectors();
  staged.computeEigenvalues(d, e);
  staged.computeEigenvectors();
  VERIFY_IS_EQUAL(local.info(), Success);
  VERIFY_IS_EQUAL(staged.info(), Success);
  // The block's eigenvalues all lie below big, so they are the first nb columns. Bitwise equality also relies on
  // the Rayleigh-Ritz refinement leaving both results alone, which it does while their residuals are at eps.
  const MatrixType block = staged.eigenvectors().bottomLeftCorner(nb, nb);
  VERIFY_IS_EQUAL(block, local.eigenvectors());
  VERIFY_IS_EQUAL(staged.eigenvectors().topLeftCorner(1, nb).squaredNorm(), Scalar(0));
  // Vectors in different xSTEIN clusters are orthogonal to about eps * ||T_b|| / ortol, with ortol = 1e-3 ||T_b||.
  const Scalar cross_cluster_bound = Scalar(1e3) * NumTraits<Scalar>::epsilon();
  VERIFY((block.transpose() * block - MatrixType::Identity(nb, nb)).cwiseAbs().maxCoeff() <= cross_cluster_bound);
}

// Which of `excepts` f() raises, run with the floating-point environment held; -1 if it cannot be held.
template <typename Func>
int fp_exceptions_raised_by(int excepts, const Func& f) {
  std::fenv_t environment;
  if (std::feholdexcept(&environment) != 0) {
    std::cout << "SKIP: floating-point exception check: feholdexcept failed.\n";
    f();
    return -1;
  }
  f();
  const int raised = std::fetestexcept(excepts);
  VERIFY_IS_EQUAL(std::fesetenv(&environment), 0);
  return raised;
}

// The gate deciding whether to re-bisect a block's shifts compares their error bound with the block's gap without
// forming the ratio of the two, which finite input can make overflow when cubed, or 0/0. FE_DIVBYZERO is not checked:
// an exact shift's vanishing LU pivot has an infinite reciprocal by design.
template <typename Scalar>
void tridiagonal_eigensolver_block_gate_fp_exceptions() {
#if defined(FE_OVERFLOW) && defined(FE_INVALID)
  using VectorType = Matrix<Scalar, Dynamic, 1>;
  // diag(sqrt(highest), tridiag(1, 2, 1)_4), staged: (shift error / gap)^3 overflows. The block's vectors are still
  // those of the block solved alone.
  const Index nb = 4;
  VectorType d = VectorType::Constant(nb + 1, Scalar(2)), e = VectorType::Ones(nb);
  d(0) = numext::sqrt(NumTraits<Scalar>::highest());
  e(0) = Scalar(0);
  TridiagonalEigenSolver<Scalar> local, staged;
  local.computeEigenvalues(d.tail(nb).eval(), e.tail(nb - 1).eval());
  local.computeEigenvectors();
  staged.computeEigenvalues(d, e);
  int raised = fp_exceptions_raised_by(FE_OVERFLOW | FE_INVALID, [&] { staged.computeEigenvectors(); });
  if (raised >= 0) VERIFY_IS_EQUAL(raised, 0);
  VERIFY_IS_EQUAL(staged.info(), Success);
  VERIFY_IS_EQUAL(staged.eigenvectors().bottomLeftCorner(nb, nb), local.eigenvectors());

  // diag(1, [0 a; a 0]) with a = 8 denorm_min and its exact eigenvalues supplied: the block's gap underflows to zero
  // and supplied shifts carry a zero error bound, so the ratio was 0/0. (Hardware that flushes subnormal inputs splits
  // the block instead.)
  const Scalar a = Scalar(8) * std::numeric_limits<Scalar>::denorm_min();
  VectorType ds(3), es(2), w(3);
  ds << Scalar(1), Scalar(0), Scalar(0);
  es << Scalar(0), a;
  w << -a, a, Scalar(1);
  TridiagonalEigenSolver<Scalar> supplied;
  raised = fp_exceptions_raised_by(FE_OVERFLOW | FE_INVALID, [&] { supplied.computeEigenvectors(ds, es, w); });
  if (raised >= 0) VERIFY_IS_EQUAL(raised, 0);
  VERIFY_IS_EQUAL(supplied.info(), Success);
#else
  std::cout << "SKIP: block gate exception check: FE_OVERFLOW or FE_INVALID is unavailable.\n";
#endif
}

// d and e against their power-of-two scaled copies, computed beforehand, in every flush-to-zero mode: eigenvalues to
// the bisection error plus the quantization of the range they are stored in, eigenvectors (invariant under the
// scaling) against the scaled residual.
template <typename RealScalar>
void tridiagonal_check_scaled_pair(const Matrix<RealScalar, Dynamic, 1>& d, const Matrix<RealScalar, Dynamic, 1>& e,
                                   int k) {
  using MatrixType = Matrix<RealScalar, Dynamic, Dynamic>;
  using VectorType = Matrix<RealScalar, Dynamic, 1>;
  const RealScalar eps = NumTraits<RealScalar>::epsilon();
  constexpr int digits = std::numeric_limits<RealScalar>::digits;
  const Index n = d.size();
  const VectorType ds = d.unaryExpr(internal::scale_by_exponent_op<RealScalar>(k));
  const VectorType es = e.unaryExpr(internal::scale_by_exponent_op<RealScalar>(k));
  const MatrixType Ts = dense_symmetric_tridiag(ds, es);
  TridiagonalEigenSolver<RealScalar> ref;
  ref.compute(ds, es);
  VERIFY_IS_EQUAL(ref.info(), Success);

  forEachFlushToZeroMode([&](FlushToZeroMode) {
    TridiagonalEigenSolver<RealScalar> sub;
    sub.compute(d, e);
    VERIFY_IS_EQUAL(sub.info(), Success);
    const VectorType up = sub.eigenvalues().unaryExpr(internal::scale_by_exponent_op<RealScalar>(k));
    const RealScalar radius = ref.eigenvalues().cwiseAbs().maxCoeff();
    // denorm_min 2^k: the spacing of the subnormal range the eigenvalues were stored in, scaled up with them.
    const RealScalar granularity =
        numext::ldexp(RealScalar(1), std::numeric_limits<RealScalar>::min_exponent - digits + k);
    // Named before the checks: MSVC does not capture a local that a lambda first uses after a `.template` call in the
    // same expression (C2065).
    const RealScalar valueBound = RealScalar(16) * (RealScalar(n) * eps * radius + granularity);
    const RealScalar residualBound = RealScalar(64) * RealScalar(n) * eps * radius;
    VERIFY((up - ref.eigenvalues()).cwiseAbs().template maxCoeff<PropagateNaN>() <= valueBound);
    const MatrixType V = sub.eigenvectors();
    VERIFY_IS_UNITARY(V);
    VERIFY((Ts * V - V * ref.eigenvalues().asDiagonal()).cwiseAbs().template maxCoeff<PropagateNaN>() <= residualBound);
  });
}

// All-subnormal d and e, assembled from significands without floating-point arithmetic, which a SIMD unit that
// flushes subnormal inputs (ARMv7 NEON, Arm FZ, DAZ) reads as zero in the maximum that selects the normalization.
template <typename RealScalar>
void tridiagonal_eigensolver_flushed_subnormal(Index n) {
  using VectorType = Matrix<RealScalar, Dynamic, 1>;
  using Binary = internal::binary_floating_point_traits<RealScalar>;
  using Bits = typename Binary::Bits;
  constexpr int digits = std::numeric_limits<RealScalar>::digits;
  // Distinct diagonal significands of digits - 2 bits, off-diagonal ones of alternating sign.
  const Bits top = Bits(1) << (digits - 3);
  VectorType d(n), e(n - 1);
  for (Index i = 0; i < n; ++i) d(i) = numext::bit_cast<RealScalar>(top + Bits(i) * (top / Bits(16)));
  for (Index i = 0; i < n - 1; ++i) {
    const Bits sign = (i % 2 == 0) ? Bits(0) : Binary::kSignBit;
    e(i) = numext::bit_cast<RealScalar>(sign | (top / Bits(2) + Bits(i) * (top / Bits(32))));
  }
  tridiagonal_check_scaled_pair(d, e, 60);
}

// A normal maximum below min / eps with subnormal couplings: |e| flushed to zero would split the matrix into 1 x 1
// blocks with eigenvectors e_i, although the true ones are (1, +-1) / sqrt(2) for equal d.
template <typename RealScalar>
void tridiagonal_eigensolver_flushed_subnormal_coupling() {
  using VectorType = Matrix<RealScalar, Dynamic, 1>;
  constexpr int minExponent = std::numeric_limits<RealScalar>::min_exponent;
  VectorType d(4), e(3);
  d.setConstant(numext::ldexp(RealScalar(1), minExponent + 5));
  for (Index i = 0; i < 3; ++i) e(i) = numext::ldexp(RealScalar(1) + RealScalar(i) / RealScalar(4), minExponent - 4);
  tridiagonal_check_scaled_pair(d, e, 40);
}

// The staged and the supplied-eigenvalue eigenvector passes, out of line so that none of their floating-point
// operations moves across the caller's exception-flag test.
template <typename Scalar>
EIGEN_DONT_INLINE void tridiagonal_staged_and_supplied_eigenvectors(TridiagonalEigenSolver<Scalar>& staged,
                                                                    TridiagonalEigenSolver<Scalar>& supplied,
                                                                    const Matrix<Scalar, Dynamic, 1>& d,
                                                                    const Matrix<Scalar, Dynamic, 1>& e,
                                                                    const Matrix<Scalar, Dynamic, 1>& w) {
  staged.computeEigenvectors();
  supplied.computeEigenvectors(d, e, w);
}

// Assigning eigenvalues to disconnected blocks takes Sturm counts at shifts in each block's normalized units. For a
// shift far outside a small block, or within its tolerance of the overflow threshold, the count is 0 or the block's
// size, decided without forming the normalized shift, which overflows. FE_DIVBYZERO is not checked: an exact shift's
// vanishing LU pivot has an infinite reciprocal by design.
template <typename Scalar>
void tridiagonal_eigensolver_block_assignment_overflow() {
  using VectorType = Matrix<Scalar, Dynamic, 1>;
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic>;
  const Scalar highest = NumTraits<Scalar>::highest(), eps = NumTraits<Scalar>::epsilon();
  const Index nb = 3;
  // T = A (+) s * tridiag(1, 2, 1)_3, with A first and last, through the staged and supplied-eigenvalue paths.
  auto check = [&](const VectorType& ad, const VectorType& ae, Scalar s) {
    const Index na = ad.size(), n = na + nb;
    for (const bool a_first : {true, false}) {
      const Index a0 = a_first ? 0 : nb, b0 = a_first ? na : 0;
      VectorType d(n), e = VectorType::Zero(n - 1);
      d.segment(a0, na) = ad;
      e.segment(a0, na - 1) = ae;
      d.segment(b0, nb).setConstant(Scalar(2) * s);
      e.segment(b0, nb - 1).setConstant(s);
      TridiagonalEigenSolver<Scalar> staged, supplied;
      staged.computeEigenvalues(d, e);
      VERIFY_IS_EQUAL(staged.info(), Success);
      const VectorType w = staged.eigenvalues();
#if defined(FE_OVERFLOW) && defined(FE_INVALID)
      const int raised = fp_exceptions_raised_by(
          FE_OVERFLOW | FE_INVALID, [&] { tridiagonal_staged_and_supplied_eigenvectors(staged, supplied, d, e, w); });
      if (raised >= 0) VERIFY_IS_EQUAL(raised, 0);
#else
      std::cout << "SKIP: block assignment overflow flag check: FE_OVERFLOW or FE_INVALID is unavailable.\n";
      tridiagonal_staged_and_supplied_eigenvectors(staged, supplied, d, e, w);
#endif
      for (const TridiagonalEigenSolver<Scalar>* es : {&staged, &supplied}) {
        VERIFY_IS_EQUAL(es->info(), Success);
        const MatrixType& V = es->eigenvectors();
        VERIFY((V.transpose() * V - MatrixType::Identity(n, n)).cwiseAbs().maxCoeff() <= Scalar(128) * Scalar(n) * eps);
        // Every vector lies in exactly one block, and A holds na of them.
        Index in_a = 0;
        for (Index j = 0; j < n; ++j) {
          const bool zero_a = (V.col(j).segment(a0, na).array() == Scalar(0)).all();
          const bool zero_b = (V.col(j).segment(b0, nb).array() == Scalar(0)).all();
          VERIFY(zero_a != zero_b);
          in_a += zero_b ? 1 : 0;
        }
        VERIFY_IS_EQUAL(in_a, na);
      }
    }
  };
  VectorType ad(1), ae(0);
  // A's shifts in units of a block at sqrt(min) overflow.
  ad << highest / Scalar(4);
  check(ad, ae, numext::sqrt((std::numeric_limits<Scalar>::min)()));
  // The largest shift plus its tolerance overflows.
  ad << highest;
  check(ad, ae, Scalar(1));
  // The same in A's own refinement check, which needs na > 1: with c = highest eps, A's largest eigenvalue is about
  // highest - 2c, within its tolerance of highest, while its row sums stay finite.
  const Scalar c = highest * eps;
  ad.resize(2);
  ae.resize(1);
  ad << highest - Scalar(2) * c, Scalar(0);
  ae << c;
  check(ad, ae, Scalar(1));
}

EIGEN_DECLARE_TEST(tridiagonal_eigensolver) {
  CALL_SUBTEST_1(tridiagonal_eigensolver_subnormal_staged<double>());
  CALL_SUBTEST_2(tridiagonal_eigensolver_subnormal_staged<float>());
  CALL_SUBTEST_2(tridiagonal_eigensolver_staged_small_block<float>());
  CALL_SUBTEST_1(tridiagonal_eigensolver_block_gate_fp_exceptions<double>());
  CALL_SUBTEST_2(tridiagonal_eigensolver_block_gate_fp_exceptions<float>());
  CALL_SUBTEST_2(tridiagonal_eigensolver_power_of_two_scaling<>());
  CALL_SUBTEST_2(tridiagonal_eigensolver_scaling_units<float>());
  CALL_SUBTEST_1(tridiagonal_eigensolver_scaling_units<double>());
  for (Index n : {Index(1), Index(2), Index(9)}) {
    EIGEN_UNUSED_VARIABLE(n);  // parts 3-6 compile no subtest that takes n
    CALL_SUBTEST_1(tridiagonal_eigensolver_flushed_subnormal<double>(n));
    CALL_SUBTEST_2(tridiagonal_eigensolver_flushed_subnormal<float>(n));
  }
  CALL_SUBTEST_1(tridiagonal_eigensolver_flushed_subnormal_coupling<double>());
  CALL_SUBTEST_2(tridiagonal_eigensolver_flushed_subnormal_coupling<float>());
  CALL_SUBTEST_1(tridiagonal_eigensolver_block_assignment_overflow<double>());
  CALL_SUBTEST_2(tridiagonal_eigensolver_block_assignment_overflow<float>());
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(tridiagonal_eigensolver_bisection<double>());
    CALL_SUBTEST_2(tridiagonal_eigensolver_bisection<float>());
    CALL_SUBTEST_3(tridiagonal_eigensolver_eigenvectors<double>());
    CALL_SUBTEST_4(tridiagonal_eigensolver_eigenvectors<float>());
    CALL_SUBTEST_5(tridiagonal_eigensolver_narrow<Eigen::half>());
    CALL_SUBTEST_6(tridiagonal_eigensolver_narrow<Eigen::bfloat16>());
  }
}
