// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2013-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_JACOBISVD_H
#define EIGEN_JACOBISVD_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {

// forward declaration (needed by ICC)
// the empty body is required by MSVC
template <typename MatrixType, int Options, bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
struct svd_precondition_2x2_block_to_be_real {};

/*** QR preconditioners (R-SVD)
 ***
 *** Their role is to reduce the problem of computing the SVD to the case of a square matrix.
 *** This approach, known as R-SVD, is an optimization for rectangular-enough matrices, and is a requirement for
 *** JacobiSVD which by itself is only able to work on square matrices.
 ***/

enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols };

template <typename MatrixType, int QRPreconditioner, int Case>
struct qr_preconditioner_should_do_anything
    : bool_constant<!((QRPreconditioner == NoQRPreconditioner) ||
                      (Case == PreconditionIfMoreColsThanRows && MatrixType::RowsAtCompileTime != Dynamic &&
                       MatrixType::ColsAtCompileTime != Dynamic &&
                       MatrixType::ColsAtCompileTime <= MatrixType::RowsAtCompileTime) ||
                      (Case == PreconditionIfMoreRowsThanCols && MatrixType::RowsAtCompileTime != Dynamic &&
                       MatrixType::ColsAtCompileTime != Dynamic &&
                       MatrixType::RowsAtCompileTime <= MatrixType::ColsAtCompileTime))> {};

template <typename MatrixType, int Options, int QRPreconditioner, int Case,
          bool DoAnything = qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::value>
struct qr_preconditioner_impl {};

template <typename MatrixType, int Options, int QRPreconditioner, int Case>
class qr_preconditioner_impl<MatrixType, Options, QRPreconditioner, Case, false> {
 public:
  void allocate(const JacobiSVD<MatrixType, Options>&) {}
  template <typename Xpr>
  bool run(JacobiSVD<MatrixType, Options>&, const Xpr&) {
    return false;
  }
};

/*** preconditioner using FullPivHouseholderQR ***/

template <typename MatrixType, int Options>
class qr_preconditioner_impl<MatrixType, Options, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols,
                             true> {
 public:
  using Scalar = typename MatrixType::Scalar;
  using SVDType = JacobiSVD<MatrixType, Options>;

  enum { WorkspaceSize = MatrixType::RowsAtCompileTime, MaxWorkspaceSize = MatrixType::MaxRowsAtCompileTime };

  using WorkspaceType = Matrix<Scalar, 1, WorkspaceSize, RowMajor, 1, MaxWorkspaceSize>;

  void allocate(const SVDType& svd) {
    if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) {
      internal::destroy_at(&m_qr);
      internal::construct_at(&m_qr, svd.rows(), svd.cols());
    }
    if (svd.m_computeFullU) m_workspace.resize(svd.rows());
  }
  template <typename Xpr>
  bool run(SVDType& svd, const Xpr& matrix) {
    if (matrix.rows() > matrix.cols()) {
      m_qr.compute(matrix);
      svd.m_workMatrix = m_qr.matrixQR().block(0, 0, matrix.cols(), matrix.cols()).template triangularView<Upper>();
      if (svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace);
      if (svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
      return true;
    }
    return false;
  }

 private:
  using QRType = FullPivHouseholderQR<MatrixType>;
  QRType m_qr;
  WorkspaceType m_workspace;
};

template <typename MatrixType, int Options>
class qr_preconditioner_impl<MatrixType, Options, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows,
                             true> {
 public:
  using Scalar = typename MatrixType::Scalar;
  using SVDType = JacobiSVD<MatrixType, Options>;

  enum {
    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
    MatrixOptions = traits<MatrixType>::Options
  };

  using TransposeTypeWithSameStorageOrder =
      typename internal::make_proper_matrix_type<Scalar, ColsAtCompileTime, RowsAtCompileTime, MatrixOptions,
                                                 MaxColsAtCompileTime, MaxRowsAtCompileTime>::type;

  void allocate(const SVDType& svd) {
    if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) {
      internal::destroy_at(&m_qr);
      internal::construct_at(&m_qr, svd.cols(), svd.rows());
    }
    if (svd.m_computeFullV) m_workspace.resize(svd.cols());
  }
  template <typename Xpr>
  bool run(SVDType& svd, const Xpr& matrix) {
    if (matrix.cols() > matrix.rows()) {
      m_qr.compute(matrix.adjoint());
      svd.m_workMatrix =
          m_qr.matrixQR().block(0, 0, matrix.rows(), matrix.rows()).template triangularView<Upper>().adjoint();
      if (svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace);
      if (svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
      return true;
    } else
      return false;
  }

 private:
  using QRType = FullPivHouseholderQR<TransposeTypeWithSameStorageOrder>;
  QRType m_qr;
  typename plain_row_type<MatrixType>::type m_workspace;
};

/*** preconditioner using ColPivHouseholderQR ***/

template <typename MatrixType, int Options>
class qr_preconditioner_impl<MatrixType, Options, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols,
                             true> {
 public:
  using Scalar = typename MatrixType::Scalar;
  using SVDType = JacobiSVD<MatrixType, Options>;

  enum {
    WorkspaceSize = internal::traits<SVDType>::MatrixUColsAtCompileTime,
    MaxWorkspaceSize = internal::traits<SVDType>::MatrixUMaxColsAtCompileTime
  };

  using WorkspaceType = Matrix<Scalar, 1, WorkspaceSize, RowMajor, 1, MaxWorkspaceSize>;

  void allocate(const SVDType& svd) {
    if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) {
      internal::destroy_at(&m_qr);
      internal::construct_at(&m_qr, svd.rows(), svd.cols());
    }
    if (svd.m_computeFullU)
      m_workspace.resize(svd.rows());
    else if (svd.m_computeThinU)
      m_workspace.resize(svd.cols());
  }
  template <typename Xpr>
  bool run(SVDType& svd, const Xpr& matrix) {
    if (matrix.rows() > matrix.cols()) {
      m_qr.compute(matrix);
      svd.m_workMatrix = m_qr.matrixQR().block(0, 0, matrix.cols(), matrix.cols()).template triangularView<Upper>();
      if (svd.m_computeFullU)
        m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
      else if (svd.m_computeThinU) {
        svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
      }
      if (svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
      return true;
    }
    return false;
  }

 private:
  using QRType = ColPivHouseholderQR<MatrixType>;
  QRType m_qr;
  WorkspaceType m_workspace;
};

