// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-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_SPARSEMATRIXBASE_H
#define EIGEN_SPARSEMATRIXBASE_H

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

namespace Eigen {

/** \ingroup SparseCore_Module
 *
 * \class SparseMatrixBase
 *
 * \brief Base class of any sparse matrices or sparse expressions
 *
 * \tparam Derived is the derived type, e.g. a sparse matrix type, or an expression, etc.
 *
 * This class can be extended with the help of the plugin mechanism described on the page
 * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_SPARSEMATRIXBASE_PLUGIN.
 */
template <typename Derived>
class SparseMatrixBase : public EigenBase<Derived> {
 public:
  using Scalar = typename internal::traits<Derived>::Scalar;

  /** The numeric type of the expression's coefficients, e.g. float, double, int or std::complex<float>, etc.
   *
   * It is an alias for the Scalar type */
  using value_type = Scalar;

  using PacketScalar = typename internal::packet_traits<Scalar>::type;
  using StorageKind = typename internal::traits<Derived>::StorageKind;

  /** The integer type used to \b store indices within a SparseMatrix.
   * For a \c SparseMatrix<Scalar,Options,IndexType> it is an alias of the third template parameter \c IndexType. */
  using StorageIndex = typename internal::traits<Derived>::StorageIndex;

  using PacketReturnType = std::conditional_t<internal::is_arithmetic<PacketScalar>::value, PacketScalar,
                                              internal::add_const_on_value_type_t<PacketScalar>>;

  using StorageBaseType = SparseMatrixBase;

  using IndexVector = Matrix<StorageIndex, Dynamic, 1>;
  using ScalarVector = Matrix<Scalar, Dynamic, 1>;

  template <typename OtherDerived>
  Derived& operator=(const EigenBase<OtherDerived>& other);

  enum {

    RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
    /**< The number of rows at compile-time. This is just a copy of the value provided
     * by the \a Derived type. If a value is not known at compile-time,
     * it is set to the \a Dynamic constant.
     * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */

    ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
    /**< The number of columns at compile-time. This is just a copy of the value provided
     * by the \a Derived type. If a value is not known at compile-time,
     * it is set to the \a Dynamic constant.
     * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */

    SizeAtCompileTime = (internal::size_of_xpr_at_compile_time<Derived>::value),
    /**< This is equal to the number of coefficients, i.e. the number of
     * rows times the number of columns, or to \a Dynamic if this is not
     * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */

    MaxRowsAtCompileTime = RowsAtCompileTime,
    MaxColsAtCompileTime = ColsAtCompileTime,

    MaxSizeAtCompileTime = internal::size_at_compile_time(MaxRowsAtCompileTime, MaxColsAtCompileTime),

    IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
    /**< This is set to true if either the number of rows or the number of
     * columns is known at compile-time to be equal to 1. Indeed, in that case,
     * we are dealing with a column-vector (if there is only one column) or with
     * a row-vector (if there is only one row). */

    NumDimensions = int(MaxSizeAtCompileTime) == 1 ? 0
                    : bool(IsVectorAtCompileTime)  ? 1
                                                   : 2,
    /**< This value is equal to Tensor::NumDimensions, i.e. 0 for scalars, 1 for vectors,
     * and 2 for matrices.
     */

    Flags = internal::traits<Derived>::Flags,
    /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
     * constructed from this one. See the \ref flags "list of flags".
     */

    IsRowMajor = Flags & RowMajorBit ? 1 : 0,

    InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
                             : int(IsRowMajor)          ? int(ColsAtCompileTime)
                                                        : int(RowsAtCompileTime),

#ifndef EIGEN_PARSED_BY_DOXYGEN
    HasDirectAccess_ = (int(Flags) & DirectAccessBit) ? 1 : 0  // workaround sunCC
#endif
  };

  /** \internal the return type of MatrixBase::adjoint() */
  using AdjointReturnType =
      std::conditional_t<NumTraits<Scalar>::IsComplex,
                         CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived>>,
                         Transpose<const Derived>>;
  using TransposeReturnType = Transpose<Derived>;
  using ConstTransposeReturnType = Transpose<const Derived>;

