// 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>
//
// 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 SPARSELU_IMPL_H
#define SPARSELU_IMPL_H

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

namespace Eigen {
namespace internal {

/** \ingroup SparseLU_Module
 * \class SparseLUImpl
 * Base class for sparseLU
 */
template <typename Scalar, typename StorageIndex>
class SparseLUImpl {
 public:
  typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
  typedef Matrix<StorageIndex, Dynamic, 1> IndexVector;
  typedef Matrix<Scalar, Dynamic, Dynamic, ColMajor> ScalarMatrix;
  typedef Map<ScalarMatrix, 0, OuterStride<> > MappedMatrixBlock;
  typedef typename ScalarVector::RealScalar RealScalar;
  typedef Ref<Matrix<Scalar, Dynamic, 1> > BlockScalarVector;
  typedef Ref<Matrix<StorageIndex, Dynamic, 1> > BlockIndexVector;
  typedef LU_GlobalLU_t<IndexVector, ScalarVector> GlobalLU_t;
  typedef SparseMatrix<Scalar, ColMajor, StorageIndex> MatrixType;

 protected:
  template <typename VectorType>
  Index expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions);
  Index memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu);
  template <typename VectorType>
  Index memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions);
  void heap_relax_snode(const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants,
                        IndexVector& relax_end);
  void relax_snode(const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants,
                   IndexVector& relax_end);
  Index snode_dfs(const Index jcol, const Index kcol, const MatrixType& mat, IndexVector& xprune, IndexVector& marker,
                  GlobalLU_t& glu);
  Index snode_bmod(const Index jcol, const Index fsupc, ScalarVector& dense, GlobalLU_t& glu);
  Index pivotL(const Index jcol, const RealScalar& diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c,
               Index& pivrow, GlobalLU_t& glu);
  template <typename Traits>
  void dfs_kernel(const StorageIndex jj, IndexVector& perm_r, Index& nseg, IndexVector& panel_lsub, IndexVector& segrep,
                  Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent,
                  IndexVector& xplore, GlobalLU_t& glu, Index& nextl_col, Index krow, Traits& traits);
  void panel_dfs(const Index m, const Index w, const Index jcol, MatrixType& A, IndexVector& perm_r, Index& nseg,
                 ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz,
                 IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu);

  void panel_bmod(const Index m, const Index w, const Index jcol, const Index nseg, ScalarVector& dense,
                  ScalarVector& tempv, IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu);
  Index column_dfs(const Index m, const Index jcol, IndexVector& perm_r, Index maxsuper, Index& nseg,
                   BlockIndexVector lsub_col, IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune,
                   IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu);
  Index column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector& tempv,
                    BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t& glu);
  Index copy_to_ucol(const Index jcol, const Index nseg, IndexVector& segrep, BlockIndexVector repfnz,
                     IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu);
  void pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg,
              const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu);
  void countnz(const Index n, Index& nnzL, Index& nnzU, GlobalLU_t& glu);
  void fixupL(const Index n, const IndexVector& perm_r, GlobalLU_t& glu);

  template <typename, typename>
  friend struct column_dfs_traits;
};

}  // end namespace internal
}  // namespace Eigen

#endif