template <typename MatrixType, int Options>
class qr_preconditioner_impl<MatrixType, Options, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows,
                             true> {
 public:
  using Scalar = typename MatrixType::Scalar;
  using SVDType = JacobiSVD<MatrixType, Options>;

  enum {
    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
    MatrixOptions = internal::traits<MatrixType>::Options,
    WorkspaceSize = internal::traits<SVDType>::MatrixVColsAtCompileTime,
    MaxWorkspaceSize = internal::traits<SVDType>::MatrixVMaxColsAtCompileTime
  };

  using WorkspaceType = Matrix<Scalar, WorkspaceSize, 1, ColMajor, MaxWorkspaceSize, 1>;

  using TransposeTypeWithSameStorageOrder =
      typename internal::make_proper_matrix_type<Scalar, ColsAtCompileTime, RowsAtCompileTime, MatrixOptions,
                                                 MaxColsAtCompileTime, MaxRowsAtCompileTime>::type;

  void allocate(const SVDType& svd) {
    if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) {
      internal::destroy_at(&m_qr);
      internal::construct_at(&m_qr, svd.cols(), svd.rows());
    }
    if (svd.m_computeFullV)
      m_workspace.resize(svd.cols());
    else if (svd.m_computeThinV)
      m_workspace.resize(svd.rows());
  }
  template <typename Xpr>
  bool run(SVDType& svd, const Xpr& matrix) {
    if (matrix.cols() > matrix.rows()) {
      m_qr.compute(matrix.adjoint());

      svd.m_workMatrix =
          m_qr.matrixQR().block(0, 0, matrix.rows(), matrix.rows()).template triangularView<Upper>().adjoint();
      if (svd.m_computeFullV)
        m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
      else if (svd.m_computeThinV) {
        svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
      }
      if (svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
      return true;
    } else
      return false;
  }

 private:
  using QRType = ColPivHouseholderQR<TransposeTypeWithSameStorageOrder>;
  QRType m_qr;
  WorkspaceType m_workspace;
};

/*** preconditioner using HouseholderQR ***/

template <typename MatrixType, int Options>
class qr_preconditioner_impl<MatrixType, Options, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true> {
 public:
  using Scalar = typename MatrixType::Scalar;
  using SVDType = JacobiSVD<MatrixType, Options>;

  enum {
    WorkspaceSize = internal::traits<SVDType>::MatrixUColsAtCompileTime,
    MaxWorkspaceSize = internal::traits<SVDType>::MatrixUMaxColsAtCompileTime
  };

  using WorkspaceType = Matrix<Scalar, 1, WorkspaceSize, RowMajor, 1, MaxWorkspaceSize>;

  void allocate(const SVDType& svd) {
    if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) {
      internal::destroy_at(&m_qr);
      internal::construct_at(&m_qr, svd.rows(), svd.cols());
    }
    if (svd.m_computeFullU)
      m_workspace.resize(svd.rows());
    else if (svd.m_computeThinU)
      m_workspace.resize(svd.cols());
  }
  template <typename Xpr>
  bool run(SVDType& svd, const Xpr& matrix) {
    if (matrix.rows() > matrix.cols()) {
      m_qr.compute(matrix);
      svd.m_workMatrix = m_qr.matrixQR().block(0, 0, matrix.cols(), matrix.cols()).template triangularView<Upper>();
      if (svd.m_computeFullU)
        m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
      else if (svd.m_computeThinU) {
        svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
      }
      if (svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols());
      return true;
    }
    return false;
  }

 private:
  using QRType = HouseholderQR<MatrixType>;
  QRType m_qr;
  WorkspaceType m_workspace;
};

template <typename MatrixType, int Options>
class qr_preconditioner_impl<MatrixType, Options, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true> {
 public:
  using Scalar = typename MatrixType::Scalar;
  using SVDType = JacobiSVD<MatrixType, Options>;

  enum {
    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
    MatrixOptions = internal::traits<MatrixType>::Options,
    WorkspaceSize = internal::traits<SVDType>::MatrixVColsAtCompileTime,
    MaxWorkspaceSize = internal::traits<SVDType>::MatrixVMaxColsAtCompileTime
  };

  using WorkspaceType = Matrix<Scalar, WorkspaceSize, 1, ColMajor, MaxWorkspaceSize, 1>;

  using TransposeTypeWithSameStorageOrder =
      typename internal::make_proper_matrix_type<Scalar, ColsAtCompileTime, RowsAtCompileTime, MatrixOptions,
                                                 MaxColsAtCompileTime, MaxRowsAtCompileTime>::type;

  void allocate(const SVDType& svd) {
    if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) {
      internal::destroy_at(&m_qr);
      internal::construct_at(&m_qr, svd.cols(), svd.rows());
    }
    if (svd.m_computeFullV)
      m_workspace.resize(svd.cols());
    else if (svd.m_computeThinV)
      m_workspace.resize(svd.rows());
  }

  template <typename Xpr>
  bool run(SVDType& svd, const Xpr& matrix) {
    if (matrix.cols() > matrix.rows()) {
      m_qr.compute(matrix.adjoint());

      svd.m_workMatrix =
          m_qr.matrixQR().block(0, 0, matrix.rows(), matrix.rows()).template triangularView<Upper>().adjoint();
      if (svd.m_computeFullV)
        m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
      else if (svd.m_computeThinV) {
        svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
      }
      if (svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows());
      return true;
    } else
      return false;
  }

 private:
  using QRType = HouseholderQR<TransposeTypeWithSameStorageOrder>;
  QRType m_qr;
  WorkspaceType m_workspace;
};

/*** 2x2 SVD implementation
 ***
 *** JacobiSVD consists in performing a series of 2x2 SVD subproblems
 ***/

template <typename MatrixType, int Options>
struct svd_precondition_2x2_block_to_be_real<MatrixType, Options, false> {
  using SVD = JacobiSVD<MatrixType, Options>;
  using RealScalar = typename MatrixType::RealScalar;
  static bool run(typename SVD::WorkMatrixType&, SVD&, Index, Index, RealScalar&) { return true; }
};