  // FIXME: storage order may not match evaluator storage order.
  using PlainObject = SparseMatrix<Scalar, Flags & RowMajorBit ? RowMajor : ColMajor, StorageIndex>;

  /** This is the "real scalar" type; if the \a Scalar type is already real numbers
   * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
   * \a Scalar is \a std::complex<T> then RealScalar is \a T.
   *
   * \sa class NumTraits
   */
  using RealScalar = typename NumTraits<Scalar>::Real;

#ifndef EIGEN_PARSED_BY_DOXYGEN
  /** \internal the return type of coeff()
   */
  using CoeffReturnType = std::conditional_t<HasDirectAccess_, const Scalar&, Scalar>;

  /** \internal Represents a matrix with all coefficients equal to one another*/
  using ConstantReturnType = CwiseNullaryOp<internal::scalar_constant_op<Scalar>, Matrix<Scalar, Dynamic, Dynamic>>;

  /** type of the equivalent dense matrix */
  using DenseMatrixType = Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime>;
  /** type of the equivalent square matrix */
  using SquareMatrixType = Matrix<Scalar, internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
                                  internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime)>;

  inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
  inline Derived& derived() { return *static_cast<Derived*>(this); }
  inline Derived& const_cast_derived() const { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }

  using Base = EigenBase<Derived>;

#endif  // not EIGEN_PARSED_BY_DOXYGEN

#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
#ifdef EIGEN_PARSED_BY_DOXYGEN
#define EIGEN_DOC_UNARY_ADDONS(METHOD,                                                                               \
                               OP) /** <p>This method does not change the sparsity of \c *this: the OP is applied to \
                                      explicitly stored coefficients only. \sa SparseCompressedBase::coeffs() </p> */
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL /** <p> \warning This method returns a read-only expression for any   \
                                                  sparse matrices. \sa \ref TutorialSparse_SubMatrices "Sparse block \
                                                  operations" </p> */
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(                                                                       \
    COND) /** <p> \warning This method returns a read-write expression for COND sparse matrices only. Otherwise, the \
             returned expression is read-only. \sa \ref TutorialSparse_SubMatrices "Sparse block operations" </p> */
#else
#define EIGEN_DOC_UNARY_ADDONS(X, Y)
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
#endif
#include "../plugins/CommonCwiseUnaryOps.inc"
#include "../plugins/CommonCwiseBinaryOps.inc"
#include "../plugins/MatrixCwiseUnaryOps.inc"
#include "../plugins/MatrixCwiseBinaryOps.inc"
#include "../plugins/BlockMethods.inc"
#ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
#include EIGEN_SPARSEMATRIXBASE_PLUGIN
#endif
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
#undef EIGEN_DOC_UNARY_ADDONS
#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF

  /** \returns the number of rows. \sa cols() */
  inline Index rows() const { return derived().rows(); }
  /** \returns the number of columns. \sa rows() */
  inline Index cols() const { return derived().cols(); }
  /** \returns the number of coefficients, which is \a rows()*cols().
   * \sa rows(), cols(). */
  inline Index size() const { return rows() * cols(); }
  /** \returns true if either the number of rows or the number of columns is equal to 1.
   * In other words, this function returns
   * \code rows()==1 || cols()==1 \endcode
   * \sa rows(), cols(), IsVectorAtCompileTime. */
  inline bool isVector() const { return rows() == 1 || cols() == 1; }
  /** \returns the size of the storage major dimension,
   * i.e., the number of columns for a column major matrix, and the number of rows otherwise */
  Index outerSize() const { return (int(Flags) & RowMajorBit) ? this->rows() : this->cols(); }
  /** \returns the size of the inner dimension according to the storage order,
   * i.e., the number of rows for a column major matrix, and the number of cols otherwise */
  Index innerSize() const { return (int(Flags) & RowMajorBit) ? this->cols() : this->rows(); }

  bool isRValue() const { return m_isRValue; }
  Derived& markAsRValue() {
    m_isRValue = true;
    return derived();
  }

  SparseMatrixBase() : m_isRValue(false) { /* TODO: validate traits flags. */
  }

  template <typename OtherDerived>
  Derived& operator=(const ReturnByValue<OtherDerived>& other);

  template <typename OtherDerived>
  inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other);

  inline Derived& operator=(const Derived& other);

 protected:
  template <typename OtherDerived>
  inline Derived& assign(const OtherDerived& other);

  template <typename OtherDerived>
  inline void assignGeneric(const OtherDerived& other);

 public:
