// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2025 Charlie Schlosser <cs.schlosser@gmail.com>
//
// 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_FIND_COEFF_H
#define EIGEN_FIND_COEFF_H

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

namespace Eigen {

namespace internal {

template <typename Scalar, int NaNPropagation, bool IsInteger = NumTraits<Scalar>::IsInteger>
struct max_coeff_functor {
  EIGEN_DEVICE_FUNC inline bool compareCoeff(const Scalar& incumbent, const Scalar& candidate) const {
    return candidate > incumbent;
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Packet comparePacket(const Packet& incumbent, const Packet& candidate) const {
    return pcmp_lt(incumbent, candidate);
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Scalar predux(const Packet& a) const {
    return predux_max(a);
  }
};

template <typename Scalar>
struct max_coeff_functor<Scalar, PropagateNaN, false> {
  EIGEN_DEVICE_FUNC inline bool compareCoeff(const Scalar& incumbent, const Scalar& candidate) const {
    return (candidate > incumbent) || ((candidate != candidate) && (incumbent == incumbent));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Packet comparePacket(const Packet& incumbent, const Packet& candidate) const {
    return pandnot(pcmp_lt_or_nan(incumbent, candidate), pisnan(incumbent));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Scalar predux(const Packet& a) const {
    return predux_max<PropagateNaN>(a);
  }
};

template <typename Scalar>
struct max_coeff_functor<Scalar, PropagateNumbers, false> {
  EIGEN_DEVICE_FUNC inline bool compareCoeff(const Scalar& incumbent, const Scalar& candidate) const {
    return (candidate > incumbent) || ((candidate == candidate) && (incumbent != incumbent));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Packet comparePacket(const Packet& incumbent, const Packet& candidate) const {
    return pandnot(pcmp_lt_or_nan(incumbent, candidate), pisnan(candidate));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Scalar predux(const Packet& a) const {
    return predux_max<PropagateNumbers>(a);
  }
};

template <typename Scalar, int NaNPropagation, bool IsInteger = NumTraits<Scalar>::IsInteger>
struct min_coeff_functor {
  EIGEN_DEVICE_FUNC inline bool compareCoeff(const Scalar& incumbent, const Scalar& candidate) const {
    return candidate < incumbent;
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Packet comparePacket(const Packet& incumbent, const Packet& candidate) const {
    return pcmp_lt(candidate, incumbent);
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Scalar predux(const Packet& a) const {
    return predux_min(a);
  }
};

template <typename Scalar>
struct min_coeff_functor<Scalar, PropagateNaN, false> {
  EIGEN_DEVICE_FUNC inline bool compareCoeff(const Scalar& incumbent, const Scalar& candidate) const {
    return (candidate < incumbent) || ((candidate != candidate) && (incumbent == incumbent));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Packet comparePacket(const Packet& incumbent, const Packet& candidate) const {
    return pandnot(pcmp_lt_or_nan(candidate, incumbent), pisnan(incumbent));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Scalar predux(const Packet& a) const {
    return predux_min<PropagateNaN>(a);
  }
};

template <typename Scalar>
struct min_coeff_functor<Scalar, PropagateNumbers, false> {
  EIGEN_DEVICE_FUNC inline bool compareCoeff(const Scalar& incumbent, const Scalar& candidate) const {
    return (candidate < incumbent) || ((candidate == candidate) && (incumbent != incumbent));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Packet comparePacket(const Packet& incumbent, const Packet& candidate) const {
    return pandnot(pcmp_lt_or_nan(candidate, incumbent), pisnan(candidate));
  }
  template <typename Packet>
  EIGEN_DEVICE_FUNC inline Scalar predux(const Packet& a) const {
    return predux_min<PropagateNumbers>(a);
  }
};

// The packet loop needs pcmp_lt (and pcmp_lt_or_nan/pisnan for the NaN-aware functors); predux_max/predux_min
// fall back to a per-lane reduction, so HasMax/HasMin are not required.
template <typename Scalar>
struct min_max_traits {
  static constexpr bool PacketAccess = packet_traits<Scalar>::Vectorizable && packet_traits<Scalar>::HasCmp;
};
template <typename Scalar, int NaNPropagation>
struct functor_traits<max_coeff_functor<Scalar, NaNPropagation>> : min_max_traits<Scalar> {};
template <typename Scalar, int NaNPropagation>
struct functor_traits<min_coeff_functor<Scalar, NaNPropagation>> : min_max_traits<Scalar> {};

template <typename Evaluator, typename Func, bool Linear, bool Vectorize>
struct find_coeff_loop;
template <typename Evaluator, typename Func>
struct find_coeff_loop<Evaluator, Func, /*Linear*/ false, /*Vectorize*/ false> {
  using Scalar = typename Evaluator::Scalar;
  static EIGEN_DEVICE_FUNC inline void run(const Evaluator& eval, Func& func, Scalar& res, Index& outer, Index& inner) {
    Index outerSize = eval.outerSize();
    Index innerSize = eval.innerSize();

    /* initialization performed in calling function */
    /* result = eval.coeff(0, 0); */
    /* outer = 0; */
    /* inner = 0; */

    for (Index j = 0; j < outerSize; j++) {
      for (Index i = 0; i < innerSize; i++) {
        Scalar xprCoeff = eval.coeffByOuterInner(j, i);
        if (func.compareCoeff(res, xprCoeff)) {
          outer = j;
          inner = i;
          res = xprCoeff;
        }
      }
    }
  }
};
template <typename Evaluator, typename Func>
struct find_coeff_loop<Evaluator, Func, /*Linear*/ true, /*Vectorize*/ false> {
  using Scalar = typename Evaluator::Scalar;
  static EIGEN_DEVICE_FUNC inline void run(const Evaluator& eval, Func& func, Scalar& res, Index& index) {
    Index size = eval.size();

    /* initialization performed in calling function */
    /* result = eval.coeff(0); */
    /* index = 0; */

    for (Index k = 0; k < size; k++) {
      Scalar xprCoeff = eval.coeff(k);
      if (func.compareCoeff(res, xprCoeff)) {
        index = k;
        res = xprCoeff;
      }
    }
  }
};
template <typename Evaluator, typename Func>
struct find_coeff_loop<Evaluator, Func, /*Linear*/ false, /*Vectorize*/ true> {
  using ScalarImpl = find_coeff_loop<Evaluator, Func, false, false>;
  using Scalar = typename Evaluator::Scalar;
  using Packet = typename Evaluator::Packet;
  static constexpr int PacketSize = unpacket_traits<Packet>::size;
  static EIGEN_DEVICE_FUNC inline void run(const Evaluator& eval, Func& func, Scalar& result, Index& outer,
                                           Index& inner) {
    Index outerSize = eval.outerSize();
    Index innerSize = eval.innerSize();
    if (innerSize < PacketSize) {
      ScalarImpl::run(eval, func, result, outer, inner);
      return;
    }
    Index packetEnd = numext::round_down(innerSize, PacketSize);

    /* initialization performed in calling function */
    /* result = eval.coeff(0, 0); */
    /* outer = 0; */
    /* inner = 0; */

    bool checkPacket = false;

    for (Index j = 0; j < outerSize; j++) {
      Packet resultPacket = pset1<Packet>(result);
      for (Index i = 0; i < packetEnd; i += PacketSize) {
        Packet xprPacket = eval.template packetByOuterInner<Unaligned, Packet>(j, i);
        if (predux_any(func.comparePacket(resultPacket, xprPacket))) {
          outer = j;
          inner = i;
          result = func.predux(xprPacket);
          resultPacket = pset1<Packet>(result);
          checkPacket = true;
        }
      }

      for (Index i = packetEnd; i < innerSize; i++) {
        Scalar xprCoeff = eval.coeffByOuterInner(j, i);
        if (func.compareCoeff(result, xprCoeff)) {
          outer = j;
          inner = i;
          result = xprCoeff;
          checkPacket = false;
        }
      }
    }

    if (checkPacket) {
      result = eval.coeffByOuterInner(outer, inner);
      Index i_end = inner + PacketSize;
      for (Index i = inner; i < i_end; i++) {
        Scalar xprCoeff = eval.coeffByOuterInner(outer, i);
        if (func.compareCoeff(result, xprCoeff)) {
          inner = i;
          result = xprCoeff;
        }
      }
    }
  }
};
template <typename Evaluator, typename Func>
struct find_coeff_loop<Evaluator, Func, /*Linear*/ true, /*Vectorize*/ true> {
  using ScalarImpl = find_coeff_loop<Evaluator, Func, true, false>;
  using Scalar = typename Evaluator::Scalar;
  using Packet = typename Evaluator::Packet;
  static constexpr int PacketSize = unpacket_traits<Packet>::size;
  static constexpr int Alignment = Evaluator::Alignment;

  static EIGEN_DEVICE_FUNC inline void run(const Evaluator& eval, Func& func, Scalar& result, Index& index) {
    Index size = eval.size();
    if (size < PacketSize) {
      ScalarImpl::run(eval, func, result, index);
      return;
    }
    Index packetEnd = numext::round_down(size, PacketSize);

    /* initialization performed in calling function */
    /* result = eval.coeff(0); */
    /* index = 0; */

    Packet resultPacket = pset1<Packet>(result);
    bool checkPacket = false;

    for (Index k = 0; k < packetEnd; k += PacketSize) {
      Packet xprPacket = eval.template packet<Alignment, Packet>(k);
      if (predux_any(func.comparePacket(resultPacket, xprPacket))) {
        index = k;
        result = func.predux(xprPacket);
        resultPacket = pset1<Packet>(result);
        checkPacket = true;
      }
    }

    for (Index k = packetEnd; k < size; k++) {
      Scalar xprCoeff = eval.coeff(k);
      if (func.compareCoeff(result, xprCoeff)) {
        index = k;
        result = xprCoeff;
        checkPacket = false;
      }
    }

    if (checkPacket) {
      result = eval.coeff(index);
      Index k_end = index + PacketSize;
      for (Index k = index; k < k_end; k++) {
        Scalar xprCoeff = eval.coeff(k);
        if (func.compareCoeff(result, xprCoeff)) {
          index = k;
          result = xprCoeff;
        }
      }
    }
  }
};

template <typename Derived>
struct find_coeff_evaluator : public evaluator<Derived> {
  using Base = evaluator<Derived>;
  using Scalar = typename Derived::Scalar;
  using Packet = typename packet_traits<Scalar>::type;
  static constexpr int Flags = Base::Flags;
  static constexpr bool IsRowMajor = bool(Flags & RowMajorBit);
  EIGEN_DEVICE_FUNC inline find_coeff_evaluator(const Derived& xpr) : Base(xpr), m_xpr(xpr) {}

  EIGEN_DEVICE_FUNC inline Scalar coeffByOuterInner(Index outer, Index inner) const {
    Index row = IsRowMajor ? outer : inner;
    Index col = IsRowMajor ? inner : outer;
    return Base::coeff(row, col);
  }
  template <int LoadMode, typename PacketType>
  EIGEN_DEVICE_FUNC inline PacketType packetByOuterInner(Index outer, Index inner) const {
    Index row = IsRowMajor ? outer : inner;
    Index col = IsRowMajor ? inner : outer;
    return Base::template packet<LoadMode, PacketType>(row, col);
  }

  EIGEN_DEVICE_FUNC inline Index innerSize() const { return m_xpr.innerSize(); }
  EIGEN_DEVICE_FUNC inline Index outerSize() const { return m_xpr.outerSize(); }
  EIGEN_DEVICE_FUNC inline Index size() const { return m_xpr.size(); }

  const Derived& m_xpr;
};

template <typename Derived, typename Func>
struct find_coeff_impl {
  using Evaluator = find_coeff_evaluator<Derived>;
  static constexpr int Flags = Evaluator::Flags;
  static constexpr bool IsRowMajor = Derived::IsRowMajor;
  static constexpr int MaxInnerSizeAtCompileTime =
      IsRowMajor ? Derived::MaxColsAtCompileTime : Derived::MaxRowsAtCompileTime;
  static constexpr int MaxSizeAtCompileTime = Derived::MaxSizeAtCompileTime;

  using Scalar = typename Derived::Scalar;
  using Packet = typename Evaluator::Packet;

  static constexpr int PacketSize = unpacket_traits<Packet>::size;
  static constexpr bool Linearize = bool(Flags & LinearAccessBit);
  static constexpr bool DontVectorize =
      enum_lt_not_dynamic(Linearize ? MaxSizeAtCompileTime : MaxInnerSizeAtCompileTime, PacketSize);
  static constexpr bool Vectorize =
      !DontVectorize && bool(Flags & PacketAccessBit) && functor_traits<Func>::PacketAccess;

  using Loop = find_coeff_loop<Evaluator, Func, Linearize, Vectorize>;

  template <bool ForwardLinearAccess = Linearize, std::enable_if_t<!ForwardLinearAccess, bool> = true>
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(const Derived& xpr, Func& func, Scalar& res, Index& outer,
                                                        Index& inner) {
    Evaluator eval(xpr);
    Loop::run(eval, func, res, outer, inner);
  }
  template <bool ForwardLinearAccess = Linearize, std::enable_if_t<ForwardLinearAccess, bool> = true>
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(const Derived& xpr, Func& func, Scalar& res, Index& outer,
                                                        Index& inner) {
    // where possible, use the linear loop and back-calculate the outer and inner indices
    Index index = 0;
    run(xpr, func, res, index);
    outer = index / xpr.innerSize();
    inner = index % xpr.innerSize();
  }
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(const Derived& xpr, Func& func, Scalar& res, Index& index) {
    Evaluator eval(xpr);
    Loop::run(eval, func, res, index);
  }
};

template <typename Derived, typename IndexType, typename Func>
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar findCoeff(const DenseBase<Derived>& mat, Func& func,
                                                                       IndexType* rowPtr, IndexType* colPtr) {
  EIGEN_INTERNAL_ASSERT_NONEMPTY(mat);
  using Scalar = typename DenseBase<Derived>::Scalar;
  using FindCoeffImpl = internal::find_coeff_impl<Derived, Func>;
  Index outer = 0;
  Index inner = 0;
  Scalar res = mat.coeff(0, 0);
  FindCoeffImpl::run(mat.derived(), func, res, outer, inner);
  *rowPtr = internal::convert_index<IndexType>(Derived::IsRowMajor ? outer : inner);
  if (colPtr) *colPtr = internal::convert_index<IndexType>(Derived::IsRowMajor ? inner : outer);
  return res;
}

template <typename Derived, typename IndexType, typename Func>
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar findCoeff(const DenseBase<Derived>& mat, Func& func,
                                                                       IndexType* indexPtr) {
  EIGEN_INTERNAL_ASSERT_NONEMPTY(mat);
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
  using Scalar = typename DenseBase<Derived>::Scalar;
  using FindCoeffImpl = internal::find_coeff_impl<Derived, Func>;
  Index index = 0;
  Scalar res = mat.coeff(0);
  FindCoeffImpl::run(mat.derived(), func, res, index);
  *indexPtr = internal::convert_index<IndexType>(index);
  return res;
}

}  // namespace internal

/** \fn DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
 * \returns the minimum of all coefficients of *this and puts in *row and *col its location.
 *
 * If there are multiple coefficients with the same extreme value, the location of the first instance is returned.
 *
 * In case \c *this contains NaN, NaNPropagation determines the behavior:
 *   NaNPropagation == PropagateFast : undefined
 *   NaNPropagation == PropagateNaN : result is NaN
 *   NaNPropagation == PropagateNumbers : result is minimum of elements that are not NaN
 * \warning the matrix must be not empty, otherwise an assertion is triggered.
 *
 * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visit(), DenseBase::minCoeff()
 */
template <typename Derived>
template <int NaNPropagation, typename IndexType>
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar DenseBase<Derived>::minCoeff(IndexType* rowPtr,
                                                                                          IndexType* colPtr) const {
  using Func = internal::min_coeff_functor<Scalar, NaNPropagation>;
  Func func;
  return internal::findCoeff(derived(), func, rowPtr, colPtr);
}

/** \returns the minimum of all coefficients of *this and puts in *index its location.
 *
 * If there are multiple coefficients with the same extreme value, the location of the first instance is returned.
 *
 * In case \c *this contains NaN, NaNPropagation determines the behavior:
 *   NaNPropagation == PropagateFast : undefined
 *   NaNPropagation == PropagateNaN : result is NaN
 *   NaNPropagation == PropagateNumbers : result is minimum of elements that are not NaN
 * \warning the matrix must be not empty, otherwise an assertion is triggered.
 *
 * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visit(),
 * DenseBase::minCoeff()
 */
template <typename Derived>
template <int NaNPropagation, typename IndexType>
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar DenseBase<Derived>::minCoeff(IndexType* indexPtr) const {
  using Func = internal::min_coeff_functor<Scalar, NaNPropagation>;
  Func func;
  return internal::findCoeff(derived(), func, indexPtr);
}

/** \fn DenseBase<Derived>::maxCoeff(IndexType* rowId, IndexType* colId) const
 * \returns the maximum of all coefficients of *this and puts in *row and *col its location.
 *
 * If there are multiple coefficients with the same extreme value, the location of the first instance is returned.
 *
 * In case \c *this contains NaN, NaNPropagation determines the behavior:
 *   NaNPropagation == PropagateFast : undefined
 *   NaNPropagation == PropagateNaN : result is NaN
 *   NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
 * \warning the matrix must be not empty, otherwise an assertion is triggered.
 *
 * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::maxCoeff()
 */
template <typename Derived>
template <int NaNPropagation, typename IndexType>
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar DenseBase<Derived>::maxCoeff(IndexType* rowPtr,
                                                                                          IndexType* colPtr) const {
  using Func = internal::max_coeff_functor<Scalar, NaNPropagation>;
  Func func;
  return internal::findCoeff(derived(), func, rowPtr, colPtr);
}

/** \returns the maximum of all coefficients of *this and puts in *index its location.
 *
 * If there are multiple coefficients with the same extreme value, the location of the first instance is returned.
 *
 * In case \c *this contains NaN, NaNPropagation determines the behavior:
 *   NaNPropagation == PropagateFast : undefined
 *   NaNPropagation == PropagateNaN : result is NaN
 *   NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
 * \warning the matrix must be not empty, otherwise an assertion is triggered.
 *
 * \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(),
 * DenseBase::maxCoeff()
 */
template <typename Derived>
template <int NaNPropagation, typename IndexType>
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar DenseBase<Derived>::maxCoeff(IndexType* indexPtr) const {
  using Func = internal::max_coeff_functor<Scalar, NaNPropagation>;
  Func func;
  return internal::findCoeff(derived(), func, indexPtr);
}

}  // namespace Eigen

#endif  // EIGEN_FIND_COEFF_H
