// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

// References:
//  [1] G. H. Golub and C. F. Van Loan, "Matrix Computations", 4th ed., Johns
//      Hopkins University Press, 2013, chapter 4.7 (Toeplitz, Hankel and
//      related systems) and chapter 4.8 (fast products via circulant embedding
//      and the FFT).
//  [2] R. H. Chan and X.-Q. Jin, "An Introduction to Iterative Toeplitz
//      Solvers", SIAM, 2007 (a Hankel matrix is a column-reversed Toeplitz
//      matrix, so its products and solves reduce to the Toeplitz machinery).

#ifndef EIGEN_STRUCTURED_HANKEL_H
#define EIGEN_STRUCTURED_HANKEL_H

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

namespace Eigen {

template <typename Scalar_, int Rows_ = Dynamic, int Cols_ = Dynamic>
class Hankel;

namespace internal {

template <typename Scalar_, int Rows_, int Cols_>
struct traits<Hankel<Scalar_, Rows_, Cols_>> {
  using Scalar = Scalar_;
  using StorageKind = Dense;
  using XprKind = MatrixXpr;
  using StorageIndex = int;
  static constexpr int RowsAtCompileTime = Rows_;
  static constexpr int ColsAtCompileTime = Cols_;
  static constexpr int MaxRowsAtCompileTime = Rows_;
  static constexpr int MaxColsAtCompileTime = Cols_;
  // Deliberately no NestByRefBit: transpose(), conjugate() and adjoint() return
  // owning temporaries, so Product must nest the operator by value for a
  // delayed-evaluated product expression to keep its left factor alive. The copy
  // is O(n), negligible against the O(n log n) product evaluation.
  static constexpr unsigned int Flags = 0;
};

template <typename Scalar_, int Rows_, int Cols_>
struct evaluator_traits<Hankel<Scalar_, Rows_, Cols_>> {
  using Kind = IndexBased;
  using Shape = StructuredShape;
};

}  // namespace internal

/** \ingroup StructuredMatrices_Module
 * \class Hankel
 * \brief An \c m x \c n Hankel matrix represented by its first column and last row.
 *
 * A Hankel matrix has constant anti-diagonals: entry \c (i,j) equals \c h[i+j],
 * where \c h is the length \c m+n-1 sequence formed by the first column followed
 * by the tail of the last row. The overlap entry \c h[m-1] is taken from the
 * column, so \c row[0] is ignored. Every column of the matrix is a contiguous
 * slice of \c h. A real square Hankel matrix is symmetric.
 *
 * The matrix-vector product (\c operator*) is evaluated in O(n log n): a Hankel
 * matrix is a column-reversed Toeplitz matrix, so the product is a circulant
 * convolution of \c h with the reversed input, evaluated through a DFT symbol
 * computed once at construction. (Small operators, and single-row or
 * single-column ones -- whose products cost O(n) directly -- skip the FFT for a
 * direct evaluation.) As with \ref Toeplitz, \c operator* returns an Eigen
 * product expression, so a \c Hankel plugs into the matrix-free iterative
 * solvers (including the least-squares solvers, through \ref adjoint), and it can
 * be assigned to a dense matrix when an explicit representation is needed. As
 * with any matrix-free operator, the iterative solvers must be instantiated with
 * \c IdentityPreconditioner (e.g.
 * \c LeastSquaresConjugateGradient<Hankel<double>,IdentityPreconditioner>):
 * the default preconditioners read individual coefficients through \c col() or
 * \c InnerIterator, which the structured operators do not expose.
 *
 * The class is closed under \ref transpose, \ref conjugate and \ref adjoint. The
 * transpose is the Hankel matrix of the same sequence with the dimensions
 * swapped, and its symbol is obtained from the cached one by a diagonal phase
 * multiplication instead of a new FFT.
 *
 * Square linear systems are solved directly in O(n^2) through the column-reversed
 * \ref Toeplitz equivalent (\ref toToeplitz) and the \ref LookAheadLevinson
 * solver, see \ref solve.
 *
 * \tparam Scalar_ the scalar type, real or complex.
 * \tparam Rows_ the number of rows at compile time, or \c Dynamic (the default).
 * \tparam Cols_ the number of columns at compile time, or \c Dynamic (the default).
 *
 * \par Examples
 * \ref StructuredExamplePade "Pade approximation",
 * \ref StructuredExampleProny "Prony's method".
 *
 * \sa class Toeplitz, class Circulant, makeHankel()
 */
template <typename Scalar_, int Rows_, int Cols_>
class Hankel : public EigenBase<Hankel<Scalar_, Rows_, Cols_>> {
 public:
  using Scalar = Scalar_;
  using RealScalar = typename NumTraits<Scalar>::Real;
  using StorageIndex = int;
  using Complex = std::complex<RealScalar>;
  using ColGeneratorType = Matrix<Scalar, Rows_, 1>;
  using RowGeneratorType = Matrix<Scalar, Cols_, 1>;
  using ComplexVector = Matrix<Complex, Dynamic, 1>;

  static constexpr int RowsAtCompileTime = Rows_;
  static constexpr int ColsAtCompileTime = Cols_;
  static constexpr int MaxRowsAtCompileTime = Rows_;
  static constexpr int MaxColsAtCompileTime = Cols_;
  static constexpr int SizeAtCompileTime = internal::size_at_compile_time(Rows_, Cols_);
  static constexpr int MaxSizeAtCompileTime = SizeAtCompileTime;
  static constexpr bool IsRowMajor = false;
  // Deliberately no IsVectorAtCompileTime: Ref<const Hankel>'s default StrideType
  // argument reads it, so its absence makes internal::is_ref_compatible SFINAE to
  // false and keeps the iterative solvers on their matrix-free path.

  /** \internal Compile-time length of the generating sequence h. */
  static constexpr int GenSizeAtCompileTime = (Rows_ == Dynamic || Cols_ == Dynamic) ? Dynamic : (Rows_ + Cols_ - 1);
  using GeneratorType = Matrix<Scalar, GenSizeAtCompileTime, 1>;

  /** Builds a Hankel matrix from its first column \a col and last row \a row.
   * The anti-diagonal overlap entry is taken from \a col, hence \c row[0] is
   * ignored.
   *
   * Unless the matrix is small, or a single row or column (whose products are
   * always evaluated directly, in linear time), the DFT symbol of the underlying
   * circulant convolution is computed here, once, and reused by every subsequent
   * product. */
  template <typename ColDerived, typename RowDerived>
  Hankel(const MatrixBase<ColDerived>& col, const MatrixBase<RowDerived>& row)
      : m_rows(col.size()), m_cols(row.size()) {
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(ColDerived)
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(RowDerived)
    const Index m = col.size(), n = row.size();
    EIGEN_INTERNAL_ASSERT_NONEMPTY_SIZE_MSG(col, m, "Hankel generators must be non-empty");
    EIGEN_INTERNAL_ASSERT_NONEMPTY_SIZE_MSG(row, n, "Hankel generators must be non-empty");
    m_h.resize(m + n - 1);
    m_h.head(m) = col;
    if (n > 1) m_h.tail(n - 1) = row.tail(n - 1);
    if (m > 1 && n > 1 && (m > internal::structured_direct_threshold() || n > internal::structured_direct_threshold()))
      m_symbol = computeSymbol();
  }

  EIGEN_DEVICE_FUNC Index rows() const { return m_rows.value(); }
  EIGEN_DEVICE_FUNC Index cols() const { return m_cols.value(); }

  /** \returns the generating sequence \c h of length \c m+n-1; entry \c (i,j) of
   * the matrix is \c h[i+j]. */
  const GeneratorType& generator() const { return m_h; }

  /** \returns the first column, \c h[0..m-1]. */
  ColGeneratorType column() const { return m_h.head(rows()); }

  /** \returns the last row, \c h[m-1..m+n-2]. */
  RowGeneratorType lastRow() const { return m_h.segment(rows() - 1, cols()); }

  /** \returns the symbol of the underlying circulant convolution: the DFT of the
   * generating sequence, zero-padded to a 5-smooth size p >= m+n-1 and rotated so
   * the product appears in the leading \c m entries of the back-transform. Cached
   * when the operator is large enough for products to take the FFT path, computed
   * on the fly for small operators. */
  ComplexVector symbol() const { return m_symbol.size() > 0 ? m_symbol : computeSymbol(); }

  /** \returns the coefficient at row \a row and column \a col. */
  Scalar coeff(Index row, Index col) const { return m_h.coeff(row + col); }

  /** \returns the transpose of \c *this, itself a Hankel operator: the same
   * generating sequence with the dimensions swapped. The cached symbol, when
   * present, is reused: transposing changes the rotation of the embedding from
   * \c n-1 to \c m-1, which multiplies DFT entry \c f by \c exp(2 pi i f (m-n)/p)
   * -- a diagonal phase multiplication instead of a new FFT. */
  Hankel<Scalar, Cols_, Rows_> transpose() const {
    return Hankel<Scalar, Cols_, Rows_>(m_h, cols(), rows(), transposedSymbol());
  }

