17faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This file is part of Eigen, a lightweight C++ template library
27faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// for linear algebra.
37faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
47faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
57faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
67faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This Source Code Form is subject to the terms of the Mozilla
77faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Public License v. 2.0. If a copy of the MPL was not distributed
87faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
97faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/* This file is a modified version of heap_relax_snode.c file in SuperLU
117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * -- SuperLU routine (version 3.0) --
127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * Univ. of California Berkeley, Xerox Palo Alto Research Center,
137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * and Lawrence Berkeley National Lab.
147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * October 15, 2003
157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez *
167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez *
187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez *
217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * Permission is hereby granted to use or copy this program for any
227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * purpose, provided the above notices are retained on all copies.
237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * Permission to modify the code and to distribute modified code is
247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * granted, provided the above notices are retained, and a notice that
257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * the code was modified is included with the above copyright notice.
267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez */
277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#ifndef SPARSELU_RELAX_SNODE_H
297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#define SPARSELU_RELAX_SNODE_H
307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace Eigen {
327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace internal {
347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/**
367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \brief Identify the initial relaxed supernodes
377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez *
387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * This routine is applied to a column elimination tree.
397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * It assumes that the matrix has been reordered according to the postorder of the etree
407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param n  the number of columns
417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param et elimination tree
427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param relax_columns Maximum number of columns allowed in a relaxed snode
437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param descendants Number of descendants of each node in the etree
447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param relax_end last column in a supernode
457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez */
467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate <typename Scalar, typename Index>
477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid SparseLUImpl<Scalar,Index>::relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end)
487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // compute the number of descendants of each node in the etree
517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Index j, parent;
527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  relax_end.setConstant(emptyIdxLU);
537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  descendants.setZero();
547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  for (j = 0; j < n; j++)
557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  {
567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    parent = et(j);
577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    if (parent != n) // not the dummy root
587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      descendants(parent) += descendants(j) + 1;
597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Identify the relaxed supernodes by postorder traversal of the etree
617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Index snode_start; // beginning of a snode
627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  for (j = 0; j < n; )
637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  {
647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    parent = et(j);
657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    snode_start = j;
667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    while ( parent != n && descendants(parent) < relax_columns )
677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    {
687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      j = parent;
697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      parent = et(j);
707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // Found a supernode in postordered etree, j is the last column
727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    relax_end(snode_start) = j; // Record last column
737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    j++;
747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // Search for a new leaf
757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    while (descendants(j) != 0 && j < n) j++;
767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  } // End postorder traversal of the etree
777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} // end namespace internal
817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} // end namespace Eigen
837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif
84