template <typename MatrixType, int Options>
struct svd_precondition_2x2_block_to_be_real<MatrixType, Options, true> {
  using SVD = JacobiSVD<MatrixType, Options>;
  using Scalar = typename MatrixType::Scalar;
  using RealScalar = typename MatrixType::RealScalar;
  static bool run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q, RealScalar& maxDiagEntry) {
    using numext::abs;
    using numext::sqrt;
    Scalar z;
    JacobiRotation<Scalar> rot;
    RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p, p)) + numext::abs2(work_matrix.coeff(q, p)));

    const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
    const RealScalar precision = NumTraits<Scalar>::epsilon();

    if (numext::is_exactly_zero(n)) {
      // make sure first column is zero
      work_matrix.coeffRef(p, p) = work_matrix.coeffRef(q, p) = Scalar(0);

      if (abs(numext::imag(work_matrix.coeff(p, q))) > considerAsZero) {
        // work_matrix.coeff(p,q) can be zero if work_matrix.coeff(q,p) is not zero but small enough to underflow when
        // computing n
        z = abs(work_matrix.coeff(p, q)) / work_matrix.coeff(p, q);
        work_matrix.row(p) *= z;
        if (svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
      }
      if (abs(numext::imag(work_matrix.coeff(q, q))) > considerAsZero) {
        z = abs(work_matrix.coeff(q, q)) / work_matrix.coeff(q, q);
        work_matrix.row(q) *= z;
        if (svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
      }
      // otherwise the second row is already zero, so we have nothing to do.
    } else {
      rot.c() = conj(work_matrix.coeff(p, p)) / n;
      rot.s() = work_matrix.coeff(q, p) / n;
      work_matrix.applyOnTheLeft(p, q, rot);
      if (svd.computeU()) svd.m_matrixU.applyOnTheRight(p, q, rot.adjoint());
      if (abs(numext::imag(work_matrix.coeff(p, q))) > considerAsZero) {
        z = abs(work_matrix.coeff(p, q)) / work_matrix.coeff(p, q);
        work_matrix.col(q) *= z;
        if (svd.computeV()) svd.m_matrixV.col(q) *= z;
      }
      if (abs(numext::imag(work_matrix.coeff(q, q))) > considerAsZero) {
        z = abs(work_matrix.coeff(q, q)) / work_matrix.coeff(q, q);
        work_matrix.row(q) *= z;
        if (svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
      }
    }

    // update largest diagonal entry
    maxDiagEntry = numext::maxi<RealScalar>(
        maxDiagEntry, numext::maxi<RealScalar>(abs(work_matrix.coeff(p, p)), abs(work_matrix.coeff(q, q))));
    // and check whether the 2x2 block is already diagonal
    RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
    return abs(work_matrix.coeff(p, q)) > threshold || abs(work_matrix.coeff(q, p)) > threshold;
  }
};

template <typename WorkMatrixType, typename MatrixUType, typename MatrixVType>
EIGEN_DONT_INLINE bool jacobi_svd_nonblocking_sweep(WorkMatrixType& work_matrix, MatrixUType& matrix_u,
                                                    MatrixVType& matrix_v, bool compute_u, bool compute_v,
                                                    typename WorkMatrixType::RealScalar considerAsZero,
                                                    typename WorkMatrixType::RealScalar precision,
                                                    typename WorkMatrixType::RealScalar& maxDiagEntry) {
  using numext::abs;
  using numext::sqrt;
  using Scalar = typename WorkMatrixType::Scalar;
  using RealScalar = typename WorkMatrixType::RealScalar;
  const Index n = work_matrix.rows();
  bool notFinished = false;

  EIGEN_IF_CONSTEXPR (NumTraits<Scalar>::IsComplex) {
    // Complex non-blocking sweep: condition each 2x2 block to be real before diagonalizing.
    for (Index p = 1; p < n; ++p) {
      for (Index q = 0; q < p; ++q) {
        RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
        if (abs(work_matrix.coeff(p, q)) > threshold || abs(work_matrix.coeff(q, p)) > threshold) {
          notFinished = true;
          Scalar z;
          bool doRealSvd = true;
          RealScalar nn = sqrt(numext::abs2(work_matrix.coeff(p, p)) + numext::abs2(work_matrix.coeff(q, p)));

          if (numext::is_exactly_zero(nn)) {
            // Make sure first column is zero.
            work_matrix.coeffRef(p, p) = work_matrix.coeffRef(q, p) = Scalar(0);

            if (abs(numext::imag(work_matrix.coeff(p, q))) > considerAsZero) {
              // work_matrix.coeff(p, q) can be zero if work_matrix.coeff(q, p) is not zero but small enough to
              // underflow when computing nn.
              z = abs(work_matrix.coeff(p, q)) / work_matrix.coeff(p, q);
              work_matrix.row(p) *= z;
              if (compute_u) matrix_u.col(p) *= numext::conj(z);
            }
            if (abs(numext::imag(work_matrix.coeff(q, q))) > considerAsZero) {
              z = abs(work_matrix.coeff(q, q)) / work_matrix.coeff(q, q);
              work_matrix.row(q) *= z;
              if (compute_u) matrix_u.col(q) *= numext::conj(z);
            }
          } else {
            JacobiRotation<Scalar> rot;
            rot.c() = numext::conj(work_matrix.coeff(p, p)) / nn;
            rot.s() = work_matrix.coeff(q, p) / nn;
            work_matrix.applyOnTheLeft(p, q, rot);
            if (compute_u) matrix_u.applyOnTheRight(p, q, rot.adjoint());
            if (abs(numext::imag(work_matrix.coeff(p, q))) > considerAsZero) {
              z = abs(work_matrix.coeff(p, q)) / work_matrix.coeff(p, q);
              work_matrix.col(q) *= z;
              if (compute_v) matrix_v.col(q) *= z;
            }
            if (abs(numext::imag(work_matrix.coeff(q, q))) > considerAsZero) {
              z = abs(work_matrix.coeff(q, q)) / work_matrix.coeff(q, q);
              work_matrix.row(q) *= z;
              if (compute_u) matrix_u.col(q) *= numext::conj(z);
            }
          }

          maxDiagEntry = numext::maxi<RealScalar>(
              maxDiagEntry, numext::maxi<RealScalar>(abs(work_matrix.coeff(p, p)), abs(work_matrix.coeff(q, q))));
          threshold = numext::maxi<RealScalar>(considerAsZero, NumTraits<Scalar>::epsilon() * maxDiagEntry);
          doRealSvd = abs(work_matrix.coeff(p, q)) > threshold || abs(work_matrix.coeff(q, p)) > threshold;

          if (doRealSvd) {
            JacobiRotation<RealScalar> j_left, j_right;
            internal::real_2x2_jacobi_svd(work_matrix, p, q, &j_left, &j_right);
            work_matrix.applyOnTheLeft(p, q, j_left);
            if (compute_u) matrix_u.applyOnTheRight(p, q, j_left.transpose());
            work_matrix.applyOnTheRight(p, q, j_right);
            if (compute_v) matrix_v.applyOnTheRight(p, q, j_right);
            maxDiagEntry = numext::maxi<RealScalar>(
                maxDiagEntry, numext::maxi<RealScalar>(abs(work_matrix.coeff(p, p)), abs(work_matrix.coeff(q, q))));
          }
        }
      }
    }
  } else {
    // Real non-blocking sweep: diagonalize each 2x2 block directly.
    RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
    for (Index p = 1; p < n; ++p) {
      for (Index q = 0; q < p; ++q) {
        if (abs(work_matrix.coeff(p, q)) > threshold || abs(work_matrix.coeff(q, p)) > threshold) {
          notFinished = true;
          JacobiRotation<RealScalar> j_left, j_right;
          internal::real_2x2_jacobi_svd(work_matrix, p, q, &j_left, &j_right);
          work_matrix.applyOnTheLeft(p, q, j_left);
          if (compute_u) matrix_u.applyOnTheRight(p, q, j_left.transpose());
          work_matrix.applyOnTheRight(p, q, j_right);
          if (compute_v) matrix_v.applyOnTheRight(p, q, j_right);
          maxDiagEntry = numext::maxi<RealScalar>(
              maxDiagEntry, numext::maxi<RealScalar>(abs(work_matrix.coeff(p, p)), abs(work_matrix.coeff(q, q))));
          threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
        }
      }
    }
  }

  return notFinished;
}

template <typename MatrixType_, int Options>
struct traits<JacobiSVD<MatrixType_, Options>> : svd_traits<MatrixType_, Options> {
  using MatrixType = MatrixType_;
};

}  // end namespace internal

