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

/**
 * \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 IndexVector, typename ScalarVector, typename BlockIndexVector>
void LU_pruneL(const int jcol, const IndexVector& perm_r, const int pivrow, const int nseg, const IndexVector& segrep, BlockIndexVector& repfnz, IndexVector& xprune, LU_GlobalLU_t<IndexVector, ScalarVector>& glu)
{
  typedef typename IndexVector::Scalar Index; 
  typedef typename ScalarVector::Scalar Scalar; 
    
  // For each supernode-rep irep in U(*,j]
  int jsupno = glu.supno(jcol); 
  int i,irep,irep1; 
  bool movnum, do_prune = false; 
  Index kmin, kmax, 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) == IND_EMPTY) 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)) == IND_EMPTY)
            kmax--; 
          else if ( perm_r(glu.lsub(kmin)) != IND_EMPTY)
            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) = kmin;  //Pruning 
      } // end if do_prune 
    } // end pruning 
  } // End for each U-segment
}

#endif