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.main
				 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