  /** \returns the complex conjugate of \c *this, itself a Hankel operator. The
   * cached symbol, when present, is reused: the symbol of the conjugate is the
   * conjugated index reversal of the symbol. */
  Hankel conjugate() const {
    return Hankel(m_h.conjugate(), rows(), cols(), internal::structured_reverse_symbol(m_symbol).conjugate());
  }

  /** \returns the adjoint of \c *this, itself a Hankel operator (the conjugated
   * transpose); the cached symbol is reused through the composition of the
   * \ref conjugate and \ref transpose rules. */
  Hankel<Scalar, Cols_, Rows_> adjoint() const { return conjugate().transpose(); }

  /** \returns the column-reversed \ref Toeplitz equivalent \c T = H*E (with \c E
   * the exchange matrix), i.e. \c T(i,j) = h[i + n-1 - j]. Its symbol is computed
   * afresh. Useful for solving Hankel systems with the Toeplitz machinery:
   * \c H*x = b is \c T*(E*x) = b. */
  Toeplitz<Scalar, Rows_, Cols_> toToeplitz() const {
    ColGeneratorType c = m_h.segment(cols() - 1, rows());
    RowGeneratorType r = m_h.head(cols()).reverse();
    return Toeplitz<Scalar, Rows_, Cols_>(c, r);
  }

  /** \internal Compile-time row count of solve() results: the solution of a
   * square system has cols() == rows() entries, so either fixed dimension
   * determines it at compile time. */
  static constexpr int SolveRowsAtCompileTime = Cols_ != Dynamic ? Cols_ : Rows_;

  /** \returns the solution \c x of \c (*this) * x = b for a \b square Hankel
   * matrix, computed in O(n^2) by solving the column-reversed Toeplitz system
   * \c T*y = b with the \ref LookAheadLevinson solver and reversing the solution.
   * Supports multiple right-hand sides. Each call factorizes anew; to reuse a
   * factorization across calls, or to check for numerical breakdown through
   * \c info(), use \c LookAheadLevinson on \ref toToeplitz directly and reverse
   * the solution rows. */
  template <typename Rhs>
  Matrix<Scalar, SolveRowsAtCompileTime, Rhs::ColsAtCompileTime> solve(const MatrixBase<Rhs>& b) const {
    EIGEN_INTERNAL_ASSERT_SQUARE_MSG(*this, "Hankel::solve requires a square matrix");
    EIGEN_INTERNAL_ASSERT_SOLVER_RHS_MSG(*this, b, false, "right-hand side has the wrong number of rows");
    LookAheadLevinson<Scalar> levinson(toToeplitz());
    eigen_assert(levinson.info() == Success &&
                 "Hankel::solve: the Levinson recursion broke down; "
                 "use LookAheadLevinson on toToeplitz() for diagnostics");
    return levinson.solve(b).colwise().reverse();
  }

  /** \internal Writes the dense representation into \a dst; column \c j is the
   * contiguous slice \c h[j..j+m-1]. Row-major destinations copy the contiguous
   * slice \c h[i..i+n-1] into row i. Invoked through \c dense = hankel; */
  template <typename Dest>
  void evalTo(Dest& dst) const {
    EIGEN_IF_CONSTEXPR (Dest::IsRowMajor) {
      for (Index i = 0; i < rows(); ++i) dst.row(i) = m_h.segment(i, cols()).transpose();
      return;
    }
    for (Index j = 0; j < cols(); ++j) dst.col(j) = m_h.segment(j, rows());
  }

  /** \internal Computes \c dst += (*this), see evalTo(). */
  template <typename Dest>
  void addTo(Dest& dst) const {
    EIGEN_IF_CONSTEXPR (Dest::IsRowMajor) {
      for (Index i = 0; i < rows(); ++i) dst.row(i) += m_h.segment(i, cols()).transpose();
      return;
    }
    for (Index j = 0; j < cols(); ++j) dst.col(j) += m_h.segment(j, rows());
  }

  /** \internal Computes \c dst -= (*this), see evalTo(). */
  template <typename Dest>
  void subTo(Dest& dst) const {
    EIGEN_IF_CONSTEXPR (Dest::IsRowMajor) {
      for (Index i = 0; i < rows(); ++i) dst.row(i) -= m_h.segment(i, cols()).transpose();
      return;
    }
    for (Index j = 0; j < cols(); ++j) dst.col(j) -= m_h.segment(j, rows());
  }

