// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
// Copyright (C) 2013 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_SPARSEBLOCKMATRIX_H
#define EIGEN_SPARSEBLOCKMATRIX_H

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

namespace Eigen {
/** \ingroup SparseCore_Module
 *
 * \class BlockSparseMatrix
 *
 * \brief A versatile sparse matrix representation where each element is a block
 *
 * This class provides routines to manipulate block sparse matrices stored in a
 * BSR-like representation. There are two main types :
 *
 * 1. All blocks have the same number of rows and columns, called block size
 * in the following. In this case, if this block size is known at compile time,
 * it can be given as a template parameter like
 * \code
 * BlockSparseMatrix<Scalar, 3, ColMajor> bmat(b_rows, b_cols);
 * \endcode
 * Here, bmat is a b_rows x b_cols block sparse matrix
 * where each coefficient is a 3x3 dense matrix.
 * If the block size is fixed but will be given at runtime,
 * \code
 * BlockSparseMatrix<Scalar, Dynamic, ColMajor> bmat(b_rows, b_cols);
 * bmat.setBlockSize(block_size);
 * \endcode
 *
 * 2. The second case is for variable-block sparse matrices.
 * Here each block has its own dimensions. The only restriction is that all the blocks
 * in a row (resp. a column) should have the same number of rows (resp. of columns).
 * It is thus required in this case to describe the layout of the matrix by calling
 * setBlockLayout(rowBlocks, colBlocks).
 *
 * In any of the previous case, the matrix can be filled by calling setFromTriplets().
 * A regular sparse matrix can be converted to a block sparse matrix and vice versa.
 * It is obviously required to describe the block layout beforehand by calling either
 * setBlockSize() for fixed-size blocks or setBlockLayout for variable-size blocks.
 *
 * \tparam Scalar_ The Scalar type
 * \tparam _BlockAtCompileTime The block layout option. It takes the following values
 * Dynamic : block size known at runtime
 * a numeric number : fixed-size block known at compile time
 */
template <typename Scalar_, int _BlockAtCompileTime = Dynamic, int Options_ = ColMajor, typename StorageIndex_ = int>
class BlockSparseMatrix;

template <typename BlockSparseMatrixT>
class BlockSparseMatrixView;

namespace internal {
template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename Index_>
struct traits<BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, Index_> > {
  typedef Scalar_ Scalar;
  typedef Index_ Index;
  typedef Sparse StorageKind;  // FIXME Where is it used ??
  typedef MatrixXpr XprKind;
  enum {
    RowsAtCompileTime = Dynamic,
    ColsAtCompileTime = Dynamic,
    MaxRowsAtCompileTime = Dynamic,
    MaxColsAtCompileTime = Dynamic,
    BlockSize = _BlockAtCompileTime,
    Flags = Options_ | NestByRefBit | LvalueBit,
    CoeffReadCost = NumTraits<Scalar>::ReadCost,
    SupportedAccessPatterns = InnerRandomAccessPattern
  };
};
template <typename BlockSparseMatrixT>
struct traits<BlockSparseMatrixView<BlockSparseMatrixT> > {
  typedef Ref<
      Matrix<typename BlockSparseMatrixT::Scalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> >
      Scalar;
  typedef Ref<
      Matrix<typename BlockSparseMatrixT::RealScalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> >
      RealScalar;
};

// Function object to sort a triplet list
template <typename Iterator, bool IsColMajor>
struct TripletComp {
  typedef typename Iterator::value_type Triplet;
  bool operator()(const Triplet& a, const Triplet& b) {
    if (IsColMajor)
      return ((a.col() == b.col() && a.row() < b.row()) || (a.col() < b.col()));
    else
      return ((a.row() == b.row() && a.col() < b.col()) || (a.row() < b.row()));
  }
};
}  // end namespace internal

/* Proxy to view the block sparse matrix as a regular sparse matrix */
template <typename BlockSparseMatrixT>
class BlockSparseMatrixView : public SparseMatrixBase<BlockSparseMatrixT> {
 public:
  typedef Ref<typename BlockSparseMatrixT::BlockScalar> Scalar;
  typedef Ref<typename BlockSparseMatrixT::BlockRealScalar> RealScalar;
  typedef typename BlockSparseMatrixT::Index Index;
  typedef BlockSparseMatrixT Nested;
  enum {
    Flags = BlockSparseMatrixT::Options,
    Options = BlockSparseMatrixT::Options,
    RowsAtCompileTime = BlockSparseMatrixT::RowsAtCompileTime,
    ColsAtCompileTime = BlockSparseMatrixT::ColsAtCompileTime,
    MaxColsAtCompileTime = BlockSparseMatrixT::MaxColsAtCompileTime,
    MaxRowsAtCompileTime = BlockSparseMatrixT::MaxRowsAtCompileTime
  };

 public:
  BlockSparseMatrixView(const BlockSparseMatrixT& spblockmat) : m_spblockmat(spblockmat) {}