/** \ingroup SVD_Module
 *
 *
 * \class JacobiSVD
 *
 * \brief Two-sided Jacobi SVD decomposition of a rectangular matrix
 *
 * \tparam MatrixType_ the type of the matrix of which we are computing the SVD decomposition
 * \tparam Options this optional parameter allows one to specify the type of QR decomposition that will be used
 * internally for the R-SVD step for non-square matrices. Additionally, it allows one to specify whether to compute thin
 * or full unitaries \a U and \a V. See discussion of possible values below.
 *
 * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product
 *   \f[ A = U S V^* \f]
 * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero
 * outside of its main diagonal; the diagonal entries of S are known as the \em singular \em values of \a A and the
 * columns of \a U and \a V are known as the left and right \em singular \em vectors of \a A respectively.
 *
 * Singular values are always sorted in decreasing order.
 *
 * This JacobiSVD decomposition computes only the singular values by default. If you want \a U or \a V, you need to ask
 * for them explicitly.
 *
 * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p
 * matrix, letting \a m be the smaller value among \a n and \a p, there are only \a m singular vectors; the remaining
 * columns of \a U and \a V do not correspond to actual singular vectors. Asking for \em thin \a U or \a V means asking
 * for only their \a m first columns to be formed. So \a U is then a n-by-m matrix, and \a V is then a p-by-m matrix.
 * Notice that thin \a U and \a V are all you need for (least squares) solving.
 *
 * Here's an example demonstrating basic usage:
 * \include JacobiSVD_basic.cpp
 * Output: \verbinclude JacobiSVD_basic.out
 *
 * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The
 * downside is that it's slower than bidiagonalizing SVD algorithms for large square matrices; however its complexity is
 * still \f$ O(n^2p) \f$ where \a n is the smaller dimension and \a p is the greater dimension, meaning that it is still
 * of the same order of complexity as the faster bidiagonalizing R-SVD algorithms. In particular, like any R-SVD, it
 * takes advantage of non-squareness in that its complexity is only linear in the greater dimension.
 *
 * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is
 * guaranteed to terminate in finite (and reasonable) time.
 *
 * The possible QR preconditioners that can be set with Options template parameter are:
 * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR.
 * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR.
 *     Contrary to other QRs, it doesn't allow computing thin unitaries.
 * \li HouseholderQRPreconditioner is the fastest, and less safe and accurate than the pivoting variants. It uses
 * non-pivoting QR. This is very similar in safety and accuracy to the bidiagonalization process used by bidiagonalizing
 * SVD algorithms (since bidiagonalization is inherently non-pivoting). However the resulting SVD is still more reliable
 * than bidiagonalizing SVDs because the Jacobi-based iterative process is more reliable than the optimized bidiagonal
 * SVD iterations. \li NoQRPreconditioner allows not to use a QR preconditioner at all. This is useful if you know that
 * you will only be computing JacobiSVD decompositions of square matrices. Non-square matrices require a QR
 * preconditioner. Using this option will result in faster compilation and smaller executable code. It won't
 * significantly speed up computation, since JacobiSVD is always checking if QR preconditioning is needed before
 * applying it anyway.
 *
 * One may also use the Options template parameter to specify how the unitaries should be computed. The options are
 * #ComputeThinU, #ComputeThinV, #ComputeFullU, #ComputeFullV. It is not possible to request both the thin and full
 * versions of a unitary. By default, unitaries will not be computed.
 *
 * You can set the QRPreconditioner and unitary options together: JacobiSVD<MatrixType,
 * ColPivHouseholderQRPreconditioner | ComputeThinU | ComputeFullV>
 *
 * \sa MatrixBase::jacobiSvd()
 */
template <typename MatrixType_, int Options_>
class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_>> {
  using Base = SVDBase<JacobiSVD>;

 public:
  using MatrixType = MatrixType_;
  using Scalar = typename Base::Scalar;
  using RealScalar = typename Base::RealScalar;
  enum : int {
    Options = Options_,
    QRPreconditioner = internal::get_qr_preconditioner(Options),
    RowsAtCompileTime = Base::RowsAtCompileTime,
    ColsAtCompileTime = Base::ColsAtCompileTime,
    DiagSizeAtCompileTime = Base::DiagSizeAtCompileTime,
    MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime,
    MaxColsAtCompileTime = Base::MaxColsAtCompileTime,
    MaxDiagSizeAtCompileTime = Base::MaxDiagSizeAtCompileTime,
    MatrixOptions = Base::MatrixOptions
  };

  using MatrixUType = typename Base::MatrixUType;
  using MatrixVType = typename Base::MatrixVType;
  using SingularValuesType = typename Base::SingularValuesType;
  using WorkMatrixType = Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime, MatrixOptions,
                                MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>;

  /** \brief Default Constructor.
   *
   * The default constructor is useful in cases in which the user intends to
   * perform decompositions via JacobiSVD::compute(const MatrixType&).
   */
  JacobiSVD() {}

