Browse Source

solvers now can allocated auxiliary memory

Former-commit-id: 76dc1a1679
tempestpy_adaptions
dehnert 8 years ago
parent
commit
83c4b1647c
  1. 2
      src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp
  2. 2
      src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp
  3. 2
      src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
  4. 52
      src/solver/GmmxxLinearEquationSolver.cpp
  5. 10
      src/solver/GmmxxLinearEquationSolver.h
  6. 50
      src/solver/LinearEquationSolver.cpp
  7. 36
      src/solver/LinearEquationSolver.h
  8. 6
      src/solver/MinMaxLinearEquationSolver.cpp
  9. 6
      src/solver/MinMaxLinearEquationSolver.h
  10. 52
      src/solver/NativeLinearEquationSolver.cpp
  11. 12
      src/solver/NativeLinearEquationSolver.h
  12. 82
      src/solver/StandardMinMaxLinearEquationSolver.cpp
  13. 19
      src/solver/StandardMinMaxLinearEquationSolver.h
  14. 18
      src/solver/TopologicalMinMaxLinearEquationSolver.cpp
  15. 4
      src/solver/TopologicalMinMaxLinearEquationSolver.h
  16. 10
      test/functional/solver/GmmxxMinMaxLinearEquationSolverTest.cpp
  17. 10
      test/functional/solver/NativeMinMaxLinearEquationSolverTest.cpp

2
src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp

@ -629,7 +629,7 @@ namespace storm {
}
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(std::move(uniformizedMatrix));
solver->allocateAuxStorage(storm::solver::LinearEquationSolverOperation::MultiplyRepeatedly);
solver->allocateAuxMemory(storm::solver::LinearEquationSolverOperation::MultiplyRepeatedly);
if (!useMixedPoissonProbabilities && std::get<0>(foxGlynnResult) > 1) {
// Perform the matrix-vector multiplications (without adding).

2
src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp

@ -86,7 +86,7 @@ namespace storm {
}
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(aProbabilistic);
solver->allocateAuxStorage(storm::solver::MinMaxLinearEquationSolverOperation::SolveEquations);
solver->allocateAuxMemory(storm::solver::MinMaxLinearEquationSolverOperation::SolveEquations);
// Perform the actual value iteration
// * loop until the step bound has been reached

2
src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp

@ -67,7 +67,7 @@ namespace storm {
storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>());
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(transitionMatrix);
solver->repeatedMultiply(dir, result);
solver->repeatedMultiply(dir, result, nullptr, 1);
return result;
}

52
src/solver/GmmxxLinearEquationSolver.cpp