  Index outerSize() const { return (Flags & RowMajorBit) == 1 ? this->rows() : this->cols(); }
  Index cols() const { return m_spblockmat.blockCols(); }
  Index rows() const { return m_spblockmat.blockRows(); }
  Scalar coeff(Index row, Index col) { return m_spblockmat.coeff(row, col); }
  Scalar coeffRef(Index row, Index col) { return m_spblockmat.coeffRef(row, col); }
  // Wrapper to iterate over all blocks
  class InnerIterator : public BlockSparseMatrixT::BlockInnerIterator {
   public:
    InnerIterator(const BlockSparseMatrixView& mat, Index outer)
        : BlockSparseMatrixT::BlockInnerIterator(mat.m_spblockmat, outer) {}
  };

 protected:
  const BlockSparseMatrixT& m_spblockmat;
};

// Proxy to view a regular vector as a block vector
template <typename BlockSparseMatrixT, typename VectorType>
class BlockVectorView {
 public:
  enum {
    BlockSize = BlockSparseMatrixT::BlockSize,
    ColsAtCompileTime = VectorType::ColsAtCompileTime,
    RowsAtCompileTime = VectorType::RowsAtCompileTime,
    Flags = VectorType::Flags
  };
  typedef Ref<const Matrix<typename BlockSparseMatrixT::Scalar, (RowsAtCompileTime == 1) ? 1 : BlockSize,
                           (ColsAtCompileTime == 1) ? 1 : BlockSize> >
      Scalar;
  typedef typename BlockSparseMatrixT::Index Index;

 public:
  BlockVectorView(const BlockSparseMatrixT& spblockmat, const VectorType& vec) : m_spblockmat(spblockmat), m_vec(vec) {}
  inline Index cols() const { return m_vec.cols(); }
  inline Index size() const { return m_spblockmat.blockRows(); }
  inline Scalar coeff(Index bi) const {
    Index startRow = m_spblockmat.blockRowsIndex(bi);
    Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
    return m_vec.middleRows(startRow, rowSize);
  }
  inline Scalar coeff(Index bi, Index j) const {
    Index startRow = m_spblockmat.blockRowsIndex(bi);
    Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
    return m_vec.block(startRow, j, rowSize, 1);
  }

 protected:
  const BlockSparseMatrixT& m_spblockmat;
  const VectorType& m_vec;
};

template <typename VectorType, typename Index>
class BlockVectorReturn;

// Proxy to view a regular vector as a block vector
template <typename BlockSparseMatrixT, typename VectorType>
class BlockVectorReturn {
 public:
  enum {
    ColsAtCompileTime = VectorType::ColsAtCompileTime,
    RowsAtCompileTime = VectorType::RowsAtCompileTime,
    Flags = VectorType::Flags
  };
  typedef Ref<Matrix<typename VectorType::Scalar, RowsAtCompileTime, ColsAtCompileTime> > Scalar;
  typedef typename BlockSparseMatrixT::Index Index;

 public:
  BlockVectorReturn(const BlockSparseMatrixT& spblockmat, VectorType& vec) : m_spblockmat(spblockmat), m_vec(vec) {}
  inline Index size() const { return m_spblockmat.blockRows(); }
  inline Scalar coeffRef(Index bi) {
    Index startRow = m_spblockmat.blockRowsIndex(bi);
    Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
    return m_vec.middleRows(startRow, rowSize);
  }
  inline Scalar coeffRef(Index bi, Index j) {
    Index startRow = m_spblockmat.blockRowsIndex(bi);
    Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
    return m_vec.block(startRow, j, rowSize, 1);
  }

 protected:
  const BlockSparseMatrixT& m_spblockmat;
  VectorType& m_vec;
};

// Block version of the sparse dense product
template <typename Lhs, typename Rhs>
class BlockSparseTimeDenseProduct;

namespace internal {

template <typename BlockSparseMatrixT, typename VecType>
struct traits<BlockSparseTimeDenseProduct<BlockSparseMatrixT, VecType> > {
  typedef Dense StorageKind;
  typedef MatrixXpr XprKind;
  typedef typename BlockSparseMatrixT::Scalar Scalar;
  typedef typename BlockSparseMatrixT::Index Index;
  enum {
    RowsAtCompileTime = Dynamic,
    ColsAtCompileTime = Dynamic,
    MaxRowsAtCompileTime = Dynamic,
    MaxColsAtCompileTime = Dynamic,
    Flags = 0,
    CoeffReadCost = internal::traits<BlockSparseMatrixT>::CoeffReadCost
  };
};
}  // end namespace internal

template <typename Lhs, typename Rhs>
class BlockSparseTimeDenseProduct : public ProductBase<BlockSparseTimeDenseProduct<Lhs, Rhs>, Lhs, Rhs> {
 public:
  EIGEN_PRODUCT_PUBLIC_INTERFACE(BlockSparseTimeDenseProduct)

  BlockSparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs, rhs) {}

  template <typename Dest>
  void scaleAndAddTo(Dest& dest, const typename Rhs::Scalar& alpha) const {
    BlockVectorReturn<Lhs, Dest> tmpDest(m_lhs, dest);
    internal::sparse_time_dense_product(BlockSparseMatrixView<Lhs>(m_lhs), BlockVectorView<Lhs, Rhs>(m_lhs, m_rhs),
                                        tmpDest, alpha);
  }

 private:
  BlockSparseTimeDenseProduct& operator=(const BlockSparseTimeDenseProduct&);
};