#ifndef EIGEN_NO_IO
  friend std::ostream& operator<<(std::ostream& s, const SparseMatrixBase& m) {
    using Nested = typename Derived::Nested;
    using NestedCleaned = internal::remove_all_t<Nested>;

    EIGEN_IF_CONSTEXPR (Flags & RowMajorBit) {
      Nested nm(m.derived());
      internal::evaluator<NestedCleaned> thisEval(nm);

      // compute global width
      std::size_t width = 0;
      {
        std::ostringstream ss0;
        ss0.copyfmt(s);
        ss0 << Scalar(0);
        width = ss0.str().size();
        for (Index row = 0; row < nm.outerSize(); ++row) {
          for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, row); it; ++it) {
            std::ostringstream ss;
            ss.copyfmt(s);
            ss << it.value();

            const std::size_t potential_width = ss.str().size();
            if (potential_width > width) width = potential_width;
          }
        }
      }

      for (Index row = 0; row < nm.outerSize(); ++row) {
        Index col = 0;
        for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, row); it; ++it) {
          for (; col < it.index(); ++col) {
            s.width(width);
            s << Scalar(0) << " ";
          }
          s.width(width);
          s << it.value() << " ";
          ++col;
        }
        for (; col < m.cols(); ++col) {
          s.width(width);
          s << Scalar(0) << " ";
        }
        s << std::endl;
      }
    } else {
      Nested nm(m.derived());
      internal::evaluator<NestedCleaned> thisEval(nm);
      if (m.cols() == 1) {
        // compute local width (single col)
        std::size_t width = 0;
        {
          std::ostringstream ss0;
          ss0.copyfmt(s);
          ss0 << Scalar(0);
          width = ss0.str().size();
          for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, 0); it; ++it) {
            std::ostringstream ss;
            ss.copyfmt(s);
            ss << it.value();

            const std::size_t potential_width = ss.str().size();
            if (potential_width > width) width = potential_width;
          }
        }

        Index row = 0;
        for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, 0); it; ++it) {
          for (; row < it.index(); ++row) {
            s.width(width);
            s << Scalar(0) << std::endl;
          }
          s.width(width);
          s << it.value() << std::endl;
          ++row;
        }
        for (; row < m.rows(); ++row) {
          s.width(width);
          s << Scalar(0) << std::endl;
        }
      } else {
        SparseMatrix<Scalar, RowMajorBit, StorageIndex> trans = m;
        s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, StorageIndex>>&>(trans);
      }
    }
    return s;
  }
