@ -7,6 +7,11 @@ 
			
		
	
		
			
				
					# include  "src/utility/graph.h" 
  
			
		
	
		
			
				
					# include  "src/models/PseudoModel.h" 
  
			
		
	
		
			
				
					# include  "src/storage/StronglyConnectedComponentDecomposition.h" 
  
			
		
	
		
			
				
					# include  "src/exceptions/IllegalArgumentException.h" 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "log4cplus/logger.h" 
  
			
		
	
		
			
				
					# include  "log4cplus/loggingmacros.h" 
  
			
		
	
		
			
				
					extern  log4cplus : : Logger  logger ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					namespace  storm  {  
			
		
	
		
			
				
					    namespace  solver  {  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -39,11 +44,29 @@ namespace storm { 
			
		
	
		
			
				
								//std::vector<std::vector<uint_fast64_t>> stronglyConnectedComponents = storm::utility::graph::performSccDecomposition(this->getModel(), stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph);
  
			
		
	
		
			
				
								//storm::storage::SparseMatrix<T> stronglyConnectedComponentsDependencyGraph = this->getModel().extractSccDependencyGraph(stronglyConnectedComponents);
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								std : : cout  < <  " TopoSolver Input Matrix:  "  < <  A . getRowCount ( )  < <  "  x  "  < <  A . getColumnCount ( )  < <  "  with  "  < <  A . getEntryCount ( )  < <  "  Entries: "  < <  std : : endl ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								uint_fast64_t  const  rowCount  =  A . getRowCount ( ) ;  
			
		
	
		
			
				
								for  ( uint_fast64_t  row  =  0 ;  row  <  rowCount ;  + + row )  {  
			
		
	
		
			
				
									std : : cout  < <  " Row  "  < <  row  < <  " :  " ;  
			
		
	
		
			
				
									auto  const &  rowElement  =  A . getRow ( row ) ;  
			
		
	
		
			
				
									for  ( auto  rowIt  =  rowElement . begin ( ) ;  rowIt  ! =  rowElement . end ( ) ;  + + rowIt )  {  
			
		
	
		
			
				
										std : : cout  < <  rowIt - > first  < <  "  [ "  < <  rowIt - > second  < <  " ],  " ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
									std : : cout  < <  std : : endl ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								storm : : models : : NonDeterministicMatrixBasedPseudoModel < ValueType >  pseudoModel ( A ,  nondeterministicChoiceIndices ) ;  
			
		
	
		
			
				
								storm : : storage : : StronglyConnectedComponentDecomposition < ValueType >  sccDecomposition ( * static_cast < storm : : models : : AbstractPseudoModel < ValueType > * > ( & pseudoModel ) ,  false ,  false ) ;  
			
		
	
		
			
				
								storm : : storage : : SparseMatrix < ValueType >  stronglyConnectedComponentsDependencyGraph  =  pseudoModel . extractPartitionDependencyGraph ( sccDecomposition ) ;  
			
		
	
		
			
				
								 
			
		
	
		
			
				
								//storm::storage::StronglyConnectedComponentDecomposition<ValueType> sccDecomposition(*static_cast<storm::models::AbstractPseudoModel<ValueType>*>(&pseudoModel), false, false);
  
			
		
	
		
			
				
								storm : : storage : : StronglyConnectedComponentDecomposition < ValueType >  sccDecomposition ( pseudoModel ,  false ,  false ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								if  ( sccDecomposition . size ( )  = =  0 )  {  
			
		
	
		
			
				
									LOG4CPLUS_ERROR ( logger ,  " Can not solve given Equation System as the SCC Decomposition returned no SCCs. " ) ;  
			
		
	
		
			
				
									throw  storm : : exceptions : : IllegalArgumentException ( )  < <  " Can not solve given Equation System as the SCC Decomposition returned no SCCs. " ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								storm : : storage : : SparseMatrix < ValueType >  stronglyConnectedComponentsDependencyGraph  =  pseudoModel . extractPartitionDependencyGraph ( sccDecomposition ) ;  
			
		
	
		
			
				
								std : : vector < uint_fast64_t >  topologicalSort  =  storm : : utility : : graph : : getTopologicalSort ( stronglyConnectedComponentsDependencyGraph ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								// Set up the environment for the power method.
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -52,12 +75,12 @@ namespace storm { 
			
		
	
		
			
				
									multiplyResult  =  new  std : : vector < ValueType > ( A . getRowCount ( ) ) ;  
			
		
	
		
			
				
									multiplyResultMemoryProvided  =  false ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								std : : vector < ValueType > *  currentX  =  & x ;  
			
		
	
		
			
				
								bool  xMemoryProvided  =  true ;  
			
		
	
		
			
				
								if  ( newX  = =  nullptr )  {  
			
		
	
		
			
				
									newX  =  new  std : : vector < ValueType > ( x . size ( ) ) ;   
			
		
	
		
			
				
									xMemoryProvided  =  false ;   
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								std : : vector < ValueType > *  currentX  =  nullptr ;  
			
		
	
		
			
				
								//bool xMemoryProvided = true;
  
			
		
	
		
			
				
								//if (newX == nullptr) {
  
			
		
	
		
			
				
								//	newX = new std::vector<ValueType>(x.size());
  
			
		
	
		
			
				
								//	xMemoryProvided = false;
  
			
		
	
		
			
				
								//}
  
			
		
	
		
			
				
								std : : vector < ValueType > *  swap  =  nullptr ;  
			
		
	
		
			
				
								uint_fast64_t  currentMaxLocalIterations  =  0 ;  
			
		
	
		
			
				
								uint_fast64_t  localIterations  =  0 ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -68,20 +91,62 @@ namespace storm { 
			
		
	
		
			
				
								// solved after all SCCs it depends on have been solved.
  
			
		
	
		
			
				
								int  counter  =  0 ;  
			
		
	
		
			
				
								std : : cout  < <  " Solving Equation System using the TopologicalValueIterationNon... "  < <  std : : endl ;  
			
		
	
		
			
				
								std : : cout  < <  " Found  "  < <  sccDecomposition . size ( )  < <  "  SCCs. "  < <  std : : endl ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								for  ( auto  sccIndexIt  =  topologicalSort . begin ( ) ;  sccIndexIt  ! =  topologicalSort . end ( )  & &  converged ;  + + sccIndexIt )  {  
			
		
	
		
			
				
									storm : : storage : : StateBlock  const &  scc  =  sccDecomposition [ * sccIndexIt ] ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									std : : cout  < <  " SCC  "  < <  counter  < <  "  contains: "  < <  std : : endl ;  
			
		
	
		
			
				
									for  ( auto  sccIt  =  scc . cbegin ( ) ;  sccIt  ! =  scc . cend ( ) ;  + + sccIt )  {  
			
		
	
		
			
				
										std : : cout  < <  * sccIt  < <  " ,  " ;  
			
		
	
		
			
				
									std : : cout  < <  " SCC  "  < <  counter  < <  "  from Index  "  < <  * sccIndexIt  < <  "  contains: "  < <  std : : endl ;  
			
		
	
		
			
				
									+ + counter ;  
			
		
	
		
			
				
									for  ( auto  state  :  scc )  {  
			
		
	
		
			
				
										std : : cout  < <  state  < <  " ,  " ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
									std : : cout  < <  std : : endl ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									// Generate a submatrix
  
			
		
	
		
			
				
									storm : : storage : : BitVector  subMatrixIndices ( rowCount ,  scc . cbegin ( ) ,  scc . cend ( ) ) ;  
			
		
	
		
			
				
									storm : : storage : : SparseMatrix < ValueType >  sccSubmatrix  =  A . getSubmatrix ( subMatrixIndices ,  nondeterministicChoiceIndices ,  true ) ;  
			
		
	
		
			
				
									std : : vector < ValueType >  sccSubB ( sccSubmatrix . getRowCount ( ) ) ;  
			
		
	
		
			
				
									storm : : utility : : vector : : selectVectorValues < ValueType > ( sccSubB ,  subMatrixIndices ,  nondeterministicChoiceIndices ,  b ) ;  
			
		
	
		
			
				
									std : : vector < ValueType >  sccSubX ( sccSubmatrix . getColumnCount ( ) ) ;  
			
		
	
		
			
				
									std : : vector < ValueType >  sccSubXSwap ( sccSubmatrix . getColumnCount ( ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									// Prepare the pointers for swapping in the calculation
  
			
		
	
		
			
				
									currentX  =  & sccSubX ;  
			
		
	
		
			
				
									swap  =  & sccSubXSwap ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									storm : : utility : : vector : : selectVectorValues < ValueType > ( sccSubX ,  subMatrixIndices ,  x ) ;  // x is getCols() large, where as b and multiplyResult are getRows() (nondet. choices times states)
  
			
		
	
		
			
				
									std : : vector < uint_fast64_t >  sccSubNondeterministicChoiceIndices ( sccSubmatrix . getColumnCount ( )  +  1 ) ;  
			
		
	
		
			
				
									sccSubNondeterministicChoiceIndices . at ( 0 )  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									// Preprocess all dependant states
  
			
		
	
		
			
				
									// Remove outgoing transitions and create the ChoiceIndices
  
			
		
	
		
			
				
									uint_fast64_t  innerIndex  =  0 ;  
			
		
	
		
			
				
									for  ( uint_fast64_t  state :  scc )  {  
			
		
	
		
			
				
										// Choice Indices
  
			
		
	
		
			
				
										sccSubNondeterministicChoiceIndices . at ( innerIndex  +  1 )  =  sccSubNondeterministicChoiceIndices . at ( innerIndex )  +  ( nondeterministicChoiceIndices [ state  +  1 ]  -  nondeterministicChoiceIndices [ state ] ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										for  ( auto  rowGroupIt  =  nondeterministicChoiceIndices [ state ] ;  rowGroupIt  ! =  nondeterministicChoiceIndices [ state  +  1 ] ;  + + rowGroupIt )  {  
			
		
	
		
			
				
											storm : : storage : : SparseMatrix < ValueType > : : const_rows  row  =  A . getRow ( rowGroupIt ) ;  
			
		
	
		
			
				
											for  ( auto  rowIt  =  row . begin ( ) ;  rowIt  ! =  row . end ( ) ;  + + rowIt )  {  
			
		
	
		
			
				
												if  ( ! subMatrixIndices . get ( rowIt - > first ) )  {  
			
		
	
		
			
				
													// This is an outgoing transition of a state in the SCC to a state not included in the SCC
  
			
		
	
		
			
				
													// Subtracting Pr(tau) * x_other from b fixes that
  
			
		
	
		
			
				
													sccSubB . at ( innerIndex )  =  sccSubB . at ( innerIndex )  -  ( rowIt - > second  *  x . at ( rowIt - > first ) ) ;  
			
		
	
		
			
				
												}  
			
		
	
		
			
				
											}  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
										+ + innerIndex ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									// For the current SCC, we need to perform value iteration until convergence.
  
			
		
	
		
			
				
									localIterations  =  0 ;  
			
		
	
		
			
				
									converged  =  false ;  
			
		
	
		
			
				
									while  ( ! converged  & &  localIterations  <  this - > maximalNumberOfIterations )  {  
			
		
	
		
			
				
										// Compute x' = A*x + b.
  
			
		
	
		
			
				
										sccSubmatrix . multiplyWithVector ( * currentX ,  * multiplyResult ) ;  
			
		
	
		
			
				
										storm : : utility : : vector : : addVectorsInPlace < ValueType > ( * multiplyResult ,  sccSubB ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										//A.multiplyWithVector(scc, nondeterministicChoiceIndices, *currentX, multiplyResult);
  
			
		
	
		
			
				
										//storm::utility::addVectors(scc, nondeterministicChoiceIndices, multiplyResult, b);
  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -93,43 +158,46 @@ namespace storm { 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										// Reduce the vector x' by applying min/max for all non-deterministic choices.
  
			
		
	
		
			
				
										if  ( minimize )  {  
			
		
	
		
			
				
											//storm::utility::reduceVectorMin(*multiplyResult, *newX, scc, nondeterministicChoiceIndices);
  
			
		
	
		
			
				
											storm : : utility : : vector : : reduceVectorMin < ValueType > ( * multiplyResult ,  * swap ,  sccSubNondeterministicChoiceIndices ) ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
										else  {  
			
		
	
		
			
				
											//storm::utility::reduceVectorMax(*multiplyResult, *newX, scc, nondeterministicChoiceIndices);
  
			
		
	
		
			
				
											storm : : utility : : vector : : reduceVectorMax < ValueType > ( * multiplyResult ,  * swap ,  sccSubNondeterministicChoiceIndices ) ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										// Determine whether the method converged.
  
			
		
	
		
			
				
										// TODO: It seems that the equalModuloPrecision call that compares all values should have a higher
  
			
		
	
		
			
				
										// running time. In fact, it is faster. This has to be investigated.
  
			
		
	
		
			
				
										// converged = storm::utility::equalModuloPrecision(*currentX, *newX, scc, precision, relative);
  
			
		
	
		
			
				
										converged  =  storm : : utility : : vector : : equalModuloPrecision < ValueType > ( * currentX ,  * newX ,  this - > precision ,  this - > relative ) ;  
			
		
	
		
			
				
										converged  =  storm : : utility : : vector : : equalModuloPrecision < ValueType > ( * currentX ,  * swap ,  this - > precision ,  this - > relative ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										// Update environment variables.
  
			
		
	
		
			
				
										swap  =  currentX ;  
			
		
	
		
			
				
										currentX  =  newX ;  
			
		
	
		
			
				
										newX  =  swap ;  
			
		
	
		
			
				
										std : : swap ( currentX ,  swap ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
										+ + localIterations ;  
			
		
	
		
			
				
										+ + globalIterations ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									// The Result of this SCC has to be taken back into the main result vector
  
			
		
	
		
			
				
									innerIndex  =  0 ;  
			
		
	
		
			
				
									for  ( uint_fast64_t  state :  scc )  {  
			
		
	
		
			
				
										x . at ( state )  =  currentX - > at ( innerIndex ) ;  
			
		
	
		
			
				
										+ + innerIndex ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									// Since the pointers for swapping in the calculation point to temps they should not be valide anymore
  
			
		
	
		
			
				
									currentX  =  nullptr ;  
			
		
	
		
			
				
									swap  =  nullptr ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									// As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep
  
			
		
	
		
			
				
									// track of the maximum.
  
			
		
	
		
			
				
									if  ( localIterations  >  currentMaxLocalIterations )  {  
			
		
	
		
			
				
										currentMaxLocalIterations  =  localIterations ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								// If we performed an odd number of global iterations, we need to swap the x and currentX, because the newest
  
			
		
	
		
			
				
								// result is currently stored in currentX, but x is the output vector.
  
			
		
	
		
			
				
								// TODO: Check whether this is correct or should be put into the for-loop over SCCs.
  
			
		
	
		
			
				
								if  ( globalIterations  %  2  = =  1 )  {  
			
		
	
		
			
				
									std : : swap ( x ,  * currentX ) ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								 
			
		
	
		
			
				
								if  ( ! xMemoryProvided )  {  
			
		
	
		
			
				
									delete  newX ;   
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								//if (!xMemoryProvided) {
  
			
		
	
		
			
				
								//	delete newX;
  
			
		
	
		
			
				
								//}
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								if  ( ! multiplyResultMemoryProvided )  {  
			
		
	
		
			
				
									delete  multiplyResult ;