template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename StorageIndex_>
class BlockSparseMatrix
    : public SparseMatrixBase<BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_> > {
 public:
  typedef Scalar_ Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef StorageIndex_ StorageIndex;
  typedef
      typename internal::ref_selector<BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_> >::type
          Nested;

  enum {
    Options = Options_,
    Flags = Options,
    BlockSize = _BlockAtCompileTime,
    RowsAtCompileTime = Dynamic,
    ColsAtCompileTime = Dynamic,
    MaxRowsAtCompileTime = Dynamic,
    MaxColsAtCompileTime = Dynamic,
    IsVectorAtCompileTime = 0,
    IsColMajor = Flags & RowMajorBit ? 0 : 1
  };
  typedef Matrix<Scalar, _BlockAtCompileTime, _BlockAtCompileTime, IsColMajor ? ColMajor : RowMajor> BlockScalar;
  typedef Matrix<RealScalar, _BlockAtCompileTime, _BlockAtCompileTime, IsColMajor ? ColMajor : RowMajor>
      BlockRealScalar;
  typedef std::conditional_t<_BlockAtCompileTime == Dynamic, Scalar, BlockScalar> BlockScalarReturnType;
  typedef BlockSparseMatrix<Scalar, BlockSize, IsColMajor ? ColMajor : RowMajor, StorageIndex> PlainObject;

 public:
  // Default constructor
  BlockSparseMatrix()
      : m_innerBSize(0),
        m_outerBSize(0),
        m_innerOffset(0),
        m_outerOffset(0),
        m_nonzerosblocks(0),
        m_values(0),
        m_blockPtr(0),
        m_indices(0),
        m_outerIndex(0),
        m_blockSize(BlockSize) {}

  /**
   * \brief Construct and resize
   *
   */
  BlockSparseMatrix(Index brow, Index bcol)
      : m_innerBSize(IsColMajor ? brow : bcol),
        m_outerBSize(IsColMajor ? bcol : brow),
        m_innerOffset(0),
        m_outerOffset(0),
        m_nonzerosblocks(0),
        m_values(0),
        m_blockPtr(0),
        m_indices(0),
        m_outerIndex(0),
        m_blockSize(BlockSize) {}

  /**
   * \brief Copy-constructor
   */
  BlockSparseMatrix(const BlockSparseMatrix& other)
      : m_innerBSize(other.m_innerBSize),
        m_outerBSize(other.m_outerBSize),
        m_nonzerosblocks(other.m_nonzerosblocks),
        m_nonzeros(other.m_nonzeros),
        m_blockPtr(0),
        m_blockSize(other.m_blockSize) {
    // should we allow copying between variable-size blocks and fixed-size blocks ??
    eigen_assert(m_blockSize == BlockSize && " CAN NOT COPY BETWEEN FIXED-SIZE AND VARIABLE-SIZE BLOCKS");

    std::copy(other.m_innerOffset, other.m_innerOffset + m_innerBSize + 1, m_innerOffset);
    std::copy(other.m_outerOffset, other.m_outerOffset + m_outerBSize + 1, m_outerOffset);
    std::copy(other.m_values, other.m_values + m_nonzeros, m_values);

    if (m_blockSize != Dynamic) std::copy(other.m_blockPtr, other.m_blockPtr + m_nonzerosblocks, m_blockPtr);

    std::copy(other.m_indices, other.m_indices + m_nonzerosblocks, m_indices);
    std::copy(other.m_outerIndex, other.m_outerIndex + m_outerBSize, m_outerIndex);
  }

  friend void swap(BlockSparseMatrix& first, BlockSparseMatrix& second) {
    std::swap(first.m_innerBSize, second.m_innerBSize);
    std::swap(first.m_outerBSize, second.m_outerBSize);
    std::swap(first.m_innerOffset, second.m_innerOffset);
    std::swap(first.m_outerOffset, second.m_outerOffset);
    std::swap(first.m_nonzerosblocks, second.m_nonzerosblocks);
    std::swap(first.m_nonzeros, second.m_nonzeros);
    std::swap(first.m_values, second.m_values);
    std::swap(first.m_blockPtr, second.m_blockPtr);
    std::swap(first.m_indices, second.m_indices);
    std::swap(first.m_outerIndex, second.m_outerIndex);
    std::swap(first.m_BlockSize, second.m_blockSize);
  }

  BlockSparseMatrix& operator=(BlockSparseMatrix other) {
    // Copy-and-swap paradigm ... avoid leaked data if thrown
    swap(*this, other);
    return *this;
  }

  // Destructor
  ~BlockSparseMatrix() {
    delete[] m_outerIndex;
    delete[] m_innerOffset;
    delete[] m_outerOffset;
    delete[] m_indices;
    delete[] m_blockPtr;
    delete[] m_values;
  }

  /**
   * \brief Constructor from a sparse matrix
   *
   */
  template <typename MatrixType>
  inline BlockSparseMatrix(const MatrixType& spmat) : m_blockSize(BlockSize) {
    EIGEN_STATIC_ASSERT((m_blockSize != Dynamic), THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE);

    *this = spmat;
  }

  /**
   * \brief Assignment from a sparse matrix with the same storage order
   *
   * Convert from a sparse matrix to block sparse matrix.
   * \warning Before calling this function, tt is necessary to call
   * either setBlockLayout() (matrices with variable-size blocks)
   * or setBlockSize() (for fixed-size blocks).
   */
  template <typename MatrixType>
  inline BlockSparseMatrix& operator=(const MatrixType& spmat) {
    eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) &&
                 "Trying to assign to a zero-size matrix, call resize() first");
    eigen_assert(((MatrixType::Options & RowMajorBit) != IsColMajor) && "Wrong storage order");
    typedef SparseMatrix<bool, MatrixType::Options, typename MatrixType::Index> MatrixPatternType;
    MatrixPatternType blockPattern(blockRows(), blockCols());
    m_nonzeros = 0;

    // First, compute the number of nonzero blocks and their locations
    for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
      // Browse each outer block and compute the structure
      std::vector<bool> nzblocksFlag(m_innerBSize, false);  // Record the existing blocks
      blockPattern.startVec(bj);
      for (StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj + 1); ++j) {
        typename MatrixType::InnerIterator it_spmat(spmat, j);
        for (; it_spmat; ++it_spmat) {
          StorageIndex bi = innerToBlock(it_spmat.index());  // Index of the current nonzero block
          if (!nzblocksFlag[bi]) {
            // Save the index of this nonzero block
            nzblocksFlag[bi] = true;
            blockPattern.insertBackByOuterInnerUnordered(bj, bi) = true;
            // Compute the total number of nonzeros (including explicit zeros in blocks)
            m_nonzeros += blockOuterSize(bj) * blockInnerSize(bi);
          }
        }
      }  // end current outer block
    }
    blockPattern.finalize();

    // Allocate the internal arrays
    setBlockStructure(blockPattern);

    for (StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
    for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
      // Now copy the values
      for (StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj + 1); ++j) {
        // Browse the outer block column by column (for column-major matrices)
        typename MatrixType::InnerIterator it_spmat(spmat, j);
        for (; it_spmat; ++it_spmat) {
          StorageIndex idx = 0;                              // Position of this block in the column block
          StorageIndex bi = innerToBlock(it_spmat.index());  // Index of the current nonzero block
          // Go to the inner block where this element belongs to
          while (bi > m_indices[m_outerIndex[bj] + idx]) ++idx;  // Not expensive for ordered blocks
          StorageIndex idxVal;  // Get the right position in the array of values for this element
          if (m_blockSize == Dynamic) {
            // Offset from all blocks before ...
            idxVal = m_blockPtr[m_outerIndex[bj] + idx];
            // ... and offset inside the block
            idxVal += (j - blockOuterIndex(bj)) * blockOuterSize(bj) + it_spmat.index() - m_innerOffset[bi];
          } else {
            // All blocks before
            idxVal = (m_outerIndex[bj] + idx) * m_blockSize * m_blockSize;
            // inside the block
            idxVal += (j - blockOuterIndex(bj)) * m_blockSize + (it_spmat.index() % m_blockSize);
          }
          // Insert the value
          m_values[idxVal] = it_spmat.value();
        }  // end of this column
      }    // end of this block
    }      // end of this outer block

    return *this;
  }

  /**
   * \brief Set the nonzero block pattern of the matrix
   *
   * Given a sparse matrix describing the nonzero block pattern,
   * this function prepares the internal pointers for values.
   * After calling this function, any *nonzero* block (bi, bj) can be set
   * with a simple call to coeffRef(bi,bj).
   *
   *
   * \warning Before calling this function, tt is necessary to call
   * either setBlockLayout() (matrices with variable-size blocks)
   * or setBlockSize() (for fixed-size blocks).
   *
   * \param blockPattern Sparse matrix of boolean elements describing the block structure
   *
   * \sa setBlockLayout() \sa setBlockSize()
   */
  template <typename MatrixType>
  void setBlockStructure(const MatrixType& blockPattern) {
    resize(blockPattern.rows(), blockPattern.cols());
    reserve(blockPattern.nonZeros());

    // Browse the block pattern and set up the various pointers
    m_outerIndex[0] = 0;
    if (m_blockSize == Dynamic) m_blockPtr[0] = 0;
    for (StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
    for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
      // Browse each outer block

      // First, copy and save the indices of nonzero blocks
      // FIXME : find a way to avoid this ...
      std::vector<int> nzBlockIdx;
      typename MatrixType::InnerIterator it(blockPattern, bj);
      for (; it; ++it) {
        nzBlockIdx.push_back(it.index());
      }
      std::sort(nzBlockIdx.begin(), nzBlockIdx.end());

      // Now, fill block indices and (eventually) pointers to blocks
      for (StorageIndex idx = 0; idx < nzBlockIdx.size(); ++idx) {
        StorageIndex offset = m_outerIndex[bj] + idx;  // offset in m_indices
        m_indices[offset] = nzBlockIdx[idx];
        if (m_blockSize == Dynamic)
          m_blockPtr[offset] = m_blockPtr[offset - 1] + blockInnerSize(nzBlockIdx[idx]) * blockOuterSize(bj);
        // There is no blockPtr for fixed-size blocks... not needed !???
      }
      // Save the pointer to the next outer block
      m_outerIndex[bj + 1] = m_outerIndex[bj] + nzBlockIdx.size();
    }
  }

  /**
   * \brief Set the number of rows and columns blocks
   */
  inline void resize(Index brow, Index bcol) {
    m_innerBSize = IsColMajor ? brow : bcol;
    m_outerBSize = IsColMajor ? bcol : brow;
  }

  /**
   * \brief set the block size at runtime for fixed-size block layout
   *
   * Call this only for fixed-size blocks
   */
  inline void setBlockSize(Index blockSize) { m_blockSize = blockSize; }

  /**
   * \brief Set the row and column block layouts,
   *
   * This function set the size of each row and column block.
   * So this function should be used only for blocks with variable size.
   * \param rowBlocks : Number of rows per row block
   * \param colBlocks : Number of columns per column block
   * \sa resize(), setBlockSize()
   */
  inline void setBlockLayout(const VectorXi& rowBlocks, const VectorXi& colBlocks) {
    const VectorXi& innerBlocks = IsColMajor ? rowBlocks : colBlocks;
    const VectorXi& outerBlocks = IsColMajor ? colBlocks : rowBlocks;
    eigen_assert(m_innerBSize == innerBlocks.size() && "CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
    eigen_assert(m_outerBSize == outerBlocks.size() && "CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
    m_outerBSize = outerBlocks.size();
    //  starting index of blocks... cumulative sums
    m_innerOffset = new StorageIndex[m_innerBSize + 1];
    m_outerOffset = new StorageIndex[m_outerBSize + 1];
    m_innerOffset[0] = 0;
    m_outerOffset[0] = 0;
    std::partial_sum(&innerBlocks[0], &innerBlocks[m_innerBSize - 1] + 1, &m_innerOffset[1]);
    std::partial_sum(&outerBlocks[0], &outerBlocks[m_outerBSize - 1] + 1, &m_outerOffset[1]);

    // Compute the total number of nonzeros
    m_nonzeros = 0;
    for (StorageIndex bj = 0; bj < m_outerBSize; ++bj)
      for (StorageIndex bi = 0; bi < m_innerBSize; ++bi) m_nonzeros += outerBlocks[bj] * innerBlocks[bi];
  }

  /**
   * \brief Allocate the internal array of pointers to blocks and their inner indices
   *
   * \note For fixed-size blocks, call setBlockSize() to set the block.
   * And For variable-size blocks, call setBlockLayout() before using this function
   *
   * \param nonzerosblocks Number of nonzero blocks. The total number of nonzeros is
   * is computed in setBlockLayout() for variable-size blocks
   * \sa setBlockSize()
   */
  inline void reserve(const Index nonzerosblocks) {
    eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) &&
                 "TRYING TO RESERVE ZERO-SIZE MATRICES, CALL resize() first");

    // FIXME Should free if already allocated
    m_outerIndex = new StorageIndex[m_outerBSize + 1];

    m_nonzerosblocks = nonzerosblocks;
    if (m_blockSize != Dynamic) {
      m_nonzeros = nonzerosblocks * (m_blockSize * m_blockSize);
      m_blockPtr = 0;
    } else {
      // m_nonzeros  is already computed in setBlockLayout()
      m_blockPtr = new StorageIndex[m_nonzerosblocks + 1];
    }
    m_indices = new StorageIndex[m_nonzerosblocks + 1];
    m_values = new Scalar[m_nonzeros];
  }

  /**
   * \brief Fill values in a matrix  from a triplet list.
   *
   * Each triplet item has a block stored in an Eigen dense matrix.
   * The InputIterator class should provide the functions row(), col() and value()
   *
   * \note For fixed-size blocks, call setBlockSize() before this function.
   *
   * FIXME Do not accept duplicates
   */
  template <typename InputIterator>
  void setFromTriplets(const InputIterator& begin, const InputIterator& end) {
    eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) && "ZERO BLOCKS, PLEASE CALL resize() before");

    /* First, sort the triplet list
     * FIXME This can be unnecessarily expensive since only the inner indices have to be sorted
     * The best approach is like in SparseMatrix::setFromTriplets()
     */
    internal::TripletComp<InputIterator, IsColMajor> tripletcomp;
    std::sort(begin, end, tripletcomp);

    /* Count the number of rows and column blocks,
     * and the number of nonzero blocks per outer dimension
     */
    VectorXi rowBlocks(m_innerBSize);  // Size of each block row
    VectorXi colBlocks(m_outerBSize);  // Size of each block column
    rowBlocks.setZero();
    colBlocks.setZero();
    VectorXi nzblock_outer(m_outerBSize);  // Number of nz blocks per outer vector
    VectorXi nz_outer(m_outerBSize);       // Number of nz per outer vector...for variable-size blocks
    nzblock_outer.setZero();
    nz_outer.setZero();
    for (InputIterator it(begin); it != end; ++it) {
      eigen_assert(it->row() >= 0 && it->row() < this->blockRows() && it->col() >= 0 && it->col() < this->blockCols());
      eigen_assert((it->value().rows() == it->value().cols() && (it->value().rows() == m_blockSize)) ||
                   (m_blockSize == Dynamic));

      if (m_blockSize == Dynamic) {
        eigen_assert((rowBlocks[it->row()] == 0 || rowBlocks[it->row()] == it->value().rows()) &&
                     "NON CORRESPONDING SIZES FOR ROW BLOCKS");
        eigen_assert((colBlocks[it->col()] == 0 || colBlocks[it->col()] == it->value().cols()) &&
                     "NON CORRESPONDING SIZES FOR COLUMN BLOCKS");
        rowBlocks[it->row()] = it->value().rows();
        colBlocks[it->col()] = it->value().cols();
      }
      nz_outer(IsColMajor ? it->col() : it->row()) += it->value().rows() * it->value().cols();
      nzblock_outer(IsColMajor ? it->col() : it->row())++;
    }
    // Allocate member arrays
    if (m_blockSize == Dynamic) setBlockLayout(rowBlocks, colBlocks);
    StorageIndex nzblocks = nzblock_outer.sum();
    reserve(nzblocks);

    // Temporary markers
    VectorXi block_id(m_outerBSize);  // To be used as a block marker during insertion

    // Setup outer index pointers and markers
    m_outerIndex[0] = 0;
    if (m_blockSize == Dynamic) m_blockPtr[0] = 0;
    for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
      m_outerIndex[bj + 1] = m_outerIndex[bj] + nzblock_outer(bj);
      block_id(bj) = m_outerIndex[bj];
      if (m_blockSize == Dynamic) {
        m_blockPtr[m_outerIndex[bj + 1]] = m_blockPtr[m_outerIndex[bj]] + nz_outer(bj);
      }
    }

    // Fill the matrix
    for (InputIterator it(begin); it != end; ++it) {
      StorageIndex outer = IsColMajor ? it->col() : it->row();
      StorageIndex inner = IsColMajor ? it->row() : it->col();
      m_indices[block_id(outer)] = inner;
      StorageIndex block_size = it->value().rows() * it->value().cols();
      StorageIndex nz_marker = blockPtr(block_id[outer]);
      memcpy(&(m_values[nz_marker]), it->value().data(), block_size * sizeof(Scalar));
      if (m_blockSize == Dynamic) {
        m_blockPtr[block_id(outer) + 1] = m_blockPtr[block_id(outer)] + block_size;
      }
      block_id(outer)++;
    }

    // An alternative when the outer indices are sorted...no need to use an array of markers
    //      for(Index bcol = 0; bcol < m_outerBSize; ++bcol)
    //      {
    //      Index id = 0, id_nz = 0, id_nzblock = 0;
    //      for(InputIterator it(begin); it!=end; ++it)
    //      {
    //        while (id<bcol) // one pass should do the job unless there are empty columns
    //        {
    //          id++;
    //          m_outerIndex[id+1]=m_outerIndex[id];
    //        }
    //        m_outerIndex[id+1] += 1;
    //        m_indices[id_nzblock]=brow;
    //        Index block_size = it->value().rows()*it->value().cols();
    //        m_blockPtr[id_nzblock+1] = m_blockPtr[id_nzblock] + block_size;
    //        id_nzblock++;
    //        memcpy(&(m_values[id_nz]),it->value().data(), block_size*sizeof(Scalar));
    //        id_nz += block_size;
    //      }
    //      while(id < m_outerBSize-1) // Empty columns at the end
    //      {
    //        id++;
    //        m_outerIndex[id+1]=m_outerIndex[id];
    //      }
    //      }
  }

  /**
   * \returns the number of rows
   */
  inline Index rows() const {
    //      return blockRows();
    return (IsColMajor ? innerSize() : outerSize());
  }

  /**
   * \returns the number of cols
   */
  inline Index cols() const {
    //      return blockCols();
    return (IsColMajor ? outerSize() : innerSize());
  }

  inline Index innerSize() const {
    if (m_blockSize == Dynamic)
      return m_innerOffset[m_innerBSize];
    else
      return (m_innerBSize * m_blockSize);
  }

  inline Index outerSize() const {
    if (m_blockSize == Dynamic)
      return m_outerOffset[m_outerBSize];
    else
      return (m_outerBSize * m_blockSize);
  }
  /** \returns the number of rows grouped by blocks */
  inline Index blockRows() const { return (IsColMajor ? m_innerBSize : m_outerBSize); }
  /** \returns the number of columns grouped by blocks */
  inline Index blockCols() const { return (IsColMajor ? m_outerBSize : m_innerBSize); }

  inline Index outerBlocks() const { return m_outerBSize; }
  inline Index innerBlocks() const { return m_innerBSize; }

  /** \returns the block index where outer belongs to */
  inline Index outerToBlock(Index outer) const {
    eigen_assert(outer < outerSize() && "OUTER INDEX OUT OF BOUNDS");

    if (m_blockSize != Dynamic) return (outer / m_blockSize);  // Integer division

    StorageIndex b_outer = 0;
    while (m_outerOffset[b_outer] <= outer) ++b_outer;
    return b_outer - 1;
  }
  /** \returns  the block index where inner belongs to */
  inline Index innerToBlock(Index inner) const {
    eigen_assert(inner < innerSize() && "OUTER INDEX OUT OF BOUNDS");

    if (m_blockSize != Dynamic) return (inner / m_blockSize);  // Integer division

    StorageIndex b_inner = 0;
    while (m_innerOffset[b_inner] <= inner) ++b_inner;
    return b_inner - 1;
  }

  /**
   *\returns a reference to the (i,j) block as an Eigen Dense Matrix
   */
  Ref<BlockScalar> coeffRef(Index brow, Index bcol) {
    eigen_assert(brow < blockRows() && "BLOCK ROW INDEX OUT OF BOUNDS");
    eigen_assert(bcol < blockCols() && "BLOCK nzblocksFlagCOLUMN OUT OF BOUNDS");

    StorageIndex rsize = IsColMajor ? blockInnerSize(brow) : blockOuterSize(bcol);
    StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
    StorageIndex inner = IsColMajor ? brow : bcol;
    StorageIndex outer = IsColMajor ? bcol : brow;
    StorageIndex offset = m_outerIndex[outer];
    while (offset < m_outerIndex[outer + 1] && m_indices[offset] != inner) offset++;
    if (m_indices[offset] == inner) {
      return Map<BlockScalar>(&(m_values[blockPtr(offset)]), rsize, csize);
    } else {
      // FIXME the block does not exist, Insert it !!!!!!!!!
      eigen_assert("DYNAMIC INSERTION IS NOT YET SUPPORTED");
    }
  }

  /**
   * \returns the value of the (i,j) block as an Eigen Dense Matrix
   */
  Map<const BlockScalar> coeff(Index brow, Index bcol) const {
    eigen_assert(brow < blockRows() && "BLOCK ROW INDEX OUT OF BOUNDS");
    eigen_assert(bcol < blockCols() && "BLOCK COLUMN OUT OF BOUNDS");

    StorageIndex rsize = IsColMajor ? blockInnerSize(brow) : blockOuterSize(bcol);
    StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
    StorageIndex inner = IsColMajor ? brow : bcol;
    StorageIndex outer = IsColMajor ? bcol : brow;
    StorageIndex offset = m_outerIndex[outer];
    while (offset < m_outerIndex[outer + 1] && m_indices[offset] != inner) offset++;
    if (m_indices[offset] == inner) {
      return Map<const BlockScalar>(&(m_values[blockPtr(offset)]), rsize, csize);
    } else
      //        return BlockScalar::Zero(rsize, csize);
      eigen_assert("NOT YET SUPPORTED");
  }

  // Block Matrix times vector product
  template <typename VecType>
  BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType> operator*(const VecType& lhs) const {
    return BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType>(*this, lhs);
  }

  /** \returns the number of nonzero blocks */
  inline Index nonZerosBlocks() const { return m_nonzerosblocks; }
  /** \returns the total number of nonzero elements, including eventual explicit zeros in blocks */
  inline Index nonZeros() const { return m_nonzeros; }

  inline BlockScalarReturnType* valuePtr() { return static_cast<BlockScalarReturnType*>(m_values); }
  //    inline Scalar *valuePtr(){ return m_values; }
  inline StorageIndex* innerIndexPtr() { return m_indices; }
  inline const StorageIndex* innerIndexPtr() const { return m_indices; }
  inline StorageIndex* outerIndexPtr() { return m_outerIndex; }
  inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; }

  /** \brief for compatibility purposes with the SparseMatrix class */
  inline bool isCompressed() const { return true; }
  /**
   * \returns the starting index of the bi row block
   */
  inline Index blockRowsIndex(Index bi) const { return IsColMajor ? blockInnerIndex(bi) : blockOuterIndex(bi); }

  /**
   * \returns the starting index of the bj col block
   */
  inline Index blockColsIndex(Index bj) const { return IsColMajor ? blockOuterIndex(bj) : blockInnerIndex(bj); }

  inline Index blockOuterIndex(Index bj) const {
    return (m_blockSize == Dynamic) ? m_outerOffset[bj] : (bj * m_blockSize);
  }
  inline Index blockInnerIndex(Index bi) const {
    return (m_blockSize == Dynamic) ? m_innerOffset[bi] : (bi * m_blockSize);
  }

  // Not needed ???
  inline Index blockInnerSize(Index bi) const {
    return (m_blockSize == Dynamic) ? (m_innerOffset[bi + 1] - m_innerOffset[bi]) : m_blockSize;
  }
  inline Index blockOuterSize(Index bj) const {
    return (m_blockSize == Dynamic) ? (m_outerOffset[bj + 1] - m_outerOffset[bj]) : m_blockSize;
  }

  /**
   * \brief Browse the matrix by outer index
   */
  class InnerIterator;  // Browse column by column

  /**
   * \brief Browse the matrix by block outer index
   */
  class BlockInnerIterator;  // Browse block by block

  friend std::ostream& operator<<(std::ostream& s, const BlockSparseMatrix& m) {
    for (StorageIndex j = 0; j < m.outerBlocks(); ++j) {
      BlockInnerIterator itb(m, j);
      for (; itb; ++itb) {
        s << "(" << itb.row() << ", " << itb.col() << ")\n";
        s << itb.value() << "\n";
      }
    }
    s << std::endl;
    return s;
  }

  /**
   * \returns the starting position of the block \p id in the array of values
   */
  Index blockPtr(Index id) const {
    if (m_blockSize == Dynamic)
      return m_blockPtr[id];
    else
      return id * m_blockSize * m_blockSize;
    // return blockDynIdx(id, std::conditional_t<(BlockSize==Dynamic), internal::true_type, internal::false_type>());
  }

 protected:
  //    inline Index blockDynIdx(Index id, internal::true_type) const
  //    {
  //      return m_blockPtr[id];
  //    }
  //    inline Index blockDynIdx(Index id, internal::false_type) const
  //    {
  //      return id * BlockSize * BlockSize;
  //    }

  // To be implemented
  // Insert a block at a particular location... need to make a room for that
  Map<BlockScalar> insert(Index brow, Index bcol);

  Index m_innerBSize;           // Number of block rows
  Index m_outerBSize;           // Number of block columns
  StorageIndex* m_innerOffset;  // Starting index of each inner block (size m_innerBSize+1)
  StorageIndex* m_outerOffset;  // Starting index of each outer block (size m_outerBSize+1)
  Index m_nonzerosblocks;       // Total nonzeros blocks (lower than  m_innerBSize x m_outerBSize)
  Index m_nonzeros;             // Total nonzeros elements
  Scalar* m_values;             // Values stored block column after block column (size m_nonzeros)
  StorageIndex* m_blockPtr;     // Pointer to the beginning of each block in m_values, size m_nonzeroblocks ... null for
                                // fixed-size blocks
  StorageIndex* m_indices;      // Inner block indices, size m_nonzerosblocks ... OK
  StorageIndex* m_outerIndex;   // Starting pointer of each block column in m_indices (size m_outerBSize)... OK
  Index m_blockSize;            // Size of a block for fixed-size blocks, otherwise -1
};

