// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
// Copyright (C) 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/.

#ifndef EIGEN_INCOMPLETE_LUT_H
#define EIGEN_INCOMPLETE_LUT_H

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

namespace Eigen {

namespace internal {

/** \internal
 * Compute a quick-sort split of a vector
 * On output, the vector row is permuted such that its elements satisfy
 * abs(row(i)) >= abs(row(ncut)) if i<ncut
 * abs(row(i)) <= abs(row(ncut)) if i>ncut
 * \param row The vector of values
 * \param ind The array of index for the elements in @p row
 * \param ncut  The number of largest elements to keep
 **/
template <typename VectorV, typename VectorI>
Index QuickSplit(VectorV& row, VectorI& ind, Index ncut) {
  typedef typename VectorV::RealScalar RealScalar;
  using std::abs;
  using std::swap;
  Index mid;
  Index n = row.size(); /* length of the vector */
  Index first, last;

  ncut--; /* to fit the zero-based indices */
  first = 0;
  last = n - 1;
  if (ncut < first || ncut > last) return 0;

  do {
    mid = first;
    RealScalar abskey = abs(row(mid));
    for (Index j = first + 1; j <= last; j++) {
      if (abs(row(j)) > abskey) {
        ++mid;
        swap(row(mid), row(j));
        swap(ind(mid), ind(j));
      }
    }
    /* Interchange for the pivot element */
    swap(row(mid), row(first));
    swap(ind(mid), ind(first));

    if (mid > ncut)
      last = mid - 1;
    else if (mid < ncut)
      first = mid + 1;
  } while (mid != ncut);

  return 0; /* mid is equal to ncut */
}

}  // end namespace internal

/** \ingroup IterativeLinearSolvers_Module
 * \class IncompleteLUT
 * \brief Incomplete LU factorization with dual-threshold strategy
 *
 * \implsparsesolverconcept
 *
 * During the numerical factorization, two dropping rules are used :
 *  1) any element whose magnitude is less than some tolerance is dropped.
 *    This tolerance is obtained by multiplying the input tolerance @p droptol
 *    by the average magnitude of all the original elements in the current row.
 *  2) After the elimination of the row, only the @p fill largest elements in
 *    the L part and the @p fill largest elements in the U part are kept
 *    (in addition to the diagonal element ). Note that @p fill is computed from
 *    the input parameter @p fillfactor which is used the ratio to control the fill_in
 *    relatively to the initial number of nonzero elements.
 *
 * The two extreme cases are when @p droptol=0 (to keep all the @p fill*2 largest elements)
 * and when @p fill=n/2 with @p droptol being different to zero.
 *
 * References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization,
 *              Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994.
 *
 * NOTE : The following implementation is derived from the ILUT implementation
 * in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota
 *  released under the terms of the GNU LGPL:
 *    http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README
 * However, Yousef Saad gave us permission to relicense his ILUT code to MPL2.
 * See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012:
 *   http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html
 * alternatively, on GMANE:
 *   http://comments.gmane.org/gmane.comp.lib.eigen/3302
 */
template <typename Scalar_, typename StorageIndex_ = int>
class IncompleteLUT : public SparseSolverBase<IncompleteLUT<Scalar_, StorageIndex_> > {
 protected:
  typedef SparseSolverBase<IncompleteLUT> Base;
  using Base::m_isInitialized;

 public:
  typedef Scalar_ Scalar;
  typedef StorageIndex_ StorageIndex;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, Dynamic, 1> Vector;
  typedef Matrix<StorageIndex, Dynamic, 1> VectorI;
  typedef SparseMatrix<Scalar, RowMajor, StorageIndex> FactorType;

  enum { ColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic };

 public:
  IncompleteLUT()
      : m_droptol(NumTraits<Scalar>::dummy_precision()),
        m_fillfactor(10),
        m_analysisIsOk(false),
        m_factorizationIsOk(false) {}

