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

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

namespace Eigen {

namespace internal {

template <typename Lhs, typename Rhs, int Mode,
          int UpLo = (Mode & Lower)   ? Lower
                     : (Mode & Upper) ? Upper
                                      : -1,
          int StorageOrder = int(traits<Lhs>::Flags) & RowMajorBit>
struct sparse_solve_triangular_selector;

// forward substitution, row-major
template <typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs, Rhs, Mode, Lower, RowMajor> {
  using Scalar = typename Rhs::Scalar;
  using LhsEval = evaluator<Lhs>;
  using LhsIterator = typename evaluator<Lhs>::InnerIterator;
  static void run(const Lhs& lhs, Rhs& other) {
    LhsEval lhsEval(lhs);
    for (Index col = 0; col < other.cols(); ++col) {
      for (Index i = 0; i < lhs.rows(); ++i) {
        Scalar tmp = other.coeff(i, col);
        Scalar lastVal(0);
        Index lastIndex = 0;
        for (LhsIterator it(lhsEval, i); it; ++it) {
          lastVal = it.value();
          lastIndex = it.index();
          if (lastIndex == i) break;
          tmp = numext::madd<Scalar>(-lastVal, other.coeff(lastIndex, col), tmp);
        }
        EIGEN_IF_CONSTEXPR (Mode & UnitDiag)
          other.coeffRef(i, col) = tmp;
        else {
          eigen_assert(lastIndex == i);
          other.coeffRef(i, col) = tmp / lastVal;
        }
      }
    }
  }
};

// backward substitution, row-major
template <typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs, Rhs, Mode, Upper, RowMajor> {
  using Scalar = typename Rhs::Scalar;
  using LhsEval = evaluator<Lhs>;
  using LhsIterator = typename evaluator<Lhs>::InnerIterator;
  static void run(const Lhs& lhs, Rhs& other) {
    LhsEval lhsEval(lhs);
    for (Index col = 0; col < other.cols(); ++col) {
      for (Index i = lhs.rows() - 1; i >= 0; --i) {
        Scalar tmp = other.coeff(i, col);
        Scalar l_ii(0);
        LhsIterator it(lhsEval, i);
        while (it && it.index() < i) ++it;
        EIGEN_IF_CONSTEXPR (!(Mode & UnitDiag)) {
          eigen_assert(it && it.index() == i);
          l_ii = it.value();
          ++it;
        } else if (it && it.index() == i)
          ++it;
        for (; it; ++it) {
          tmp = numext::madd<Scalar>(-it.value(), other.coeff(it.index(), col), tmp);
        }

        EIGEN_IF_CONSTEXPR (Mode & UnitDiag)
          other.coeffRef(i, col) = tmp;
        else
          other.coeffRef(i, col) = tmp / l_ii;
      }
    }
  }
};

// forward substitution, col-major
template <typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs, Rhs, Mode, Lower, ColMajor> {
  using Scalar = typename Rhs::Scalar;
  using LhsEval = evaluator<Lhs>;
  using LhsIterator = typename evaluator<Lhs>::InnerIterator;
  static void run(const Lhs& lhs, Rhs& other) {
    LhsEval lhsEval(lhs);
    for (Index col = 0; col < other.cols(); ++col) {
      for (Index i = 0; i < lhs.cols(); ++i) {
        Scalar& tmp = other.coeffRef(i, col);
        if (!numext::is_exactly_zero(tmp))  // optimization when other is actually sparse
        {
          LhsIterator it(lhsEval, i);
          while (it && it.index() < i) ++it;
          EIGEN_IF_CONSTEXPR (!(Mode & UnitDiag)) {
            eigen_assert(it && it.index() == i);
            tmp /= it.value();
          }
          if (it && it.index() == i) ++it;
          for (; it; ++it) {
            other.coeffRef(it.index(), col) = numext::madd<Scalar>(-tmp, it.value(), other.coeffRef(it.index(), col));
          }
        }
      }
    }
  }
};

// backward substitution, col-major
template <typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs, Rhs, Mode, Upper, ColMajor> {
  using Scalar = typename Rhs::Scalar;
  using LhsEval = evaluator<Lhs>;
  using LhsIterator = typename evaluator<Lhs>::InnerIterator;
  static void run(const Lhs& lhs, Rhs& other) {
    LhsEval lhsEval(lhs);
    for (Index col = 0; col < other.cols(); ++col) {
      for (Index i = lhs.cols() - 1; i >= 0; --i) {
        Scalar& tmp = other.coeffRef(i, col);
        if (!numext::is_exactly_zero(tmp))  // optimization when other is actually sparse
        {
          EIGEN_IF_CONSTEXPR (!(Mode & UnitDiag)) {
            // TODO: replace this with a binary search. make sure the binary search is safe for partially sorted
            // elements
            LhsIterator it(lhsEval, i);
            while (it && it.index() != i) ++it;
            eigen_assert(it && it.index() == i);
            other.coeffRef(i, col) /= it.value();
          }
          LhsIterator it(lhsEval, i);
          for (; it && it.index() < i; ++it) {
            other.coeffRef(it.index(), col) = numext::madd<Scalar>(-tmp, it.value(), other.coeffRef(it.index(), col));
          }
        }
      }
    }
  }
};

}  // end namespace internal

#ifndef EIGEN_PARSED_BY_DOXYGEN

template <typename ExpressionType, unsigned int Mode>
template <typename OtherDerived>
void TriangularViewImpl<ExpressionType, Mode, Sparse>::solveInPlace(MatrixBase<OtherDerived>& other) const {
  eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
  eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper | Lower)));

  enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit };

  using OtherCopy =
      std::conditional_t<copy, typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>;
  OtherCopy otherCopy(other.derived());

  internal::sparse_solve_triangular_selector<ExpressionType, std::remove_reference_t<OtherCopy>, Mode>::run(
      derived().nestedExpression(), otherCopy);

  if (copy) other = otherCopy;
}
#endif

