// 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>
// Copyright (C) 2012 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 SPARSELU_KERNEL_BMOD_H
#define SPARSELU_KERNEL_BMOD_H

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

namespace Eigen {
namespace internal {

template <int SegSizeAtCompileTime>
struct LU_kernel_bmod {
  /** \internal
   * \brief Performs numeric block updates from a given supernode to a single column
   *
   * \param segsize Size of the segment (and blocks) to use for updates
   * \param[in,out] dense Packed values of the original matrix
   * \param tempv temporary vector to use for updates
   * \param lusup array containing the supernodes
   * \param lda Leading dimension in the supernode
   * \param nrow Number of rows in the rectangular part of the supernode
   * \param lsub compressed row subscripts of supernodes
   * \param lptr pointer to the first column of the current supernode in lsub
   * \param no_zeros Number of nonzeros elements before the diagonal part of the supernode
   */
  template <typename BlockScalarVector, typename ScalarVector, typename IndexVector>
  static EIGEN_DONT_INLINE void run(const Index segsize, BlockScalarVector& dense, ScalarVector& tempv,
                                    ScalarVector& lusup, Index& luptr, const Index lda, const Index nrow,
                                    IndexVector& lsub, const Index lptr, const Index no_zeros);
};

template <int SegSizeAtCompileTime>
template <typename BlockScalarVector, typename ScalarVector, typename IndexVector>
EIGEN_DONT_INLINE void LU_kernel_bmod<SegSizeAtCompileTime>::run(const Index segsize, BlockScalarVector& dense,
                                                                 ScalarVector& tempv, ScalarVector& lusup, Index& luptr,
                                                                 const Index lda, const Index nrow, IndexVector& lsub,
                                                                 const Index lptr, const Index no_zeros) {
  typedef typename ScalarVector::Scalar Scalar;
  // First, copy U[*,j] segment from dense(*) to tempv(*)
  // The result of triangular solve is in tempv[*];
  // The result of matrix-vector update is in dense[*]
  Index isub = lptr + no_zeros;
  Index i;
  Index irow;
  for (i = 0; i < ((SegSizeAtCompileTime == Dynamic) ? segsize : SegSizeAtCompileTime); i++) {
    irow = lsub(isub);
    tempv(i) = dense(irow);
    ++isub;
  }
  // Dense triangular solve -- start effective triangle
  luptr += lda * no_zeros + no_zeros;
  // Form Eigen matrix and vector
  Map<Matrix<Scalar, SegSizeAtCompileTime, SegSizeAtCompileTime, ColMajor>, 0, OuterStride<> > A(
      &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda));
  Map<Matrix<Scalar, SegSizeAtCompileTime, 1> > u(tempv.data(), segsize);

  u = A.template triangularView<UnitLower>().solve(u);

  // Dense matrix-vector product y <-- B*x
  luptr += segsize;
  const Index PacketSize = internal::packet_traits<Scalar>::size;
  Index ldl = internal::first_multiple(nrow, PacketSize);
  Map<Matrix<Scalar, Dynamic, SegSizeAtCompileTime, ColMajor>, 0, OuterStride<> > B(&(lusup.data()[luptr]), nrow,
                                                                                    segsize, OuterStride<>(lda));
  Index aligned_offset = internal::first_default_aligned(tempv.data() + segsize, PacketSize);
  Index aligned_with_B_offset = (PacketSize - internal::first_default_aligned(B.data(), PacketSize)) % PacketSize;
  Map<Matrix<Scalar, Dynamic, 1>, 0, OuterStride<> > l(tempv.data() + segsize + aligned_offset + aligned_with_B_offset,
                                                       nrow, OuterStride<>(ldl));

  l.noalias() = B * u;

  // Scatter tempv[] into SPA dense[] as a temporary storage
  isub = lptr + no_zeros;
  for (i = 0; i < ((SegSizeAtCompileTime == Dynamic) ? segsize : SegSizeAtCompileTime); i++) {
    irow = lsub(isub++);
    dense(irow) = tempv(i);
  }

  // Scatter l into SPA dense[]
  for (i = 0; i < nrow; i++) {
    irow = lsub(isub++);
    dense(irow) -= l(i);
  }
}

template <>
struct LU_kernel_bmod<1> {
  template <typename BlockScalarVector, typename ScalarVector, typename IndexVector>
  static EIGEN_DONT_INLINE void run(const Index /*segsize*/, BlockScalarVector& dense, ScalarVector& /*tempv*/,
                                    ScalarVector& lusup, Index& luptr, const Index lda, const Index nrow,
                                    IndexVector& lsub, const Index lptr, const Index no_zeros);
};

template <typename BlockScalarVector, typename ScalarVector, typename IndexVector>
EIGEN_DONT_INLINE void LU_kernel_bmod<1>::run(const Index /*segsize*/, BlockScalarVector& dense,
                                              ScalarVector& /*tempv*/, ScalarVector& lusup, Index& luptr,
                                              const Index lda, const Index nrow, IndexVector& lsub, const Index lptr,
                                              const Index no_zeros) {
  typedef typename ScalarVector::Scalar Scalar;
  typedef typename IndexVector::Scalar StorageIndex;
  Scalar f = dense(lsub(lptr + no_zeros));
  luptr += lda * no_zeros + no_zeros + 1;
  const Scalar* a(lusup.data() + luptr);
  const StorageIndex* irow(lsub.data() + lptr + no_zeros + 1);
  Index i = 0;
  for (; i + 1 < nrow; i += 2) {
    Index i0 = *(irow++);
    Index i1 = *(irow++);
    Scalar a0 = *(a++);
    Scalar a1 = *(a++);
    Scalar d0 = dense.coeff(i0);
    Scalar d1 = dense.coeff(i1);
    d0 -= f * a0;
    d1 -= f * a1;
    dense.coeffRef(i0) = d0;
    dense.coeffRef(i1) = d1;
  }
  if (i < nrow) dense.coeffRef(*(irow++)) -= f * *(a++);
}

}  // end namespace internal

}  // end namespace Eigen
#endif  // SPARSELU_KERNEL_BMOD_H
