@ -1,11 +1,3 @@
/*
* SparseMatrix . cpp
*
* Created on : Nov 18 , 2013
* Author : Manuel Sascha Weiand
*/
# include <iomanip>
# include <boost/functional/hash.hpp>
# include "src/storage/SparseMatrix.h"
@ -16,354 +8,234 @@
extern log4cplus : : Logger logger ;
namespace storm {
namespace storage {
namespace storage {
// Functions of the nested ConstIterator class.
template < typename T >
template < typename ValueType >
SparseMatrix < T > : : BaseIterator < ValueType > : : BaseIterator ( ValueType * valuePtr , uint_fast64_t const * columnPtr ) : valuePtr ( valuePtr ) , columnPtr ( columnPtr ) {
// Intentionally left empty.
}
template < typename T >
SparseMatrix < T > : : ConstIterator : : ConstIterator ( T const * valuePtr , uint_fast64_t const * columnPtr ) : valuePtr ( valuePtr ) , columnPtr ( columnPtr ) {
template < typename ValueType >
SparseMatrix < T > : : BaseIterator < ValueType > : : BaseIterator ( SparseMatrix < T > : : BaseIterator < ValueType > const & other ) : valuePtr ( other . valuePtr ) , columnPtr ( other . columnPtr ) {
// Intentionally left empty.
}
template < typename T >
typename SparseMatrix < T > : : ConstIterator & SparseMatrix < T > : : ConstIterator : : operator + + ( ) {
template < typename ValueType >
typename SparseMatrix < T > : : template BaseIterator < ValueType > & SparseMatrix < T > : : BaseIterator < ValueType > : : operator = ( BaseIterator < ValueType > const & other ) {
if ( this ! = & other ) {
valuePtr = other . valuePtr ,
columnPtr = other . columnPtr ;
}
return * this ;
}
template < typename T >
template < typename ValueType >
SparseMatrix < T > : : BaseIterator < ValueType > & SparseMatrix < T > : : BaseIterator < ValueType > : : operator + + ( ) {
this - > valuePtr + + ;
this - > columnPtr + + ;
return * this ;
}
template < typename T >
typename SparseMatrix < T > : : ConstIterator & SparseMatrix < T > : : ConstIterator : : operator * ( ) {
template < typename ValueType >
SparseMatrix < T > : : BaseIterator < ValueType > & SparseMatrix < T > : : BaseIterator < ValueType > : : operator * ( ) {
return * this ;
}
template < typename T >
bool SparseMatrix < T > : : ConstIterator : : operator ! = ( ConstIterator const & other ) const {
template < typename ValueType >
bool SparseMatrix < T > : : BaseIterator < ValueType > : : operator ! = ( BaseIterator < ValueType > const & other ) const {
return this - > valuePtr ! = other . valuePtr ;
}
template < typename T >
typename SparseMatrix < T > : : ConstIterator & SparseMatrix < T > : : ConstIterator : : operator = ( ConstIterator const & other ) {
this - > valuePtr = other . valuePtr ;
this - > columnPtr = other . columnPtr ;
return * this ;
template < typename ValueType >
bool SparseMatrix < T > : : BaseIterator < ValueType > : : operator = = ( BaseIterator < ValueType > const & other ) const {
return this - > valuePtr = = other . valuePtr ;
}
template < typename T >
uint_fast64_t SparseMatrix < T > : : ConstIterator : : column ( ) const {
template < typename ValueType >
uint_fast64_t SparseMatrix < T > : : BaseIterator < ValueType > : : column ( ) const {
return * columnPtr ;
}
template < typename T >
T const & SparseMatrix < T > : : ConstIterator : : value ( ) const {
template < typename ValueType >
ValueType & SparseMatrix < T > : : BaseIterator < ValueType > : : value ( ) const {
return * valuePtr ;
}
// Functions of the nested Rows class.
template < typename T >
SparseMatrix < T > : : Rows : : R ows( T const * valuePtr , uint_fast64_t const * columnPtr , uint_fast64_t entryCount ) : valuePtr ( valuePtr ) , columnPtr ( columnPtr ) , entryCount ( entryCount ) {
SparseMatrix < T > : : rows : : rows ( T * valuePtr , uint_fast64_t const * columnPtr , uint_fast64_t entryCount ) : valuePtr ( valuePtr ) , columnPtr ( columnPtr ) , entryCount ( entryCount ) {
// Intentionally left empty.
}
template < typename T >
typename SparseMatrix < T > : : ConstI terator SparseMatrix < T > : : R ows: : begin ( ) const {
return ConstI terator ( valuePtr , columnPtr ) ;
typename SparseMatrix < T > : : i terator SparseMatrix < T > : : r ows: : begin ( ) {
return i terator ( valuePtr , columnPtr ) ;
}
template < typename T >
typename SparseMatrix < T > : : ConstI terator SparseMatrix < T > : : R ows: : end ( ) const {
return ConstI terator ( valuePtr + entryCount , columnPtr + entryCount ) ;
typename SparseMatrix < T > : : i terator SparseMatrix < T > : : r ows: : end ( ) {
return i terator ( valuePtr + entryCount , columnPtr + entryCount ) ;
}
// Functions of the nested ConstRowsIterator class.
template < typename T >
SparseMatrix < T > : : ConstRowIterator : : ConstRowIterator ( T const * startV aluePtr, uint_fast64_t const * startColumnPtr , uint_fast64_t const * rowPtr ) : startValuePtr ( startValuePtr ) , startColumnPtr ( startColumnPtr ) , rowPtr ( rowPtr ) {
SparseMatrix < T > : : const_rows : : const_rows ( T const * valuePtr , uint_fast64_t const * columnPtr , uint_fast64_t entryCount ) : valuePtr ( valuePtr ) , columnPtr ( columnPtr ) , entryCount ( entryCount ) {
// Intentionally left empty.
}
template < typename T >
typename SparseMatrix < T > : : ConstRowIterator & SparseMatrix < T > : : ConstRowIterator : : operator + + ( ) {
+ + rowPtr ;
return * this ;
}
template < typename T >
bool SparseMatrix < T > : : ConstRowIterator : : operator ! = ( ConstRowIterator const & other ) const {
return this - > rowPtr ! = other . rowPtr ;
typename SparseMatrix < T > : : const_iterator SparseMatrix < T > : : const_rows : : begin ( ) const {
return const_iterator ( valuePtr , columnPtr ) ;
}
template < typename T >
typename SparseMatrix < T > : : ConstI terator SparseMatrix < T > : : ConstRowIterator : : b egi n( ) const {
return ConstIterator ( startValuePtr + * rowPtr , startColumnPtr + * rowPtr ) ;
typename SparseMatrix < T > : : const_iterator SparseMatrix < T > : : const_rows : : end ( ) const {
return const_iterator ( valuePtr + entryCount , columnPtr + entryCount ) ;
}
template < typename T >
typename SparseMatrix < T > : : ConstIterator SparseMatrix < T > : : ConstRowIterator : : end ( ) const {
return ConstIterator ( startValuePtr + * ( rowPtr + 1 ) , startColumnPtr + * ( rowPtr + 1 ) ) ;
SparseMatrix < T > : : SparseMatrix ( uint_fast64_t rows , uint_fast64_t columns , uint_fast64_t entries ) : rowCount ( rows ) , columnCount ( columns ) , entryCount ( entries ) , internalStatus ( UNINITIALIZED ) , valueStorage ( ) , columnIndications ( ) , rowIndications ( ) , currentEntryCount ( 0 ) , lastRow ( 0 ) , lastColumn ( 0 ) {
storagePreallocated = rows ! = 0 & & columns ! = 0 & & entries ! = 0 ;
prepareInternalStorage ( ) ;
}
// Functions of the SparseMatrix class.
template < typename T >
SparseMatrix < T > : : SparseMatrix ( uint_fast64_t rows , uint_fast64_t cols ) : rowCount ( rows ) , colCount ( cols ) ,
nonZeroEntryCount ( 0 ) , internalStatus ( MatrixStatus : : UnInitialized ) , currentSize ( 0 ) , lastRow ( 0 ) {
SparseMatrix < T > : : SparseMatrix ( uint_fast64_t size , uint_fast64_t entries ) : SparseMatrix ( size , size , entries ) {
// Intentionally left empty.
}
template < typename T >
SparseMatrix < T > : : SparseMatrix ( uint_fast64_t size )
: rowCount ( size ) , colCount ( size ) , nonZeroEntryCount ( 0 ) ,
internalStatus ( MatrixStatus : : UnInitialized ) , currentSize ( 0 ) , lastRow ( 0 ) {
SparseMatrix < T > : : SparseMatrix ( SparseMatrix < T > const & other ) : rowCount ( other . rowCount ) , columnCount ( other . columnCount ) , entryCount ( other . entryCount ) , storagePreallocated ( other . storagePreallocated ) , valueStorage ( other . valueStorage ) , columnIndications ( other . columnIndications ) , rowIndications ( other . rowIndications ) , internalStatus ( other . internalStatus ) , currentEntryCount ( other . currentEntryCount ) , lastRow ( other . lastRow ) , lastColumn ( other . lastColumn ) {
// Intentionally left empty.
}
template < typename T >
SparseMatrix < T > : : SparseMatrix ( SparseMatrix < T > & & other )
: rowCount ( other . rowCount ) , colCount ( other . colCount ) , nonZeroEntryCount ( other . nonZeroEntryCount ) ,
valueStorage ( std : : move ( other . valueStorage ) ) , columnIndications ( std : : move ( other . columnIndications ) ) ,
rowIndications ( std : : move ( other . rowIndications ) ) , internalStatus ( other . internalStatus ) ,
currentSize ( other . currentSize ) , lastRow ( other . lastRow ) {
SparseMatrix < T > : : SparseMatrix ( SparseMatrix < T > & & other ) : rowCount ( other . rowCount ) , columnCount ( other . columnCount ) , entryCount ( other . entryCount ) , storagePreallocated ( other . storagePreallocated ) , valueStorage ( std : : move ( other . valueStorage ) ) , columnIndications ( std : : move ( other . columnIndications ) ) , rowIndications ( std : : move ( other . rowIndications ) ) , internalStatus ( other . internalStatus ) , currentEntryCount ( other . currentEntryCount ) , lastRow ( other . lastRow ) , lastColumn ( other . lastColumn ) {
// Now update the source matrix
other . rowCount = 0 ;
other . colCount = 0 ;
other . nonZeroEntryCount = 0 ;
other . internalStatus = MatrixStatus : : Error ;
other . currentSize = 0 ;
other . columnCount = 0 ;
other . entryCount = 0 ;
other . storagePreallocated = false ;
other . internalStatus = MatrixStatus : : UNINITIALIZED ;
other . currentEntryCount = 0 ;
other . lastRow = 0 ;
other . lastColumn = 0 ;
}
template < typename T >
SparseMatrix < T > : : SparseMatrix ( const SparseMatrix < T > & other )
: rowCount ( other . rowCount ) , colCount ( other . colCount ) , nonZeroEntryCount ( other . nonZeroEntryCount ) ,
valueStorage ( other . valueStorage ) , columnIndications ( other . columnIndications ) ,
rowIndications ( other . rowIndications ) , internalStatus ( other . internalStatus ) ,
currentSize ( other . currentSize ) , lastRow ( other . lastRow ) {
}
template < typename T >
SparseMatrix < T > : : SparseMatrix ( uint_fast64_t rowCount , uint_fast64_t colCount , uint_fast64_t nonZeroEntryCount ,
std : : vector < uint_fast64_t > & & rowIndications ,
std : : vector < uint_fast64_t > & & columnIndications , std : : vector < T > & & values )
: rowCount ( rowCount ) , colCount ( colCount ) , nonZeroEntryCount ( nonZeroEntryCount ) ,
valueStorage ( values ) , columnIndications ( columnIndications ) ,
rowIndications ( rowIndications ) , internalStatus ( MatrixStatus : : Initialized ) ,
currentSize ( 0 ) , lastRow ( 0 ) {
SparseMatrix < T > : : SparseMatrix ( uint_fast64_t columnCount , std : : vector < uint_fast64_t > & & rowIndications , std : : vector < uint_fast64_t > & & columnIndications , std : : vector < T > & & values ) : rowCount ( rowIndications . size ( ) - 1 ) , columnCount ( columnCount ) , entryCount ( values . size ( ) ) , valueStorage ( std : : move ( values ) ) , columnIndications ( std : : move ( columnIndications ) ) , rowIndications ( std : : move ( rowIndications ) ) , internalStatus ( INITIALIZED ) , currentEntryCount ( 0 ) , lastRow ( 0 ) , lastColumn ( 0 ) {
// Intentionally left empty.
}
template < typename T >
storm : : storage : : SparseMatrix < T > & SparseMatrix < T > : : operator = ( SparseMatrix < T > const & other ) {
this - > rowCount = other . rowCount ;
this - > colCount = other . colCount ;
this - > nonZeroEntryCount = other . nonZeroEntryCount ;
SparseMatrix < T > & SparseMatrix < T > : : operator = ( SparseMatrix < T > const & other ) {
// Only perform assignment if source and target are not the same.
if ( this ! = & other ) {
rowCount = other . rowCount ;
columnCount = other . columnCount ;
entryCount = other . entryCount ;
this - > valueStorage = other . valueStorage ;
this - > columnIndications = other . columnIndications ;
this - > rowIndications = other . rowIndications ;
valueStorage = other . valueStorage ;
columnIndications = other . columnIndications ;
rowIndications = other . rowIndications ;
this - > internalStatus = other . internalStatus ;
this - > currentSize = other . currentSize ;
this - > lastRow = other . lastRow ;
return * this ;
internalStatus = other . internalStatus ;
currentEntryCount = other . currentEntryCount ;
lastRow = other . lastRow ;
lastColumn = other . lastColumn ;
}
template < typename T >
void SparseMatrix < T > : : initialize ( uint_fast64_t nonZeroEntries ) {
// Check whether initializing the matrix is safe.
if ( internalStatus ! = MatrixStatus : : UnInitialized ) {
triggerErrorState ( ) ;
LOG4CPLUS_ERROR ( logger , " Trying to initialize matrix that is not uninitialized. " ) ;
throw storm : : exceptions : : InvalidStateException ( " Trying to initialize matrix that is not uninitialized. " ) ;
} else if ( ( rowCount * colCount ) < nonZeroEntries ) {
triggerErrorState ( ) ;
LOG4CPLUS_ERROR ( logger , " Trying to initialize a matrix with more non-zero entries than there can be. " ) ;
throw storm : : exceptions : : InvalidArgumentException ( " Trying to initialize a matrix with more non-zero entries than there can be. " ) ;
} else {
// If it is safe, initialize necessary members and prepare the
// internal storage.
nonZeroEntryCount = nonZeroEntries ;
lastRow = 0 ;
if ( ! prepareInternalStorage ( ) ) {
triggerErrorState ( ) ;
throw std : : bad_alloc ( ) ;
} else {
setState ( MatrixStatus : : Initialized ) ;
}
}
return * this ;
}
template < typename T >
void SparseMatrix < T > : : addNextValue ( const uint_fast64_t row , const uint_fast64_t col , T const & value ) {
// Check whether the given row and column positions are valid and throw
// error otherwise .
if ( ( row > rowCount ) | | ( col > colCount ) ) {
triggerErrorState ( ) ;
LOG4CPLUS_ERROR ( logger , " Trying to add a value at illegal position ( " < < row < < " , " < < col < < " ) in matrix of size ( " < < rowCount < < " , " < < colCount < < " ). " ) ;
throw storm : : exceptions : : OutOfRangeException ( ) < < " Trying to add a value at illegal position (" < < row < < " , " < < col < < " ) in matrix of size ( " < < rowCount < < " , " < < colCount < < " ). " ;
void SparseMatrix < T > : : addNextValue ( uint_fast64_t row , uint_fast64_t column , T const & value ) {
// Depending on whether the internal data storage was preallocated or not, adding the value is done somewhat
// differently.
if ( storagePreallocated ) {
// Check whether the given row and column positions are valid and throw error otherwise.
if ( row > rowCount | | column > columnCount ) {
throw storm : : exceptions : : OutOfRangeException ( ) < < " Illegal call to SparseMatrix::addNextValue: adding entry at out-of-bounds position ( " < < row < < " , " < < column < < " ) in matrix of size ( " < < rowCount < < " , " < < columnCount < < " ). " ;
}
// If we switched to another row, we have to adjust the missing
// entries in the row_indications array.
if ( row ! = lastRow ) {
for ( uint_fast64_t i = lastRow + 1 ; i < = row ; + + i ) {
rowIndications [ i ] = currentSize ;
}
lastRow = row ;
}
// Finally, set the element and increase the current size.
valueStorage [ currentSize ] = value ;
columnIndications [ currentSize ] = col ;
+ + currentSize ;
// Check that we did not move backwards wrt. the row.
if ( row < lastRow ) {
throw storm : : exceptions : : InvalidArgumentException ( ) < < " Illegal call to SparseMatrix::addNextValue: adding an element in row " < < row < < " , but an element in row " < < lastRow < < " has already been added. " < < std : : endl ;
}
template < typename T >
void SparseMatrix < T > : : insertNextValue ( const uint_fast64_t row , const uint_fast64_t col , T const & value , bool pushRowIndication ) {
// Check whether the given row and column positions are valid and throw
// error otherwise.
if ( row < lastRow ) {
triggerErrorState ( ) ;
LOG4CPLUS_ERROR ( logger , " Trying to insert a value at illegal position ( " < < row < < " , " < < col < < " ). " ) ;
throw storm : : exceptions : : OutOfRangeException ( ) < < " Trying to insert a value at illegal position ( " < < row < < " , " < < col < < " ). " ;
// Check that we did not move backwards wrt. to column.
if ( row = = lastRow & & column < lastColumn ) {
throw storm : : exceptions : : InvalidArgumentException ( ) < < " Illegal call to SparseMatrix::addNextValue: adding an element in column " < < column < < " in row " < < row < < " , but an element in column " < < lastColumn < < " has already been added in that row. " < < std : : endl ;
}
// If we switched to another row, we have to adjust the missing entries in the rowIndications array .
// If we switched to another row, we have to adjust the missing entries in the row indices vector.
if ( row ! = lastRow ) {
if ( storagePreallocated ) {
// If the storage was preallocated, we can access the elements in the vectors with the subscript
// operator.
for ( uint_fast64_t i = lastRow + 1 ; i < = row ; + + i ) {
if ( pushRowIndication ) {
rowIndications . push_back ( currentSize ) ;
rowIndications [ i ] = currentEntryCount ;
}
} else {
rowIndications [ i ] = currentSize ;
// Otherwise, we need to push the correct values to the vectors, which might trigger reallocations.
for ( uint_fast64_t i = lastRow + 1 ; i < = row ; + + i ) {
rowIndications . push_back ( currentEntryCount ) ;
}
}
rowCount = row + 1 ;
lastRow = row ;
}
// Finally, set the element and increase the current size.
valueStorage . push_back ( value ) ;
columnIndications . push_back ( col ) ;
+ + nonZeroEntryCount ;
+ + currentSize ;
// Check that we also have the correct number of columns.
colCount = std : : max ( colCount , col + 1 ) ;
}
lastColumn = column ;
template < typename T >
void SparseMatrix < T > : : insertEmptyRow ( bool pushRowIndication ) {
if ( pushRowIndication ) {
rowIndications . push_back ( currentSize ) ;
// Finally, set the element and increase the current size.
if ( storagePreallocated ) {
valueStorage [ currentEntryCount ] = value ;
columnIndications [ currentEntryCount ] = column ;
+ + currentEntryCount ;
} else {
rowIndications [ lastRow + 1 ] = currentSize ;
valueStorage . push_back ( value ) ;
columnIndications . push_back ( column ) ;
}
+ + rowCount ;
+ + lastRow ;
}
template < typename T >
void SparseMatrix < T > : : finalize ( bool pushSentinelElement ) {
void SparseMatrix < T > : : finalize ( ) {
// Check whether it's safe to finalize the matrix and throw error otherwise.
if ( ! isInitialized ( ) ) {
triggerErrorState ( ) ;
LOG4CPLUS_ERROR ( logger , " Trying to finalize an uninitialized matrix. " ) ;
throw storm : : exceptions : : InvalidStateException ( " Trying to finalize an uninitialized matrix. " ) ;
} else if ( currentSize ! = nonZeroEntryCount ) {
triggerErrorState ( ) ;
LOG4CPLUS_ERROR ( logger , " Trying to finalize a matrix that was initialized with more non-zero entries than given (expected " < < nonZeroEntryCount < < " but got " < < currentSize < < " instead) " ) ;
throw storm : : exceptions : : InvalidStateException ( ) < < " Trying to finalize a matrix that was initialized with more non-zero entries than given (expected " < < nonZeroEntryCount < < " but got " < < currentSize < < " instead). " ;
if ( internalStatus = = INITIALIZED ) {
throw storm : : exceptions : : InvalidStateException ( ) < < " Illegal call to SparseMatrix::finalize: finalizing an initialized matrix is forbidden. " ;
} else if ( storagePreallocated & & currentEntryCount ! = entryCount ) {
throw storm : : exceptions : : InvalidStateException ( ) < < " Illegal call to SparseMatrix::finalize: expected " < < entryCount < < " entries, but got " < < currentEntryCount < < " instead. " ;
} else {
// Fill in the missing entries in the row_indications array .
// (Can happen because of empty rows at the end.)
// Fill in the missing entries in the row indices array, as there may be empty rows at the end.
if ( storagePreallocated ) {
for ( uint_fast64_t i = lastRow + 1 ; i < rowCount ; + + i ) {
rowIndications [ i ] = currentSize ;
rowIndications [ i ] = currentEntryCount ;
}
// Set a sentinel element at the last position of the row_indications array. This eases iteration work, as
// now the indices of row i are always between rowIndications[i] and rowIndications[i + 1], also for the
// first and last row.
if ( pushSentinelElement ) {
rowIndications . push_back ( nonZeroEntryCount ) ;
} else {
rowIndications [ rowCount ] = nonZeroEntryCount ;
}
setState ( MatrixStatus : : ReadReady ) ;
}
}
template < typename T >
inline bool SparseMatrix < T > : : getValue ( uint_fast64_t row , uint_fast64_t col , T * const target ) const {
// Check for illegal access indices.
if ( ( row > rowCount ) | | ( col > colCount ) ) {
LOG4CPLUS_ERROR ( logger , " Trying to read a value from illegal position ( " < < row < < " , " < < col < < " ). " ) ;
throw storm : : exceptions : : OutOfRangeException ( " Trying to read a value from illegal position. " ) ;
return false ;
}
// In case the element is not on the diagonal, we have to iterate
// over the accessed row to find the element.
uint_fast64_t rowStart = rowIndications [ row ] ;
uint_fast64_t rowEnd = rowIndications [ row + 1 ] ;
while ( rowStart < rowEnd ) {
// If the lement is found, write the content to the specified
// position and return true.
if ( columnIndications [ rowStart ] = = col ) {
* target = valueStorage [ rowStart ] ;
return true ;
}
// If the column of the current element is already larger than the
// requested column, the requested element cannot be contained
// in the matrix and we may therefore stop searching.
if ( columnIndications [ rowStart ] > col ) {
break ;
}
+ + rowStart ;
}
// Set 0 as the content and return false in case the element was not found.
* target = 0 ;
return false ;
for ( uint_fast64_t i = lastRow + 1 ; i < rowCount ; + + i ) {
rowIndications . push_back ( currentEntryCount ) ;
}
template < typename T >
inline T & SparseMatrix < T > : : getValue ( uint_fast64_t row , uint_fast64_t col ) {
// Check for illegal access indices.
if ( ( row > rowCount ) | | ( col > colCount ) ) {
LOG4CPLUS_ERROR ( logger , " Trying to read a value from illegal position ( " < < row < < " , " < < col < < " ). " ) ;
throw storm : : exceptions : : OutOfRangeException ( " Trying to read a value from illegal position. " ) ;
}
// we have to iterate
// over the accessed row to find the element.
uint_fast64_t rowStart = rowIndications [ row ] ;
uint_fast64_t rowEnd = rowIndications [ row + 1 ] ;
while ( rowStart < rowEnd ) {
// If the lement is found, return it.
if ( columnIndications [ rowStart ] = = col ) {
return valueStorage [ rowStart ] ;
// We put a sentinel element at the last position of the row indices array. This eases iteration work,
// as now the indices of row i are always between rowIndications[i] and rowIndications[i + 1], also for
// the first and last row.
if ( storagePreallocated ) {
rowIndications [ rowCount ] = entryCount ;
} else {
rowIndications . push_back ( entryCount ) ;
}
// If the column of the current element is already larger than the
// requested column, the requested element cannot be contained
// in the matrix and we may therefore stop searching.
if ( columnIndications [ rowStart ] > col ) {
break ;
internalStatus = INITIALIZED ;
}
+ + rowStart ;
}
throw storm : : exceptions : : InvalidArgumentException ( " Trying to get a reference to a non-existant value. " ) ;
}
template < typename T >
@ -373,86 +245,60 @@ namespace storage {
template < typename T >
uint_fast64_t SparseMatrix < T > : : getColumnCount ( ) const {
return colCount ;
}
template < typename T >
bool SparseMatrix < T > : : isReadReady ( ) {
return ( internalStatus = = MatrixStatus : : ReadReady ) ;
return columnCount ;
}
template < typename T >
bool SparseMatrix < T > : : isInitialized ( ) {
return ( internalStatus = = MatrixStatus : : Initialized | | internalStatus = = MatrixStatus : : ReadReady ) ;
return internalStatus = = INITIALIZED ;
}
template < typename T >
typename SparseMatrix < T > : : MatrixStatus SparseMatrix < T > : : getState ( ) {
return internalStatus ;
uint_fast64_t SparseMatrix < T > : : getEntryCount ( ) const {
return entryCount ;
}
template < typename T >
bool SparseMatrix < T > : : hasError ( ) const {
return ( internalStatus = = MatrixStatus : : Error ) ;
}
template < typename T >
uint_fast64_t SparseMatrix < T > : : getNonZeroEntryCount ( ) const {
return nonZeroEntryCount ;
}
template < typename T >
bool SparseMatrix < T > : : makeRowsAbsorbing ( storm : : storage : : BitVector const & rows ) {
bool result = true ;
void SparseMatrix < T > : : makeRowsAbsorbing ( storm : : storage : : BitVector const & rows ) {
for ( auto row : rows ) {
result & = makeRowAbsorbing ( row , row ) ;
makeRowAbsorbing ( row , row ) ;
}
return result ;
}
template < typename T >
bool SparseMatrix < T > : : makeRowsAbsorbing ( storm : : storage : : BitVector const & rowGroupConstraint , std : : vector < uint_fast64_t > const & rowGroupIndices ) {
bool result = true ;
void SparseMatrix < T > : : makeRowsAbsorbing ( storm : : storage : : BitVector const & rowGroupConstraint , std : : vector < uint_fast64_t > const & rowGroupIndices ) {
for ( auto rowGroup : rowGroupConstraint ) {
for ( uint_fast64_t row = rowGroupIndices [ rowGroup ] ; row < rowGroupIndices [ rowGroup + 1 ] ; + + row ) {
result & = makeRowAbsorbing ( row , rowGroup ) ;
makeRowAbsorbing ( row , rowGroup ) ;
}
}
return result ;
}
template < typename T >
bool SparseMatrix < T > : : makeRowAbsorbing ( const uint_fast64_t row , const uint_fast64_t column ) {
// Check whether the accessed state exists.
void SparseMatrix < T > : : makeRowAbsorbing ( const uint_fast64_t row , const uint_fast64_t column ) {
if ( row > rowCount ) {
LOG4CPLUS_ERROR ( logger , " Trying to make an illegal row " < < row < < " absorbing. " ) ;
throw storm : : exceptions : : OutOfRangeException ( ) < < " Trying to make an illegal row " < < row < < " absorbing. " ;
return false ;
throw storm : : exceptions : : OutOfRangeException ( ) < < " Illegal call to SparseMatrix::makeRowAbsorbing: access to row " < < row < < " is out of bounds. " ;
}
// Iterate over the elements in the row that are not on the diagonal
// and set them to zero.
uint_fast64_t rowStart = rowIndications [ row ] ;
uint_fast64_t rowEnd = rowIndications [ row + 1 ] ;
// Iterate over the elements in the row that are not on the diagonal and set them to zero.
T * valuePtr = valueStorage . data ( ) + rowIndications [ row ] ;
T * valuePtrEnd = valueStorage . data ( ) + rowIndications [ row + 1 ] ;
uint_fast64_t * columnPtr = columnIndications . data ( ) + rowIndications [ row ] ;
// If the row has no elements in it, we cannot make it absorbing, because we would need to
// move all elements in the vector of nonzeros otherwise.
if ( rowStart > = rowEnd ) {
LOG4CPLUS_ERROR ( logger , " Cannot make row " < < row < < " absorbing, because there is no entry in this row. " ) ;
throw storm : : exceptions : : InvalidStateException ( ) < < " Cannot make row " < < row < < " absorbing, because there is no entry in this row. " ;
// If the row has no elements in it, we cannot make it absorbing, because we would need to move all elements
// in the vector of nonzeros otherwise.
if ( valuePtr > = valuePtrEnd ) {
throw storm : : exceptions : : InvalidStateException ( ) < < " Illegal call to SparseMatrix::makeRowAbsorbing: cannot make row " < < row < < " absorbing, but there is no entry in this row. " ;
}
// If there is at least one nonzero entry in this row, we can just set it to one, modify its
// column indication to the one given by the parameter and set all subsequent elements of this
// row to zero.
valueStorage [ rowStart ] = storm : : utility : : constantOne < T > ( ) ;
columnIndications [ rowStart ] = column ;
for ( uint_fast64_t index = rowStart + 1 ; index < rowEnd ; + + index ) {
valueStorage [ index ] = storm : : utility : : constantZero < T > ( ) ;
columnIndications [ index ] = 0 ;
// If there is at least one entry in this row, we can just set it to one, modify its column value to the
// one given by the parameter and set all subsequent elements of this row to zero.
* valuePtr = storm : : utility : : constantOne < T > ( ) ;
* columnPtr = column ;
for ( ; valuePtr ! = valuePtrEnd ; + + valuePtr ) {
* valuePtr = storm : : utility : : constantZero < T > ( ) ;
* columnPtr = 0 ;
}
return true ;
}
template < typename T >
@ -1136,7 +982,7 @@ namespace storage {
# endif
} // namespace storage
} // namespace storage
} // namespace storm