@ -111,12 +111,12 @@ namespace storm {
}
template<typename ValueType>
GmmxxLinearEquationSolver<ValueType>::GmmxxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, GmmxxLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), gmmxxMatrix(nullptr), settings(settings), auxiliaryJacobiStorage(nullptr) {
GmmxxLinearEquationSolver<ValueType>::GmmxxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, GmmxxLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), gmmxxMatrix(nullptr), settings(settings), auxiliaryJacobiMemory(nullptr) {
this->setMatrix(A);
}
template<typename ValueType>
GmmxxLinearEquationSolver<ValueType>::GmmxxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, GmmxxLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), gmmxxMatrix(nullptr), settings(settings), auxiliaryJacobiStorage(nullptr) {
GmmxxLinearEquationSolver<ValueType>::GmmxxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, GmmxxLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), gmmxxMatrix(nullptr), settings(settings), auxiliaryJacobiMemory(nullptr) {
this->setMatrix(std::move(A));
}
@ -202,9 +202,9 @@ namespace storm {
template<typename ValueType>
uint_fast64_t GmmxxLinearEquationSolver<ValueType>::solveLinearEquationSystemWithJacobi(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType>& x, std::vector<ValueType> const& b) const {
bool allocatedAuxStorage = !this->hasAuxStorage(LinearEquationSolverOperation::SolveEquations);
if (allocatedAuxStorage) {
auxiliaryJacobiStorage = std::make_unique<std::vector<ValueType>>(x.size());
bool allocatedAuxMemory = !this->hasAuxMemory(LinearEquationSolverOperation::SolveEquations);
if (allocatedAuxMemory) {
this->allocateAuxMemory(LinearEquationSolverOperation::SolveEquations);
}
// Get a Jacobi decomposition of the matrix A.
@ -214,7 +214,7 @@ namespace storm {
std::unique_ptr<gmm::csr_matrix<ValueType>> gmmLU = storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<ValueType>(std::move(jacobiDecomposition.first));
std::vector<ValueType>* currentX = &x;
std::vector<ValueType>* nextX = auxiliaryJacobiStorage.get();
std::vector<ValueType>* nextX = auxiliaryJacobiMemory.get();
// Set up additional environment variables.
uint_fast64_t iterationCount = 0;
@ -237,13 +237,13 @@ namespace storm {
// If the last iteration did not write to the original x we have to swap the contents, because the
// output has to be written to the input parameter x.
if (currentX == auxiliaryJacobiStorage.get()) {
if (currentX == auxiliaryJacobiMemory.get()) {
std::swap(x, *currentX);
}
// If we allocated auxiliary storage, we need to dispose of it now.
if (allocatedAuxStorage) {
auxiliaryJacobiStorage.reset();
// If we allocated auxiliary memory, we need to dispose of it now.
if (allocatedAuxMemory) {
this->deallocateAuxMemory(LinearEquationSolverOperation::SolveEquations);
}
return iterationCount;
@ -260,53 +260,53 @@ namespace storm {
}
template<typename ValueType>
bool GmmxxLinearEquationSolver<ValueType>::allocateAuxStorage(LinearEquationSolverOperation operation) {
bool GmmxxLinearEquationSolver<ValueType>::allocateAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
if (this->getSettings().getSolutionMethod() == GmmxxLinearEquationSolverSettings<ValueType>::SolutionMethod::Jacobi) {
if (!auxiliaryJacobiStorage) {
auxiliaryJacobiStorage = std::make_unique<std::vector<ValueType>>(this->getMatrixRowCount());
if (!auxiliaryJacobiMemory) {
auxiliaryJacobiMemory = std::make_unique<std::vector<ValueType>>(this->getMatrixRowCount());
result = true;
}
}
}
result |= LinearEquationSolver<ValueType>::allocateAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::allocateAuxMemory(operation);
return result;
}
template<typename ValueType>
bool GmmxxLinearEquationSolver<ValueType>::deallocateAuxStorage(LinearEquationSolverOperation operation) {
bool GmmxxLinearEquationSolver<ValueType>::deallocateAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
if (auxiliaryJacobiStorage) {
if (auxiliaryJacobiMemory) {
result = true;
auxiliaryJacobiMemory.reset();
}
auxiliaryJacobiStorage.reset();
}
result |= LinearEquationSolver<ValueType>::deallocateAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::deallocateAuxMemory(operation);
return result;
}
template<typename ValueType>
bool GmmxxLinearEquationSolver<ValueType>::reallocateAuxStorage(LinearEquationSolverOperation operation) {
bool GmmxxLinearEquationSolver<ValueType>::reallocateAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
if (auxiliaryJacobiStorage != nullptr) {
result = auxiliaryJacobiStorage->size() != this->getMatrixColumnCount();
auxiliaryJacobiStorage->resize(this->getMatrixRowCount());
if (auxiliaryJacobiMemory) {
result = auxiliaryJacobiMemory->size() != this->getMatrixColumnCount();
auxiliaryJacobiMemory->resize(this->getMatrixRowCount());
}
}
result |= LinearEquationSolver<ValueType>::reallocateAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::reallocateAuxMemory(operation);
return result;
}
template<typename ValueType>
bool GmmxxLinearEquationSolver<ValueType>::hasAuxStorage(LinearEquationSolverOperation operation) const {
bool GmmxxLinearEquationSolver<ValueType>::hasAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
result |= auxiliaryJacobiStorage != nullptr;
result |= static_cast<bool>(auxiliaryJacobiMemory);
}
result |= LinearEquationSolver<ValueType>::hasAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::hasAuxMemory(operation);
return result;
}

10
src/solver/GmmxxLinearEquationSolver.h

@ -98,10 +98,10 @@ namespace storm {
GmmxxLinearEquationSolverSettings<ValueType>& getSettings();
GmmxxLinearEquationSolverSettings<ValueType> const& getSettings() const;
virtual bool allocateAuxStorage(LinearEquationSolverOperation operation) override;
virtual bool deallocateAuxStorage(LinearEquationSolverOperation operation) override;
virtual bool reallocateAuxStorage(LinearEquationSolverOperation operation) override;
virtual bool hasAuxStorage(LinearEquationSolverOperation operation) const override;
virtual bool allocateAuxMemory(LinearEquationSolverOperation operation) const override;
virtual bool deallocateAuxMemory(LinearEquationSolverOperation operation) const override;
virtual bool reallocateAuxMemory(LinearEquationSolverOperation operation) const override;
virtual bool hasAuxMemory(LinearEquationSolverOperation operation) const override;
private:
/*!
@ -136,7 +136,7 @@ namespace storm {
GmmxxLinearEquationSolverSettings<ValueType> settings;
// Auxiliary storage for the Jacobi method.
mutable std::unique_ptr<std::vector<ValueType>> auxiliaryJacobiStorage;
mutable std::unique_ptr<std::vector<ValueType>> auxiliaryJacobiMemory;
};
template<typename ValueType>

50
src/solver/LinearEquationSolver.cpp

@ -14,21 +14,21 @@ namespace storm {
namespace solver {
template<typename ValueType>
LinearEquationSolver<ValueType>::LinearEquationSolver() : auxiliaryRepeatedMultiplyStorage(nullptr) {
LinearEquationSolver<ValueType>::LinearEquationSolver() : auxiliaryRepeatedMultiplyMemory(nullptr) {
// Intentionally left empty.
}
template<typename ValueType>
void LinearEquationSolver<ValueType>::repeatedMultiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const {
bool allocatedAuxStorage = !this->hasAuxStorage(LinearEquationSolverOperation::MultiplyRepeatedly);
if (allocatedAuxStorage) {
auxiliaryRepeatedMultiplyStorage = std::make_unique<std::vector<ValueType>>(x.size());
bool allocatedAuxMemory = !this->hasAuxMemory(LinearEquationSolverOperation::MultiplyRepeatedly);
if (allocatedAuxMemory) {
this->allocateAuxMemory(LinearEquationSolverOperation::MultiplyRepeatedly);
}
// Set up some temporary variables so that we can just swap pointers instead of copying the result after
// each iteration.
std::vector<ValueType>* currentX = &x;
std::vector<ValueType>* nextX = auxiliaryRepeatedMultiplyStorage.get();
std::vector<ValueType>* nextX = auxiliaryRepeatedMultiplyMemory.get();
// Now perform matrix-vector multiplication as long as we meet the bound.
for (uint_fast64_t i = 0; i < n; ++i) {
@ -38,54 +38,52 @@ namespace storm {
// If we performed an odd number of repetitions, we need to swap the contents of currentVector and x,
// because the output is supposed to be stored in the input vector x.
if (currentX == auxiliaryRepeatedMultiplyStorage.get()) {
if (currentX == auxiliaryRepeatedMultiplyMemory.get()) {
std::swap(x, *currentX);
}
// If we allocated auxiliary storage, we need to dispose of it now.
if (allocatedAuxStorage) {
auxiliaryRepeatedMultiplyStorage.reset();
// If we allocated auxiliary memory, we need to dispose of it now.
if (allocatedAuxMemory) {
this->deallocateAuxMemory(LinearEquationSolverOperation::MultiplyRepeatedly);
}
}
template<typename ValueType>
bool LinearEquationSolver<ValueType>::allocateAuxStorage(LinearEquationSolverOperation operation) {
if (this->hasAuxStorage(operation)) {
return false;
bool LinearEquationSolver<ValueType>::allocateAuxMemory(LinearEquationSolverOperation operation) const {
if (!auxiliaryRepeatedMultiplyMemory) {
auxiliaryRepeatedMultiplyMemory = std::make_unique<std::vector<ValueType>>(this->getMatrixColumnCount());
return true;
}
auxiliaryRepeatedMultiplyStorage = std::make_unique<std::vector<ValueType>>(this->getMatrixColumnCount());
return true;
return false;
}
template<typename ValueType>
bool LinearEquationSolver<ValueType>::deallocateAuxStorage(LinearEquationSolverOperation operation) {
bool LinearEquationSolver<ValueType>::deallocateAuxMemory(LinearEquationSolverOperation operation) const {
if (operation == LinearEquationSolverOperation::MultiplyRepeatedly) {
bool result = auxiliaryRepeatedMultiplyStorage != nullptr;
if (result) {
auxiliaryRepeatedMultiplyStorage.reset();
if (auxiliaryRepeatedMultiplyMemory) {
auxiliaryRepeatedMultiplyMemory.reset();
return true;
}
return result;
}
return false;
}
template<typename ValueType>
bool LinearEquationSolver<ValueType>::reallocateAuxStorage(LinearEquationSolverOperation operation) {
bool LinearEquationSolver<ValueType>::reallocateAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::MultiplyRepeatedly) {
if (auxiliaryRepeatedMultiplyStorage != nullptr) {
result = auxiliaryRepeatedMultiplyStorage->size() != this->getMatrixColumnCount();
auxiliaryRepeatedMultiplyStorage->resize(this->getMatrixColumnCount());
if (auxiliaryRepeatedMultiplyMemory) {
result = auxiliaryRepeatedMultiplyMemory->size() != this->getMatrixColumnCount();
auxiliaryRepeatedMultiplyMemory->resize(this->getMatrixColumnCount());
}
}
return result;
}
template<typename ValueType>
bool LinearEquationSolver<ValueType>::hasAuxStorage(LinearEquationSolverOperation operation) const {
bool LinearEquationSolver<ValueType>::hasAuxMemory(LinearEquationSolverOperation operation) const {
if (operation == LinearEquationSolverOperation::MultiplyRepeatedly) {
return auxiliaryRepeatedMultiplyStorage != nullptr;
return static_cast<bool>(auxiliaryRepeatedMultiplyMemory);
}
return false;
}

36
src/solver/LinearEquationSolver.h

@ -69,36 +69,36 @@ namespace storm {
// Methods related to allocating/freeing auxiliary storage.
/*!
* Allocates auxiliary storage that can be used to perform the provided operation. Repeated calls to the
* corresponding function can then be run without allocating/deallocating this storage repeatedly.
* Note: Since the allocated storage is fit to the currently selected options of the solver, they must not
* be changed any more after allocating the auxiliary storage until the storage is deallocated again.
* Allocates auxiliary memory that can be used to perform the provided operation. Repeated calls to the
* corresponding function can then be run without allocating/deallocating this memory repeatedly.
* Note: Since the allocated memory is fit to the currently selected options of the solver, they must not
* be changed any more after allocating the auxiliary memory until it is deallocated again.
*
* @return True iff auxiliary storage was allocated.
* @return True iff auxiliary memory was allocated.
*/
virtual bool allocateAuxStorage(LinearEquationSolverOperation operation);
virtual bool allocateAuxMemory(LinearEquationSolverOperation operation) const;
/*!
* Destroys previously allocated auxiliary storage for the provided operation.
* Destroys previously allocated auxiliary memory for the provided operation.
*
* @return True iff auxiliary storage was deallocated.
* @return True iff auxiliary memory was deallocated.
*/
virtual bool deallocateAuxStorage(LinearEquationSolverOperation operation);
virtual bool deallocateAuxMemory(LinearEquationSolverOperation operation) const;
/*!
* If the matrix dimensions changed and auxiliary storage was allocated, this function needs to be called to
* update the auxiliary storage.
* If the matrix dimensions changed and auxiliary memory was allocated, this function needs to be called to
* update the auxiliary memory.
*
* @return True iff the auxiliary storage was reallocated.
* @return True iff the auxiliary memory was reallocated.
*/
virtual bool reallocateAuxStorage(LinearEquationSolverOperation operation);
virtual bool reallocateAuxMemory(LinearEquationSolverOperation operation) const;
/*!
* Checks whether the solver has allocated auxiliary storage for the provided operation.
* Checks whether the solver has allocated auxiliary memory for the provided operation.
*
* @return True iff auxiliary storage was previously allocated (and not yet deallocated).
* @return True iff auxiliary memory was previously allocated (and not yet deallocated).
*/
virtual bool hasAuxStorage(LinearEquationSolverOperation operation) const;
virtual bool hasAuxMemory(LinearEquationSolverOperation operation) const;
private:
/*!
@ -111,8 +111,8 @@ namespace storm {
*/
virtual uint64_t getMatrixColumnCount() const = 0;
// Auxiliary storage for repeated matrix-vector multiplication.
mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRepeatedMultiplyStorage;
// Auxiliary memory for repeated matrix-vector multiplication.
mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRepeatedMultiplyMemory;
};
template<typename ValueType>

6
src/solver/MinMaxLinearEquationSolver.cpp

@ -80,17 +80,17 @@ namespace storm {
}
template<typename ValueType>
bool MinMaxLinearEquationSolver<ValueType>::allocateAuxStorage(MinMaxLinearEquationSolverOperation operation) {
bool MinMaxLinearEquationSolver<ValueType>::allocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const {
return false;
}
template<typename ValueType>
bool MinMaxLinearEquationSolver<ValueType>::deallocateAuxStorage(MinMaxLinearEquationSolverOperation operation) {
bool MinMaxLinearEquationSolver<ValueType>::deallocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const {
return false;
}
template<typename ValueType>
bool MinMaxLinearEquationSolver<ValueType>::hasAuxStorage(MinMaxLinearEquationSolverOperation operation) const {
bool MinMaxLinearEquationSolver<ValueType>::hasAuxMemory(MinMaxLinearEquationSolverOperation operation) const {
return false;
}

6
src/solver/MinMaxLinearEquationSolver.h

@ -126,21 +126,21 @@ namespace storm {
*
* @return True iff auxiliary storage was allocated.
*/
virtual bool allocateAuxStorage(MinMaxLinearEquationSolverOperation operation);
virtual bool allocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const;
/*!
* Destroys previously allocated auxiliary storage for the provided operation.
*
* @return True iff auxiliary storage was deallocated.
*/
virtual bool deallocateAuxStorage(MinMaxLinearEquationSolverOperation operation);
virtual bool deallocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const;
/*!
* Checks whether the solver has allocated auxiliary storage for the provided operation.
*
* @return True iff auxiliary storage was previously allocated (and not yet deallocated).
*/
virtual bool hasAuxStorage(MinMaxLinearEquationSolverOperation operation) const;
virtual bool hasAuxMemory(MinMaxLinearEquationSolverOperation operation) const;
protected:
/// The optimization direction to use for calls to functions that do not provide it explicitly. Can also be unset.

52
src/solver/NativeLinearEquationSolver.cpp

@ -84,12 +84,12 @@ namespace storm {
}
template<typename ValueType>
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, NativeLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), settings(settings), auxiliarySolvingStorage(nullptr) {
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, NativeLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), settings(settings), auxiliarySolvingMemory(nullptr) {
this->setMatrix(A);
}
template<typename ValueType>
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, NativeLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), settings(settings), auxiliarySolvingStorage(nullptr) {
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, NativeLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), settings(settings), auxiliarySolvingMemory(nullptr) {
this->setMatrix(std::move(A));
}
@ -107,9 +107,9 @@ namespace storm {
template<typename ValueType>
void NativeLinearEquationSolver<ValueType>::solveEquations(std::vector<ValueType>& x, std::vector<ValueType> const& b) const {
bool allocatedAuxStorage = !this->hasAuxStorage(LinearEquationSolverOperation::SolveEquations);
bool allocatedAuxStorage = !this->hasAuxMemory(LinearEquationSolverOperation::SolveEquations);
if (allocatedAuxStorage) {
auxiliarySolvingStorage = std::make_unique<std::vector<ValueType>>(x.size());
this->allocateAuxMemory(LinearEquationSolverOperation::SolveEquations);
}
if (this->getSettings().getSolutionMethod() == NativeLinearEquationSolverSettings<ValueType>::SolutionMethod::SOR || this->getSettings().getSolutionMethod() == NativeLinearEquationSolverSettings<ValueType>::SolutionMethod::GaussSeidel) {
@ -124,11 +124,11 @@ namespace storm {
A->performSuccessiveOverRelaxationStep(omega, x, b);
// Now check if the process already converged within our precision.
converged = storm::utility::vector::equalModuloPrecision<ValueType>(*auxiliarySolvingStorage, x, static_cast<ValueType>(this->getSettings().getPrecision()), this->getSettings().getRelativeTerminationCriterion()) || (this->hasCustomTerminationCondition() && this->getTerminationCondition().terminateNow(x));
converged = storm::utility::vector::equalModuloPrecision<ValueType>(*auxiliarySolvingMemory, x, static_cast<ValueType>(this->getSettings().getPrecision()), this->getSettings().getRelativeTerminationCriterion()) || (this->hasCustomTerminationCondition() && this->getTerminationCondition().terminateNow(x));
// If we did not yet converge, we need to backup the contents of x.
if (!converged) {
*auxiliarySolvingStorage = x;
*auxiliarySolvingMemory = x;
}
// Increase iteration count so we can abort if convergence is too slow.
@ -139,7 +139,7 @@ namespace storm {
std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> jacobiDecomposition = A->getJacobiDecomposition();
std::vector<ValueType>* currentX = &x;
std::vector<ValueType>* nextX = auxiliarySolvingStorage.get();
std::vector<ValueType>* nextX = auxiliarySolvingMemory.get();
// Set up additional environment variables.
uint_fast64_t iterationCount = 0;
@ -163,14 +163,14 @@ namespace storm {
// If the last iteration did not write to the original x we have to swap the contents, because the
// output has to be written to the input parameter x.
if (currentX == auxiliarySolvingStorage.get()) {
if (currentX == auxiliarySolvingMemory.get()) {
std::swap(x, *currentX);
}
}
// If we allocated auxiliary storage, we need to dispose of it now.
// If we allocated auxiliary memory, we need to dispose of it now.
if (allocatedAuxStorage) {
auxiliarySolvingStorage.reset();
this->deallocateAuxMemory(LinearEquationSolverOperation::SolveEquations);
}
}
@ -202,51 +202,51 @@ namespace storm {
}
template<typename ValueType>
bool NativeLinearEquationSolver<ValueType>::allocateAuxStorage(LinearEquationSolverOperation operation) {
bool NativeLinearEquationSolver<ValueType>::allocateAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
if (!auxiliarySolvingStorage) {
auxiliarySolvingStorage = std::make_unique<std::vector<ValueType>>(this->getMatrixRowCount());
if (!auxiliarySolvingMemory) {
auxiliarySolvingMemory = std::make_unique<std::vector<ValueType>>(this->getMatrixRowCount());
result = true;
}
}
result |= LinearEquationSolver<ValueType>::allocateAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::allocateAuxMemory(operation);
return result;
}
template<typename ValueType>
bool NativeLinearEquationSolver<ValueType>::deallocateAuxStorage(LinearEquationSolverOperation operation) {
bool NativeLinearEquationSolver<ValueType>::deallocateAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
if (auxiliarySolvingStorage) {
if (auxiliarySolvingMemory) {
result = true;
auxiliarySolvingMemory.reset();
}
auxiliarySolvingStorage.reset();
}
result |= LinearEquationSolver<ValueType>::deallocateAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::deallocateAuxMemory(operation);
return result;
}
template<typename ValueType>
bool NativeLinearEquationSolver<ValueType>::reallocateAuxStorage(LinearEquationSolverOperation operation) {
bool NativeLinearEquationSolver<ValueType>::reallocateAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
if (auxiliarySolvingStorage) {
result = auxiliarySolvingStorage->size() != this->getMatrixColumnCount();
auxiliarySolvingStorage->resize(this->getMatrixRowCount());
if (auxiliarySolvingMemory) {
result = auxiliarySolvingMemory->size() != this->getMatrixColumnCount();
auxiliarySolvingMemory->resize(this->getMatrixRowCount());
}
}
result |= LinearEquationSolver<ValueType>::reallocateAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::reallocateAuxMemory(operation);
return result;
}
template<typename ValueType>
bool NativeLinearEquationSolver<ValueType>::hasAuxStorage(LinearEquationSolverOperation operation) const {
bool NativeLinearEquationSolver<ValueType>::hasAuxMemory(LinearEquationSolverOperation operation) const {
bool result = false;
if (operation == LinearEquationSolverOperation::SolveEquations) {
result |= auxiliarySolvingStorage != nullptr;
result |= static_cast<bool>(auxiliarySolvingMemory);
}
result |= LinearEquationSolver<ValueType>::hasAuxStorage(operation);
result |= LinearEquationSolver<ValueType>::hasAuxMemory(operation);
return result;
}

12
src/solver/NativeLinearEquationSolver.h

@ -55,10 +55,10 @@ namespace storm {
NativeLinearEquationSolverSettings<ValueType>& getSettings();
NativeLinearEquationSolverSettings<ValueType> const& getSettings() const;
virtual bool allocateAuxStorage(LinearEquationSolverOperation operation) override;
virtual bool deallocateAuxStorage(LinearEquationSolverOperation operation) override;
virtual bool reallocateAuxStorage(LinearEquationSolverOperation operation) override;
virtual bool hasAuxStorage(LinearEquationSolverOperation operation) const override;
virtual bool allocateAuxMemory(LinearEquationSolverOperation operation) const override;
virtual bool deallocateAuxMemory(LinearEquationSolverOperation operation) const override;
virtual bool reallocateAuxMemory(LinearEquationSolverOperation operation) const override;
virtual bool hasAuxMemory(LinearEquationSolverOperation operation) const override;
private:
virtual uint64_t getMatrixRowCount() const override;
@ -75,8 +75,8 @@ namespace storm {
// The settings used by the solver.
NativeLinearEquationSolverSettings<ValueType> settings;
// Auxiliary storage for the equation solving methods.
mutable std::unique_ptr<std::vector<ValueType>> auxiliarySolvingStorage;
// Auxiliary memory for the equation solving methods.
mutable std::unique_ptr<std::vector<ValueType>> auxiliarySolvingMemory;
};
template<typename ValueType>

82
src/solver/StandardMinMaxLinearEquationSolver.cpp

@ -106,7 +106,7 @@ namespace storm {
// Create a solver that we will use throughout the procedure. We will modify the matrix in each iteration.
auto solver = linearEquationSolverFactory->create(std::move(submatrix));
solver->allocateAuxStorage(LinearEquationSolverOperation::SolveEquations);
solver->allocateAuxMemory(LinearEquationSolverOperation::SolveEquations);
Status status = Status::InProgress;
uint64_t iterations = 0;
@ -183,14 +183,13 @@ namespace storm {
template<typename ValueType>
void StandardMinMaxLinearEquationSolver<ValueType>::solveEquationsValueIteration(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const {
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory->create(A);
bool allocatedAuxStorage = !this->hasAuxStorage(MinMaxLinearEquationSolverOperation::SolveEquations);
if (allocatedAuxStorage) {
auxiliarySolvingMultiplyStorage = std::make_unique<std::vector<ValueType>>(this->A.getRowCount());
auxiliarySolvingVectorStorage = std::make_unique<std::vector<ValueType>>(x.size());
bool allocatedAuxMemory = !this->hasAuxMemory(MinMaxLinearEquationSolverOperation::SolveEquations);
if (allocatedAuxMemory) {
this->allocateAuxMemory(MinMaxLinearEquationSolverOperation::SolveEquations);
}
std::vector<ValueType>* currentX = &x;
std::vector<ValueType>* newX = auxiliarySolvingVectorStorage.get();
std::vector<ValueType>* newX = auxiliarySolvingVectorMemory.get();
// Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations.
uint64_t iterations = 0;
@ -198,10 +197,10 @@ namespace storm {
Status status = Status::InProgress;
while (status == Status::InProgress) {
// Compute x' = A*x + b.
solver->multiply(*currentX, &b, *auxiliarySolvingMultiplyStorage);
solver->multiply(*currentX, &b, *auxiliarySolvingMultiplyMemory);
// Reduce the vector x' by applying min/max for all non-deterministic choices.
storm::utility::vector::reduceVectorMinOrMax(dir, *auxiliarySolvingMultiplyStorage, *newX, this->A.getRowGroupIndices());
storm::utility::vector::reduceVectorMinOrMax(dir, *auxiliarySolvingMultiplyMemory, *newX, this->A.getRowGroupIndices());
// Determine whether the method converged.
if (storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, this->getSettings().getPrecision(), this->getSettings().getRelativeTerminationCriterion())) {
@ -218,37 +217,36 @@ namespace storm {
// If we performed an odd number of iterations, we need to swap the x and currentX, because the newest result
// is currently stored in currentX, but x is the output vector.
if (currentX == auxiliarySolvingVectorStorage.get()) {
if (currentX == auxiliarySolvingVectorMemory.get()) {
std::swap(x, *currentX);
}
// If we allocated auxiliary storage, we need to dispose of it now.
if (allocatedAuxStorage) {
auxiliarySolvingMultiplyStorage.reset();
auxiliarySolvingVectorStorage.reset();
// If we allocated auxiliary memory, we need to dispose of it now.
if (allocatedAuxMemory) {
this->deallocateAuxMemory(MinMaxLinearEquationSolverOperation::SolveEquations);
}
}
template<typename ValueType>
void StandardMinMaxLinearEquationSolver<ValueType>::multiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const {
bool allocatedAuxStorage = !this->hasAuxStorage(MinMaxLinearEquationSolverOperation::MultiplyRepeatedly);
if (allocatedAuxStorage) {
auxiliaryRepeatedMultiplyStorage = std::make_unique<std::vector<ValueType>>(this->A.getRowCount());
void StandardMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const {
bool allocatedAuxMemory = !this->hasAuxMemory(MinMaxLinearEquationSolverOperation::MultiplyRepeatedly);
if (allocatedAuxMemory) {
this->allocateAuxMemory(MinMaxLinearEquationSolverOperation::MultiplyRepeatedly);
}
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory->create(A);
for (uint64_t i = 0; i < n; ++i) {
solver->multiply(x, b, *auxiliaryRepeatedMultiplyStorage);
solver->multiply(x, b, *auxiliaryRepeatedMultiplyMemory);
// Reduce the vector x' by applying min/max for all non-deterministic choices as given by the topmost
// element of the min/max operator stack.
storm::utility::vector::reduceVectorMinOrMax(dir, *auxiliaryRepeatedMultiplyStorage, x, this->A.getRowGroupIndices());
storm::utility::vector::reduceVectorMinOrMax(dir, *auxiliaryRepeatedMultiplyMemory, x, this->A.getRowGroupIndices());
}
// If we allocated auxiliary storage, we need to dispose of it now.
if (allocatedAuxStorage) {
auxiliaryRepeatedMultiplyStorage.reset();
// If we allocated auxiliary memory, we need to dispose of it now.
if (allocatedAuxMemory) {
this->deallocateAuxMemory(MinMaxLinearEquationSolverOperation::MultiplyRepeatedly);
}
}
@ -286,47 +284,44 @@ namespace storm {
}
template<typename ValueType>
bool StandardMinMaxLinearEquationSolver<ValueType>::allocateAuxStorage(MinMaxLinearEquationSolverOperation operation) {
bool StandardMinMaxLinearEquationSolver<ValueType>::allocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const {
bool result = false;
if (operation == MinMaxLinearEquationSolverOperation::SolveEquations) {
if (this->getSettings().getSolutionMethod() == StandardMinMaxLinearEquationSolverSettings<ValueType>::SolutionMethod::ValueIteration) {
if (!auxiliarySolvingMultiplyStorage) {
if (!auxiliarySolvingMultiplyMemory) {
result = true;
auxiliarySolvingMultiplyStorage = std::make_unique<std::vector<ValueType>>(this->A.getRowCount());
auxiliarySolvingMultiplyMemory = std::make_unique<std::vector<ValueType>>(this->A.getRowCount());
}
if (!auxiliarySolvingVectorStorage) {
if (!auxiliarySolvingVectorMemory) {
result = true;
auxiliarySolvingVectorStorage = std::make_unique<std::vector<ValueType>>(this->A.getRowGroupCount());
auxiliarySolvingVectorMemory = std::make_unique<std::vector<ValueType>>(this->A.getRowGroupCount());
}
} else if (this->getSettings().getSolutionMethod() == StandardMinMaxLinearEquationSolverSettings<ValueType>::SolutionMethod::PolicyIteration) {
if (!auxiliarySolvingVectorStorage) {
result = true;
auxiliarySolvingVectorStorage = std::make_unique<std::vector<ValueType>>(this->A.getRowGroupCount());
}
// Nothing to do in this case.
} else {
STORM_LOG_ASSERT(false, "Cannot allocate aux storage for this method.");
}
} else {
if (!auxiliaryRepeatedMultiplyStorage) {
if (!auxiliaryRepeatedMultiplyMemory) {
result = true;
auxiliaryRepeatedMultiplyStorage = std::make_unique<std::vector<ValueType>>(this->A.getRowCount());
auxiliaryRepeatedMultiplyMemory = std::make_unique<std::vector<ValueType>>(this->A.getRowCount());
}
}
return result;
}
template<typename ValueType>
bool StandardMinMaxLinearEquationSolver<ValueType>::deallocateAuxStorage(MinMaxLinearEquationSolverOperation operation) {
bool StandardMinMaxLinearEquationSolver<ValueType>::deallocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const {
bool result = false;
if (operation == MinMaxLinearEquationSolverOperation::SolveEquations) {
if (this->getSettings().getSolutionMethod() == StandardMinMaxLinearEquationSolverSettings<ValueType>::SolutionMethod::ValueIteration) {
if (auxiliarySolvingMultiplyStorage) {
if (auxiliarySolvingMultiplyMemory) {
result = true;
auxiliarySolvingMultiplyStorage.reset();
auxiliarySolvingMultiplyMemory.reset();
}
if (auxiliarySolvingVectorStorage) {
if (auxiliarySolvingVectorMemory) {
result = true;
auxiliarySolvingVectorStorage.reset();
auxiliarySolvingVectorMemory.reset();
}
} else if (this->getSettings().getSolutionMethod() == StandardMinMaxLinearEquationSolverSettings<ValueType>::SolutionMethod::PolicyIteration) {
// Nothing to do in this case.
@ -334,23 +329,24 @@ namespace storm {
STORM_LOG_ASSERT(false, "Cannot allocate aux storage for this method.");
}
} else {
if (auxiliaryRepeatedMultiplyStorage) {
if (auxiliaryRepeatedMultiplyMemory) {
result = true;
auxiliaryRepeatedMultiplyStorage.reset();
auxiliaryRepeatedMultiplyMemory.reset();
}
}
return result;
}
template<typename ValueType>
bool StandardMinMaxLinearEquationSolver<ValueType>::hasAuxStorage(MinMaxLinearEquationSolverOperation operation) const {
bool StandardMinMaxLinearEquationSolver<ValueType>::hasAuxMemory(MinMaxLinearEquationSolverOperation operation) const {
if (operation == MinMaxLinearEquationSolverOperation::SolveEquations) {
if (this->getSettings().getSolutionMethod() == StandardMinMaxLinearEquationSolverSettings<ValueType>::SolutionMethod::ValueIteration) {
return auxiliarySolvingMultiplyStorage && auxiliarySolvingVectorStorage;
return auxiliarySolvingMultiplyMemory && auxiliarySolvingVectorMemory;
} else {
return false;
}
} else {
return static_cast<bool>(auxiliaryRepeatedMultiplyStorage);
return static_cast<bool>(auxiliaryRepeatedMultiplyMemory);
}
}

19
src/solver/StandardMinMaxLinearEquationSolver.h

@ -39,14 +39,14 @@ namespace storm {
StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, StandardMinMaxLinearEquationSolverSettings<ValueType> const& settings = StandardMinMaxLinearEquationSolverSettings<ValueType>());
virtual void solveEquations(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override;
virtual void multiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const override;
virtual void repeatedMultiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const override;
StandardMinMaxLinearEquationSolverSettings<ValueType> const& getSettings() const;
StandardMinMaxLinearEquationSolverSettings<ValueType>& getSettings();
virtual bool allocateAuxStorage(MinMaxLinearEquationSolverOperation operation) override;
virtual bool deallocateAuxStorage(MinMaxLinearEquationSolverOperation operation) override;
virtual bool hasAuxStorage(MinMaxLinearEquationSolverOperation operation) const override;
virtual bool allocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const override;
virtual bool deallocateAuxMemory(MinMaxLinearEquationSolverOperation operation) const override;
virtual bool hasAuxMemory(MinMaxLinearEquationSolverOperation operation) const override;
private:
void solveEquationsPolicyIteration(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const;
@ -75,13 +75,12 @@ namespace storm {
// the reference refers to localA.
storm::storage::SparseMatrix<ValueType> const& A;
// Auxiliary storage for equation solving.
// Auxiliary storage for repeated matrix-vector multiplication.
mutable std::unique_ptr<std::vector<ValueType>> auxiliarySolvingMultiplyStorage;
mutable std::unique_ptr<std::vector<ValueType>> auxiliarySolvingVectorStorage;
// Auxiliary memory for equation solving.
mutable std::unique_ptr<std::vector<ValueType>> auxiliarySolvingMultiplyMemory;
mutable std::unique_ptr<std::vector<ValueType>> auxiliarySolvingVectorMemory;
// Auxiliary storage for repeated matrix-vector multiplication.
mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRepeatedMultiplyStorage;
// Auxiliary memory for repeated matrix-vector multiplication.
mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRepeatedMultiplyMemory;
};
template<typename ValueType>

18
src/solver/TopologicalMinMaxLinearEquationSolver.cpp

@ -33,7 +33,7 @@ namespace storm {
}
template<typename ValueType>
void TopologicalMinMaxLinearEquationSolver<ValueType>::solveEquations(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult, std::vector<ValueType>* newX) const {
void TopologicalMinMaxLinearEquationSolver<ValueType>::solveEquations(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const {
#ifdef GPU_USE_FLOAT
#define __FORCE_FLOAT_CALCULATION true
@ -49,7 +49,7 @@ namespace storm {
std::vector<float> new_x = storm::utility::vector::toValueType<float>(x);
std::vector<float> const new_b = storm::utility::vector::toValueType<float>(b);
newSolver.solveEquations(dir, new_x, new_b, nullptr, nullptr);
newSolver.solveEquations(dir, new_x, new_b);
for (size_t i = 0, size = new_x.size(); i < size; ++i) {
x.at(i) = new_x.at(i);
@ -422,14 +422,8 @@ namespace storm {
}
template<typename ValueType>
void TopologicalMinMaxLinearEquationSolver<ValueType>::multiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n, std::vector<ValueType>* multiplyResult) const {
// If scratch memory was not provided, we need to create it.
bool multiplyResultMemoryProvided = true;
if (multiplyResult == nullptr) {
multiplyResult = new std::vector<ValueType>(this->A.getRowCount());
multiplyResultMemoryProvided = false;
}
void TopologicalMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const {
std::unique_ptr<std::vector<ValueType>> multiplyResult = std::make_unique<std::vector<ValueType>>(this->A.getRowCount());
// Now perform matrix-vector multiplication as long as we meet the bound of the formula.
for (uint_fast64_t i = 0; i < n; ++i) {
@ -445,10 +439,6 @@ namespace storm {
storm::utility::vector::reduceVectorMinOrMax(dir, *multiplyResult, x, this->A.getRowGroupIndices());
}
if (!multiplyResultMemoryProvided) {
delete multiplyResult;
}
}
template<typename ValueType>

4
src/solver/TopologicalMinMaxLinearEquationSolver.h

@ -32,9 +32,9 @@ namespace storm {
*/
TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, double precision = 1e-6, uint_fast64_t maximalNumberOfIterations = 20000, bool relative = true);
virtual void solveEquations(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult = nullptr, std::vector<ValueType>* newX = nullptr) const override;
virtual void solveEquations(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override;
virtual void multiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n, std::vector<ValueType>* multiplyResult) const override;
virtual void repeatedMultiply(OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const override;
private:
storm::storage::SparseMatrix<ValueType> const& A;

10
test/functional/solver/GmmxxMinMaxLinearEquationSolverTest.cpp

@ -78,23 +78,23 @@ TEST(GmmxxMinMaxLinearEquationSolver, MatrixVectorMultiplication) {
auto factory = storm::solver::GmmxxMinMaxLinearEquationSolverFactory<double>();
auto solver = factory.create(A);
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Minimize, x, nullptr, 1));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Minimize, x, nullptr, 1));
ASSERT_LT(std::abs(x[0] - 0.099), storm::settings::getModule<storm::settings::modules::GmmxxEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Minimize, x, nullptr, 2));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Minimize, x, nullptr, 2));
ASSERT_LT(std::abs(x[0] - 0.1881), storm::settings::getModule<storm::settings::modules::GmmxxEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Minimize, x, nullptr, 20));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Minimize, x, nullptr, 20));
ASSERT_LT(std::abs(x[0] - 0.5), storm::settings::getModule<storm::settings::modules::GmmxxEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Maximize, x, nullptr, 1));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Maximize, x, nullptr, 1));
ASSERT_LT(std::abs(x[0] - 0.5), storm::settings::getModule<storm::settings::modules::GmmxxEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Maximize, x, nullptr, 20));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Maximize, x, nullptr, 20));
ASSERT_LT(std::abs(x[0] - 0.9238082658), storm::settings::getModule<storm::settings::modules::GmmxxEquationSolverSettings>().getPrecision());
}

10
test/functional/solver/NativeMinMaxLinearEquationSolverTest.cpp

@ -49,23 +49,23 @@ TEST(NativeMinMaxLinearEquationSolver, MatrixVectorMultiplication) {
auto factory = storm::solver::NativeMinMaxLinearEquationSolverFactory<double>();
auto solver = factory.create(A);
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Minimize, x, nullptr, 1));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Minimize, x, nullptr, 1));
ASSERT_LT(std::abs(x[0] - 0.099), storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Minimize, x, nullptr, 2));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Minimize, x, nullptr, 2));
ASSERT_LT(std::abs(x[0] - 0.1881), storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Minimize, x, nullptr, 20));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Minimize, x, nullptr, 20));
ASSERT_LT(std::abs(x[0] - 0.5), storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Maximize, x, nullptr, 1));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Maximize, x, nullptr, 1));
ASSERT_LT(std::abs(x[0] - 0.5), storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
x = {0, 1, 0};
ASSERT_NO_THROW(solver->multiply(storm::OptimizationDirection::Maximize, x, nullptr, 20));
ASSERT_NO_THROW(solver->repeatedMultiply(storm::OptimizationDirection::Maximize, x, nullptr, 20));
ASSERT_LT(std::abs(x[0] - 0.9238082658), storm::settings::getModule<storm::settings::modules::NativeEquationSolverSettings>().getPrecision());
}

Loading…
Cancel
Save