@ -6,6 +6,8 @@ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/settings/modules/GeneralSettings.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/settings/modules/MinMaxEquationSolverSettings.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/utility/KwekMehlhorn.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/utility/vector.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/utility/macros.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/exceptions/InvalidSettingsException.h" 
  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -632,7 +634,10 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // If the value does not match the one in the values vector, the given vector is not a solution.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! comparator . isEqual ( groupValue ,  * valueIt ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : cout  < <  " group value for  "  < <  group  < <  "  is  "  < <  groupValue  < <  "  is not  "  < <  * valueIt  < <  " , diff is  "  < <  ( groupValue  -  * valueIt )  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : cout  < <  " group value for  "  < <  group  < <  "  is  "  < <  groupValue  < <  "  is actually  "  < <  * valueIt  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -641,63 +646,13 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : pair < ValueType ,  ValueType >  findRational ( ValueType  const &  alpha ,  ValueType  const &  beta ,  ValueType  const &  gamma ,  ValueType  const &  delta )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            ValueType  alphaDivBeta  =  alpha  /  beta ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            ValueType  alphaDivBetaFloor  =  storm : : utility : : floor ( alphaDivBeta ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            ValueType  gammaDivDeltaFloor  =  storm : : utility : : floor < ValueType > ( gamma  /  delta ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( alphaDivBetaFloor  = =  gammaDivDeltaFloor  & &  ! storm : : utility : : isInteger ( alphaDivBeta ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : pair < ValueType ,  ValueType >  subresult  =  findRational ( delta ,  storm : : utility : : mod ( gamma ,  delta ) ,  beta ,  storm : : utility : : mod ( alpha ,  beta ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auto  result  =  std : : make_pair ( alphaDivBetaFloor  *  subresult . first  +  subresult . second ,  subresult . first ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auto  result  =  std : : make_pair ( storm : : utility : : ceil ( alphaDivBeta ) ,  storm : : utility : : one < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  PreciseValueType ,  typename  ImpreciseValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        PreciseValueType  truncateToRational ( ImpreciseValueType  const &  value ,  uint64_t  precision )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_ASSERT ( precision  <  16 ,  " Truncating via double is not sound. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            PreciseValueType  powerOfTen  =  storm : : utility : : pow ( storm : : utility : : convertNumber < PreciseValueType > ( 10 ) ,  precision ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            PreciseValueType  truncated  =  storm : : utility : : trunc < PreciseValueType > ( value  *  powerOfTen ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  truncated  /  powerOfTen ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  PreciseValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        PreciseValueType  truncateToRational ( double  const &  value ,  uint64_t  precision )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_ASSERT ( precision  <  16 ,  " Truncating via double is not sound. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            auto  powerOfTen  =  std : : pow ( 10 ,  precision ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            double  truncated  =  std : : trunc ( value  *  powerOfTen ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  storm : : utility : : convertNumber < PreciseValueType > ( truncated )  /  storm : : utility : : convertNumber < PreciseValueType > ( powerOfTen ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  PreciseValueType ,  typename  ImpreciseValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        PreciseValueType  findRational ( uint64_t  precision ,  ImpreciseValueType  const &  value )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            PreciseValueType  truncatedFraction  =  truncateToRational < PreciseValueType > ( value ,  precision ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            PreciseValueType  ten  =  storm : : utility : : convertNumber < PreciseValueType > ( 10 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            PreciseValueType  powerOfTen  =  storm : : utility : : pow < PreciseValueType > ( ten ,  precision ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            PreciseValueType  multiplier  =  powerOfTen  /  storm : : utility : : denominator ( truncatedFraction ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            PreciseValueType  numerator  =  storm : : utility : : numerator ( truncatedFraction )  *  multiplier ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  RationalType ,  typename  ImpreciseType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  IterativeMinMaxLinearEquationSolver < ValueType > : : sharpen ( storm : : OptimizationDirection  dir ,  uint64_t  precision ,  storm : : storage : : SparseMatrix < RationalType >  const &  A ,  std : : vector < ImpreciseType >  const &  x ,  std : : vector < RationalType >  const &  b ,  std : : vector < RationalType > &  tmp )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : pair < PreciseValueType ,  PreciseValueType >  result  =  findRational < PreciseValueType > ( numerator ,  powerOfTen ,  numerator  +  storm : : utility : : one < PreciseValueType > ( ) ,  powerOfTen ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  result . first  /  result . second ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  PreciseValueType ,  typename  ImpreciseValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  IterativeMinMaxLinearEquationSolver < ValueType > : : sharpen ( storm : : OptimizationDirection  dir ,  uint64_t  precision ,  storm : : storage : : SparseMatrix < PreciseValueType >  const &  A ,  std : : vector < ImpreciseValueType >  const &  x ,  std : : vector < PreciseValueType >  const &  b ,  std : : vector < PreciseValueType > &  tmp )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( uint64_t  p  =  1 ;  p  <  precision ;  + + p )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( uint64_t  state  =  0 ;  state  <  x . size ( ) ;  + + state )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    PreciseValueType  rationalX  =  storm : : utility : : convertNumber < PreciseValueType ,  ImpreciseValueType > ( x [ state ] ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    PreciseValueType  integer  =  storm : : utility : : floor ( rationalX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    PreciseValueType  fraction  =  rationalX  -  integer ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    tmp [ state ]  =  integer  +  findRational < PreciseValueType > ( p ,  storm : : utility : : convertNumber < ImpreciseValueType ,  PreciseValueType > ( fraction ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( IterativeMinMaxLinearEquationSolver < PreciseValueType > : : isSolution ( dir ,  A ,  tmp ,  b ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : utility : : kwek_mehlhorn : : sharpen ( precision ,  x ,  tmp ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( IterativeMinMaxLinearEquationSolver < RationalType > : : isSolution ( dir ,  A ,  tmp ,  b ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -710,8 +665,8 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ImpreciseValue Type >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  std : : enable_if < std : : is_same < ValueType ,  ImpreciseValue Type > : : value  & &  ! NumberTraits < ValueType > : : IsExact ,  bool > : : type  IterativeMinMaxLinearEquationSolver < ValueType > : : solveEquationsRationalSearchHelper ( OptimizationDirection  dir ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ImpreciseType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  std : : enable_if < std : : is_same < ValueType ,  ImpreciseType > : : value  & &  ! NumberTraits < ValueType > : : IsExact ,  bool > : : type  IterativeMinMaxLinearEquationSolver < ValueType > : : solveEquationsRationalSearchHelper ( OptimizationDirection  dir ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Create a rational representation of the input so we can check for a proper solution later.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : SparseMatrix < storm : : RationalNumber >  rationalA  =  this - > A - > template  toValueType < storm : : RationalNumber > ( ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -727,52 +682,25 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auxiliaryRowGroupVector  =  std : : make_unique < std : : vector < ValueType > > ( this - > A - > getRowGroupCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ValueType > *  newX  =  auxiliaryRowGroupVector . get ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ValueType > *  currentX  =  & x ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            Status  status  =  Status : : InProgress ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            uint64_t  overallIterations  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            ValueType  precision  =  this - > getSettings ( ) . getPrecision ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > startMeasureProgress ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            while  ( status  = =  Status : : InProgress  & &  overallIterations  <  this - > getSettings ( ) . getMaximalNumberOfIterations ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Perform value iteration with the current precision.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                ValueIterationResult  result  =  performValueIteration ( dir ,  currentX ,  newX ,  b ,  precision ,  this - > getSettings ( ) . getRelativeTerminationCriterion ( ) ,  SolverGuarantee : : LessOrEqual ,  overallIterations ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Count the iterations.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                overallIterations  + =  result . iterations ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Try to sharpen the result.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                uint64_t  p  =  storm : : utility : : convertNumber < uint64_t > ( storm : : utility : : ceil ( storm : : utility : : log10 < storm : : RationalNumber > ( storm : : utility : : one < storm : : RationalNumber > ( )  /  storm : : utility : : convertNumber < storm : : RationalNumber > ( precision ) ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bool  foundSolution  =  sharpen ( dir ,  p ,  rationalA ,  * currentX ,  rationalB ,  rationalX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( foundSolution )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    status  =  Status : : Converged ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  rationalIt  =  rationalX . begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    for  ( auto  it  =  x . begin ( ) ,  ite  =  x . end ( ) ;  it  ! =  ite ;  + + it ,  + + rationalIt )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        * it  =  storm : : utility : : convertNumber < ValueType > ( * rationalIt ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    precision  =  precision  /  10 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Forward the call to the core rational search routine.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  converged  =  solveEquationsRationalSearchHelper < storm : : RationalNumber ,  ImpreciseType > ( dir ,  * this ,  rationalA ,  rationalX ,  rationalB ,  * this - > A ,  x ,  b ,  * auxiliaryRowGroupVector ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( status  = =  Status : : InProgress  & &  overallIterations  = =  this - > getSettings ( ) . getMaximalNumberOfIterations ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                status  =  Status : : MaximalIterationsExceeded ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Translate back rational result to imprecise result.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            auto  targetIt  =  x . begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  it  =  rationalX . begin ( ) ,  ite  =  rationalX . end ( ) ;  it  ! =  ite ;  + + it ,  + + targetIt )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                * targetIt  =  storm : : utility : : convertNumber < ValueType > ( * it ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            reportStatus ( status ,  overallIterations ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ! this - > isCachingEnabled ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                clearCache ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > clearCache ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  status  = =  Status : : C onverged | |  status  = =  Status : : TerminatedEarly  ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  converged ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ImpreciseValue Type >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  std : : enable_if < std : : is_same < ValueType ,  ImpreciseValue Type > : : value  & &  NumberTraits < ValueType > : : IsExact ,  bool > : : type  IterativeMinMaxLinearEquationSolver < ValueType > : : solveEquationsRationalSearchHelper ( OptimizationDirection  dir ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ImpreciseType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  std : : enable_if < std : : is_same < ValueType ,  ImpreciseType > : : value  & &  NumberTraits < ValueType > : : IsExact ,  bool > : : type  IterativeMinMaxLinearEquationSolver < ValueType > : : solveEquationsRationalSearchHelper ( OptimizationDirection  dir ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ! this - > linEqSolverA )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > linEqSolverA  =  this - > linearEquationSolverFactory - > create ( * this - > A ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -783,95 +711,168 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auxiliaryRowGroupVector  =  std : : make_unique < std : : vector < ValueType > > ( this - > A - > getRowGroupCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ValueType > *  newX  =  auxiliaryRowGroupVector . get ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ValueType > *  currentX  =  & x ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            Status  status  =  Status : : InProgress ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            uint64_t  overallIterations  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            ValueType  precision  =  this - > getSettings ( ) . getPrecision ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > startMeasureProgress ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            while  ( status  = =  Status : : InProgress  & &  overallIterations  <  this - > getSettings ( ) . getMaximalNumberOfIterations ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Perform value iteration with the current precision.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                ValueIterationResult  result  =  performValueIteration ( dir ,  currentX ,  newX ,  b ,  precision ,  this - > getSettings ( ) . getRelativeTerminationCriterion ( ) ,  SolverGuarantee : : LessOrEqual ,  overallIterations ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Count the iterations.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                overallIterations  + =  result . iterations ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Try to sharpen the result.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                uint64_t  p  =  storm : : utility : : convertNumber < uint64_t > ( storm : : utility : : ceil ( storm : : utility : : log10 < ValueType > ( storm : : utility : : one < ValueType > ( )  /  precision ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bool  foundSolution  =  sharpen ( dir ,  p ,  * this - > A ,  * currentX ,  b ,  * newX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( foundSolution )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    status  =  Status : : Converged ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Swap the result in place.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( & x  = =  currentX )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        std : : swap ( * currentX ,  * newX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    precision  =  precision  /  10 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Forward the call to the core rational search routine.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  converged  =  solveEquationsRationalSearchHelper < ValueType ,  ImpreciseType > ( dir ,  * this ,  * this - > A ,  x ,  b ,  * this - > A ,  * auxiliaryRowGroupVector ,  b ,  x ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( status  = =  Status : : InProgress  & &  overallIterations  = =  this - > getSettings ( ) . getMaximalNumberOfIterations ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                status  =  Status : : MaximalIterationsExceeded ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            reportStatus ( status ,  overallIterations ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ! this - > isCachingEnabled ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                clearCache ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > clearCache ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  status  = =  Status : : C onverged | |  status  = =  Status : : TerminatedEarly  ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  converged ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ImpreciseValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  std : : enable_if < ! std : : is_same < ValueType ,  ImpreciseValueType > : : value ,  bool > : : type  IterativeMinMaxLinearEquationSolver < ValueType > : : solveEquationsRationalSearchHelper ( OptimizationDirection  dir ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Create an imprecise solver with caching enabled.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            IterativeMinMaxLinearEquationSolver < ImpreciseValueType >  impreciseSolver ( std : : make_unique < storm : : solver : : GeneralLinearEquationSolverFactory < ImpreciseValueType > > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            impreciseSolver . setMatrix ( this - > A - > template  toValueType < ImpreciseValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            impreciseSolver . createLinearEquationSolver ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            impreciseSolver . setCachingEnabled ( true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ImpreciseType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  std : : enable_if < ! std : : is_same < ValueType ,  ImpreciseType > : : value ,  bool > : : type  IterativeMinMaxLinearEquationSolver < ValueType > : : solveEquationsRationalSearchHelper ( OptimizationDirection  dir ,  std : : vector < ValueType > &  x ,  std : : vector < ValueType >  const &  b )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Translate A to its imprecise version.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : SparseMatrix < ImpreciseType >  impreciseA  =  this - > A - > template  toValueType < ImpreciseType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseValueType >  impreciseX ( x . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Translate x to its imprecise version.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseType >  impreciseX ( x . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : vector < ValueType >  tmp ( x . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > createLowerBoundsVector ( tmp ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auto  targetIt  =  impreciseX . begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  sourceIt  =  tmp . begin ( ) ;  targetIt  ! =  impreciseX . end ( ) ;  + + targetIt ,  + + sourceIt )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    * targetIt  =  storm : : utility : : convertNumber < ImpreciseValue Type ,  ValueType > ( * sourceIt ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    * targetIt  =  storm : : utility : : convertNumber < ImpreciseType ,  ValueType > ( * sourceIt ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseValueType >  impreciseTmpX ( x . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseValueType >  impreciseB ( b . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Create temporary storage for an imprecise x.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseType >  impreciseTmpX ( x . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Translate b to its imprecise version.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseType >  impreciseB ( b . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            auto  targetIt  =  impreciseB . begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  sourceIt  =  b . begin ( ) ;  targetIt  ! =  impreciseB . end ( ) ;  + + targetIt ,  + + sourceIt )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                * targetIt  =  storm : : utility : : convertNumber < ImpreciseValueType ,  ValueType > ( * sourceIt ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                * targetIt  =  storm : : utility : : convertNumber < ImpreciseType ,  ValueType > ( * sourceIt ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseValueType > *  currentX  =  & impreciseX ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseValueType > *  newX  =  & impreciseTmpX ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Create imprecise solver from the imprecise data.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            IterativeMinMaxLinearEquationSolver < ImpreciseType >  impreciseSolver ( std : : make_unique < storm : : solver : : GeneralLinearEquationSolverFactory < ImpreciseType > > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            impreciseSolver . setMatrix ( impreciseA ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            impreciseSolver . createLinearEquationSolver ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            impreciseSolver . setCachingEnabled ( true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  converged  =  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            try  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Forward the call to the core rational search routine.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                converged  =  solveEquationsRationalSearchHelper < ValueType ,  ImpreciseType > ( dir ,  impreciseSolver ,  * this - > A ,  x ,  b ,  impreciseA ,  impreciseX ,  impreciseB ,  impreciseTmpX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  catch  ( storm : : exceptions : : PrecisionExceededException  const &  e )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_WARN ( " Precision of double was exceeded, trying to recover by switching to rational arithmetic. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! auxiliaryRowGroupVector )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auxiliaryRowGroupVector  =  std : : make_unique < std : : vector < ValueType > > ( this - > A - > getRowGroupCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Translate the imprecise value iteration result to the one we are going to use from now on.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auto  targetIt  =  auxiliaryRowGroupVector - > begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  it  =  impreciseX . begin ( ) ,  ite  =  impreciseX . end ( ) ;  it  ! =  ite ;  + + it ,  + + targetIt )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    * targetIt  =  storm : : utility : : convertNumber < ValueType > ( * it ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : cout  < <  " converting vector[ "  < <  std : : distance ( impreciseX . begin ( ) ,  it )  < <  " ] from  "  < <  * it  < <  "  to  "  < <  * targetIt  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Get rid of the superfluous data structures.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                impreciseX  =  std : : vector < ImpreciseType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                impreciseTmpX  =  std : : vector < ImpreciseType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                impreciseB  =  std : : vector < ImpreciseType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                impreciseA  =  storm : : storage : : SparseMatrix < ImpreciseType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( ! this - > linEqSolverA )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > linEqSolverA  =  this - > linearEquationSolverFactory - > create ( * this - > A ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    this - > linEqSolverA - > setCachingEnabled ( true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Forward the call to the core rational search routine, but now with our value type as the imprecise value type.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                converged  =  solveEquationsRationalSearchHelper < ValueType ,  ValueType > ( dir ,  * this ,  * this - > A ,  x ,  b ,  * this - > A ,  * auxiliaryRowGroupVector ,  b ,  x ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ! this - > isCachingEnabled ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > clearCache ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  converged ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  RationalType ,  typename  ImpreciseType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        struct  TemporaryHelper  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            static  std : : vector < RationalType > *  getFreeRational ( std : : vector < RationalType > &  rationalX ,  std : : vector < ImpreciseType > * &  currentX ,  std : : vector < ImpreciseType > * &  newX )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  & rationalX ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            static  void  swapSolutions ( std : : vector < RationalType > &  rationalX ,  std : : vector < RationalType > * &  rationalSolution ,  std : : vector < ImpreciseType > &  x ,  std : : vector < ImpreciseType > * &  currentX ,  std : : vector < ImpreciseType > * &  newX )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Nothing to do.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  RationalType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        struct  TemporaryHelper < RationalType ,  RationalType >  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            static  std : : vector < RationalType > *  getFreeRational ( std : : vector < RationalType > &  rationalX ,  std : : vector < RationalType > * &  currentX ,  std : : vector < RationalType > * &  newX )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( & rationalX  = =  currentX )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  newX ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  currentX ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            static  void  swapSolutions ( std : : vector < RationalType > &  rationalX ,  std : : vector < RationalType > * &  rationalSolution ,  std : : vector < RationalType > &  x ,  std : : vector < RationalType > * &  currentX ,  std : : vector < RationalType > * &  newX )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( & rationalX  = =  rationalSolution )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // In this case, the rational solution is in place.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // However, since the rational solution is no alias to current x, the imprecise solution is stored
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // in current x and and rational x is not an alias to x, we can swap the contents of currentX to x.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : swap ( x ,  * currentX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Still, we may assume that the rational solution is not current x and is therefore new x.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : swap ( rationalX ,  * rationalSolution ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : swap ( x ,  * currentX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  RationalType ,  typename  ImpreciseType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  IterativeMinMaxLinearEquationSolver < ValueType > : : solveEquationsRationalSearchHelper ( OptimizationDirection  dir ,  IterativeMinMaxLinearEquationSolver < ImpreciseType >  const &  impreciseSolver ,  storm : : storage : : SparseMatrix < RationalType >  const &  rationalA ,  std : : vector < RationalType > &  rationalX ,  std : : vector < RationalType >  const &  rationalB ,  storm : : storage : : SparseMatrix < ImpreciseType >  const &  A ,  std : : vector < ImpreciseType > &  x ,  std : : vector < ImpreciseType >  const &  b ,  std : : vector < ImpreciseType > &  tmpX )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseType > *  currentX  =  & x ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ImpreciseType > *  newX  =  & tmpX ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            Status  status  =  Status : : InProgress ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            uint64_t  overallIterations  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            uint64_t  valueIterationInvocations  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            ValueType  precision  =  this - > getSettings ( ) . getPrecision ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            impreciseSolver . startMeasureProgress ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            while  ( status  = =  Status : : InProgress  & &  overallIterations  <  this - > getSettings ( ) . getMaximalNumberOfIterations ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Perform value iteration with the current precision.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                typename  IterativeMinMaxLinearEquationSolver < ImpreciseValueType > : : ValueIterationResult  result  =  impreciseSolver . performValueIteration ( dir ,  currentX ,  newX ,  impreciseB ,  storm : : utility : : convertNumber < ImpreciseValueType ,  ValueType > ( precision ) ,  this - > getSettings ( ) . getRelativeTerminationCriterion ( ) ,  SolverGuarantee : : LessOrEqual ,  overallIterations ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                typename  IterativeMinMaxLinearEquationSolver < ImpreciseType > : : ValueIterationResult  result  =  impreciseSolver . performValueIteration ( dir ,  currentX ,  newX ,  b ,  storm : : utility : : convertNumber < ImpreciseType ,  ValueType > ( precision ) ,  this - > getSettings ( ) . getRelativeTerminationCriterion ( ) ,  SolverGuarantee : : LessOrEqual ,  overallIterations ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // At this point, the result of the imprecise value iteration is stored in the (imprecise) current x.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                + + valueIterationInvocations ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_TRACE ( " Completed  "  < <  valueIterationInvocations  < <  "  value iteration invocations, the last one with precision  "  < <  precision  < <  " . " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Count the iterations.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                overallIterations  + =  result . iterations ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Try to sharpen the result.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                uint64_t  p  =  storm : : utility : : convertNumber < uint64_t > ( storm : : utility : : ceil ( storm : : utility : : log10 < ValueType > ( storm : : utility : : one < ValueType > ( )  /  precision ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bool  foundSolution  =  sharpen ( dir ,  p ,  * this - > A ,  * currentX ,  b ,  x ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Make sure that currentX and rationalX are not aliased.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : vector < RationalType > *  freeRational  =  TemporaryHelper < RationalType ,  ImpreciseType > : : getFreeRational ( rationalX ,  currentX ,  newX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Sharpen solution and place it in rationalX.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bool  foundSolution  =  sharpen ( dir ,  p ,  rationalA ,  * currentX ,  rationalB ,  * freeRational ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // After sharpen, if a solution was found, it is contained in the current rational x.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( foundSolution )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    status  =  Status : : Converged ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    TemporaryHelper < RationalType ,  ImpreciseType > : : swapSolutions ( rationalX ,  freeRational ,  x ,  currentX ,  newX ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Increase the precision.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    precision  =  precision  /  10 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -879,14 +880,9 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( status  = =  Status : : InProgress  & &  overallIterations  = =  this - > getSettings ( ) . getMaximalNumberOfIterations ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                status  =  Status : : MaximalIterationsExceeded ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            reportStatus ( status ,  overallIterations ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ! this - > isCachingEnabled ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                clearCache ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  status  = =  Status : : Converged  | |  status  = =  Status : : TerminatedEarly ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1019,7 +1015,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  IterativeMinMaxLinearEquationSolver < ValueType > : : reportStatus ( Status  status ,  uint64_t  iterations )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  IterativeMinMaxLinearEquationSolver < ValueType > : : reportStatus ( Status  status ,  uint64_t  iterations )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            switch  ( status )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                case  Status : : Converged :  STORM_LOG_INFO ( " Iterative solver converged after  "  < <  iterations  < <  "  iterations. " ) ;  break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                case  Status : : TerminatedEarly :  STORM_LOG_INFO ( " Iterative solver terminated early after  "  < <  iterations  < <  "  iterations. " ) ;  break ;