  /** \brief Default Constructor with memory preallocation
   *
   * Like the default constructor but with preallocation of the internal data
   * according to the specified problem size and \a Options template parameter.
   *
   * \sa JacobiSVD()
   */
  JacobiSVD(Index rows, Index cols) { allocate(rows, cols, internal::get_computation_options(Options)); }

  /** \brief Default Constructor with memory preallocation
   *
   * Like the default constructor but with preallocation of the internal data
   * according to the specified problem size.
   *
   * One \b cannot request unitaries using both the \a Options template parameter
   * and the constructor. If possible, prefer using the \a Options template parameter.
   *
   * \param rows number of rows for the input matrix
   * \param cols number of columns for the input matrix
   * \param computationOptions specify whether to compute Thin/Full unitaries U/V
   * \sa JacobiSVD()
   *
   * \deprecated Will be removed in the next major Eigen version. Options should
   * be specified in the \a Options template parameter.
   */
  EIGEN_DEPRECATED_WITH_REASON("Options should be specified using the class template parameter.")
  JacobiSVD(Index rows, Index cols, unsigned int computationOptions) {
    internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, rows, cols);
    allocate(rows, cols, computationOptions);
  }

  /** \brief Constructor performing the decomposition of given matrix, using the custom options specified
   *         with the \a Options template parameter.
   *
   * \param matrix the matrix to decompose
   */
  template <typename Derived>
  explicit JacobiSVD(const MatrixBase<Derived>& matrix) {
    compute_impl(matrix, internal::get_computation_options(Options));
  }

  template <typename Derived>
  explicit JacobiSVD(const TriangularBase<Derived>& matrix) {
    compute_impl(matrix, internal::get_computation_options(Options));
  }

  /** \brief Constructor performing the decomposition of given matrix using specified options
   *         for computing unitaries.
   *
   *  One \b cannot request unitiaries using both the \a Options template parameter
   *  and the constructor. If possible, prefer using the \a Options template parameter.
   *
   * \param matrix the matrix to decompose
   * \param computationOptions specify whether to compute Thin/Full unitaries U/V
   *
   * \deprecated Will be removed in the next major Eigen version. Options should
   * be specified in the \a Options template parameter.
   */
  // EIGEN_DEPRECATED // TODO(cantonios): re-enable after fixing a few 3p libraries that error on deprecation warnings.
  template <typename Derived>
  JacobiSVD(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
    internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
    compute_impl(matrix, computationOptions);
  }

  /** \brief Method performing the decomposition of given matrix. Computes Thin/Full unitaries U/V if specified
   *         using the \a Options template parameter or the class constructor.
   *
   * \param matrix the matrix to decompose
   */
  template <typename Derived>
  JacobiSVD& compute(const MatrixBase<Derived>& matrix) {
    return compute_impl(matrix, m_computationOptions);
  }

  template <typename Derived>
  JacobiSVD& compute(const TriangularBase<Derived>& matrix) {
    return compute_impl(matrix, m_computationOptions);
  }

  /** \brief Method performing the decomposition of given matrix, as specified by
   *         the `computationOptions` parameter.
   *
   * \param matrix the matrix to decompose
   * \param computationOptions specify whether to compute Thin/Full unitaries U/V
   *
   * \deprecated Will be removed in the next major Eigen version. Options should
   * be specified in the \a Options template parameter.
   */
  template <typename Derived>
  EIGEN_DEPRECATED_WITH_REASON("Options should be specified using the class template parameter.")
  JacobiSVD& compute(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
    internal::check_svd_options_assertions<MatrixType, Options>(m_computationOptions, matrix.rows(), matrix.cols());
    return compute_impl(matrix, computationOptions);
  }

  using Base::cols;
  using Base::computeU;
  using Base::computeV;
  using Base::diagSize;
  using Base::rank;
  using Base::rows;

  void allocate(Index rows_, Index cols_, unsigned int computationOptions) {
    if (Base::allocate(rows_, cols_, computationOptions)) return;
    eigen_assert(!(ShouldComputeThinU && int(QRPreconditioner) == int(FullPivHouseholderQRPreconditioner)) &&
                 !(ShouldComputeThinU && int(QRPreconditioner) == int(FullPivHouseholderQRPreconditioner)) &&
                 "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
                 "Use the ColPivHouseholderQR preconditioner instead.");

    m_workMatrix.resize(diagSize(), diagSize());
    if (cols() > rows()) m_qr_precond_morecols.allocate(*this);
    if (rows() > cols()) m_qr_precond_morerows.allocate(*this);
  }

 private:
  template <typename Derived>
  JacobiSVD& compute_impl(const TriangularBase<Derived>& matrix, unsigned int computationOptions);
  template <typename Derived>
  JacobiSVD& compute_impl(const MatrixBase<Derived>& matrix, unsigned int computationOptions);

  // Blocked sweep for the Jacobi SVD (works for both real and complex scalars).
  // Extracted into a separate EIGEN_DONT_INLINE method to prevent the blocking
  // code from interfering with the compiler's optimization of the non-blocking
  // scalar sweep.
  EIGEN_DONT_INLINE bool blocked_sweep(RealScalar considerAsZero, RealScalar precision, RealScalar& maxDiagEntry);

 protected:
  using Base::m_computationOptions;
  using Base::m_computeFullU;
  using Base::m_computeFullV;
  using Base::m_computeThinU;
  using Base::m_computeThinV;
  using Base::m_info;
  using Base::m_isAllocated;
  using Base::m_isInitialized;
  using Base::m_matrixU;
  using Base::m_matrixV;
  using Base::m_nonzeroSingularValues;
  using Base::m_prescribedThreshold;
  using Base::m_singularValues;
  using Base::m_usePrescribedThreshold;
  using Base::ShouldComputeThinU;
  using Base::ShouldComputeThinV;

  EIGEN_STATIC_ASSERT(!(ShouldComputeThinU && int(QRPreconditioner) == int(FullPivHouseholderQRPreconditioner)) &&
                          !(ShouldComputeThinU && int(QRPreconditioner) == int(FullPivHouseholderQRPreconditioner)),
                      "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
                      "Use the ColPivHouseholderQR preconditioner instead.")

  template <typename MatrixType__, int Options__, bool IsComplex_>
  friend struct internal::svd_precondition_2x2_block_to_be_real;
  template <typename MatrixType__, int Options__, int QRPreconditioner_, int Case_, bool DoAnything_>
  friend struct internal::qr_preconditioner_impl;

  internal::qr_preconditioner_impl<MatrixType, Options, QRPreconditioner, internal::PreconditionIfMoreColsThanRows>
      m_qr_precond_morecols;
  internal::qr_preconditioner_impl<MatrixType, Options, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols>
      m_qr_precond_morerows;
  WorkMatrixType m_workMatrix;

  // Blocking parameters for the Jacobi SVD sweep.
