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
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							235 lines
						
					
					
						
							10 KiB
						
					
					
				| From 4d2074e54b27877bcd694add91447b569d88e918 Mon Sep 17 00:00:00 2001 | |
| From: Tim Quatmann <tim.quatmann@cs.rwth-aachen.de> | |
| Date: Wed, 20 May 2020 15:48:43 +0200 | |
| Subject: [PATCH] Eigen Patch | |
| 
 | |
| --- | |
|  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       | 79 +++++++++++++++------- | |
|  5 files changed, 63 insertions(+), 36 deletions(-) | |
| 
 | |
| diff --git a/Eigen/src/SparseLU/SparseLU.h b/Eigen/src/SparseLU/SparseLU.h | |
| index 7104831..9aeceb0 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 b57f068..be15e5e 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 c32d8d8..03c8aaf 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 822cf32..5dc819c 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 a86dac9..f1ebd3c 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, 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) { | |
| +        Scalar rtemp = 0; | |
| +        for (Index isub = nsupc; isub < nsupr; ++isub) { | |
| +            rtemp = storm::utility::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, 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) { | |
| +            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,42 +109,30 @@ 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); | |
|    } | |
|     | |
| -  RealScalar thresh = diagpivotthresh * pivmax;  | |
| -   | |
| -  // Choose appropriate pivotal element  | |
| -   | |
| +  // Choose appropriate pivotal element | |
|    { | |
|      // Test if the diagonal element can be used as a pivot (given the threshold value) | |
|      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 +152,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.21.0 (Apple Git-122) | |
| 
 |