@ -555,6 +555,99 @@ namespace storm { 
			
		
	
		
			
				
					            return  converged ;  
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					         
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        template < typename  ValueType >  
			
		
	
		
			
				
					        bool  NativeLinearEquationSolver < ValueType > : : solveEquationsQuickSoundPower ( Environment  const &  env ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
			
		
	
		
			
				
					            STORM_LOG_INFO ( " Solving linear equation system ( "  < <  x . size ( )  < <  "  rows) with NativeLinearEquationSolver (QuickPower) " ) ;  
			
		
	
		
			
				
					            // Prepare the solution vectors.
  
			
		
	
		
			
				
					            if  ( ! this - > cachedRowVector )  {  
			
		
	
		
			
				
					                this - > cachedRowVector  =  std : : make_unique < std : : vector < ValueType > > ( getMatrixRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					            }  else  {  
			
		
	
		
			
				
					                this - > cachedRowVector - > assign ( getMatrixRowCount ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            if  ( ! this - > cachedRowVector2 )  {  
			
		
	
		
			
				
					                this - > cachedRowVector2  =  std : : make_unique < std : : vector < ValueType > > ( getMatrixRowCount ( ) ,  storm : : utility : : one < ValueType > ( ) ) ;  
			
		
	
		
			
				
					            }  else  {  
			
		
	
		
			
				
					                this - > cachedRowVector2 - > assign ( getMatrixRowCount ( ) ,  storm : : utility : : one < ValueType > ( ) ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            std : : vector < ValueType > *  stepBoundedValues  =  this - > cachedRowVector . get ( ) ;  
			
		
	
		
			
				
					            std : : vector < ValueType > *  stepBoundedStayProbabilities  =  this - > cachedRowVector2 . get ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            std : : vector < ValueType > *  tmp  =  & x ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            bool  converged  =  false ;  
			
		
	
		
			
				
					            bool  terminate  =  false ;  
			
		
	
		
			
				
					            uint64_t  iterations  =  0 ;  
			
		
	
		
			
				
					            bool  doConvergenceCheck  =  true ;  
			
		
	
		
			
				
					            bool  useDiffs  =  this - > hasRelevantValues ( ) ;  
			
		
	
		
			
				
					            ValueType  precision  =  storm : : utility : : convertNumber < ValueType > ( env . solver ( ) . native ( ) . getPrecision ( ) ) ;  
			
		
	
		
			
				
					            ValueType  lowerValueBound ,  upperValueBound ;  
			
		
	
		
			
				
					            bool  relative  =  env . solver ( ) . native ( ) . getRelativeTerminationCriterion ( ) ;  
			
		
	
		
			
				
					            if  ( ! relative )  {  
			
		
	
		
			
				
					                precision  * =  storm : : utility : : convertNumber < ValueType > ( 2.0 ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            uint64_t  maxIter  =  env . solver ( ) . native ( ) . getMaximalNumberOfIterations ( ) ;  
			
		
	
		
			
				
					            this - > startMeasureProgress ( ) ;  
			
		
	
		
			
				
					            auto  firstProb1EntryIt  =  stepBoundedStayProbabilities - > begin ( ) ;  
			
		
	
		
			
				
					            while  ( ! converged  & &  ! terminate  & &  iterations  <  maxIter )  {  
			
		
	
		
			
				
					                this - > multiplier . multAdd ( * this - > A ,  * stepBoundedValues ,  & b ,  * tmp ) ;  
			
		
	
		
			
				
					                std : : swap ( tmp ,  stepBoundedValues ) ;  
			
		
	
		
			
				
					                this - > multiplier . multAdd ( * this - > A ,  * stepBoundedStayProbabilities ,  nullptr ,  * tmp ) ;  
			
		
	
		
			
				
					                std : : swap ( tmp ,  stepBoundedStayProbabilities ) ;  
			
		
	
		
			
				
					                for  ( ;  firstProb1EntryIt  ! =  stepBoundedStayProbabilities - > end ( ) ;  + + firstProb1EntryIt )  {  
			
		
	
		
			
				
					                    static_assert ( NumberTraits < ValueType > : : IsExact  | |  std : : is_same < ValueType ,  double > : : value ,  " Considered ValueType not handled. " ) ;  
			
		
	
		
			
				
					                    if  ( NumberTraits < ValueType > : : IsExact )  {  
			
		
	
		
			
				
					                        if  ( storm : : utility : : isOne ( * firstProb1EntryIt ) )  {  
			
		
	
		
			
				
					                            break ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  else  {  
			
		
	
		
			
				
					                        if  ( storm : : utility : : isAlmostOne ( storm : : utility : : convertNumber < double > ( * firstProb1EntryIt ) ) )  {  
			
		
	
		
			
				
					                            break ;  
			
		
	
		
			
				
					                        }  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                if  ( firstProb1EntryIt  = =  stepBoundedStayProbabilities - > end ( ) )  {  
			
		
	
		
			
				
					                    auto  valIt  =  stepBoundedValues - > begin ( ) ;  
			
		
	
		
			
				
					                    auto  valIte  =  stepBoundedValues - > end ( ) ;  
			
		
	
		
			
				
					                    auto  probIt  =  stepBoundedStayProbabilities - > begin ( ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( ! storm : : utility : : isOne ( * probIt ) ,  " Did not expect staying-probability 1 at this point. " ) ;  
			
		
	
		
			
				
					                    lowerValueBound  =  * valIt  /  ( storm : : utility : : one < ValueType > ( )  -  * probIt ) ;  
			
		
	
		
			
				
					                    upperValueBound  =  lowerValueBound ;  
			
		
	
		
			
				
					                    ValueType  largestStayProb  =  * probIt ;  
			
		
	
		
			
				
					                    for  ( ;  valIt  ! =  valIte ;  + + valIt ,  + + probIt )  {  
			
		
	
		
			
				
					                        ValueType  currentBound  =  * valIt  /  ( storm : : utility : : one < ValueType > ( )  -  * probIt ) ;  
			
		
	
		
			
				
					                        lowerValueBound  =  std : : min ( lowerValueBound ,  currentBound ) ;  
			
		
	
		
			
				
					                        upperValueBound  =  std : : max ( upperValueBound ,  currentBound ) ;  
			
		
	
		
			
				
					                        largestStayProb  =  std : : max ( largestStayProb ,  * probIt ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( ! relative ,  " Relative termination criterion not implemented currently. " ) ;  
			
		
	
		
			
				
					                    converged  =  largestStayProb  *  ( upperValueBound  -  lowerValueBound )  <  precision ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                // Potentially show progress.
  
			
		
	
		
			
				
					                this - > showProgressIterative ( iterations ) ;  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                // Set up next iteration.
  
			
		
	
		
			
				
					                + + iterations ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            // Finally set up the solution vector
  
			
		
	
		
			
				
					            ValueType  meanBound  =  ( upperValueBound  -  lowerValueBound )  /  storm : : utility : : convertNumber < ValueType > ( 2.0 ) ;  
			
		
	
		
			
				
					            storm : : utility : : vector : : applyPointwise ( * stepBoundedValues ,  * stepBoundedStayProbabilities ,  x ,  [ & meanBound ]  ( ValueType  const &  v ,  ValueType  const &  p )  {  return  v  +  p  *  meanBound ;  } ) ;  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            if  ( ! this - > isCachingEnabled ( ) )  {  
			
		
	
		
			
				
					                clearCache ( ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            this - > logIterations ( converged ,  terminate ,  iterations ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            return  converged ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        template < typename  ValueType >  
			
		
	
		
			
				
					        bool  NativeLinearEquationSolver < ValueType > : : solveEquationsRationalSearch ( Environment  const &  env ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
			
		
	
		
			
				
					            return  solveEquationsRationalSearchHelper < double > ( env ,  x ,  b ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -828,7 +921,7 @@ namespace storm { 
			
		
	
		
			
				
					                }  else  {  
			
		
	
		
			
				
					                    STORM_LOG_WARN ( " The selected solution method does not guarantee exact results. " ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					            }  else  if  ( env . solver ( ) . isForceSoundness ( )  & &  method  ! =  NativeLinearEquationSolverMethod : : Power  & &  method  ! =  NativeLinearEquationSolverMethod : : RationalSearch )  {  
			
		
	
		
			
				
					            }  else  if  ( env . solver ( ) . isForceSoundness ( )  & &  method  ! =  NativeLinearEquationSolverMethod : : Power  & &  method  ! =  NativeLinearEquationSolverMethod : : RationalSearch  & &  method  ! =  NativeLinearEquationSolverMethod : : QuickPower  )  {  
			
		
	
		
			
				
					                if  ( env . solver ( ) . native ( ) . isMethodSetFromDefault ( ) )  {  
			
		
	
		
			
				
					                    method  =  NativeLinearEquationSolverMethod : : Power ;  
			
		
	
		
			
				
					                    STORM_LOG_INFO ( " Selecting ' "  +  toString ( method )  +  " ' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method. " ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -857,6 +950,8 @@ namespace storm { 
			
		
	
		
			
				
					                    }  else  {  
			
		
	
		
			
				
					                        return  this - > solveEquationsPower ( env ,  x ,  b ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                case  NativeLinearEquationSolverMethod : : QuickPower :  
			
		
	
		
			
				
					                        return  this - > solveEquationsQuickSoundPower ( env ,  x ,  b ) ;  
			
		
	
		
			
				
					                case  NativeLinearEquationSolverMethod : : RationalSearch :  
			
		
	
		
			
				
					                    return  this - > solveEquationsRationalSearch ( env ,  x ,  b ) ;  
			
		
	
		
			
				
					            }  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -921,7 +1016,7 @@ namespace storm { 
			
		
	
		
			
				
					        template < typename  ValueType >  
			
		
	
		
			
				
					        LinearEquationSolverProblemFormat  NativeLinearEquationSolver < ValueType > : : getEquationProblemFormat ( Environment  const &  env )  const  {  
			
		
	
		
			
				
					            auto  method  =  getMethod ( env ,  storm : : NumberTraits < ValueType > : : IsExact ) ;  
			
		
	
		
			
				
					            if  ( method  = =  NativeLinearEquationSolverMethod : : Power  | |  method  = =  NativeLinearEquationSolverMethod : : RationalSearch )  {  
			
		
	
		
			
				
					            if  ( method  = =  NativeLinearEquationSolverMethod : : Power  | |  method  = =  NativeLinearEquationSolverMethod : : RationalSearch  | |  method  = =  NativeLinearEquationSolverMethod : : QuickPower  )  {  
			
		
	
		
			
				
					                return  LinearEquationSolverProblemFormat : : FixedPointSystem ;  
			
		
	
		
			
				
					            }  else  {  
			
		
	
		
			
				
					                return  LinearEquationSolverProblemFormat : : EquationSystem ;