  template <typename MatrixType>
  explicit IncompleteLUT(const MatrixType& mat, const RealScalar& droptol = NumTraits<Scalar>::dummy_precision(),
                         int fillfactor = 10)
      : m_droptol(droptol), m_fillfactor(fillfactor), m_analysisIsOk(false), m_factorizationIsOk(false) {
    eigen_assert(fillfactor != 0);
    compute(mat);
  }

  /** \brief Extraction Method for L-Factor */
  const FactorType matrixL() const;

  /** \brief Extraction Method for U-Factor */
  const FactorType matrixU() const;

  constexpr Index rows() const noexcept { return m_lu.rows(); }

  constexpr Index cols() const noexcept { return m_lu.cols(); }

  /** \brief Reports whether previous computation was successful.
   *
   * \returns \c Success if computation was successful,
   *          \c NumericalIssue if a zero pivot was encountered during
   *          factorization (the resulting preconditioner is unlikely to be
   *          usable; the input matrix typically has zero diagonal entries
   *          that cannot be moved by a static row permutation, e.g. it is
   *          structurally singular).
   */
  ComputationInfo info() const {
    eigen_assert(m_isInitialized && "IncompleteLUT is not initialized.");
    return m_info;
  }

  template <typename MatrixType>
  void analyzePattern(const MatrixType& amat);

  template <typename MatrixType>
  void factorize(const MatrixType& amat);

  /**
   * Compute an incomplete LU factorization with dual threshold on the matrix mat
   * No partial pivoting is done in this version. A static row permutation
   * (maximum bipartite matching) is computed in \c analyzePattern so that
   * the permuted matrix has a structurally nonzero diagonal whenever one
   * exists; without it, the lack of pivoting makes ILUT silently produce
   * a useless preconditioner on matrices with zero diagonal entries.
   *
   **/
  template <typename MatrixType>
  IncompleteLUT& compute(const MatrixType& amat) {
    analyzePattern(amat);
    factorize(amat);
    return *this;
  }

  void setDroptol(const RealScalar& droptol);
  void setFillfactor(int fillfactor);

  template <typename Rhs, typename Dest>
  void _solve_impl(const Rhs& b, Dest& x) const {
    x = m_PinvPr * b;
    x = m_lu.template triangularView<UnitLower>().solve(x);
    x = m_lu.template triangularView<Upper>().solve(x);
    x = m_P * x;
  }

 protected:
  /** keeps off-diagonal entries; drops diagonal entries */
  struct keep_diag {
    inline bool operator()(const Index& row, const Index& col, const Scalar&) const { return row != col; }
  };

  template <typename MatrixType>
  Index computeRowMatching(const MatrixType& amat);

  // Produce a column-major CSC sparsity pattern for `amat` (integers only —
  // the scalar values are never read or copied). When `amat` is already a
  // compressed column-major SparseMatrix, `outer`/`inner` point directly into
  // its index storage; otherwise the pattern is materialized into the local
  // `outer_buf`/`inner_buf` arrays and pointers are set into them.
  static void patternColMajor(const SparseMatrix<Scalar, ColMajor, StorageIndex>& amat,
                              Matrix<StorageIndex, Dynamic, 1>& outer_buf, Matrix<StorageIndex, Dynamic, 1>& inner_buf,
                              const StorageIndex*& outer, const StorageIndex*& inner);

  template <typename MatrixType>
  static void patternColMajor(const MatrixType& amat, Matrix<StorageIndex, Dynamic, 1>& outer_buf,
                              Matrix<StorageIndex, Dynamic, 1>& inner_buf, const StorageIndex*& outer,
                              const StorageIndex*& inner);