#ifdef EIGEN_JACOBI_SVD_BLOCK_SIZE
  static constexpr Index kDefaultBlockSize = EIGEN_JACOBI_SVD_BLOCK_SIZE;
#else
  static constexpr Index kDefaultBlockSize = 32;
#endif

  // Use the lower of the default block size and static maximum matrix dimensions.
  static constexpr Index kBlockSize = internal::min_size_prefer_fixed(kDefaultBlockSize, MaxDiagSizeAtCompileTime);
};

template <typename MatrixType, int Options>
template <typename Derived>
JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute_impl(const TriangularBase<Derived>& matrix,
                                                                             unsigned int computationOptions) {
  return compute_impl(matrix.toDenseMatrix(), computationOptions);
}

template <typename MatrixType, int Options>
template <typename Derived>
JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute_impl(const MatrixBase<Derived>& matrix,
                                                                             unsigned int computationOptions) {
  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived, MatrixType);
  EIGEN_STATIC_ASSERT((std::is_same<typename Derived::Scalar, typename MatrixType::Scalar>::value),
                      Input matrix must have the same Scalar type as the JacobiSVD object.);

  using numext::abs;

  allocate(matrix.rows(), matrix.cols(), computationOptions);

  // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number
  // of iterations, only worsening the precision of U and V as we accumulate more rotations
  const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();

  // limit for denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
  const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();

  // Scaling factor to reduce over/under-flows
  RealScalar scale = matrix.cwiseAbs().template maxCoeff<PropagateNaN>();
  if (!(numext::isfinite)(scale)) {
    m_isInitialized = true;
    m_info = InvalidInput;
    m_nonzeroSingularValues = 0;
    m_singularValues.setZero();
    return *this;
  }
  if (numext::is_exactly_zero(scale)) scale = RealScalar(1);

  /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */

  if (rows() != cols()) {
    m_qr_precond_morecols.run(*this, matrix / scale);
    m_qr_precond_morerows.run(*this, matrix / scale);
  } else {
    m_workMatrix =
        matrix.template topLeftCorner<DiagSizeAtCompileTime, DiagSizeAtCompileTime>(diagSize(), diagSize()) / scale;
    if (m_computeFullU) m_matrixU.setIdentity(rows(), rows());
    if (m_computeThinU) m_matrixU.setIdentity(rows(), diagSize());
    if (m_computeFullV) m_matrixV.setIdentity(cols(), cols());
    if (m_computeThinV) m_matrixV.setIdentity(cols(), diagSize());
  }

  /*** step 2. The main Jacobi SVD iteration. ***/
  RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();

  bool finished = false;
  while (!finished) {
    finished = true;

    {
      // Sweep with optional blocking for large matrices.
      // Use blocking when the matrix is large enough that individual left rotations
      // (strided row operations on column-major data) cause significant cache misses.
      // The threshold is derived from the L2 cache size: blocking becomes worthwhile
      // when n exceeds sqrt(L2 / 4). We divide by sizeof(float) rather than sizeof(RealScalar)
      // because the cache miss pattern depends on the number of columns accessed (one cache
      // line per column), not the scalar size. This also makes the threshold appropriately
      // more conservative for larger types where GEMM overhead is higher.
      const Index n = diagSize();
#ifdef EIGEN_JACOBI_SVD_BLOCKING_THRESHOLD
      const Index blockingThreshold = EIGEN_JACOBI_SVD_BLOCKING_THRESHOLD;
#else
      const Index blockingThreshold =
          static_cast<Index>(numext::sqrt(static_cast<double>(l2CacheSize() / sizeof(float))));
#endif

      if (n >= blockingThreshold) {
        // The blocked sweep is in a separate EIGEN_DONT_INLINE method to prevent
        // the blocking code from interfering with the compiler's optimization of
        // the non-blocking scalar sweep below.
        finished = !blocked_sweep(considerAsZero, precision, maxDiagEntry);
      } else
        finished = !internal::jacobi_svd_nonblocking_sweep(m_workMatrix, m_matrixU, m_matrixV, computeU(), computeV(),
                                                           considerAsZero, precision, maxDiagEntry);
    }
  }

  /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values
   * ***/

  for (Index i = 0; i < diagSize(); ++i) {
    // For a complex matrix, some diagonal coefficients might not have been
    // treated by svd_precondition_2x2_block_to_be_real, and the imaginary part
    // of some diagonal entry might not be null.
    bool diagonal_has_imaginary_part = false;
    EIGEN_IF_CONSTEXPR (NumTraits<Scalar>::IsComplex) {
      diagonal_has_imaginary_part = abs(numext::imag(m_workMatrix.coeff(i, i))) > considerAsZero;
    }
    if (diagonal_has_imaginary_part) {
      RealScalar a = abs(m_workMatrix.coeff(i, i));
      m_singularValues.coeffRef(i) = abs(a);
      if (computeU()) m_matrixU.col(i) *= m_workMatrix.coeff(i, i) / a;
    } else {
      // m_workMatrix.coeff(i,i) is already real, no difficulty:
      RealScalar a = numext::real(m_workMatrix.coeff(i, i));
      m_singularValues.coeffRef(i) = abs(a);
      if (computeU() && (a < RealScalar(0))) m_matrixU.col(i) = -m_matrixU.col(i);
    }
  }

  m_singularValues *= scale;

  /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/

  m_nonzeroSingularValues = diagSize();
  for (Index i = 0; i < diagSize(); i++) {
    Index pos;
    RealScalar maxRemainingSingularValue = m_singularValues.tail(diagSize() - i).maxCoeff(&pos);
    if (numext::is_exactly_zero(maxRemainingSingularValue)) {
      m_nonzeroSingularValues = i;
      break;
    }
    if (pos) {
      pos += i;
      std::swap(m_singularValues.coeffRef(i), m_singularValues.coeffRef(pos));
      if (computeU()) m_matrixU.col(pos).swap(m_matrixU.col(i));
      if (computeV()) m_matrixV.col(pos).swap(m_matrixV.col(i));
    }
  }

  m_isInitialized = true;
  return *this;
}

