You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							87 lines
						
					
					
						
							5.6 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							87 lines
						
					
					
						
							5.6 KiB
						
					
					
				| #include "src/solver/SymbolicLinearEquationSolver.h" | |
|  | |
| #include "src/storage/dd/DdManager.h" | |
| #include "src/storage/dd/Add.h" | |
|  | |
| #include "src/settings/SettingsManager.h" | |
| #include "src/settings/modules/NativeEquationSolverSettings.h" | |
|  | |
| namespace storm { | |
|     namespace solver { | |
|          | |
|         template<storm::dd::DdType DdType, typename ValueType> | |
|         SymbolicLinearEquationSolver<DdType, ValueType>::SymbolicLinearEquationSolver(storm::dd::Add<DdType, ValueType> const& A, storm::dd::Bdd<DdType> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : A(A), allRows(allRows), rowMetaVariables(rowMetaVariables), columnMetaVariables(columnMetaVariables), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs), precision(precision), maximalNumberOfIterations(maximalNumberOfIterations), relative(relative) { | |
|             // Intentionally left empty. | |
|         } | |
|          | |
|         template<storm::dd::DdType DdType, typename ValueType> | |
|         SymbolicLinearEquationSolver<DdType, ValueType>::SymbolicLinearEquationSolver(storm::dd::Add<DdType, ValueType> const& A, storm::dd::Bdd<DdType> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) : A(A), allRows(allRows), rowMetaVariables(rowMetaVariables), columnMetaVariables(columnMetaVariables), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs) { | |
|             // Get the settings object to customize solving. | |
|             storm::settings::modules::NativeEquationSolverSettings const& settings = storm::settings::nativeEquationSolverSettings(); | |
|              | |
|             // Get appropriate settings. | |
|             maximalNumberOfIterations = settings.getMaximalIterationCount(); | |
|             precision = settings.getPrecision(); | |
|             relative = settings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative; | |
|         } | |
|          | |
|         template<storm::dd::DdType DdType, typename ValueType> | |
|         storm::dd::Add<DdType, ValueType>  SymbolicLinearEquationSolver<DdType, ValueType>::solveEquationSystem(storm::dd::Add<DdType, ValueType> const& x, storm::dd::Add<DdType, ValueType> const& b) const { | |
|             // Start by computing the Jacobi decomposition of the matrix A. | |
|             storm::dd::Add<DdType, ValueType> diagonal = x.getDdManager()->template getAddOne<ValueType>(); | |
|             for (auto const& pair : rowColumnMetaVariablePairs) { | |
|                 diagonal *= x.getDdManager()->template getIdentity<ValueType>(pair.first).equals(x.getDdManager()->template getIdentity<ValueType>(pair.second)).template toAdd<ValueType>(); | |
|                 diagonal *= x.getDdManager()->getRange(pair.first).template toAdd<ValueType>() * x.getDdManager()->getRange(pair.second).template toAdd<ValueType>(); | |
|             } | |
|             diagonal *= allRows.template toAdd<ValueType>(); | |
|              | |
|             storm::dd::Add<DdType, ValueType> lu = diagonal.ite(this->A.getDdManager()->template getAddZero<ValueType>(), this->A); | |
|             storm::dd::Add<DdType, ValueType> dinv = diagonal / (diagonal * this->A); | |
|              | |
|             // Set up additional environment variables. | |
|             storm::dd::Add<DdType, ValueType> xCopy = x; | |
|             uint_fast64_t iterationCount = 0; | |
|             bool converged = false; | |
|              | |
|             while (!converged && iterationCount < maximalNumberOfIterations) { | |
|                 storm::dd::Add<DdType, ValueType> xCopyAsColumn = xCopy.swapVariables(this->rowColumnMetaVariablePairs); | |
|                 storm::dd::Add<DdType, ValueType> tmp = lu.multiplyMatrix(xCopyAsColumn, this->columnMetaVariables); | |
|                 tmp = b - tmp; | |
|                 tmp = tmp.swapVariables(this->rowColumnMetaVariablePairs); | |
|                 tmp = dinv.multiplyMatrix(tmp, this->columnMetaVariables); | |
|                  | |
|                 // Now check if the process already converged within our precision. | |
|                 converged = xCopy.equalModuloPrecision(tmp, precision, relative); | |
|                  | |
|                 // If the method did not converge yet, we prepare the x vector for the next iteration. | |
|                 if (!converged) { | |
|                     xCopy = tmp; | |
|                 } | |
|                  | |
|                 // Increase iteration count so we can abort if convergence is too slow. | |
|                 ++iterationCount; | |
|             } | |
|              | |
|             return xCopy; | |
|         } | |
|          | |
|         template<storm::dd::DdType DdType, typename ValueType> | |
|         storm::dd::Add<DdType, ValueType> SymbolicLinearEquationSolver<DdType, ValueType>::performMatrixVectorMultiplication(storm::dd::Add<DdType, ValueType> const& x, storm::dd::Add<DdType, ValueType> const* b, uint_fast64_t n) const { | |
|             storm::dd::Add<DdType, ValueType> xCopy = x; | |
|              | |
|             // Perform matrix-vector multiplication while the bound is met. | |
|             for (uint_fast64_t i = 0; i < n; ++i) { | |
|                 xCopy = xCopy.swapVariables(this->rowColumnMetaVariablePairs); | |
|                 xCopy = this->A.multiplyMatrix(xCopy, this->columnMetaVariables); | |
|                 if (b != nullptr) { | |
|                     xCopy += *b; | |
|                 } | |
|             } | |
|              | |
|             return xCopy; | |
|         } | |
|          | |
|         template class SymbolicLinearEquationSolver<storm::dd::DdType::CUDD, double>; | |
|          | |
|     } | |
| }
 |