@ -533,7 +533,7 @@ namespace storm {
}
template < DdType LibraryType , typename ValueType >
std : : vector < ValueType > Add < LibraryType , ValueType > : : toVector ( storm : : dd : : Add < LibraryType , ValueType > const & matrix , std : : vector < uint_fast64_t > const & rowGroupIndices , std : : set < storm : : expressions : : Variable > const & rowMetaVariables , std : : set < storm : : expressions : : Variable > const & columnMetaVariables , std : : set < storm : : expressions : : Variable > const & groupMetaVariables , storm : : dd : : Odd const & rowOdd , storm : : dd : : Odd const & columnOdd ) const {
std : : vector < ValueType > Add < LibraryType , ValueType > : : toVector ( storm : : dd : : Add < LibraryType , ValueType > const & matrix , std : : vector < uint_fast64_t > const & rowGroupIndices , std : : set < storm : : expressions : : Variable > const & rowMetaVariables , std : : set < storm : : expressions : : Variable > const & columnMetaVariables , std : : set < storm : : expressions : : Variable > const & groupMetaVariables , storm : : dd : : Odd const & rowOdd ) const {
std : : vector < uint_fast64_t > ddRowVariableIndices ;
std : : vector < uint_fast64_t > ddColumnVariableIndices ;
std : : vector < uint_fast64_t > ddGroupVariableIndices ;
@ -894,6 +894,38 @@ namespace storm {
template < DdType LibraryType , typename ValueType >
std : : pair < storm : : storage : : SparseMatrix < ValueType > , std : : vector < ValueType > > Add < LibraryType , ValueType > : : toMatrixVector ( std : : vector < uint_fast64_t > & & rowGroupIndices , storm : : dd : : Add < LibraryType , ValueType > const & vector , std : : set < storm : : expressions : : Variable > const & rowMetaVariables , std : : set < storm : : expressions : : Variable > const & columnMetaVariables , std : : set < storm : : expressions : : Variable > const & groupMetaVariables , storm : : dd : : Odd const & rowOdd , storm : : dd : : Odd const & columnOdd ) const {
auto resultAsVector = toMatrixVectors ( std : : move ( rowGroupIndices ) , { vector } , rowMetaVariables , columnMetaVariables , groupMetaVariables , rowOdd , columnOdd ) ;
return std : : make_pair ( resultAsVector . first , resultAsVector . second . front ( ) ) ;
}
template < DdType LibraryType , typename ValueType >
std : : pair < storm : : storage : : SparseMatrix < ValueType > , std : : vector < std : : vector < ValueType > > > Add < LibraryType , ValueType > : : toMatrixVectors ( std : : vector < storm : : dd : : Add < LibraryType , ValueType > > const & vectors , std : : set < storm : : expressions : : Variable > const & groupMetaVariables , storm : : dd : : Odd const & rowOdd , storm : : dd : : Odd const & columnOdd ) const {
std : : set < storm : : expressions : : Variable > rowMetaVariables ;
std : : set < storm : : expressions : : Variable > columnMetaVariables ;
for ( auto const & variable : this - > getContainedMetaVariables ( ) ) {
// If the meta variable is a group meta variable, we do not insert it into the set of row/column meta variables.
if ( groupMetaVariables . find ( variable ) ! = groupMetaVariables . end ( ) ) {
continue ;
}
if ( variable . getName ( ) . size ( ) > 0 & & variable . getName ( ) . back ( ) = = ' \' ' ) {
columnMetaVariables . insert ( variable ) ;
} else {
rowMetaVariables . insert ( variable ) ;
}
}
// Count how many choices each row group has.
Bdd < LibraryType > vectorsNotZero = this - > getDdManager ( ) . getBddZero ( ) ;
for ( auto const & v : vectors ) {
vectorsNotZero | = v . notZero ( ) ;
}
std : : vector < uint_fast64_t > rowGroupIndices = ( this - > notZero ( ) . existsAbstract ( columnMetaVariables ) | | vectorsNotZero ) . template toAdd < uint_fast64_t > ( ) . sumAbstract ( groupMetaVariables ) . toVector ( rowOdd ) ;
return toMatrixVectors ( std : : move ( rowGroupIndices ) , vectors , rowMetaVariables , columnMetaVariables , groupMetaVariables , rowOdd , columnOdd ) ;
}
template < DdType LibraryType , typename ValueType >
std : : pair < storm : : storage : : SparseMatrix < ValueType > , std : : vector < std : : vector < ValueType > > > Add < LibraryType , ValueType > : : toMatrixVectors ( std : : vector < uint_fast64_t > & & rowGroupIndices , std : : vector < storm : : dd : : Add < LibraryType , ValueType > > const & vectors , std : : set < storm : : expressions : : Variable > const & rowMetaVariables , std : : set < storm : : expressions : : Variable > const & columnMetaVariables , std : : set < storm : : expressions : : Variable > const & groupMetaVariables , storm : : dd : : Odd const & rowOdd , storm : : dd : : Odd const & columnOdd ) const {
std : : vector < uint_fast64_t > ddRowVariableIndices ;
std : : vector < uint_fast64_t > ddColumnVariableIndices ;
std : : vector < uint_fast64_t > ddGroupVariableIndices ;
@ -936,14 +968,36 @@ namespace storm {
}
rowGroupIndices [ 0 ] = 0 ;
// Create the explicit vector we need to fill later.
std : : vector < ValueType > explicitVector ( rowGroupIndices . back ( ) ) ;
// Create the explicit vectors we need to fill later.
std : : vector < std : : vector < ValueType > > explicitVectors ( vectors . size ( ) ) ;
for ( auto & v : explicitVectors ) {
v . resize ( rowGroupIndices . back ( ) ) ;
}
// Next, we split the matrix into one for each group. Note that this only works if the group variables are at the very top.
std : : vector < std : : pair < InternalAdd < LibraryType , ValueType > , InternalAdd < LibraryType , ValueType > > > internalAddGroups = internalAdd . splitIntoGroups ( vector , ddGroupVariableIndices ) ;
std : : vector < std : : pair < Add < LibraryType , ValueType > , Add < LibraryType , ValueType > > > groups ;
std : : vector < std : : vector < Add < LibraryType , ValueType > > > groups ;
if ( vectors . size ( ) = = 1 ) {
// This version potentially has slightly reduced overhead
std : : vector < std : : pair < InternalAdd < LibraryType , ValueType > , InternalAdd < LibraryType , ValueType > > > internalAddGroups = internalAdd . splitIntoGroups ( vectors . front ( ) , ddGroupVariableIndices ) ;
for ( auto const & internalAdd : internalAddGroups ) {
groups . push_back ( std : : make_pair ( Add < LibraryType , ValueType > ( this - > getDdManager ( ) , internalAdd . first , rowAndColumnMetaVariables ) , Add < LibraryType , ValueType > ( this - > getDdManager ( ) , internalAdd . second , rowMetaVariables ) ) ) ;
groups . push_back ( { Add < LibraryType , ValueType > ( this - > getDdManager ( ) , internalAdd . second , rowMetaVariables ) , Add < LibraryType , ValueType > ( this - > getDdManager ( ) , internalAdd . first , rowAndColumnMetaVariables ) } ) ;
}
} else {
std : : vector < InternalAdd < LibraryType , ValueType > > internalVectors ;
for ( Add < LibraryType , ValueType > const & v : vectors ) {
internalVectors . push_back ( v . getInternalAdd ( ) ) ;
}
std : : vector < std : : vector < InternalAdd < LibraryType , ValueType > > > internalAddGroups = internalAdd . splitIntoGroups ( internalVectors , ddGroupVariableIndices ) ;
for ( auto const & internalAddGroup : internalAddGroups ) {
STORM_LOG_ASSERT ( internalAddGroup . size ( ) = = vectors . size ( ) + 1 , " Unexpected group size. " ) ;
std : : vector < Add < LibraryType , ValueType > > group ;
for ( uint64_t vectorIndex = 0 ; vectorIndex < vectors . size ( ) ; + + vectorIndex ) {
group . push_back ( Add < LibraryType , ValueType > ( this - > getDdManager ( ) , internalAddGroup [ vectorIndex ] , rowMetaVariables ) ) ;
}
// The last group member corresponds to the matrix.
group . push_back ( Add < LibraryType , ValueType > ( this - > getDdManager ( ) , internalAddGroup . back ( ) , rowAndColumnMetaVariables ) ) ;
groups . push_back ( std : : move ( group ) ) ;
}
}
// Create the actual storage for the non-zero entries.
@ -955,16 +1009,19 @@ namespace storm {
std : : vector < InternalAdd < LibraryType , uint_fast64_t > > statesWithGroupEnabled ( groups . size ( ) ) ;
InternalAdd < LibraryType , uint_fast64_t > stateToRowGroupCount = this - > getDdManager ( ) . template getAddZero < uint_fast64_t > ( ) ;
for ( uint_fast64_t i = 0 ; i < groups . size ( ) ; + + i ) {
std : : pair < Add < LibraryType , ValueType > , Add < LibraryType , ValueType > > const & ddPair = groups [ i ] ;
Bdd < LibraryType > matrixDdNotZero = ddPair . first . notZero ( ) ;
Bdd < LibraryType > vectorDdNotZero = ddPair . second . notZero ( ) ;
std : : vector < Add < LibraryType , ValueType > > const & group = groups [ i ] ;
Bdd < LibraryType > matrixDdNotZero = group . back ( ) . notZero ( ) ;
std : : vector < uint64_t > tmpRowIndications = matrixDdNotZero . template toAdd < uint_fast64_t > ( ) . sumAbstract ( columnMetaVariables ) . toVector ( rowOdd ) ;
for ( uint64_t offset = 0 ; offset < tmpRowIndications . size ( ) ; + + offset ) {
rowIndications [ rowGroupIndices [ offset ] ] + = tmpRowIndications [ offset ] ;
}
ddPair . second . internalAdd . composeWithExplicitVector ( rowOdd , ddRowVariableIndices , rowGroupIndices , explicitVector , std : : plus < ValueType > ( ) ) ;
Bdd < LibraryType > vectorDdNotZero = this - > getDdManager ( ) . getBddZero ( ) ;
for ( uint64_t vectorIndex = 0 ; vectorIndex < vectors . size ( ) ; + + vectorIndex ) {
vectorDdNotZero | = group [ vectorIndex ] . notZero ( ) ;
group [ vectorIndex ] . internalAdd . composeWithExplicitVector ( rowOdd , ddRowVariableIndices , rowGroupIndices , explicitVectors [ vectorIndex ] , std : : plus < ValueType > ( ) ) ;
}
statesWithGroupEnabled [ i ] = ( matrixDdNotZero . existsAbstract ( columnMetaVariables ) | | vectorDdNotZero ) . template toAdd < uint_fast64_t > ( ) ;
stateToRowGroupCount + = statesWithGroupEnabled [ i ] ;
@ -986,7 +1043,7 @@ namespace storm {
// Now actually fill the entry vector.
for ( uint_fast64_t i = 0 ; i < groups . size ( ) ; + + i ) {
auto const & dd = groups [ i ] . first ;
auto const & dd = groups [ i ] . back ( ) ;
dd . internalAdd . toMatrixComponents ( rowGroupIndices , rowIndications , columnsAndValues , rowOdd , columnOdd , ddRowVariableIndices , ddColumnVariableIndices , true ) ;
statesWithGroupEnabled [ i ] . composeWithExplicitVector ( rowOdd , ddRowVariableIndices , rowGroupIndices , std : : plus < uint_fast64_t > ( ) ) ;
@ -1001,10 +1058,11 @@ namespace storm {
}
rowIndications [ 0 ] = 0 ;
return std : : make_pair ( storm : : storage : : SparseMatrix < ValueType > ( columnOdd . getTotalOffset ( ) , std : : move ( rowIndications ) , std : : move ( columnsAndValues ) , std : : move ( rowGroupIndices ) ) , std : : move ( explicitVector ) ) ;
return std : : make_pair ( storm : : storage : : SparseMatrix < ValueType > ( columnOdd . getTotalOffset ( ) , std : : move ( rowIndications ) , std : : move ( columnsAndValues ) , std : : move ( rowGroupIndices ) ) , std : : move ( explicitVectors ) ) ;
}
template < DdType LibraryType , typename ValueType >
void Add < LibraryType , ValueType > : : exportToDot ( std : : string const & filename , bool showVariablesIfPossible ) const {
internalAdd . exportToDot ( filename , this - > getDdManager ( ) . getDdVariableNames ( ) , showVariablesIfPossible ) ;