 protected:
  FactorType m_lu;
  RealScalar m_droptol;
  int m_fillfactor;
  bool m_analysisIsOk;
  bool m_factorizationIsOk;
  ComputationInfo m_info;
  PermutationMatrix<Dynamic, Dynamic, StorageIndex> m_P;       // Fill-reducing permutation
  PermutationMatrix<Dynamic, Dynamic, StorageIndex> m_Pinv;    // Inverse permutation
  PermutationMatrix<Dynamic, Dynamic, StorageIndex> m_Pr;      // Static row permutation (matching-based)
  PermutationMatrix<Dynamic, Dynamic, StorageIndex> m_PinvPr;  // Cached composition m_Pinv * m_Pr for solve
};

/**
 * Set control parameter droptol
 *  \param droptol   Drop any element whose magnitude is less than this tolerance
 **/
template <typename Scalar, typename StorageIndex>
void IncompleteLUT<Scalar, StorageIndex>::setDroptol(const RealScalar& droptol) {
  this->m_droptol = droptol;
}

/**
 * Set control parameter fillfactor
 * \param fillfactor  This is used to compute the  number @p fill_in of largest elements to keep on each row.
 **/
template <typename Scalar, typename StorageIndex>
void IncompleteLUT<Scalar, StorageIndex>::setFillfactor(int fillfactor) {
  this->m_fillfactor = fillfactor;
}

/**
 * get L-Factor
 * \return L-Factor is a matrix containing the lower triangular part of the sparse matrix. All elements of the matrix
 * above the main diagonal are zero.
 **/
template <typename Scalar, typename StorageIndex>
const typename IncompleteLUT<Scalar, StorageIndex>::FactorType IncompleteLUT<Scalar, StorageIndex>::matrixL() const {
  eigen_assert(m_factorizationIsOk && "factorize() should be called first");
  return m_lu.template triangularView<UnitLower>();
}

/**
 * get U-Factor
 * \return L-Factor is a matrix containing the upper triangular part of the sparse matrix. All elements of the matrix
 * below the main diagonal are zero.
 **/
template <typename Scalar, typename StorageIndex>
const typename IncompleteLUT<Scalar, StorageIndex>::FactorType IncompleteLUT<Scalar, StorageIndex>::matrixU() const {
  eigen_assert(m_factorizationIsOk && "Factorization must be computed first.");
  return m_lu.template triangularView<Upper>();
}

// Specialization: amat is already a column-major SparseMatrix.
// Share its index storage directly when compressed; otherwise materialize the
// indices (without copying any scalar values) into outer_buf/inner_buf.
template <typename Scalar, typename StorageIndex>
void IncompleteLUT<Scalar, StorageIndex>::patternColMajor(const SparseMatrix<Scalar, ColMajor, StorageIndex>& amat,
                                                          Matrix<StorageIndex, Dynamic, 1>& outer_buf,
                                                          Matrix<StorageIndex, Dynamic, 1>& inner_buf,
                                                          const StorageIndex*& outer, const StorageIndex*& inner) {
  if (amat.isCompressed()) {
    outer = amat.outerIndexPtr();
    inner = amat.innerIndexPtr();
    return;
  }
  const Index n = amat.cols();
  const StorageIndex* a_outer = amat.outerIndexPtr();
  const StorageIndex* a_inner_nz = amat.innerNonZeroPtr();
  const StorageIndex* a_inner = amat.innerIndexPtr();
  outer_buf.resize(n + 1);
  outer_buf(0) = 0;
  for (Index j = 0; j < n; ++j) outer_buf(j + 1) = outer_buf(j) + a_inner_nz[j];
  inner_buf.resize(outer_buf(n));
  for (Index j = 0; j < n; ++j) {
    const StorageIndex* src = a_inner + a_outer[j];
    std::copy(src, src + a_inner_nz[j], inner_buf.data() + outer_buf(j));
  }
  outer = outer_buf.data();
  inner = inner_buf.data();
}

// Generic fallback: any other sparse input (row-major, expressions). Build a
// column-major pattern via inner iterators — no scalar values are read.
template <typename Scalar, typename StorageIndex>
template <typename MatrixType_>
void IncompleteLUT<Scalar, StorageIndex>::patternColMajor(const MatrixType_& amat,
                                                          Matrix<StorageIndex, Dynamic, 1>& outer_buf,
                                                          Matrix<StorageIndex, Dynamic, 1>& inner_buf,
                                                          const StorageIndex*& outer, const StorageIndex*& inner) {
  using internal::convert_index;
  const Index n = amat.cols();
  outer_buf.setZero(n + 1);
  for (Index i = 0; i < amat.outerSize(); ++i)
    for (typename MatrixType_::InnerIterator it(amat, i); it; ++it) ++outer_buf(it.col() + 1);
  for (Index j = 0; j < n; ++j) outer_buf(j + 1) += outer_buf(j);
  inner_buf.resize(outer_buf(n));
  Matrix<StorageIndex, Dynamic, 1> head = outer_buf.head(n);
  for (Index i = 0; i < amat.outerSize(); ++i)
    for (typename MatrixType_::InnerIterator it(amat, i); it; ++it)
      inner_buf(head(it.col())++) = convert_index<StorageIndex>(it.row());
  outer = outer_buf.data();
  inner = inner_buf.data();
}

// Compute a row permutation m_Pr such that (m_Pr * amat) has a structurally
// nonzero diagonal wherever one exists. Returns the number of matched columns.
// Uses a maximum bipartite cardinality matching on the sparsity pattern, with
// a greedy initialization that prefers the natural diagonal so that matrices
// already having a nonzero diagonal yield the identity permutation.
template <typename Scalar, typename StorageIndex>
template <typename MatrixType_>
Index IncompleteLUT<Scalar, StorageIndex>::computeRowMatching(const MatrixType_& amat) {
  using internal::convert_index;
  const Index n = amat.rows();
  // We only need the column-major sparsity pattern; never read scalar values.
  // Share amat's index storage when it is already a compressed column-major
  // SparseMatrix, otherwise build a value-free pattern into local arrays.
  Matrix<StorageIndex, Dynamic, 1> outer_buf;
  Matrix<StorageIndex, Dynamic, 1> inner_buf;
  const StorageIndex* outer = nullptr;
  const StorageIndex* inner = nullptr;
  patternColMajor(amat, outer_buf, inner_buf, outer, inner);

  const StorageIndex kUnmatched = StorageIndex(-1);
  // match_row[j] = original row matched to column j; match_col[i] = column matched to row i.
  std::vector<StorageIndex> match_row(n, kUnmatched);
  std::vector<StorageIndex> match_col(n, kUnmatched);

  // The matching uses the stored sparsity pattern only and is independent of
  // numerical values. This preserves the analyzePattern/factorize contract:
  // the same analysis is reusable for any matrix sharing this stored pattern.
  // Phase 1: greedy diagonal preference.
  for (Index j = 0; j < n; ++j) {
    for (Index k = outer[j]; k < outer[j + 1]; ++k) {
      if (Index(inner[k]) == j) {
        match_row[j] = convert_index<StorageIndex>(j);
        match_col[j] = convert_index<StorageIndex>(j);
        break;
      }
    }
  }
  // Phase 2: greedy off-diagonal pickup of any free row.
  for (Index j = 0; j < n; ++j) {
    if (match_row[j] != kUnmatched) continue;
    for (Index k = outer[j]; k < outer[j + 1]; ++k) {
      Index i = inner[k];
      if (match_col[i] == kUnmatched) {
        match_row[j] = convert_index<StorageIndex>(i);
        match_col[i] = convert_index<StorageIndex>(j);
        break;
      }
    }
  }
  // Phase 3: augmenting paths for any column still unmatched.
  std::vector<StorageIndex> visited(n, kUnmatched);
  // Iterative DFS: the stack frames are (column, edge index, chosen row).
  // chosen_row[k] is the row that frame k will commit to if a path is found.
  std::vector<Index> stack_col;
  std::vector<Index> stack_pos;
  std::vector<Index> stack_chosen_row;
  stack_col.reserve(n);
  stack_pos.reserve(n);
  stack_chosen_row.reserve(n);

  for (Index start = 0; start < n; ++start) {
    if (match_row[start] != kUnmatched) continue;
    StorageIndex epoch = convert_index<StorageIndex>(start);
    stack_col.clear();
    stack_pos.clear();
    stack_chosen_row.clear();
    stack_col.push_back(start);
    stack_pos.push_back(outer[start]);
    stack_chosen_row.push_back(-1);

    while (!stack_col.empty()) {
      Index j = stack_col.back();
      Index pos = stack_pos.back();
      Index col_end = outer[j + 1];
      bool advanced = false;

      while (pos < col_end) {
        Index i = inner[pos];
        ++pos;
        if (visited[i] == epoch) continue;
        visited[i] = epoch;

        if (match_col[i] == kUnmatched) {
          // Found an augmenting path: commit it.
          stack_chosen_row.back() = i;
          stack_pos.back() = pos;
          for (size_t k = 0; k < stack_col.size(); ++k) {
            Index col = stack_col[k];
            Index row = stack_chosen_row[k];
            match_row[col] = convert_index<StorageIndex>(row);
            match_col[row] = convert_index<StorageIndex>(col);
          }
          stack_col.clear();
          break;
        } else {
          // Descend into the column currently matched to row i.
          stack_chosen_row.back() = i;
          stack_pos.back() = pos;
          Index next_col = match_col[i];
          stack_col.push_back(next_col);
          stack_pos.push_back(outer[next_col]);
          stack_chosen_row.push_back(-1);
          advanced = true;
          break;
        }
      }

      if (!advanced && !stack_col.empty()) {
        stack_col.pop_back();
        stack_pos.pop_back();
        stack_chosen_row.pop_back();
      }
    }
  }

  // Build the row permutation. Matched columns get their matching row;
  // any leftover columns are filled in identity-fashion with the leftover rows.
  m_Pr.resize(n);
  std::vector<bool> col_used(n, false), row_used(n, false);
  Index matched = 0;
  for (Index j = 0; j < n; ++j) {
    if (match_row[j] != kUnmatched) {
      m_Pr.indices()(match_row[j]) = convert_index<StorageIndex>(j);
      col_used[j] = true;
      row_used[match_row[j]] = true;
      ++matched;
    }
  }
  Index next_col = 0;
  for (Index i = 0; i < n; ++i) {
    if (row_used[i]) continue;
    while (next_col < n && col_used[next_col]) ++next_col;
    m_Pr.indices()(i) = convert_index<StorageIndex>(next_col);
    ++next_col;
  }
  return matched;
}

template <typename Scalar, typename StorageIndex>
template <typename MatrixType_>
void IncompleteLUT<Scalar, StorageIndex>::analyzePattern(const MatrixType_& amat) {
  eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix");
  // 1. Compute a static row permutation that makes the diagonal structurally
  //    nonzero. This is a workaround for the lack of partial pivoting in ILUT.
  //    For matrices that already have a nonzero diagonal, this returns the
  //    identity permutation and is essentially free.
  computeRowMatching(amat);

  // 2. Compute the Fill-reducing permutation on the row-permuted matrix.
  // Since ILUT does not perform any numerical pivoting,
  // it is highly preferable to keep the diagonal through symmetric permutations.
  // To this end, let's symmetrize the pattern and perform AMD on it.
  SparseMatrix<Scalar, ColMajor, StorageIndex> mat1 = m_Pr * amat;
  SparseMatrix<Scalar, ColMajor, StorageIndex> mat2 = mat1.transpose();
  // FIXME: for a nearly symmetric pattern, mat2+mat1 is appropriate;
  //        for a highly non-symmetric pattern, mat2*mat1 should be preferred.
  SparseMatrix<Scalar, ColMajor, StorageIndex> AtA = mat2 + mat1;
  AMDOrdering<StorageIndex> ordering;
  ordering(AtA, m_P);
  m_Pinv = m_P.inverse();  // cache the inverse permutation
  // Cache the composition m_Pinv * m_Pr so _solve_impl applies a single
  // permutation to the RHS instead of two.
  m_PinvPr = m_Pinv * m_Pr;
  m_analysisIsOk = true;
  m_factorizationIsOk = false;
  m_isInitialized = true;
}

template <typename Scalar, typename StorageIndex>
template <typename MatrixType_>
void IncompleteLUT<Scalar, StorageIndex>::factorize(const MatrixType_& amat) {
  using internal::convert_index;
  using std::abs;
  using std::sqrt;
  using std::swap;

  eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix");
  Index n = amat.cols();  // Size of the matrix
  m_lu.resize(n, n);
  // Declare Working vectors and variables
  Vector u(n);    // real values of the row -- maximum size is n --
  VectorI ju(n);  // column position of the values in u -- maximum size  is n
  VectorI jr(n);  // Indicate the position of the nonzero elements in the vector u -- A zero location is indicated by -1

  // Apply the static row permutation (from analyzePattern), then the
  // fill-reducing symmetric permutation.
  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
  SparseMatrix<Scalar, RowMajor, StorageIndex> row_permuted_mat = m_Pr * amat;
  SparseMatrix<Scalar, RowMajor, StorageIndex> mat;
  mat = row_permuted_mat.twistedBy(m_Pinv);
  Index zero_pivots = 0;

  // Initialization
  jr.fill(-1);
  ju.fill(0);
  u.fill(0);

  // number of largest elements to keep in each row:
  Index fill_in = (amat.nonZeros() * m_fillfactor) / n + 1;
  if (fill_in > n) fill_in = n;

  // number of largest nonzero elements to keep in the L and the U part of the current row:
  Index nnzL = fill_in / 2;
  Index nnzU = nnzL;
  m_lu.reserve(n * (nnzL + nnzU + 1));

  // global loop over the rows of the sparse matrix
  for (Index ii = 0; ii < n; ii++) {
    // 1 - copy the lower and the upper part of the row i of mat in the working vector u

    Index sizeu = 1;  // number of nonzero elements in the upper part of the current row
    Index sizel = 0;  // number of nonzero elements in the lower part of the current row
    ju(ii) = convert_index<StorageIndex>(ii);
    u(ii) = 0;
    jr(ii) = convert_index<StorageIndex>(ii);
    RealScalar rownorm = 0;

    typename FactorType::InnerIterator j_it(mat, ii);  // Iterate through the current row ii
    for (; j_it; ++j_it) {
      Index k = j_it.index();
      if (k < ii) {
        // copy the lower part
        ju(sizel) = convert_index<StorageIndex>(k);
        u(sizel) = j_it.value();
        jr(k) = convert_index<StorageIndex>(sizel);
        ++sizel;
      } else if (k == ii) {
        u(ii) = j_it.value();
      } else {
        // copy the upper part
        Index jpos = ii + sizeu;
        ju(jpos) = convert_index<StorageIndex>(k);
        u(jpos) = j_it.value();
        jr(k) = convert_index<StorageIndex>(jpos);
        ++sizeu;
      }
      rownorm += numext::abs2(j_it.value());
    }

    // 2 - detect possible zero row
    if (rownorm == 0) {
      m_info = NumericalIssue;
      return;
    }
    // Take the 2-norm of the current row as a relative tolerance
    rownorm = sqrt(rownorm);

    // 3 - eliminate the previous nonzero rows
    Index jj = 0;
    Index len = 0;
    while (jj < sizel) {
      // In order to eliminate in the correct order,
      // we must select first the smallest column index among  ju(jj:sizel)
      Index k;
      Index minrow = ju.segment(jj, sizel - jj).minCoeff(&k);  // k is relative to the segment
      k += jj;
      if (minrow != ju(jj)) {
        // swap the two locations
        Index j = ju(jj);
        swap(ju(jj), ju(k));
        jr(minrow) = convert_index<StorageIndex>(jj);
        jr(j) = convert_index<StorageIndex>(k);
        swap(u(jj), u(k));
      }
      // Reset this location
      jr(minrow) = -1;

      // Start elimination
      typename FactorType::InnerIterator ki_it(m_lu, minrow);
      while (ki_it && ki_it.index() < minrow) ++ki_it;
      eigen_internal_assert(ki_it && ki_it.col() == minrow);
      Scalar fact = u(jj) / ki_it.value();

      // drop too small elements
      if (abs(fact) <= m_droptol) {
        jj++;
        continue;
      }

      // linear combination of the current row ii and the row minrow
      ++ki_it;
      for (; ki_it; ++ki_it) {
        Scalar prod = fact * ki_it.value();
        Index j = ki_it.index();
        Index jpos = jr(j);
        if (jpos == -1)  // fill-in element
        {
          Index newpos;
          if (j >= ii)  // dealing with the upper part
          {
            newpos = ii + sizeu;
            sizeu++;
            eigen_internal_assert(sizeu <= n);
          } else  // dealing with the lower part
          {
            newpos = sizel;
            sizel++;
            eigen_internal_assert(sizel <= ii);
          }
          ju(newpos) = convert_index<StorageIndex>(j);
          u(newpos) = -prod;
          jr(j) = convert_index<StorageIndex>(newpos);
        } else
          u(jpos) -= prod;
      }
      // store the pivot element
      u(len) = fact;
      ju(len) = convert_index<StorageIndex>(minrow);
      ++len;

      jj++;
    }  // end of the elimination on the row ii

    // reset the upper part of the pointer jr to zero
    for (Index k = 0; k < sizeu; k++) jr(ju(ii + k)) = -1;

    // 4 - partially sort and insert the elements in the m_lu matrix

    // sort the L-part of the row
    sizel = len;
    len = (std::min)(sizel, nnzL);
    typename Vector::SegmentReturnType ul(u.segment(0, sizel));
    typename VectorI::SegmentReturnType jul(ju.segment(0, sizel));
    internal::QuickSplit(ul, jul, len);

    // store the largest m_fill elements of the L part
    m_lu.startVec(ii);
    for (Index k = 0; k < len; k++) m_lu.insertBackByOuterInnerUnordered(ii, ju(k)) = u(k);

    // store the diagonal element
    // apply a shifting rule to avoid zero pivots (we are doing an incomplete factorization)
    if (u(ii) == Scalar(0)) {
      u(ii) = sqrt(m_droptol) * rownorm;
      ++zero_pivots;
    }
    m_lu.insertBackByOuterInnerUnordered(ii, ii) = u(ii);

    // sort the U-part of the row
    // apply the dropping rule first
    len = 0;
    for (Index k = 1; k < sizeu; k++) {
      if (abs(u(ii + k)) > m_droptol * rownorm) {
        ++len;
        u(ii + len) = u(ii + k);
        ju(ii + len) = ju(ii + k);
      }
    }
    sizeu = len + 1;  // +1 to take into account the diagonal element
    len = (std::min)(sizeu, nnzU);
    typename Vector::SegmentReturnType uu(u.segment(ii + 1, sizeu - 1));
    typename VectorI::SegmentReturnType juu(ju.segment(ii + 1, sizeu - 1));
    internal::QuickSplit(uu, juu, len);

    // store the largest elements of the U part
    for (Index k = ii + 1; k < ii + len; k++) m_lu.insertBackByOuterInnerUnordered(ii, ju(k)) = u(k);
  }
  m_lu.finalize();
  m_lu.makeCompressed();

  m_factorizationIsOk = true;
  // If we had to shift any zero pivot, the factorization is not faithful to
  // the input matrix and the resulting preconditioner may be useless.
  // Report this to the caller via NumericalIssue rather than silently
  // returning Success.
  m_info = (zero_pivots == 0) ? Success : NumericalIssue;
}

}  // end namespace Eigen

#endif  // EIGEN_INCOMPLETE_LUT_H