// pure sparse path

namespace internal {

template <typename Lhs, typename Rhs, int Mode,
          int UpLo = (Mode & Lower)   ? Lower
                     : (Mode & Upper) ? Upper
                                      : -1,
          int StorageOrder = int(Lhs::Flags) & RowMajorBit>
struct sparse_solve_triangular_sparse_selector;

// True when the rhs exposes raw CSC storage with a StorageIndex matching the lhs, so a
// column's stored index slice can serve as the reach roots directly (no bIdx copy). A
// SparseVector qualifies too -- it is a single compressed column, handled below via the
// null-outerIndexPtr guard (its outerIndexPtr() is null since it has no outer array).
template <typename Lhs, typename Rhs>
using rhs_matching_slice = std::integral_constant<
    bool, has_compressed_access<Rhs>::value &&
              std::is_same<typename traits<Rhs>::StorageIndex, typename traits<Lhs>::StorageIndex>::value>;

// The reach for a column arrives in one of three compile-time-known orders, but the
// output column must store ascending inner index. reach_reorder encapsulates the
// per-order fix-up via partial specialization: an unordered reach (Ordered == false,
// the pointer/DFS path -- Upper irrelevant) is sorted; the iterator reach is already
// in solve order -- ascending for lower (no-op), descending for upper (reverse).
template <bool Ordered, bool Upper, typename StorageIndex>
struct reach_reorder {  // Ordered == false: unordered pointer/DFS reach
  static void run(StorageIndex* first, StorageIndex* last) { std::sort(first, last); }
};
template <typename StorageIndex>
struct reach_reorder<true, false, StorageIndex> {  // iterator reach, lower: already ascending
  static void run(StorageIndex* /*first*/, StorageIndex* /*last*/) {}
};
template <typename StorageIndex>
struct reach_reorder<true, true, StorageIndex> {  // iterator reach, upper: descending
  static void run(StorageIndex* first, StorageIndex* last) { std::reverse(first, last); }
};

// Common per-column finish: reorder the reach xi[top..n) to ascending inner index,
// insert reading values from xwork, and clear xwork and mark for the next column.
// The reach is a structural bound, not a numeric one: a reached coefficient can be
// exactly zero (a zero rhs entry, or numerical cancellation), so skip exact zeros at
// insertion. This matches the AmbiVector path, which pruned zeros, and keeps a zero rhs
// from materializing O(|reach|) stored zeros. xwork and mark are cleared regardless.
template <bool Ordered, bool Upper, typename Res, typename StorageIndex, typename Scalar>
void reach_insert_column(Res& res, Index col, StorageIndex* xi, Index top, Index n, Scalar* xwork, uint8_t* mark) {
  reach_reorder<Ordered, Upper, StorageIndex>::run(xi + top, xi + n);
  for (Index k = top; k < n; ++k) {
    StorageIndex j = xi[k];
    if (!numext::is_exactly_zero(xwork[j])) res.insert(j, col) = xwork[j];
    xwork[j] = Scalar(0);
    mark[j] = 0;
  }
}

// Column loop, fast path: the rhs matches (see rhs_matching_slice), so each column's
// stored index slice is the reach root list and the value slice is scattered directly
// -- no bIdx copy, so iwork is just 2n (xi | pstack).
template <bool Upper, bool UnitDiag, typename Lhs, typename Rhs, typename Res, typename Scalar,
          std::enable_if_t<rhs_matching_slice<Lhs, Rhs>::value, int> = 0>
void reach_solve_columns(const Lhs& lhs, const Rhs& other, Res& res, uint8_t* mark, Scalar* xwork, Index n) {
  using StorageIndex = typename traits<Lhs>::StorageIndex;
  Matrix<StorageIndex, Dynamic, 1> iwork(2 * n);  // xi | pstack
  StorageIndex* xi = iwork.data();
  for (Index col = 0; col < other.cols(); ++col) {
    const StorageIndex* outer = other.outerIndexPtr();  // null for a SparseVector (single column)
    const StorageIndex* nnz = other.innerNonZeroPtr();  // null when compressed
    Index p = outer ? outer[col] : 0;
    Index bCount = outer ? (nnz ? Index(nnz[col]) : Index(outer[col + 1]) - p) : other.nonZeros();
    const StorageIndex* roots = other.innerIndexPtr() + p;  // the column's stored indices
    const Scalar* vals = other.valuePtr() + p;
    // Roots are the rhs slice directly (no bIdx copy, so iwork stays 2n). An exact-zero
    // stored rhs entry is seeded harmlessly -- it propagates zeros and is dropped at
    // insertion; filtering it here would cost a compacted root buffer (the 3n path).
    for (Index r = 0; r < bCount; ++r) xwork[roots[r]] = vals[r];
    Index top = reach_solve_dense<Upper, UnitDiag>(lhs, roots, bCount, xi, mark, xwork);
    reach_insert_column<!has_compressed_access<Lhs>::value, Upper>(res, col, xi, top, n, xwork, mark);
  }
}

// Column loop, fallback: read each column through the InnerIterator, copying indices
// into the bIdx third of a 3n iwork. For a rhs without raw storage or with a
// mismatched index type.
template <bool Upper, bool UnitDiag, typename Lhs, typename Rhs, typename Res, typename Scalar,
          std::enable_if_t<!rhs_matching_slice<Lhs, Rhs>::value, int> = 0>
void reach_solve_columns(const Lhs& lhs, const Rhs& other, Res& res, uint8_t* mark, Scalar* xwork, Index n) {
  using StorageIndex = typename traits<Lhs>::StorageIndex;
  Matrix<StorageIndex, Dynamic, 1> iwork(3 * n);  // xi | pstack | bIdx
  StorageIndex* xi = iwork.data();
  StorageIndex* bIdx = iwork.data() + 2 * n;
  for (Index col = 0; col < other.cols(); ++col) {
    Index bCount = 0;
    for (typename Rhs::InnerIterator it(other, col); it; ++it) {
      if (numext::is_exactly_zero(it.value())) continue;  // a zero root seeds nothing; xwork stays clear there
      bIdx[bCount] = StorageIndex(it.index());
      xwork[it.index()] = it.value();
      ++bCount;
    }
    Index top = reach_solve_dense<Upper, UnitDiag>(lhs, bIdx, bCount, xi, mark, xwork);
    reach_insert_column<!has_compressed_access<Lhs>::value, Upper>(res, col, xi, top, n, xwork, mark);
  }
}

// Reach-based (Gilbert-Peierls) sparse triangular solve, col-major, for lower OR
// upper. Only the columns reachable from each rhs column's pattern are touched, so
// the cost is O(|reach| + flops) per column instead of a dense O(n)-per-column sweep
// (which also pays a coeff(i,i) binary search per row in the upper case). It is
// the sole col-major sparse-sparse selector, dispatching lower/upper via the UpLo
// template argument. reach_solve_dense leaves the solution values in
// xwork and the reached indices in iwork[top..n); reach_solve_columns (slice or
// fallback, selected on the rhs storage) scatters each column and solves, and
// reach_insert_column reads the values out and restores mark/xwork. Only mark and
// xwork need zeroing -- iwork is entirely written before read.
template <bool Upper, typename Lhs, typename Rhs, int Mode>
void run_sparse_reach_triangular_solve(const Lhs& lhs, Rhs& other) {
  using Scalar = typename Rhs::Scalar;
  Index n = lhs.rows();
  Matrix<uint8_t, Dynamic, 1> mark = Matrix<uint8_t, Dynamic, 1>::Zero(n);
  Matrix<Scalar, Dynamic, 1> xwork = Matrix<Scalar, Dynamic, 1>::Zero(n);
  Rhs res(other.rows(), other.cols());
  res.reserve(other.nonZeros());
  reach_solve_columns<Upper, bool(Mode & UnitDiag)>(lhs, other, res, mark.data(), xwork.data(), n);
  res.finalize();
  other = res.markAsRValue();
}

// forward and backward substitution, col-major
template <typename Lhs, typename Rhs, int Mode, int UpLo>
struct sparse_solve_triangular_sparse_selector<Lhs, Rhs, Mode, UpLo, ColMajor> {
  static void run(const Lhs& lhs, Rhs& other) {
    run_sparse_reach_triangular_solve<UpLo == Upper, Lhs, Rhs, Mode>(lhs, other);
  }
};

}  // end namespace internal

#ifndef EIGEN_PARSED_BY_DOXYGEN
template <typename ExpressionType, unsigned int Mode>
template <typename OtherDerived>
void TriangularViewImpl<ExpressionType, Mode, Sparse>::solveInPlace(SparseMatrixBase<OtherDerived>& other) const {
  eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
  eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper | Lower)));

  internal::sparse_solve_triangular_sparse_selector<ExpressionType, OtherDerived, Mode>::run(
      derived().nestedExpression(), other.derived());
}
#endif

}  // end namespace Eigen

#endif  // EIGEN_SPARSETRIANGULARSOLVER_H
