// 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>
//
// 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

/* This file is a modified version of heap_relax_snode.c file in SuperLU
 * -- SuperLU routine (version 3.0) --
 * Univ. of California Berkeley, Xerox Palo Alto Research Center,
 * and Lawrence Berkeley National Lab.
 * October 15, 2003
 *
 * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
 * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to use or copy this program for any
 * purpose, provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is
 * granted, provided the above notices are retained, and a notice that
 * the code was modified is included with the above copyright notice.
 */

#ifndef SPARSELU_HEAP_RELAX_SNODE_H
#define SPARSELU_HEAP_RELAX_SNODE_H

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

namespace Eigen {
namespace internal {

/**
 * \brief Identify the initial relaxed supernodes
 *
 * This routine applied to a symmetric elimination tree.
 * It assumes that the matrix has been reordered according to the postorder of the etree
 * \param n The number of columns
 * \param et elimination tree
 * \param relax_columns Maximum number of columns allowed in a relaxed snode
 * \param descendants Number of descendants of each node in the etree
 * \param relax_end last column in a supernode
 */
template <typename Scalar, typename StorageIndex>
void SparseLUImpl<Scalar, StorageIndex>::heap_relax_snode(const Index n, IndexVector& et, const Index relax_columns,
                                                          IndexVector& descendants, IndexVector& relax_end) {
  // The etree may not be postordered, but its heap ordered
  IndexVector post;
  internal::treePostorder(StorageIndex(n), et, post);  // Post order etree
  IndexVector inv_post(n + 1);
  for (StorageIndex i = 0; i < n + 1; ++i) inv_post(post(i)) = i;  // Compute the inverse postorder permutation.

  // Renumber etree in postorder
  IndexVector iwork(n);
  IndexVector et_save(n + 1);
  for (Index i = 0; i < n; ++i) {
    iwork(post(i)) = post(et(i));
  }
  et_save = et;  // Save the original etree
  et = iwork;

  // compute the number of descendants of each node in the etree
  relax_end.setConstant(emptyIdxLU);
  Index j, parent;
  descendants.setZero();
  for (j = 0; j < n; j++) {
    parent = et(j);
    if (parent != n)  // not the dummy root
      descendants(parent) += descendants(j) + 1;
  }
  // Identify the relaxed supernodes by postorder traversal of the etree
  Index snode_start;  // beginning of a snode
  StorageIndex k;
  StorageIndex l;
  for (j = 0; j < n;) {
    parent = et(j);
    snode_start = j;
    while (parent != n && descendants(parent) < relax_columns) {
      j = parent;
      parent = et(j);
    }
    // Found a supernode in postordered etree, j is the last column
    k = StorageIndex(n);
    for (Index i = snode_start; i <= j; ++i) k = (std::min)(k, inv_post(i));
    l = inv_post(j);
    if ((l - k) == (j - snode_start))  // Same number of columns in the snode
    {
      // This is also a supernode in the original etree
      relax_end(k) = l;  // Record last column
    } else {
      for (Index i = snode_start; i <= j; ++i) {
        l = inv_post(i);
        if (descendants(i) == 0) {
          relax_end(l) = l;
        }
      }
    }
    j++;
    // Search for a new leaf
    while (descendants(j) != 0 && j < n) j++;
  }  // End postorder traversal of the etree

  // Recover the original etree
  et = et_save;
}

}  // end namespace internal

}  // end namespace Eigen
#endif  // SPARSELU_HEAP_RELAX_SNODE_H
