Browse Source
Updated Eigen version. This fixes issue #77
Updated Eigen version. This fixes issue #77
We also now clone Eigen from the eigen git and perform a patch step. This makes updating the eigen versions more easy in the future.tempestpy_adaptions
Tim Quatmann
5 years ago
2 changed files with 289 additions and 2 deletions
@ -0,0 +1,271 @@ |
|||||
|
From 9f1a66bef29005a4cbe178241cad563fcb0dfa5f Mon Sep 17 00:00:00 2001 |
||||
|
From: Tim Quatmann <tim.quatmann@cs.rwth-aachen.de> |
||||
|
Date: Mon, 18 May 2020 11:58:47 +0200 |
||||
|
Subject: [PATCH 1/2] Adaptions for SparseLU to work with Scalar types that do |
||||
|
not default construct from a double (like CLN numbers) or that do not have an |
||||
|
operator< or std::abs |
||||
|
|
||||
|
---
|
||||
|
Eigen/src/SparseLU/SparseLU.h | 10 +-- |
||||
|
Eigen/src/SparseLU/SparseLU_column_bmod.h | 2 +- |
||||
|
Eigen/src/SparseLU/SparseLU_copy_to_ucol.h | 2 +- |
||||
|
Eigen/src/SparseLU/SparseLU_panel_bmod.h | 6 +- |
||||
|
Eigen/src/SparseLU/SparseLU_pivotL.h | 74 +++++++++++++++------- |
||||
|
5 files changed, 62 insertions(+), 32 deletions(-) |
||||
|
|
||||
|
diff --git a/Eigen/src/SparseLU/SparseLU.h b/Eigen/src/SparseLU/SparseLU.h
|
||||
|
index 7104831c0..9aeceb021 100644
|
||||
|
--- a/Eigen/src/SparseLU/SparseLU.h
|
||||
|
+++ b/Eigen/src/SparseLU/SparseLU.h
|
||||
|
@@ -97,12 +97,12 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
|
||||
|
}; |
||||
|
|
||||
|
public: |
||||
|
- SparseLU():m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
|
||||
|
+ SparseLU():m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1),m_detPermR(1)
|
||||
|
{ |
||||
|
initperfvalues(); |
||||
|
} |
||||
|
explicit SparseLU(const MatrixType& matrix) |
||||
|
- : m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
|
||||
|
+ : m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1),m_detPermR(1)
|
||||
|
{ |
||||
|
initperfvalues(); |
||||
|
compute(matrix); |
||||
|
@@ -255,7 +255,7 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
|
||||
|
using std::abs; |
||||
|
eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); |
||||
|
// Initialize with the determinant of the row matrix |
||||
|
- Scalar det = Scalar(1.);
|
||||
|
+ Scalar det = Scalar(1);
|
||||
|
// Note that the diagonal blocks of U are stored in supernodes, |
||||
|
// which are available in the L part :) |
||||
|
for (Index j = 0; j < this->cols(); ++j) |
||||
|
@@ -286,7 +286,7 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
|
||||
|
using std::abs; |
||||
|
|
||||
|
eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); |
||||
|
- Scalar det = Scalar(0.);
|
||||
|
+ Scalar det = Scalar(0);
|
||||
|
for (Index j = 0; j < this->cols(); ++j) |
||||
|
{ |
||||
|
for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it) |
||||
|
@@ -338,7 +338,7 @@ class SparseLU : public SparseSolverBase<SparseLU<_MatrixType,_OrderingType> >,
|
||||
|
{ |
||||
|
eigen_assert(m_factorizationIsOk && "The matrix should be factorized first."); |
||||
|
// Initialize with the determinant of the row matrix |
||||
|
- Scalar det = Scalar(1.);
|
||||
|
+ Scalar det = Scalar(1);
|
||||
|
// Note that the diagonal blocks of U are stored in supernodes, |
||||
|
// which are available in the L part :) |
||||
|
for (Index j = 0; j < this->cols(); ++j) |
||||
|
diff --git a/Eigen/src/SparseLU/SparseLU_column_bmod.h b/Eigen/src/SparseLU/SparseLU_column_bmod.h
|
||||
|
index b57f06802..be15e5ee6 100644
|
||||
|
--- a/Eigen/src/SparseLU/SparseLU_column_bmod.h
|
||||
|
+++ b/Eigen/src/SparseLU/SparseLU_column_bmod.h
|
||||
|
@@ -129,7 +129,7 @@ Index SparseLUImpl<Scalar,StorageIndex>::column_bmod(const Index jcol, const Ind
|
||||
|
{ |
||||
|
irow = glu.lsub(isub); |
||||
|
glu.lusup(nextlu) = dense(irow); |
||||
|
- dense(irow) = Scalar(0.0);
|
||||
|
+ dense(irow) = Scalar(0);
|
||||
|
++nextlu; |
||||
|
} |
||||
|
|
||||
|
diff --git a/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h b/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
|
||||
|
index c32d8d8b1..03c8aaf85 100644
|
||||
|
--- a/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
|
||||
|
+++ b/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
|
||||
|
@@ -87,7 +87,7 @@ Index SparseLUImpl<Scalar,StorageIndex>::copy_to_ucol(const Index jcol, const In
|
||||
|
irow = glu.lsub(isub); |
||||
|
glu.usub(nextu) = perm_r(irow); // Unlike the L part, the U part is stored in its final order |
||||
|
glu.ucol(nextu) = dense(irow); |
||||
|
- dense(irow) = Scalar(0.0);
|
||||
|
+ dense(irow) = Scalar(0);
|
||||
|
nextu++; |
||||
|
isub++; |
||||
|
} |
||||
|
diff --git a/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/Eigen/src/SparseLU/SparseLU_panel_bmod.h
|
||||
|
index 822cf32c3..5dc819cf7 100644
|
||||
|
--- a/Eigen/src/SparseLU/SparseLU_panel_bmod.h
|
||||
|
+++ b/Eigen/src/SparseLU/SparseLU_panel_bmod.h
|
||||
|
@@ -122,7 +122,7 @@ void SparseLUImpl<Scalar,StorageIndex>::panel_bmod(const Index m, const Index w,
|
||||
|
|
||||
|
Index isub = lptr + no_zeros; |
||||
|
Index off = u_rows-segsize; |
||||
|
- for (Index i = 0; i < off; i++) U(i,u_col) = 0;
|
||||
|
+ for (Index i = 0; i < off; i++) U(i,u_col) = Scalar(0);
|
||||
|
for (Index i = 0; i < segsize; i++) |
||||
|
{ |
||||
|
Index irow = glu.lsub(isub); |
||||
|
@@ -172,7 +172,7 @@ void SparseLUImpl<Scalar,StorageIndex>::panel_bmod(const Index m, const Index w,
|
||||
|
{ |
||||
|
Index irow = glu.lsub(isub++); |
||||
|
dense_col(irow) = U.coeff(i+off,u_col); |
||||
|
- U.coeffRef(i+off,u_col) = 0;
|
||||
|
+ U.coeffRef(i+off,u_col) = Scalar(0);
|
||||
|
} |
||||
|
|
||||
|
// Scatter l into SPA dense[] |
||||
|
@@ -180,7 +180,7 @@ void SparseLUImpl<Scalar,StorageIndex>::panel_bmod(const Index m, const Index w,
|
||||
|
{ |
||||
|
Index irow = glu.lsub(isub++); |
||||
|
dense_col(irow) -= L.coeff(i,u_col); |
||||
|
- L.coeffRef(i,u_col) = 0;
|
||||
|
+ L.coeffRef(i,u_col) = Scalar(0);
|
||||
|
} |
||||
|
u_col++; |
||||
|
} |
||||
|
diff --git a/Eigen/src/SparseLU/SparseLU_pivotL.h b/Eigen/src/SparseLU/SparseLU_pivotL.h
|
||||
|
index a86dac93f..2ad56531c 100644
|
||||
|
--- a/Eigen/src/SparseLU/SparseLU_pivotL.h
|
||||
|
+++ b/Eigen/src/SparseLU/SparseLU_pivotL.h
|
||||
|
@@ -32,7 +32,46 @@
|
||||
|
|
||||
|
namespace Eigen { |
||||
|
namespace internal { |
||||
|
-
|
||||
|
+ template<typename Scalar, typename StorageIndex, typename std::enable_if<std::is_same<Scalar, double>::value, int>::type = 0>
|
||||
|
+ 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) {
|
||||
|
+ double rtemp = 0;
|
||||
|
+ for (Index isub = nsupc; isub < nsupr; ++isub) {
|
||||
|
+ rtemp = std::abs(lu_col_ptr[isub]);
|
||||
|
+ if (rtemp > pivmax) {
|
||||
|
+ pivmax = rtemp;
|
||||
|
+ pivptr = isub;
|
||||
|
+ }
|
||||
|
+ if (lsub_ptr[isub] == diagind) diag = isub;
|
||||
|
+ }
|
||||
|
+ }
|
||||
|
+
|
||||
|
+ template<typename Scalar, typename StorageIndex, typename std::enable_if<!std::is_same<Scalar, double>::value, int>::type = 0>
|
||||
|
+ 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) {
|
||||
|
+ bool foundPivotElement = false;
|
||||
|
+ for (Index isub = nsupc; isub < nsupr; ++isub) {
|
||||
|
+ Scalar const& rtemp = lu_col_ptr[isub];
|
||||
|
+ if (!foundPivotElement && !storm::utility::isZero(rtemp)) {
|
||||
|
+ foundPivotElement = true;
|
||||
|
+ pivmax = rtemp;
|
||||
|
+ pivptr = isub;
|
||||
|
+ }
|
||||
|
+ if (lsub_ptr[isub] == diagind) diag = isub;
|
||||
|
+ }
|
||||
|
+ }
|
||||
|
+
|
||||
|
+ template<typename Scalar, typename std::enable_if<std::is_same<Scalar, double>::value, int>::type = 0>
|
||||
|
+ bool diagonalElementCanBePivot(Scalar const* lu_col_ptr, Index const& diag, Scalar const& diagpivotthresh, Scalar const& pivmax) {
|
||||
|
+ Scalar thresh = diagpivotthresh * pivmax;
|
||||
|
+ double rtemp = std::abs(lu_col_ptr[diag]);
|
||||
|
+ if (!storm::utility::isZero(rtemp) && rtemp >= thresh) return true;
|
||||
|
+ return false;
|
||||
|
+ }
|
||||
|
+
|
||||
|
+ template<typename Scalar, typename std::enable_if<!std::is_same<Scalar, double>::value, int>::type = 0>
|
||||
|
+ bool diagonalElementCanBePivot(Scalar const* lu_col_ptr, Index const& diag, Scalar const& diagpivotthresh, Scalar const& pivmax) {
|
||||
|
+ if (!storm::utility::isZero(lu_col_ptr[diag])) return true;
|
||||
|
+ return false;
|
||||
|
+ }
|
||||
|
/** |
||||
|
* \brief Performs the numerical pivotin on the current column of L, and the CDIV operation. |
||||
|
* |
||||
|
@@ -70,26 +109,19 @@ Index SparseLUImpl<Scalar,StorageIndex>::pivotL(const Index jcol, const RealScal
|
||||
|
StorageIndex* lsub_ptr = &(glu.lsub.data()[lptr]); // Start of row indices of the supernode |
||||
|
|
||||
|
// Determine the largest abs numerical value for partial pivoting |
||||
|
- Index diagind = iperm_c(jcol); // diagonal index
|
||||
|
- RealScalar pivmax(-1.0);
|
||||
|
- Index pivptr = nsupc;
|
||||
|
- Index diag = emptyIdxLU;
|
||||
|
- RealScalar rtemp;
|
||||
|
- Index isub, icol, itemp, k;
|
||||
|
- for (isub = nsupc; isub < nsupr; ++isub) {
|
||||
|
- using std::abs;
|
||||
|
- rtemp = abs(lu_col_ptr[isub]);
|
||||
|
- if (rtemp > pivmax) {
|
||||
|
- pivmax = rtemp;
|
||||
|
- pivptr = isub;
|
||||
|
- }
|
||||
|
- if (lsub_ptr[isub] == diagind) diag = isub;
|
||||
|
- }
|
||||
|
+ Index diagind = iperm_c(jcol); // diagonal index
|
||||
|
+ RealScalar pivmax(-1);
|
||||
|
+ Index pivptr = nsupc;
|
||||
|
+ Index diag = emptyIdxLU;
|
||||
|
+ Index icol, itemp, k;
|
||||
|
+
|
||||
|
+ findLargestAbsolutePivotElement(nsupc, nsupr, lu_col_ptr, lsub_ptr, diagind, diag, pivptr, pivmax);
|
||||
|
|
||||
|
// Test for singularity |
||||
|
- if ( pivmax <= RealScalar(0.0) ) {
|
||||
|
+ bool columnStructurallyEmpty = nsupr <= nsupc;
|
||||
|
+ if ( columnStructurallyEmpty || storm::utility::isZero(pivmax)) {
|
||||
|
// if pivmax == -1, the column is structurally empty, otherwise it is only numerically zero |
||||
|
- pivrow = pivmax < RealScalar(0.0) ? diagind : lsub_ptr[pivptr];
|
||||
|
+ pivrow = columnStructurallyEmpty ? diagind : lsub_ptr[pivptr];
|
||||
|
perm_r(pivrow) = StorageIndex(jcol); |
||||
|
return (jcol+1); |
||||
|
} |
||||
|
@@ -103,9 +135,7 @@ Index SparseLUImpl<Scalar,StorageIndex>::pivotL(const Index jcol, const RealScal
|
||||
|
if (diag >= 0 ) |
||||
|
{ |
||||
|
// Diagonal element exists |
||||
|
- using std::abs;
|
||||
|
- rtemp = abs(lu_col_ptr[diag]);
|
||||
|
- if (rtemp != RealScalar(0.0) && rtemp >= thresh) pivptr = diag;
|
||||
|
+ if (diagonalElementCanBePivot(lu_col_ptr, diag, diagpivotthresh, pivmax)) pivptr = diag;
|
||||
|
} |
||||
|
pivrow = lsub_ptr[pivptr]; |
||||
|
} |
||||
|
@@ -125,7 +155,7 @@ Index SparseLUImpl<Scalar,StorageIndex>::pivotL(const Index jcol, const RealScal
|
||||
|
} |
||||
|
} |
||||
|
// cdiv operations |
||||
|
- Scalar temp = Scalar(1.0) / lu_col_ptr[nsupc];
|
||||
|
+ Scalar temp = Scalar(1) / lu_col_ptr[nsupc];
|
||||
|
for (k = nsupc+1; k < nsupr; k++) |
||||
|
lu_col_ptr[k] *= temp; |
||||
|
return 0; |
||||
|
--
|
||||
|
2.24.2 (Apple Git-127) |
||||
|
|
||||
|
|
||||
|
From 366d73d04bedd7c58fc6b7e96f32a72422ceea89 Mon Sep 17 00:00:00 2001 |
||||
|
From: Tim Quatmann <tim.quatmann@cs.rwth-aachen.de> |
||||
|
Date: Tue, 19 May 2020 08:52:28 +0200 |
||||
|
Subject: [PATCH 2/2] Fixed actually using largest pivot with rational numbers |
||||
|
|
||||
|
---
|
||||
|
Eigen/src/SparseLU/SparseLU_pivotL.h | 8 ++++---- |
||||
|
1 file changed, 4 insertions(+), 4 deletions(-) |
||||
|
|
||||
|
diff --git a/Eigen/src/SparseLU/SparseLU_pivotL.h b/Eigen/src/SparseLU/SparseLU_pivotL.h
|
||||
|
index 2ad56531c..cc2dd9292 100644
|
||||
|
--- a/Eigen/src/SparseLU/SparseLU_pivotL.h
|
||||
|
+++ b/Eigen/src/SparseLU/SparseLU_pivotL.h
|
||||
|
@@ -32,11 +32,11 @@
|
||||
|
|
||||
|
namespace Eigen { |
||||
|
namespace internal { |
||||
|
- template<typename Scalar, typename StorageIndex, typename std::enable_if<std::is_same<Scalar, double>::value, int>::type = 0>
|
||||
|
+ template<typename Scalar, typename StorageIndex, typename std::enable_if<!std::is_same<Scalar, storm::RationalFunction>::value, int>::type = 0>
|
||||
|
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) { |
||||
|
- double rtemp = 0;
|
||||
|
+ Scalar rtemp = 0;
|
||||
|
for (Index isub = nsupc; isub < nsupr; ++isub) { |
||||
|
- rtemp = std::abs(lu_col_ptr[isub]);
|
||||
|
+ rtemp = storm::utility::abs(lu_col_ptr[isub]);
|
||||
|
if (rtemp > pivmax) { |
||||
|
pivmax = rtemp; |
||||
|
pivptr = isub; |
||||
|
@@ -45,7 +45,7 @@ namespace internal {
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- template<typename Scalar, typename StorageIndex, typename std::enable_if<!std::is_same<Scalar, double>::value, int>::type = 0>
|
||||
|
+ template<typename Scalar, typename StorageIndex, typename std::enable_if<std::is_same<Scalar, storm::RationalFunction>::value, int>::type = 0>
|
||||
|
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) { |
||||
|
bool foundPivotElement = false; |
||||
|
for (Index isub = nsupc; isub < nsupr; ++isub) { |
||||
|
--
|
||||
|
2.24.2 (Apple Git-127) |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue