// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2026 Rasmus Munk Larsen <rmlarsen@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_TRIANGULARINPLACE_H
#define EIGEN_TRIANGULARINPLACE_H

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

namespace Eigen {

namespace internal {

// In-place counterparts of LAPACK xTRTRI and xLAUUM. Each overwrites its operand; the only scratch is
// one block-sized panel, at most 128x128 elements whatever the matrix size, through which the in-place
// TRMM steps run Eigen's blocked kernel, the same way optimized BLAS implement xTRMM.

// Only the lower forms exist. An upper U runs the lower kernel on Transpose<MatrixType>: with
// V = U^T, V^-1 = (U^-1)^T and V^* V = conj(U U^*) = (U U^*)^T since U U^* is self-adjoint, so the
// lower triangle of the transposed view is the upper triangle of the original in both cases.

// Both kernels have the panel-times-trailing-block shape of the Cholesky factorization, so the block
// size tracks llt_inplace::blocked(), but each has its own floor and its own size below which the
// unblocked form still wins: TRTRI's blocked step is a TRMM plus a TRSM against a bs-wide panel, and
// its unblocked form is already a sequence of TRMVs, while LAUUM's is a TRMM plus a HERK and its
// unblocked form is a sequence of GEMVs against a strided row. Measured on Zen 4 at n = 32..512.
constexpr Index kTriangularInverseMinBlocked = 64;
constexpr Index kTriangularInverseMinBlockSize = 24;
constexpr Index kAdjointSquareMinBlocked = 128;
constexpr Index kAdjointSquareMinBlockSize = 48;

EIGEN_DEVICE_FUNC inline Index triangular_in_place_block_size(Index size, Index min_block_size) {
  const Index block_size = ((size / 8) / 8) * 8;
  return numext::mini(numext::maxi(block_size, min_block_size), Index(128));
}

template <typename MatrixType>
using triangular_in_place_workspace = Matrix<typename MatrixType::Scalar, Dynamic, Dynamic,
                                             (int(traits<MatrixType>::Flags) & RowMajorBit) ? RowMajor : ColMajor>;

// Unblocked lower triangular inverse, columns bottom-up so that the trailing block already holds
// X22 = L22^-1 when column j is reached: then X(j+1:, j) = -X22 L(j+1:, j) / L(j, j), one TRMV per
// column rather than the chain of AXPYs a forward substitution per column would run. \a tmp is
// scratch of at least n - 1 entries, since the TRMV's destination is its own operand.
template <unsigned int Mode, typename MatrixType, typename VectorType>
EIGEN_DEVICE_FUNC void triangular_inverse_unblocked(MatrixType& mat, VectorType& tmp) {
  using Scalar = typename MatrixType::Scalar;
  constexpr bool kUnitDiag = (Mode & UnitDiag) != 0;
  const Index n = mat.rows();
  eigen_internal_assert(n < 2 || tmp.size() >= n - 1);
  for (Index j = n - 1; j >= 0; --j) {
    Scalar xj = Scalar(1);
    EIGEN_IF_CONSTEXPR (!kUnitDiag) {
      xj = Scalar(1) / mat.coeff(j, j);
      mat.coeffRef(j, j) = xj;
    }
    const Index rs = n - j - 1;
    if (rs == 0) continue;
    tmp.head(rs).noalias() = mat.block(j + 1, j + 1, rs, rs).template triangularView<Mode>() * mat.col(j).tail(rs);
    mat.col(j).tail(rs) = -xj * tmp.head(rs);
  }
}

// Blocked lower triangular inverse, block columns bottom-up as in LAPACK xTRTRI. With
// L = [[L11, 0], [L21, L22]] the inverse is [[L11^-1, 0], [-L22^-1 L21 L11^-1, L22^-1]]; walking upwards
// makes X22 = L22^-1 available first, so the large operation is the TRMM X22 L21 rather than a solve
// against L22, and Eigen's TRMM runs closer to GEMM rate than its TRSM does on a 128-column operand.
template <unsigned int Mode, typename MatrixType>
EIGEN_DEVICE_FUNC void triangular_inverse_lower(MatrixType& mat) {
  eigen_assert(mat.rows() == mat.cols());
  const Index n = mat.rows();
  if (n < kTriangularInverseMinBlocked) {
    using Scalar = typename MatrixType::Scalar;
    ei_declare_aligned_stack_constructed_variable(Scalar, tmp_data, numext::maxi(n, Index(1)), 0);
    Map<Matrix<Scalar, Dynamic, 1> > tmp(tmp_data, n);
    triangular_inverse_unblocked<Mode>(mat, tmp);
    return;
  }
  const Index block_size = triangular_in_place_block_size(n, kTriangularInverseMinBlockSize);
  // One block-sized panel, whose first column doubles as the TRMV scratch of the unblocked kernel:
  // that kernel runs on L11 only after the panel's other uses in the same iteration are finished.
  triangular_in_place_workspace<MatrixType> work(block_size, block_size);
  for (Index k = ((n - 1) / block_size) * block_size; k >= 0; k -= block_size) {
    const Index bs = numext::mini(block_size, n - k);
    const Index rs = n - k - bs;
    Block<MatrixType, Dynamic, Dynamic> L11(mat, k, k, bs, bs);
    if (rs > 0) {
      Block<MatrixType, Dynamic, Dynamic> L21(mat, k + bs, k, rs, bs);
      Block<MatrixType, Dynamic, Dynamic> X22(mat, k + bs, k + bs, rs, rs);
      // L21 <- X22 L21. Row panel r of the product reads only rows <= r of L21, so going upwards
      // leaves every row a later panel still needs untouched.
      for (Index r_end = rs; r_end > 0; r_end -= block_size) {
        const Index r = numext::maxi(Index(0), r_end - block_size);
        const Index h = r_end - r;
        work.topLeftCorner(h, bs) = L21.middleRows(r, h);
        L21.middleRows(r, h).noalias() =
            X22.block(r, r, h, h).template triangularView<Mode>() * work.topLeftCorner(h, bs);
        if (r > 0) L21.middleRows(r, h).noalias() += X22.block(r, 0, h, r) * L21.topRows(r);
      }
      L11.template triangularView<Mode>().template solveInPlace<OnTheRight>(L21);
      L21 = -L21;
    }
    auto tmp = work.col(0);
    triangular_inverse_unblocked<Mode>(L11, tmp);
  }
}

template <unsigned int Mode, bool IsLower = (int(Mode) & int(Lower)) != 0>
struct triangular_inverse_selector {
  template <typename MatrixType>
  EIGEN_DEVICE_FUNC static void run(MatrixType& mat) {
    triangular_inverse_lower<Mode>(mat);
  }
};

template <unsigned int Mode>
struct triangular_inverse_selector<Mode, false> {
  template <typename MatrixType>
  EIGEN_DEVICE_FUNC static void run(MatrixType& mat) {
    Transpose<MatrixType> matt(mat);
    triangular_inverse_lower<(int(Mode) & int(UnitDiag)) | int(Lower)>(matt);
  }
};

// Unblocked lower self-adjoint square: mat <- lower(L^* L). Row i of the result reads column i of L
// below the diagonal and rows > i of the columns left of it, none of which row i's own update writes.
template <typename MatrixType>
void triangular_adjoint_square_unblocked(MatrixType& mat) {
  using Scalar = typename MatrixType::Scalar;
  const Index n = mat.rows();
  for (Index i = 0; i < n; ++i) {
    const Scalar lii = mat.coeff(i, i);
    const Index rs = n - i - 1;
    mat.coeffRef(i, i) = Scalar(mat.col(i).tail(n - i).squaredNorm());
    if (i > 0) {
      mat.row(i).head(i) *= numext::conj(lii);
      if (rs > 0) mat.row(i).head(i).noalias() += mat.col(i).tail(rs).adjoint() * mat.bottomLeftCorner(rs, i);
    }
  }
}

// Blocked lower self-adjoint square, left-looking as in LAPACK xLAUUM: block row k of the result is
// completed against the columns to its left before the trailing block rows consume the factor.
template <typename MatrixType>
void triangular_adjoint_square_lower(MatrixType& mat) {
  eigen_assert(mat.rows() == mat.cols());
  const Index n = mat.rows();
  if (n < kAdjointSquareMinBlocked) {
    triangular_adjoint_square_unblocked(mat);
    return;
  }
  const Index block_size = triangular_in_place_block_size(n, kAdjointSquareMinBlockSize);
  triangular_in_place_workspace<MatrixType> work(block_size, block_size);
  for (Index k = 0; k < n; k += block_size) {
    const Index bs = numext::mini(block_size, n - k);
    const Index rs = n - k - bs;
    Block<MatrixType, Dynamic, Dynamic> L11(mat, k, k, bs, bs);
    if (k > 0) {
      // A(k:k+bs, 0:k) = sum over rows m >= k of L(m, k:k+bs)^* L(m, 0:k), split at m = k+bs. The
      // first part is the TRMM L11^* B in place, done by column panels through the workspace.
      Block<MatrixType, Dynamic, Dynamic> B(mat, k, 0, bs, k);
      for (Index c = 0; c < k; c += block_size) {
        const Index w = numext::mini(block_size, k - c);
        work.topLeftCorner(bs, w) = B.middleCols(c, w);
        B.middleCols(c, w).noalias() = L11.adjoint().template triangularView<Upper>() * work.topLeftCorner(bs, w);
      }
      if (rs > 0) B.noalias() += mat.block(k + bs, k, rs, bs).adjoint() * mat.block(k + bs, 0, rs, k);
    }
    triangular_adjoint_square_unblocked(L11);
    if (rs > 0) L11.template selfadjointView<Lower>().rankUpdate(mat.block(k + bs, k, rs, bs).adjoint());
  }
}

template <int UpLo, bool IsLower = (int(UpLo) & int(Lower)) != 0>
struct triangular_adjoint_square_selector {
  template <typename MatrixType>
  static void run(MatrixType& mat) {
    triangular_adjoint_square_lower(mat);
  }
};

template <int UpLo>
struct triangular_adjoint_square_selector<UpLo, false> {
  template <typename MatrixType>
  static void run(MatrixType& mat) {
    Transpose<MatrixType> matt(mat);
    triangular_adjoint_square_lower(matt);
  }
};

/** \internal Replaces the \a UpLo triangle of \a mat, holding a triangular factor T, by the same
 * triangle of the self-adjoint product T^* T (\c Lower) or T T^* (\c Upper). The opposite triangle is
 * neither read nor written. This is LAPACK's xLAUUM. */
template <int UpLo, typename MatrixType>
void triangular_adjoint_square_in_place(MatrixType& mat) {
  triangular_adjoint_square_selector<UpLo>::run(mat);
}

}  // end namespace internal

#ifndef EIGEN_PARSED_BY_DOXYGEN
template <typename MatrixType, unsigned int Mode>
EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::inverseInPlace() {
  EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
  EIGEN_STATIC_ASSERT((int(Mode) & int(Upper | Lower)) != 0 && (int(Mode) & int(ZeroDiag)) == 0, PROGRAMMING_ERROR)
  eigen_assert(derived().rows() == derived().cols());
  internal::triangular_inverse_selector<Mode>::run(derived().nestedExpression());
}
#endif

}  // end namespace Eigen

#endif  // EIGEN_TRIANGULARINPLACE_H
