SparseLU_pruneL.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla
  7. // Public License v. 2.0. If a copy of the MPL was not distributed
  8. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. /*
  10. * NOTE: This file is the modified version of [s,d,c,z]pruneL.c file in SuperLU
  11. * -- SuperLU routine (version 2.0) --
  12. * Univ. of California Berkeley, Xerox Palo Alto Research Center,
  13. * and Lawrence Berkeley National Lab.
  14. * November 15, 1997
  15. *
  16. * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
  17. *
  18. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
  19. * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
  20. *
  21. * Permission is hereby granted to use or copy this program for any
  22. * purpose, provided the above notices are retained on all copies.
  23. * Permission to modify the code and to distribute modified code is
  24. * granted, provided the above notices are retained, and a notice that
  25. * the code was modified is included with the above copyright notice.
  26. */
  27. #ifndef SPARSELU_PRUNEL_H
  28. #define SPARSELU_PRUNEL_H
  29. namespace Eigen {
  30. namespace internal {
  31. /**
  32. * \brief Prunes the L-structure.
  33. *
  34. * It prunes the L-structure of supernodes whose L-structure contains the current pivot row "pivrow"
  35. *
  36. *
  37. * \param jcol The current column of L
  38. * \param[in] perm_r Row permutation
  39. * \param[out] pivrow The pivot row
  40. * \param nseg Number of segments
  41. * \param segrep
  42. * \param repfnz
  43. * \param[out] xprune
  44. * \param glu Global LU data
  45. *
  46. */
  47. template <typename Scalar, typename StorageIndex>
  48. void SparseLUImpl<Scalar,StorageIndex>::pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg,
  49. const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu)
  50. {
  51. // For each supernode-rep irep in U(*,j]
  52. Index jsupno = glu.supno(jcol);
  53. Index i,irep,irep1;
  54. bool movnum, do_prune = false;
  55. Index kmin = 0, kmax = 0, minloc, maxloc,krow;
  56. for (i = 0; i < nseg; i++)
  57. {
  58. irep = segrep(i);
  59. irep1 = irep + 1;
  60. do_prune = false;
  61. // Don't prune with a zero U-segment
  62. if (repfnz(irep) == emptyIdxLU) continue;
  63. // If a snode overlaps with the next panel, then the U-segment
  64. // is fragmented into two parts -- irep and irep1. We should let
  65. // pruning occur at the rep-column in irep1s snode.
  66. if (glu.supno(irep) == glu.supno(irep1) ) continue; // don't prune
  67. // If it has not been pruned & it has a nonz in row L(pivrow,i)
  68. if (glu.supno(irep) != jsupno )
  69. {
  70. if ( xprune (irep) >= glu.xlsub(irep1) )
  71. {
  72. kmin = glu.xlsub(irep);
  73. kmax = glu.xlsub(irep1) - 1;
  74. for (krow = kmin; krow <= kmax; krow++)
  75. {
  76. if (glu.lsub(krow) == pivrow)
  77. {
  78. do_prune = true;
  79. break;
  80. }
  81. }
  82. }
  83. if (do_prune)
  84. {
  85. // do a quicksort-type partition
  86. // movnum=true means that the num values have to be exchanged
  87. movnum = false;
  88. if (irep == glu.xsup(glu.supno(irep)) ) // Snode of size 1
  89. movnum = true;
  90. while (kmin <= kmax)
  91. {
  92. if (perm_r(glu.lsub(kmax)) == emptyIdxLU)
  93. kmax--;
  94. else if ( perm_r(glu.lsub(kmin)) != emptyIdxLU)
  95. kmin++;
  96. else
  97. {
  98. // kmin below pivrow (not yet pivoted), and kmax
  99. // above pivrow: interchange the two suscripts
  100. std::swap(glu.lsub(kmin), glu.lsub(kmax));
  101. // If the supernode has only one column, then we
  102. // only keep one set of subscripts. For any subscript
  103. // intercnahge performed, similar interchange must be
  104. // done on the numerical values.
  105. if (movnum)
  106. {
  107. minloc = glu.xlusup(irep) + ( kmin - glu.xlsub(irep) );
  108. maxloc = glu.xlusup(irep) + ( kmax - glu.xlsub(irep) );
  109. std::swap(glu.lusup(minloc), glu.lusup(maxloc));
  110. }
  111. kmin++;
  112. kmax--;
  113. }
  114. } // end while
  115. xprune(irep) = StorageIndex(kmin); //Pruning
  116. } // end if do_prune
  117. } // end pruning
  118. } // End for each U-segment
  119. }
  120. } // end namespace internal
  121. } // end namespace Eigen
  122. #endif // SPARSELU_PRUNEL_H