|  | // 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/. | 
|  |  | 
|  | /* | 
|  |  | 
|  | * NOTE: This file is the modified version of [s,d,c,z]pruneL.c file in SuperLU | 
|  |  | 
|  | * -- SuperLU routine (version 2.0) -- | 
|  | * Univ. of California Berkeley, Xerox Palo Alto Research Center, | 
|  | * and Lawrence Berkeley National Lab. | 
|  | * November 15, 1997 | 
|  | * | 
|  | * 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_PRUNEL_H | 
|  | #define SPARSELU_PRUNEL_H | 
|  |  | 
|  | namespace Eigen { | 
|  | namespace internal { | 
|  |  | 
|  | /** | 
|  | * \brief Prunes the L-structure. | 
|  | * | 
|  | * It prunes the L-structure  of supernodes whose L-structure contains the current pivot row "pivrow" | 
|  | * | 
|  | * | 
|  | * \param jcol The current column of L | 
|  | * \param[in] perm_r Row permutation | 
|  | * \param[out] pivrow  The pivot row | 
|  | * \param nseg Number of segments | 
|  | * \param segrep | 
|  | * \param repfnz | 
|  | * \param[out] xprune | 
|  | * \param glu Global LU data | 
|  | * | 
|  | */ | 
|  | template <typename Scalar, typename StorageIndex> | 
|  | void SparseLUImpl<Scalar,StorageIndex>::pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg, | 
|  | const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu) | 
|  | { | 
|  | // For each supernode-rep irep in U(*,j] | 
|  | Index jsupno = glu.supno(jcol); | 
|  | Index i,irep,irep1; | 
|  | bool movnum, do_prune = false; | 
|  | Index kmin = 0, kmax = 0, minloc, maxloc,krow; | 
|  | for (i = 0; i < nseg; i++) | 
|  | { | 
|  | irep = segrep(i); | 
|  | irep1 = irep + 1; | 
|  | do_prune = false; | 
|  |  | 
|  | // Don't prune with a zero U-segment | 
|  | if (repfnz(irep) == emptyIdxLU) continue; | 
|  |  | 
|  | // If a snode overlaps with the next panel, then the U-segment | 
|  | // is fragmented into two parts -- irep and irep1. We should let | 
|  | // pruning occur at the rep-column in irep1s snode. | 
|  | if (glu.supno(irep) == glu.supno(irep1) ) continue; // don't prune | 
|  |  | 
|  | // If it has not been pruned & it has a nonz in row L(pivrow,i) | 
|  | if (glu.supno(irep) != jsupno ) | 
|  | { | 
|  | if ( xprune (irep) >= glu.xlsub(irep1) ) | 
|  | { | 
|  | kmin = glu.xlsub(irep); | 
|  | kmax = glu.xlsub(irep1) - 1; | 
|  | for (krow = kmin; krow <= kmax; krow++) | 
|  | { | 
|  | if (glu.lsub(krow) == pivrow) | 
|  | { | 
|  | do_prune = true; | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (do_prune) | 
|  | { | 
|  | // do a quicksort-type partition | 
|  | // movnum=true means that the num values have to be exchanged | 
|  | movnum = false; | 
|  | if (irep == glu.xsup(glu.supno(irep)) ) // Snode of size 1 | 
|  | movnum = true; | 
|  |  | 
|  | while (kmin <= kmax) | 
|  | { | 
|  | if (perm_r(glu.lsub(kmax)) == emptyIdxLU) | 
|  | kmax--; | 
|  | else if ( perm_r(glu.lsub(kmin)) != emptyIdxLU) | 
|  | kmin++; | 
|  | else | 
|  | { | 
|  | // kmin below pivrow (not yet pivoted), and kmax | 
|  | // above pivrow: interchange the two suscripts | 
|  | std::swap(glu.lsub(kmin), glu.lsub(kmax)); | 
|  |  | 
|  | // If the supernode has only one column, then we | 
|  | // only keep one set of subscripts. For any subscript | 
|  | // intercnahge performed, similar interchange must be | 
|  | // done on the numerical values. | 
|  | if (movnum) | 
|  | { | 
|  | minloc = glu.xlusup(irep) + ( kmin - glu.xlsub(irep) ); | 
|  | maxloc = glu.xlusup(irep) + ( kmax - glu.xlsub(irep) ); | 
|  | std::swap(glu.lusup(minloc), glu.lusup(maxloc)); | 
|  | } | 
|  | kmin++; | 
|  | kmax--; | 
|  | } | 
|  | } // end while | 
|  |  | 
|  | xprune(irep) = StorageIndex(kmin);  //Pruning | 
|  | } // end if do_prune | 
|  | } // end pruning | 
|  | } // End for each U-segment | 
|  | } | 
|  |  | 
|  | } // end namespace internal | 
|  | } // end namespace Eigen | 
|  |  | 
|  | #endif // SPARSELU_PRUNEL_H |