  /** \returns the product expression \c (*this) * \a x, evaluated through a fast
   * FFT-based matrix-vector product. The expression carries the default product
   * tag, so assigning it behaves like any dense product: a temporary resolves
   * aliasing between the destination and \a x, and \c .noalias() skips it. */
  template <typename Rhs>
  Product<Hankel, Rhs> operator*(const MatrixBase<Rhs>& x) const {
    return Product<Hankel, Rhs>(*this, x.derived());
  }

  /** \internal Computes \c dst += alpha * (*this) * rhs. \c ProductScalar is the
   * promoted scalar of the product (complex when a real operator is applied to a
   * complex right-hand side); the accumulation runs in the promoted type.
   *
   * The FFT path evaluates the circular convolution
   * \f[ (Hx)_i = \sum_{j=0}^{n-1} h_{i+j} x_j. \f]
   * Reversing \f$x\f$ and rotating the padded symbol by \f$n-1\f$ places these
   * entries at the start of the inverse transform. */
  template <typename Dest, typename Rhs, typename ProductScalar>
  void addProduct(Dest& dst, const Rhs& rhs, const ProductScalar& alpha) const {
    const Index m = rows(), n = cols();
    EIGEN_INTERNAL_ASSERT_PRODUCT_SHAPE_MSG(*this, rhs, "invalid product: dimensions do not match");
    const bool small = m == 1 || n == 1 ||
                       (m <= internal::structured_direct_threshold() && n <= internal::structured_direct_threshold());
    if (small) {
      directProduct(dst, rhs, alpha);
      return;
    }
    internal::structured_fft_apply(dst, m_symbol, m, rhs.colwise().reverse(), alpha);
  }

 private:
  template <typename OtherScalar, int OtherRows, int OtherCols>
  friend class Hankel;

  /** \internal Builds an operator from the generating sequence and an
   * already-known symbol (empty for small operators), skipping the FFT of the
   * public constructor. Used by transpose(), conjugate() and adjoint(), whose
   * symbols are cheap transformations of the existing one. */
  Hankel(const GeneratorType& h, Index rows, Index cols, const ComplexVector& symbol)
      : m_rows(rows), m_cols(cols), m_h(h), m_symbol(symbol) {}

  /** \internal Direct kernel for column \a k of the right-hand side: computes
   * \c dst.col(k) += alpha * (*this) * rhs.col(k) without transforms. Serves
   * operators below the FFT threshold and single-row and single-column operators
   * (whose products cost O(n) directly, however large the operator). */
  template <typename Dest, typename Rhs, typename ProductScalar>
  void directProductColumn(Dest& dst, const Rhs& rhs, Index k, const ProductScalar& alpha) const {
    const Index m = rows(), n = cols();
    // A unit alpha must not multiply: even the identity complex scalar (1,0)
    // pollutes an (Inf,0) value with NaN through the 0*Inf cross term.
    const bool unitAlpha = alpha == ProductScalar(1);

    if (n == 1) {
      // The runtime-sized head keeps other fixed-size shapes well-formed.
      const ProductScalar xj = unitAlpha ? ProductScalar(rhs.coeff(0, k)) : ProductScalar(alpha * rhs.coeff(0, k));
      dst.col(k) += xj * m_h.head(m);
      return;
    }

    if (m == 1) {
      const ProductScalar acc = m_h.head(n).cwiseProduct(rhs.col(k)).sum();
      dst.coeffRef(0, k) += unitAlpha ? acc : ProductScalar(alpha * acc);
      return;
    }

    if (m <= internal::structured_scalar_threshold() && n <= internal::structured_scalar_threshold()) {
      // Tiny sizes: a plain scalar loop beats the segment-based path below, whose
      // per-segment setup dominates when segments hold only a few entries.
      for (Index i = 0; i < m; ++i) {
        ProductScalar acc(0);
        for (Index j = 0; j < n; ++j) acc += coeff(i, j) * rhs.coeff(j, k);
        dst.coeffRef(i, k) += unitAlpha ? acc : ProductScalar(alpha * acc);
      }
      return;
    }

    // Column j is the contiguous, vectorizable slice h[j..j+m-1].
    auto dstCol = dst.col(k);
    for (Index j = 0; j < n; ++j) {
      const ProductScalar xj = unitAlpha ? ProductScalar(rhs.coeff(j, k)) : ProductScalar(alpha * rhs.coeff(j, k));
      dstCol += xj * m_h.segment(j, m);
    }
  }

  /** \internal Direct product kernel over every column, see
   * directProductColumn(). */
  template <typename Dest, typename Rhs, typename ProductScalar>
  void directProduct(Dest& dst, const Rhs& rhs, const ProductScalar& alpha) const {
    for (Index k = 0; k < rhs.cols(); ++k) directProductColumn(dst, rhs, k, alpha);
  }