// Blocked Jacobi SVD sweep for both real and complex scalar types. For large n,
// applying left rotations (row operations on column-major data) causes cache
// misses due to strided access. To mitigate this, we accumulate kBlockSize left
// rotations into a small dense matrix and apply them via a single GEMM to the
// contiguous row block q..q+kBlockSize-1 and the (possibly distant) row p.
// Right rotations and column scalings act on columns (contiguous in column-major)
// and are applied individually.
//
// For complex types, the 2x2 preconditioning (making the block real) involves
// complex left rotations and row scalings, which are also accumulated into the
// block matrix. Column scalings from preconditioning are applied directly.
//
// The accumulated rotation matrix has lower-triangular structure in its top-left
// kBlockSize x kBlockSize corner, which we exploit with triangularView.
//
// Returns true if any off-diagonal element exceeded the threshold (i.e. sweep
// is not yet converged).
template <typename MatrixType, int Options>
EIGEN_DONT_INLINE bool JacobiSVD<MatrixType, Options>::blocked_sweep(RealScalar considerAsZero, RealScalar precision,
                                                                     RealScalar& maxDiagEntry) {
  using numext::abs;
  using numext::sqrt;
  const Index n = diagSize();
  RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
  bool notFinished = false;
  static constexpr Index kBlockBufferSize = (kBlockSize + 1) * (kBlockSize + 1);
  ei_declare_aligned_stack_constructed_variable(Scalar, blockBufferPtr, kBlockBufferSize, 0);
  Map<Matrix<Scalar, kBlockSize + 1, kBlockSize + 1, MatrixOptions>, AlignedMax> blockBuffer(
      blockBufferPtr, kBlockSize + 1, kBlockSize + 1);

  ei_declare_aligned_stack_constructed_variable(Scalar, accumPtr, kBlockBufferSize, 0);
  Map<Matrix<Scalar, kBlockSize + 1, kBlockSize + 1, MatrixOptions>, AlignedMax> accum(accumPtr, kBlockSize + 1,
                                                                                       kBlockSize + 1);

  for (Index p = 1; p < n; ++p) {
    Index q = 0;

    // Blocked loop: process kBlockSize pairs (p,q+qq) for qq=0..kBlockSize-1.
    // We extract the relevant (kBlockSize+1) x (kBlockSize+1) submatrix of W
    // into a small buffer, compute all rotations on the buffer, accumulate the
    // left transformations into `accum`, and apply them in one GEMM at the end.
    for (; q + kBlockSize <= p; q += kBlockSize) {
      // Buffer = [ W(q:q+k, q:q+k)  W(q:q+k, p) ]
      //          [ W(p, q:q+k)       W(p, p)      ]
      blockBuffer.template topLeftCorner<kBlockSize, kBlockSize>() =
          m_workMatrix.template block<kBlockSize, kBlockSize>(q, q);
      blockBuffer.col(kBlockSize).template head<kBlockSize>() = m_workMatrix.col(p).template segment<kBlockSize>(q);
      blockBuffer.row(kBlockSize).template head<kBlockSize>() = m_workMatrix.row(p).template segment<kBlockSize>(q);
      blockBuffer(kBlockSize, kBlockSize) = m_workMatrix(p, p);

      // Accumulator for left transformations: W <- accum * W.
      // After processing qq pairs, accum's top-left kBlockSize x kBlockSize
      // block is lower-triangular (each rotation only mixes row qq with row
      // kBlockSize, so rows 0..qq-1 are unchanged).
      accum.setIdentity(kBlockSize + 1, kBlockSize + 1);
      bool blockDirty = false;

      for (Index qq = 0; qq < kBlockSize; ++qq) {
        if (abs(blockBuffer.coeff(kBlockSize, qq)) > threshold || abs(blockBuffer.coeff(qq, kBlockSize)) > threshold) {
          notFinished = true;
          blockDirty = true;

          // Complex preconditioning: transform the 2x2 block
          //   [w_pp  w_pq] = [buffer(kBlockSize, kBlockSize)  buffer(kBlockSize, qq)]
          //   [w_qp  w_qq]   [buffer(qq, kBlockSize)          buffer(qq, qq)        ]
          // to have real entries via unitary row/column operations, so
          // real_2x2_jacobi_svd can be applied.
          //
          // Left operations (complex rotation, row scaling by e^{i*theta}) are
          // accumulated into `accum` for deferred GEMM application.
          // Right operations (column scaling) are applied directly since column
          // ops are contiguous in column-major layout.
          bool doRealSvd = true;
          EIGEN_IF_CONSTEXPR (NumTraits<Scalar>::IsComplex) {
            Scalar z;
            // nn = ||(w_pp, w_qp)||_2, the norm of the first column of the 2x2 block.
            RealScalar nn = sqrt(numext::abs2(blockBuffer.coeff(kBlockSize, kBlockSize)) +
                                 numext::abs2(blockBuffer.coeff(qq, kBlockSize)));

            if (numext::is_exactly_zero(nn)) {
              // First column is zero => block is already upper triangular.
              blockBuffer.coeffRef(kBlockSize, kBlockSize) = Scalar(0);
              blockBuffer.coeffRef(qq, kBlockSize) = Scalar(0);

              // Scale rows by z = e^{-i*arg(w)} to make remaining entries real.
              if (abs(numext::imag(blockBuffer.coeff(kBlockSize, qq))) > considerAsZero) {
                z = abs(blockBuffer.coeff(kBlockSize, qq)) / blockBuffer.coeff(kBlockSize, qq);
                blockBuffer.row(kBlockSize) *= z;
                accum.row(kBlockSize) *= z;  // accumulate left op
                if (computeU()) m_matrixU.col(p) *= numext::conj(z);
              }
              if (abs(numext::imag(blockBuffer.coeff(qq, qq))) > considerAsZero) {
                z = abs(blockBuffer.coeff(qq, qq)) / blockBuffer.coeff(qq, qq);
                blockBuffer.row(qq) *= z;
                accum.row(qq) *= z;  // accumulate left op
                if (computeU()) m_matrixU.col(q + qq) *= numext::conj(z);
              }
            } else {
              // Apply complex Givens rotation to zero out w_qp:
              //   [c  s] [w_pp]   [nn]      conj(w_pp)         w_qp
              //   [-s c] [w_qp] = [0 ]  c = ----------,  s = ------
              //                                 nn              nn
              JacobiRotation<Scalar> rot;
              rot.c() = numext::conj(blockBuffer.coeff(kBlockSize, kBlockSize)) / nn;
              rot.s() = blockBuffer.coeff(qq, kBlockSize) / nn;
              blockBuffer.applyOnTheLeft(kBlockSize, qq, rot);
              accum.applyOnTheLeft(kBlockSize, qq, rot);  // accumulate left op
              if (computeU()) m_matrixU.applyOnTheRight(p, q + qq, rot.adjoint());

              // Scale column qq by z = e^{-i*arg(w_pq)} to make w_pq real.
              if (abs(numext::imag(blockBuffer.coeff(kBlockSize, qq))) > considerAsZero) {
                z = abs(blockBuffer.coeff(kBlockSize, qq)) / blockBuffer.coeff(kBlockSize, qq);
                blockBuffer.col(qq) *= z;
                m_workMatrix.col(q + qq) *= z;  // right op: apply directly
                if (computeV()) m_matrixV.col(q + qq) *= z;
              }
              // Scale row qq by z = e^{-i*arg(w_qq)} to make w_qq real.
              if (abs(numext::imag(blockBuffer.coeff(qq, qq))) > considerAsZero) {
                z = abs(blockBuffer.coeff(qq, qq)) / blockBuffer.coeff(qq, qq);
                blockBuffer.row(qq) *= z;
                accum.row(qq) *= z;  // accumulate left op
                if (computeU()) m_matrixU.col(q + qq) *= numext::conj(z);
              }
            }
            // Update maxDiagEntry from preconditioning.
            maxDiagEntry = numext::maxi<RealScalar>(
                maxDiagEntry, numext::maxi<RealScalar>(abs(blockBuffer.coeff(kBlockSize, kBlockSize)),
                                                       abs(blockBuffer.coeff(qq, qq))));
            // Check if 2x2 block still needs diagonalizing.
            RealScalar precondThreshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
            doRealSvd = abs(blockBuffer.coeff(kBlockSize, qq)) > precondThreshold ||
                        abs(blockBuffer.coeff(qq, kBlockSize)) > precondThreshold;
          }

          if (doRealSvd) {
            // Compute real 2x2 SVD: buffer_2x2 = j_left * diag * j_right^T.
            JacobiRotation<RealScalar> j_left, j_right;
            internal::real_2x2_jacobi_svd(blockBuffer, kBlockSize, qq, &j_left, &j_right);
            blockBuffer.applyOnTheLeft(kBlockSize, qq, j_left);
            blockBuffer.applyOnTheRight(kBlockSize, qq, j_right);

            // Accumulate left rotation for deferred GEMM.
            accum.applyOnTheLeft(kBlockSize, qq, j_left);

            // Right rotation is a column op (contiguous): apply directly.
            m_workMatrix.applyOnTheRight(p, q + qq, j_right);
            if (computeU()) m_matrixU.applyOnTheRight(p, q + qq, j_left.transpose());
            if (computeV()) m_matrixV.applyOnTheRight(p, q + qq, j_right);

            maxDiagEntry = numext::maxi<RealScalar>(
                maxDiagEntry, numext::maxi<RealScalar>(abs(blockBuffer.coeff(kBlockSize, kBlockSize)),
                                                       abs(blockBuffer.coeff(qq, qq))));
          }
          threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
        }
      }

      // Apply accumulated left rotations: W <- accum * W, via GEMM.
      // When p == q + kBlockSize, all kBlockSize+1 rows are contiguous.
      // Otherwise, rows q..q+k-1 and row p are non-adjacent; we split:
      //   [Mq]      [L11  l12] [Mq]
      //   [Mp] <-   [l21  l22] [Mp]
      // L11 is lower-triangular (exploited via triangularView).
      if (blockDirty) {
        if (p == q + kBlockSize) {
          m_workMatrix.template middleRows<kBlockSize + 1>(q) =
              accum * m_workMatrix.template middleRows<kBlockSize + 1>(q);
        } else {
          const auto L11 = accum.template topLeftCorner<kBlockSize, kBlockSize>();
          const auto l12 = accum.col(kBlockSize).template head<kBlockSize>();
          const auto l21 = accum.row(kBlockSize).template head<kBlockSize>();
          const Scalar l22 = accum(kBlockSize, kBlockSize);
          auto Mq = m_workMatrix.template middleRows<kBlockSize>(q);
          auto Mp = m_workMatrix.row(p);
          Matrix<Scalar, 1, Dynamic, RowMajor, 1, MaxDiagSizeAtCompileTime> Mp_save = Mp;
          Mp.noalias() = l21 * Mq + l22 * Mp_save;
          Mq = L11.template triangularView<Lower>() * Mq + l12 * Mp_save;
        }
      }
    }

    // Scalar loop for remaining pairs after blocked processing.
    for (; q < p; ++q) {
      if (abs(m_workMatrix.coeff(p, q)) > threshold || abs(m_workMatrix.coeff(q, p)) > threshold) {
        notFinished = true;

        bool doRealSvd = true;
        EIGEN_IF_CONSTEXPR (NumTraits<Scalar>::IsComplex) {
          doRealSvd = internal::svd_precondition_2x2_block_to_be_real<MatrixType, Options>::run(m_workMatrix, *this, p,
                                                                                                q, maxDiagEntry);
        }

        if (doRealSvd) {
          JacobiRotation<RealScalar> j_left, j_right;
          internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
          m_workMatrix.applyOnTheLeft(p, q, j_left);
          if (computeU()) m_matrixU.applyOnTheRight(p, q, j_left.transpose());
          m_workMatrix.applyOnTheRight(p, q, j_right);
          if (computeV()) m_matrixV.applyOnTheRight(p, q, j_right);
          maxDiagEntry = numext::maxi<RealScalar>(
              maxDiagEntry, numext::maxi<RealScalar>(abs(m_workMatrix.coeff(p, p)), abs(m_workMatrix.coeff(q, q))));
        }
        threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
      }
    }
  }

  return notFinished;
}

/** \svd_module
 *
 * \return the singular value decomposition of \c *this computed by two-sided
 * Jacobi transformations.
 *
 * \sa class JacobiSVD
 */
template <typename Derived>
template <int Options>
JacobiSVD<typename MatrixBase<Derived>::PlainObject, Options> MatrixBase<Derived>::jacobiSvd() const {
  return JacobiSVD<PlainObject, Options>(*this);
}

template <typename Derived>
template <int Options>
JacobiSVD<typename MatrixBase<Derived>::PlainObject, Options> MatrixBase<Derived>::jacobiSvd(
    unsigned int computationOptions) const {
  return JacobiSVD<PlainObject, Options>(*this, computationOptions);
}

}  // end namespace Eigen

#endif  // EIGEN_JACOBISVD_H