template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename StorageIndex_>
class BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_>::BlockInnerIterator {
 public:
  enum { Flags = Options_ };

  BlockInnerIterator(const BlockSparseMatrix& mat, const Index outer)
      : m_mat(mat), m_outer(outer), m_id(mat.m_outerIndex[outer]), m_end(mat.m_outerIndex[outer + 1]) {}

  inline BlockInnerIterator& operator++() {
    m_id++;
    return *this;
  }

  inline const Map<const BlockScalar> value() const {
    return Map<const BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]), rows(), cols());
  }
  inline Map<BlockScalar> valueRef() {
    return Map<BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]), rows(), cols());
  }
  // Block inner index
  inline Index index() const { return m_mat.m_indices[m_id]; }
  inline Index outer() const { return m_outer; }
  // block row index
  inline Index row() const { return index(); }
  // block column index
  inline Index col() const { return outer(); }
  // FIXME Number of rows in the current block
  inline Index rows() const {
    return (m_mat.m_blockSize == Dynamic) ? (m_mat.m_innerOffset[index() + 1] - m_mat.m_innerOffset[index()])
                                          : m_mat.m_blockSize;
  }
  // Number of columns in the current block ...
  inline Index cols() const {
    return (m_mat.m_blockSize == Dynamic) ? (m_mat.m_outerOffset[m_outer + 1] - m_mat.m_outerOffset[m_outer])
                                          : m_mat.m_blockSize;
  }
  inline operator bool() const { return (m_id < m_end); }

 protected:
  const BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex>& m_mat;
  const Index m_outer;
  Index m_id;
  Index m_end;
};