#endif

  template <typename OtherDerived>
  Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
  template <typename OtherDerived>
  Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);

  template <typename OtherDerived>
  Derived& operator+=(const DiagonalBase<OtherDerived>& other);
  template <typename OtherDerived>
  Derived& operator-=(const DiagonalBase<OtherDerived>& other);

  template <typename OtherDerived>
  Derived& operator+=(const EigenBase<OtherDerived>& other);
  template <typename OtherDerived>
  Derived& operator-=(const EigenBase<OtherDerived>& other);

  Derived& operator*=(const Scalar& other);
  Derived& operator/=(const Scalar& other);

  template <typename OtherDerived>
  struct CwiseProductDenseReturnType {
    using Type = CwiseBinaryOp<
        internal::scalar_product_op<typename ScalarBinaryOpTraits<
            typename internal::traits<Derived>::Scalar, typename internal::traits<OtherDerived>::Scalar>::ReturnType>,
        const Derived, const OtherDerived>;
  };

  template <typename OtherDerived>
  EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type cwiseProduct(
      const MatrixBase<OtherDerived>& other) const;

  // sparse * diagonal
  template <typename OtherDerived>
  const Product<Derived, OtherDerived> operator*(const DiagonalBase<OtherDerived>& other) const {
    return Product<Derived, OtherDerived>(derived(), other.derived());
  }

  // diagonal * sparse
  template <typename OtherDerived>
  friend const Product<OtherDerived, Derived> operator*(const DiagonalBase<OtherDerived>& lhs,
                                                        const SparseMatrixBase& rhs) {
    return Product<OtherDerived, Derived>(lhs.derived(), rhs.derived());
  }

  // sparse * sparse
  template <typename OtherDerived>
  const Product<Derived, OtherDerived, AliasFreeProduct> operator*(const SparseMatrixBase<OtherDerived>& other) const;

  // sparse * dense
  template <typename OtherDerived>
  const Product<Derived, OtherDerived> operator*(const MatrixBase<OtherDerived>& other) const {
    return Product<Derived, OtherDerived>(derived(), other.derived());
  }

  // dense * sparse
  template <typename OtherDerived>
  friend const Product<OtherDerived, Derived> operator*(const MatrixBase<OtherDerived>& lhs,
                                                        const SparseMatrixBase& rhs) {
    return Product<OtherDerived, Derived>(lhs.derived(), rhs.derived());
  }

  /** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */
  SparseSymmetricPermutationProduct<Derived, Upper | Lower> twistedBy(
      const PermutationMatrix<Dynamic, Dynamic, StorageIndex>& perm) const {
    return SparseSymmetricPermutationProduct<Derived, Upper | Lower>(derived(), perm);
  }

  template <typename OtherDerived>
  Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);

  template <int Mode>
  inline const TriangularView<const Derived, Mode> triangularView() const;

  template <unsigned int UpLo>
  struct SelfAdjointViewReturnType {
    using Type = SparseSelfAdjointView<Derived, UpLo>;
  };
  template <unsigned int UpLo>
  struct ConstSelfAdjointViewReturnType {
    using Type = const SparseSelfAdjointView<const Derived, UpLo>;
  };

  template <unsigned int UpLo>
  inline typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
  template <unsigned int UpLo>
  inline typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();

  template <typename OtherDerived>
  Scalar dot(const MatrixBase<OtherDerived>& other) const;
  template <typename OtherDerived>
  Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
  RealScalar squaredNorm() const;
  RealScalar norm() const;
  RealScalar blueNorm() const;

  TransposeReturnType transpose() { return TransposeReturnType(derived()); }
  const ConstTransposeReturnType transpose() const { return ConstTransposeReturnType(derived()); }
  const AdjointReturnType adjoint() const { return AdjointReturnType(transpose()); }

  DenseMatrixType toDense() const { return DenseMatrixType(derived()); }

  template <typename OtherDerived>
  bool isApprox(const SparseMatrixBase<OtherDerived>& other,
                const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;

  template <typename OtherDerived>
  bool isApprox(const MatrixBase<OtherDerived>& other,
                const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const {
    return toDense().isApprox(other, prec);
  }

  /** \returns the matrix or vector obtained by evaluating this expression.
   *
   * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
   * a const reference, in order to avoid a useless copy.
   */
  inline const typename internal::eval<Derived>::type eval() const {
    return typename internal::eval<Derived>::type(derived());
  }

  Scalar sum() const;

  inline const SparseView<Derived> pruned(const Scalar& reference = Scalar(0),
                                          const RealScalar& epsilon = NumTraits<Scalar>::dummy_precision()) const;

 protected:
  bool m_isRValue;

  static inline StorageIndex convert_index(const Index idx) { return internal::convert_index<StorageIndex>(idx); }

 private:
  template <typename Dest>
  void evalTo(Dest&) const;
};

}  // end namespace Eigen

#endif  // EIGEN_SPARSEMATRIXBASE_H
