You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
10 KiB

3 months ago
  1. From 4d2074e54b27877bcd694add91447b569d88e918 Mon Sep 17 00:00:00 2001
  2. From: Tim Quatmann <tim.quatmann@cs.rwth-aachen.de>
  3. Date: Wed, 20 May 2020 15:48:43 +0200
  4. Subject: [PATCH] Eigen Patch
  5. ---
  6. Eigen/src/SparseLU/SparseLU.h | 10 +--
  7. Eigen/src/SparseLU/SparseLU_column_bmod.h | 2 +-
  8. Eigen/src/SparseLU/SparseLU_copy_to_ucol.h | 2 +-
  9. Eigen/src/SparseLU/SparseLU_panel_bmod.h | 6 +-
  10. Eigen/src/SparseLU/SparseLU_pivotL.h | 79 +++++++++++++++-------
  11. 5 files changed, 63 insertions(+), 36 deletions(-)
  12. diff --git a/Eigen/src/SparseLU/SparseLU.h b/Eigen/src/SparseLU/SparseLU.h
  13. index 7104831..9aeceb0 100644
  14. --- a/Eigen/src/SparseLU/SparseLU.h
  15. +++ b/Eigen/src/SparseLU/SparseLU.h
  16. @@ -97,12 +97,12 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
  17. };
  18. public:
  19. - SparseLU():m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
  20. + SparseLU():m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1),m_detPermR(1)
  21. {
  22. initperfvalues();
  23. }
  24. explicit SparseLU(const MatrixType& matrix)
  25. - : m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
  26. + : m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1),m_detPermR(1)
  27. {
  28. initperfvalues();
  29. compute(matrix);
  30. @@ -255,7 +255,7 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
  31. using std::abs;
  32. eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
  33. // Initialize with the determinant of the row matrix
  34. - Scalar det = Scalar(1.);
  35. + Scalar det = Scalar(1);
  36. // Note that the diagonal blocks of U are stored in supernodes,
  37. // which are available in the L part :)
  38. for (Index j = 0; j < this->cols(); ++j)
  39. @@ -286,7 +286,7 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
  40. using std::abs;
  41. eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
  42. - Scalar det = Scalar(0.);
  43. + Scalar det = Scalar(0);
  44. for (Index j = 0; j < this->cols(); ++j)
  45. {
  46. for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
  47. @@ -338,7 +338,7 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
  48. {
  49. eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
  50. // Initialize with the determinant of the row matrix
  51. - Scalar det = Scalar(1.);
  52. + Scalar det = Scalar(1);
  53. // Note that the diagonal blocks of U are stored in supernodes,
  54. // which are available in the L part :)
  55. for (Index j = 0; j < this->cols(); ++j)
  56. diff --git a/Eigen/src/SparseLU/SparseLU_column_bmod.h b/Eigen/src/SparseLU/SparseLU_column_bmod.h
  57. index b57f068..be15e5e 100644
  58. --- a/Eigen/src/SparseLU/SparseLU_column_bmod.h
  59. +++ b/Eigen/src/SparseLU/SparseLU_column_bmod.h
  60. @@ -129,7 +129,7 @@ Index SparseLUImpl<Scalar,StorageIndex>::column_bmod(const Index jcol, const Ind
  61. {
  62. irow = glu.lsub(isub);
  63. glu.lusup(nextlu) = dense(irow);
  64. - dense(irow) = Scalar(0.0);
  65. + dense(irow) = Scalar(0);
  66. ++nextlu;
  67. }
  68. diff --git a/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h b/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
  69. index c32d8d8..03c8aaf 100644
  70. --- a/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
  71. +++ b/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
  72. @@ -87,7 +87,7 @@ Index SparseLUImpl<Scalar,StorageIndex>::copy_to_ucol(const Index jcol, const In
  73. irow = glu.lsub(isub);
  74. glu.usub(nextu) = perm_r(irow); // Unlike the L part, the U part is stored in its final order
  75. glu.ucol(nextu) = dense(irow);
  76. - dense(irow) = Scalar(0.0);
  77. + dense(irow) = Scalar(0);
  78. nextu++;
  79. isub++;
  80. }
  81. diff --git a/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/Eigen/src/SparseLU/SparseLU_panel_bmod.h
  82. index 822cf32..5dc819c 100644
  83. --- a/Eigen/src/SparseLU/SparseLU_panel_bmod.h
  84. +++ b/Eigen/src/SparseLU/SparseLU_panel_bmod.h
  85. @@ -122,7 +122,7 @@ void SparseLUImpl<Scalar,StorageIndex>::panel_bmod(const Index m, const Index w,
  86. Index isub = lptr + no_zeros;
  87. Index off = u_rows-segsize;
  88. - for (Index i = 0; i < off; i++) U(i,u_col) = 0;
  89. + for (Index i = 0; i < off; i++) U(i,u_col) = Scalar(0);
  90. for (Index i = 0; i < segsize; i++)
  91. {
  92. Index irow = glu.lsub(isub);
  93. @@ -172,7 +172,7 @@ void SparseLUImpl<Scalar,StorageIndex>::panel_bmod(const Index m, const Index w,
  94. {
  95. Index irow = glu.lsub(isub++);
  96. dense_col(irow) = U.coeff(i+off,u_col);
  97. - U.coeffRef(i+off,u_col) = 0;
  98. + U.coeffRef(i+off,u_col) = Scalar(0);
  99. }
  100. // Scatter l into SPA dense[]
  101. @@ -180,7 +180,7 @@ void SparseLUImpl<Scalar,StorageIndex>::panel_bmod(const Index m, const Index w,
  102. {
  103. Index irow = glu.lsub(isub++);
  104. dense_col(irow) -= L.coeff(i,u_col);
  105. - L.coeffRef(i,u_col) = 0;
  106. + L.coeffRef(i,u_col) = Scalar(0);
  107. }
  108. u_col++;
  109. }
  110. diff --git a/Eigen/src/SparseLU/SparseLU_pivotL.h b/Eigen/src/SparseLU/SparseLU_pivotL.h
  111. index a86dac9..f1ebd3c 100644
  112. --- a/Eigen/src/SparseLU/SparseLU_pivotL.h
  113. +++ b/Eigen/src/SparseLU/SparseLU_pivotL.h
  114. @@ -32,7 +32,46 @@
  115. namespace Eigen {
  116. namespace internal {
  117. -
  118. + template<typename Scalar, typename StorageIndex, typename std::enable_if<!std::is_same<Scalar, storm::RationalFunction>::value, int>::type = 0>
  119. + void findLargestAbsolutePivotElement(const Index& nsupc, const Index& nsupr, Scalar const* lu_col_ptr, StorageIndex const* lsub_ptr, Index const& diagind, Index& diag, Index& pivptr, Scalar& pivmax) {
  120. + Scalar rtemp = 0;
  121. + for (Index isub = nsupc; isub < nsupr; ++isub) {
  122. + rtemp = storm::utility::abs(lu_col_ptr[isub]);
  123. + if (rtemp > pivmax) {
  124. + pivmax = rtemp;
  125. + pivptr = isub;
  126. + }
  127. + if (lsub_ptr[isub] == diagind) diag = isub;
  128. + }
  129. + }
  130. +
  131. + template<typename Scalar, typename StorageIndex, typename std::enable_if<std::is_same<Scalar, storm::RationalFunction>::value, int>::type = 0>
  132. + void findLargestAbsolutePivotElement(const Index& nsupc, const Index& nsupr, Scalar const* lu_col_ptr, StorageIndex const* lsub_ptr, Index const& diagind, Index& diag, Index& pivptr, Scalar& pivmax) {
  133. + bool foundPivotElement = false;
  134. + for (Index isub = nsupc; isub < nsupr; ++isub) {
  135. + Scalar const& rtemp = lu_col_ptr[isub];
  136. + if (!foundPivotElement && !storm::utility::isZero(rtemp)) {
  137. + foundPivotElement = true;
  138. + pivmax = rtemp;
  139. + pivptr = isub;
  140. + }
  141. + if (lsub_ptr[isub] == diagind) diag = isub;
  142. + }
  143. + }
  144. +
  145. + template<typename Scalar, typename std::enable_if<std::is_same<Scalar, double>::value, int>::type = 0>
  146. + bool diagonalElementCanBePivot(Scalar const* lu_col_ptr, Index const& diag, Scalar const& diagpivotthresh, Scalar const& pivmax) {
  147. + Scalar thresh = diagpivotthresh * pivmax;
  148. + double rtemp = std::abs(lu_col_ptr[diag]);
  149. + if (!storm::utility::isZero(rtemp) && rtemp >= thresh) return true;
  150. + return false;
  151. + }
  152. +
  153. + template<typename Scalar, typename std::enable_if<!std::is_same<Scalar, double>::value, int>::type = 0>
  154. + bool diagonalElementCanBePivot(Scalar const* lu_col_ptr, Index const& diag, Scalar const& diagpivotthresh, Scalar const& pivmax) {
  155. + if (!storm::utility::isZero(lu_col_ptr[diag])) return true;
  156. + return false;
  157. + }
  158. /**
  159. * \brief Performs the numerical pivotin on the current column of L, and the CDIV operation.
  160. *
  161. @@ -70,42 +109,30 @@ Index SparseLUImpl<Scalar,StorageIndex>::pivotL(const Index jcol, const RealScal
  162. StorageIndex* lsub_ptr = &(glu.lsub.data()[lptr]); // Start of row indices of the supernode
  163. // Determine the largest abs numerical value for partial pivoting
  164. - Index diagind = iperm_c(jcol); // diagonal index
  165. - RealScalar pivmax(-1.0);
  166. - Index pivptr = nsupc;
  167. - Index diag = emptyIdxLU;
  168. - RealScalar rtemp;
  169. - Index isub, icol, itemp, k;
  170. - for (isub = nsupc; isub < nsupr; ++isub) {
  171. - using std::abs;
  172. - rtemp = abs(lu_col_ptr[isub]);
  173. - if (rtemp > pivmax) {
  174. - pivmax = rtemp;
  175. - pivptr = isub;
  176. - }
  177. - if (lsub_ptr[isub] == diagind) diag = isub;
  178. - }
  179. + Index diagind = iperm_c(jcol); // diagonal index
  180. + RealScalar pivmax(-1);
  181. + Index pivptr = nsupc;
  182. + Index diag = emptyIdxLU;
  183. + Index icol, itemp, k;
  184. +
  185. + findLargestAbsolutePivotElement(nsupc, nsupr, lu_col_ptr, lsub_ptr, diagind, diag, pivptr, pivmax);
  186. // Test for singularity
  187. - if ( pivmax <= RealScalar(0.0) ) {
  188. + bool columnStructurallyEmpty = nsupr <= nsupc;
  189. + if ( columnStructurallyEmpty || storm::utility::isZero(pivmax)) {
  190. // if pivmax == -1, the column is structurally empty, otherwise it is only numerically zero
  191. - pivrow = pivmax < RealScalar(0.0) ? diagind : lsub_ptr[pivptr];
  192. + pivrow = columnStructurallyEmpty ? diagind : lsub_ptr[pivptr];
  193. perm_r(pivrow) = StorageIndex(jcol);
  194. return (jcol+1);
  195. }
  196. - RealScalar thresh = diagpivotthresh * pivmax;
  197. -
  198. - // Choose appropriate pivotal element
  199. -
  200. + // Choose appropriate pivotal element
  201. {
  202. // Test if the diagonal element can be used as a pivot (given the threshold value)
  203. if (diag >= 0 )
  204. {
  205. // Diagonal element exists
  206. - using std::abs;
  207. - rtemp = abs(lu_col_ptr[diag]);
  208. - if (rtemp != RealScalar(0.0) && rtemp >= thresh) pivptr = diag;
  209. + if (diagonalElementCanBePivot(lu_col_ptr, diag, diagpivotthresh, pivmax)) pivptr = diag;
  210. }
  211. pivrow = lsub_ptr[pivptr];
  212. }
  213. @@ -125,7 +152,7 @@ Index SparseLUImpl<Scalar,StorageIndex>::pivotL(const Index jcol, const RealScal
  214. }
  215. }
  216. // cdiv operations
  217. - Scalar temp = Scalar(1.0) / lu_col_ptr[nsupc];
  218. + Scalar temp = Scalar(1) / lu_col_ptr[nsupc];
  219. for (k = nsupc+1; k < nsupr; k++)
  220. lu_col_ptr[k] *= temp;
  221. return 0;
  222. --
  223. 2.21.0 (Apple Git-122)