template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename StorageIndex_>
class BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_>::InnerIterator {
 public:
  InnerIterator(const BlockSparseMatrix& mat, Index outer)
      : m_mat(mat),
        m_outerB(mat.outerToBlock(outer)),
        m_outer(outer),
        itb(mat, mat.outerToBlock(outer)),
        m_offset(outer - mat.blockOuterIndex(m_outerB)) {
    if (itb) {
      m_id = m_mat.blockInnerIndex(itb.index());
      m_start = m_id;
      m_end = m_mat.blockInnerIndex(itb.index() + 1);
    }
  }
  inline InnerIterator& operator++() {
    m_id++;
    if (m_id >= m_end) {
      ++itb;
      if (itb) {
        m_id = m_mat.blockInnerIndex(itb.index());
        m_start = m_id;
        m_end = m_mat.blockInnerIndex(itb.index() + 1);
      }
    }
    return *this;
  }
  inline const Scalar& value() const { return itb.value().coeff(m_id - m_start, m_offset); }
  inline Scalar& valueRef() { return itb.valueRef().coeff(m_id - m_start, m_offset); }
  inline Index index() const { return m_id; }
  inline Index outer() const { return m_outer; }
  inline Index col() const { return outer(); }
  inline Index row() const { return index(); }
  inline operator bool() const { return itb; }

 protected:
  const BlockSparseMatrix& m_mat;
  const Index m_outer;
  const Index m_outerB;
  BlockInnerIterator itb;  // Iterator through the blocks
  const Index m_offset;    // Position of this column in the block
  Index m_start;           // starting inner index of this block
  Index m_id;              // current inner index in the block
  Index m_end;             // starting inner index of the next block
};
}  // end namespace Eigen

#endif  // EIGEN_SPARSEBLOCKMATRIX_H