  /** \internal \returns the DFT of the generating sequence, zero-padded to the
   * 5-smooth size p >= m+n-1 and rotated left by n-1 so that the convolution
   * against a reversed input lands the product in the leading m entries. */
  ComplexVector computeSymbol() const {
    const Index m = rows(), n = cols();
    const Index p = internal::fft_next_good_size(m + n - 1);
    ComplexVector embedding = ComplexVector::Zero(p);
    embedding.head(m) = m_h.tail(m).template cast<Complex>();  // h[n-1 .. m+n-2]
    embedding.tail(n - 1) = m_h.head(n - 1).template cast<Complex>();
    if (p == 1) return embedding;  // the DFT of a single sample is the identity
    ComplexVector symbol(p);
    auto&& fft = internal::structured_fft_engine<RealScalar>();
    fft.fwd(symbol, embedding, p);
    return symbol;
  }

  /** \internal \returns the symbol of the transposed operator: the embedding
   * rotation changes from n-1 to m-1, which by the DFT shift theorem multiplies
   * entry f by exp(2 pi i f (m-n) / p). The frequency-shift product f*(m-n) is
   * accumulated incrementally modulo p, so the angle stays O(2 pi) at full
   * accuracy and no Index overflow can occur. An empty symbol stays empty. */
  ComplexVector transposedSymbol() const {
    ComplexVector sym = m_symbol;
    const Index p = sym.size();
    if (p > 0 && rows() != cols()) {
      Index s = (rows() - cols()) % p;
      if (s < 0) s += p;
      // Contiguous real buffers let sin/cos use packets; complex component views
      // alone have stride two and would force scalar trigonometric evaluation.
      Array<RealScalar, 64, 1> angles, values;
      Matrix<Complex, 64, 1> phases;
      Index fs = 0;  // f * s mod p
      for (Index f = 0; f < p;) {
        const Index count = numext::mini<Index>(64, p - f);
        for (Index i = 0; i < count; ++i) {
          angles[i] = RealScalar(2 * EIGEN_PI) * RealScalar(fs) / RealScalar(p);
          fs += s;
          if (fs >= p) fs -= p;
        }
        values.head(count) = angles.head(count).cos();
        phases.head(count).real() = values.head(count);
        values.head(count) = angles.head(count).sin();
        phases.head(count).imag() = values.head(count);
        sym.segment(f, count).array() *= phases.head(count).array();
        f += count;
      }
    }
    return sym;
  }

  // Empty (compile-time constant) when the corresponding dimension is fixed; the
  // dimensions cannot be recovered from m_h alone, whose length is rows()+cols()-1.
  internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
  internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
  GeneratorType m_h;
  ComplexVector m_symbol;
};

/** \ingroup StructuredMatrices_Module
 * \returns a \ref Hankel operator with first column \a col and last row \a row.
 * The compile-time dimensions of the operator are deduced from the generators. */
template <typename ColDerived, typename RowDerived>
Hankel<typename ColDerived::Scalar, ColDerived::SizeAtCompileTime, RowDerived::SizeAtCompileTime> makeHankel(
    const MatrixBase<ColDerived>& col, const MatrixBase<RowDerived>& row) {
  return Hankel<typename ColDerived::Scalar, ColDerived::SizeAtCompileTime, RowDerived::SizeAtCompileTime>(col, row);
}

namespace internal {

// Single product specialization covering every product tag; see the note in
// Circulant.h.
template <typename Scalar_, int Rows_, int Cols_, typename Rhs, int ProductTag>
struct generic_product_impl<Hankel<Scalar_, Rows_, Cols_>, Rhs, StructuredShape, DenseShape, ProductTag>
    : structured_product_impl<Hankel<Scalar_, Rows_, Cols_>, Rhs> {};

}  // namespace internal

#if EIGEN_COMP_CXXVER < 17
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::RowsAtCompileTime;
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::ColsAtCompileTime;
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::MaxRowsAtCompileTime;
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::MaxColsAtCompileTime;
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::SizeAtCompileTime;
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::MaxSizeAtCompileTime;
template <typename Scalar_, int Rows_, int Cols_>
constexpr bool Hankel<Scalar_, Rows_, Cols_>::IsRowMajor;
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::GenSizeAtCompileTime;
template <typename Scalar_, int Rows_, int Cols_>
constexpr int Hankel<Scalar_, Rows_, Cols_>::SolveRowsAtCompileTime;
#endif

}  // namespace Eigen

#endif  // EIGEN_STRUCTURED_HANKEL_H
