dehnert
7 years ago
13 changed files with 756 additions and 483 deletions
-
299src/storm/modelchecker/prctl/helper/DsMpiUpperRewardBoundsComputer.cpp
-
98src/storm/modelchecker/prctl/helper/DsMpiUpperRewardBoundsComputer.h
-
142src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
-
118src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
-
158src/storm/solver/AbstractEquationSolver.cpp
-
107src/storm/solver/AbstractEquationSolver.h
-
29src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp
-
116src/storm/solver/LinearEquationSolver.cpp
-
88src/storm/solver/LinearEquationSolver.h
-
38src/storm/solver/MinMaxLinearEquationSolver.cpp
-
43src/storm/solver/MinMaxLinearEquationSolver.h
-
2src/storm/solver/NativeLinearEquationSolver.cpp
-
1src/storm/storage/ConsecutiveUint64DynamicPriorityQueue.h
@ -0,0 +1,299 @@ |
|||||
|
#include "storm/modelchecker/prctl/helper/DsMpiUpperRewardBoundsComputer.h"
|
||||
|
|
||||
|
#include "storm-config.h"
|
||||
|
|
||||
|
#include "storm/storage/BitVector.h"
|
||||
|
#include "storm/storage/ConsecutiveUint64DynamicPriorityQueue.h"
|
||||
|
#include "storm/storage/SparseMatrix.h"
|
||||
|
|
||||
|
#include "storm/storage/sparse/StateType.h"
|
||||
|
|
||||
|
#include "storm/utility/macros.h"
|
||||
|
#include "storm/utility/constants.h"
|
||||
|
#include "storm/utility/ConstantsComparator.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace modelchecker { |
||||
|
namespace helper { |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
DsMpiDtmcUpperRewardBoundsComputer<ValueType>::DsMpiDtmcUpperRewardBoundsComputer(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& rewards, std::vector<ValueType> const& oneStepTargetProbabilities) : transitionMatrix(transitionMatrix), originalRewards(rewards), originalOneStepTargetProbabilities(oneStepTargetProbabilities), backwardTransitions(transitionMatrix.transpose()), p(transitionMatrix.getRowGroupCount()), w(transitionMatrix.getRowGroupCount()), rewards(rewards), targetProbabilities(oneStepTargetProbabilities) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
std::vector<ValueType> DsMpiDtmcUpperRewardBoundsComputer<ValueType>::computeUpperBounds() { |
||||
|
sweep(); |
||||
|
ValueType lambda = computeLambda(); |
||||
|
STORM_LOG_TRACE("DS-MPI computed lambda as " << lambda << "."); |
||||
|
|
||||
|
// Finally compute the upper bounds for the states.
|
||||
|
std::vector<ValueType> result(transitionMatrix.getRowGroupCount()); |
||||
|
auto one = storm::utility::one<ValueType>(); |
||||
|
for (storm::storage::sparse::state_type state = 0; state < result.size(); ++state) { |
||||
|
result[state] = w[state] + (one - p[state]) * lambda; |
||||
|
} |
||||
|
|
||||
|
#ifndef NDEBUG
|
||||
|
ValueType max = storm::utility::zero<ValueType>(); |
||||
|
uint64_t nonZeroCount = 0; |
||||
|
for (auto const& e : result) { |
||||
|
if (!storm::utility::isZero(e)) { |
||||
|
++nonZeroCount; |
||||
|
max = std::max(max, e); |
||||
|
} |
||||
|
} |
||||
|
STORM_LOG_TRACE("DS-MPI computed " << nonZeroCount << " non-zero upper bounds and a maximal bound of " << max << "."); |
||||
|
#endif
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
ValueType DsMpiDtmcUpperRewardBoundsComputer<ValueType>::computeLambda() const { |
||||
|
ValueType lambda = storm::utility::zero<ValueType>(); |
||||
|
for (storm::storage::sparse::state_type state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { |
||||
|
lambda = std::max(lambda, computeLambdaForChoice(state)); |
||||
|
} |
||||
|
return lambda; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
ValueType DsMpiDtmcUpperRewardBoundsComputer<ValueType>::computeLambdaForChoice(uint64_t choice) const { |
||||
|
ValueType localLambda = storm::utility::zero<ValueType>(); |
||||
|
uint64_t state = this->getStateForChoice(choice); |
||||
|
|
||||
|
// Check whether condition (I) or (II) applies.
|
||||
|
ValueType sum = storm::utility::zero<ValueType>(); |
||||
|
for (auto const& e : transitionMatrix.getRow(choice)) { |
||||
|
sum += e.getValue() * p[e.getColumn()]; |
||||
|
} |
||||
|
sum += originalOneStepTargetProbabilities[choice]; |
||||
|
|
||||
|
if (p[state] < sum) { |
||||
|
STORM_LOG_TRACE("Condition (I) does apply for state " << state << " as " << p[state] << " < " << sum << "."); |
||||
|
// Condition (I) applies.
|
||||
|
localLambda = sum - p[state]; |
||||
|
ValueType nominator = originalRewards[choice]; |
||||
|
for (auto const& e : transitionMatrix.getRow(choice)) { |
||||
|
nominator += e.getValue() * w[e.getColumn()]; |
||||
|
} |
||||
|
nominator -= w[state]; |
||||
|
localLambda = nominator / localLambda; |
||||
|
} else { |
||||
|
STORM_LOG_TRACE("Condition (I) does not apply for state " << state << " as " << p[state] << " < " << sum << "."); |
||||
|
// Here, condition (II) automatically applies and as the resulting local lambda is 0, we
|
||||
|
// don't need to consider it.
|
||||
|
|
||||
|
#ifndef NDEBUG
|
||||
|
// Actually check condition (II).
|
||||
|
ValueType sum = originalRewards[choice]; |
||||
|
for (auto const& e : transitionMatrix.getRow(choice)) { |
||||
|
sum += e.getValue() * w[e.getColumn()]; |
||||
|
} |
||||
|
STORM_LOG_WARN_COND(w[state] >= sum || storm::utility::ConstantsComparator<ValueType>().isEqual(w[state], sum), "Expected condition (II) to hold in state " << state << ", but " << w[state] << " < " << sum << "."); |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
return localLambda; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
uint64_t DsMpiDtmcUpperRewardBoundsComputer<ValueType>::getStateForChoice(uint64_t choice) const { |
||||
|
return choice; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class DsMpiDtmcPriorityLess { |
||||
|
public: |
||||
|
DsMpiDtmcPriorityLess(DsMpiDtmcUpperRewardBoundsComputer<ValueType> const& dsmpi) : dsmpi(dsmpi) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
bool operator()(storm::storage::sparse::state_type const& a, storm::storage::sparse::state_type const& b) { |
||||
|
ValueType pa = dsmpi.targetProbabilities[a]; |
||||
|
ValueType pb = dsmpi.targetProbabilities[b]; |
||||
|
if (pa < pb) { |
||||
|
return true; |
||||
|
} else if (pa == pb) { |
||||
|
return dsmpi.rewards[a] > dsmpi.rewards[b]; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
DsMpiDtmcUpperRewardBoundsComputer<ValueType> const& dsmpi; |
||||
|
}; |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void DsMpiDtmcUpperRewardBoundsComputer<ValueType>::sweep() { |
||||
|
// Create a priority queue that allows for easy retrieval of the currently best state.
|
||||
|
storm::storage::ConsecutiveUint64DynamicPriorityQueue<DsMpiDtmcPriorityLess<ValueType>> queue(transitionMatrix.getRowCount(), DsMpiDtmcPriorityLess<ValueType>(*this)); |
||||
|
|
||||
|
// Keep track of visited states.
|
||||
|
storm::storage::BitVector visited(p.size()); |
||||
|
|
||||
|
while (!queue.empty()) { |
||||
|
// Get first entry in queue.
|
||||
|
storm::storage::sparse::state_type currentState = queue.popTop(); |
||||
|
|
||||
|
// Mark state as visited.
|
||||
|
visited.set(currentState); |
||||
|
|
||||
|
// Set weight and probability for the state.
|
||||
|
w[currentState] = rewards[currentState]; |
||||
|
p[currentState] = targetProbabilities[currentState]; |
||||
|
|
||||
|
for (auto const& e : backwardTransitions.getRow(currentState)) { |
||||
|
if (visited.get(e.getColumn())) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// Update reward/probability values.
|
||||
|
rewards[e.getColumn()] += e.getValue() * w[currentState]; |
||||
|
targetProbabilities[e.getColumn()] += e.getValue() * p[currentState]; |
||||
|
|
||||
|
// Increase priority of element.
|
||||
|
queue.increase(e.getColumn()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
DsMpiMdpUpperRewardBoundsComputer<ValueType>::DsMpiMdpUpperRewardBoundsComputer(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& rewards, std::vector<ValueType> const& oneStepTargetProbabilities) : DsMpiDtmcUpperRewardBoundsComputer<ValueType>(transitionMatrix, rewards, oneStepTargetProbabilities), policy(transitionMatrix.getRowCount()) { |
||||
|
|
||||
|
// Create a mapping from choices to states.
|
||||
|
// Also pick a choice in each state that maximizes the target probability and minimizes the reward.
|
||||
|
choiceToState.resize(transitionMatrix.getRowCount()); |
||||
|
for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { |
||||
|
uint64_t choice = transitionMatrix.getRowGroupIndices()[state]; |
||||
|
|
||||
|
boost::optional<ValueType> minReward; |
||||
|
ValueType maxProb = storm::utility::zero<ValueType>(); |
||||
|
|
||||
|
for (uint64_t row = choice, endRow = transitionMatrix.getRowGroupIndices()[state + 1]; row < endRow; ++row) { |
||||
|
choiceToState[row] = state; |
||||
|
|
||||
|
if (this->targetProbabilities[row] > maxProb) { |
||||
|
maxProb = this->targetProbabilities[row]; |
||||
|
minReward = this->rewards[row]; |
||||
|
choice = row; |
||||
|
} else if (this->targetProbabilities[row] == maxProb && (!minReward || minReward.get() > this->rewards[row])) { |
||||
|
minReward = this->rewards[row]; |
||||
|
choice = row; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
setChoiceInState(state, choice); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
ValueType DsMpiMdpUpperRewardBoundsComputer<ValueType>::computeLambda() const { |
||||
|
ValueType lambda = storm::utility::zero<ValueType>(); |
||||
|
for (storm::storage::sparse::state_type state = 0; state < this->transitionMatrix.getRowGroupCount(); ++state) { |
||||
|
lambda = std::max(lambda, this->computeLambdaForChoice(this->getChoiceInState(state))); |
||||
|
} |
||||
|
return lambda; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
uint64_t DsMpiMdpUpperRewardBoundsComputer<ValueType>::getStateForChoice(uint64_t choice) const { |
||||
|
return choiceToState[choice]; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class DsMpiMdpPriorityLess { |
||||
|
public: |
||||
|
DsMpiMdpPriorityLess(DsMpiMdpUpperRewardBoundsComputer<ValueType> const& dsmpi) : dsmpi(dsmpi) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
bool operator()(storm::storage::sparse::state_type const& a, storm::storage::sparse::state_type const& b) { |
||||
|
uint64_t choiceA = dsmpi.getChoiceInState(a); |
||||
|
uint64_t choiceB = dsmpi.getChoiceInState(b); |
||||
|
|
||||
|
ValueType pa = dsmpi.targetProbabilities[choiceA]; |
||||
|
ValueType pb = dsmpi.targetProbabilities[choiceB]; |
||||
|
if (pa < pb) { |
||||
|
return true; |
||||
|
} else if (pa == pb) { |
||||
|
return dsmpi.rewards[choiceB] > dsmpi.rewards[choiceB]; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
DsMpiMdpUpperRewardBoundsComputer<ValueType> const& dsmpi; |
||||
|
}; |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void DsMpiMdpUpperRewardBoundsComputer<ValueType>::sweep() { |
||||
|
// Create a priority queue that allows for easy retrieval of the currently best state.
|
||||
|
storm::storage::ConsecutiveUint64DynamicPriorityQueue<DsMpiMdpPriorityLess<ValueType>> queue(this->transitionMatrix.getRowGroupCount(), DsMpiMdpPriorityLess<ValueType>(*this)); |
||||
|
|
||||
|
// Keep track of visited states.
|
||||
|
storm::storage::BitVector visited(this->transitionMatrix.getRowGroupCount()); |
||||
|
|
||||
|
while (!queue.empty()) { |
||||
|
// Get first entry in queue.
|
||||
|
storm::storage::sparse::state_type currentState = queue.popTop(); |
||||
|
|
||||
|
// Mark state as visited.
|
||||
|
visited.set(currentState); |
||||
|
|
||||
|
// Set weight and probability for the state.
|
||||
|
uint64_t choiceInCurrentState = this->getChoiceInState(currentState); |
||||
|
this->w[currentState] = this->rewards[choiceInCurrentState]; |
||||
|
this->p[currentState] = this->targetProbabilities[choiceInCurrentState]; |
||||
|
|
||||
|
for (auto const& choiceEntry : this->backwardTransitions.getRow(currentState)) { |
||||
|
uint64_t predecessor = this->getStateForChoice(choiceEntry.getColumn()); |
||||
|
if (visited.get(predecessor)) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// Update reward/probability values.
|
||||
|
this->rewards[choiceEntry.getColumn()] += choiceEntry.getValue() * this->w[currentState]; |
||||
|
this->targetProbabilities[choiceEntry.getColumn()] += choiceEntry.getValue() * this->p[currentState]; |
||||
|
|
||||
|
// If the choice is not the one that is currently taken in the predecessor state, we might need
|
||||
|
// to update it.
|
||||
|
uint64_t currentChoiceInPredecessor = this->getChoiceInState(predecessor); |
||||
|
if (currentChoiceInPredecessor != choiceEntry.getColumn()) { |
||||
|
// Check whether the updates choice now becomes a better choice in the predecessor state.
|
||||
|
ValueType const& newTargetProbability = this->targetProbabilities[choiceEntry.getColumn()]; |
||||
|
ValueType const& newReward = this->rewards[choiceEntry.getColumn()]; |
||||
|
ValueType const& currentTargetProbability = this->targetProbabilities[this->getChoiceInState(predecessor)]; |
||||
|
ValueType const& currentReward = this->rewards[this->getChoiceInState(predecessor)]; |
||||
|
|
||||
|
if (newTargetProbability > currentTargetProbability || (newTargetProbability == currentTargetProbability && newReward < currentReward)) { |
||||
|
setChoiceInState(predecessor, choiceEntry.getColumn()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Notify the priority of a potential increase of the priority of the element.
|
||||
|
queue.increase(predecessor); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
uint64_t DsMpiMdpUpperRewardBoundsComputer<ValueType>::getChoiceInState(uint64_t state) const { |
||||
|
return policy[state]; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void DsMpiMdpUpperRewardBoundsComputer<ValueType>::setChoiceInState(uint64_t state, uint64_t choice) { |
||||
|
policy[state] = choice; |
||||
|
} |
||||
|
|
||||
|
template class DsMpiDtmcUpperRewardBoundsComputer<double>; |
||||
|
template class DsMpiMdpUpperRewardBoundsComputer<double>; |
||||
|
|
||||
|
#ifdef STORM_HAVE_CARL
|
||||
|
template class DsMpiDtmcUpperRewardBoundsComputer<storm::RationalNumber>; |
||||
|
template class DsMpiMdpUpperRewardBoundsComputer<storm::RationalNumber>; |
||||
|
#endif
|
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,98 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <vector> |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
template<typename ValueType> |
||||
|
class SparseMatrix; |
||||
|
} |
||||
|
|
||||
|
namespace modelchecker { |
||||
|
namespace helper { |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class DsMpiDtmcPriorityLess; |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class DsMpiDtmcUpperRewardBoundsComputer { |
||||
|
public: |
||||
|
/*! |
||||
|
* Creates an object that can compute upper bounds on the expected rewards for the provided DTMC. |
||||
|
* |
||||
|
* @param transitionMatrix The matrix defining the transitions of the system without the transitions |
||||
|
* that lead directly to the goal state. |
||||
|
* @param rewards The rewards of each state. |
||||
|
* @param oneStepTargetProbabilities For each state the probability to go to a goal state in one step. |
||||
|
*/ |
||||
|
DsMpiDtmcUpperRewardBoundsComputer(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& rewards, std::vector<ValueType> const& oneStepTargetProbabilities); |
||||
|
|
||||
|
/*! |
||||
|
* Computes upper bounds on the expected rewards. |
||||
|
*/ |
||||
|
std::vector<ValueType> computeUpperBounds(); |
||||
|
|
||||
|
protected: |
||||
|
/*! |
||||
|
* Performs a Dijkstra sweep. |
||||
|
*/ |
||||
|
virtual void sweep(); |
||||
|
|
||||
|
/*! |
||||
|
* Computes the lambda used for the estimation. |
||||
|
*/ |
||||
|
virtual ValueType computeLambda() const; |
||||
|
|
||||
|
/*! |
||||
|
* Computes the lambda just for the provided choice. |
||||
|
*/ |
||||
|
ValueType computeLambdaForChoice(uint64_t choice) const; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the state associated with the given choice. |
||||
|
*/ |
||||
|
virtual uint64_t getStateForChoice(uint64_t choice) const; |
||||
|
|
||||
|
// References to input data. |
||||
|
storm::storage::SparseMatrix<ValueType> const& transitionMatrix; |
||||
|
std::vector<ValueType> const& originalRewards; |
||||
|
std::vector<ValueType> const& originalOneStepTargetProbabilities; |
||||
|
|
||||
|
// Derived from input data. |
||||
|
storm::storage::SparseMatrix<ValueType> backwardTransitions; |
||||
|
|
||||
|
// Data that the algorithm uses internally. |
||||
|
std::vector<ValueType> p; |
||||
|
std::vector<ValueType> w; |
||||
|
std::vector<ValueType> rewards; |
||||
|
std::vector<ValueType> targetProbabilities; |
||||
|
|
||||
|
friend class DsMpiDtmcPriorityLess<ValueType>; |
||||
|
}; |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class DsMpiMdpPriorityLess; |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class DsMpiMdpUpperRewardBoundsComputer : public DsMpiDtmcUpperRewardBoundsComputer<ValueType> { |
||||
|
public: |
||||
|
/*! |
||||
|
* Creates an object that can compute upper bounds on the expected rewards for the provided DTMC. |
||||
|
*/ |
||||
|
DsMpiMdpUpperRewardBoundsComputer(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& rewards, std::vector<ValueType> const& oneStepTargetProbabilities); |
||||
|
|
||||
|
private: |
||||
|
virtual void sweep() override; |
||||
|
virtual ValueType computeLambda() const override; |
||||
|
virtual uint64_t getStateForChoice(uint64_t choice) const override; |
||||
|
uint64_t getChoiceInState(uint64_t state) const; |
||||
|
void setChoiceInState(uint64_t state, uint64_t choice); |
||||
|
|
||||
|
std::vector<uint64_t> choiceToState; |
||||
|
std::vector<uint64_t> policy; |
||||
|
|
||||
|
friend class DsMpiMdpPriorityLess<ValueType>; |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,158 @@ |
|||||
|
#include "storm/solver/AbstractEquationSolver.h"
|
||||
|
|
||||
|
#include "storm/adapters/RationalNumberAdapter.h"
|
||||
|
#include "storm/adapters/RationalFunctionAdapter.h"
|
||||
|
|
||||
|
#include "storm/utility/macros.h"
|
||||
|
#include "storm/exceptions/UnmetRequirementException.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace solver { |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setTerminationCondition(std::unique_ptr<TerminationCondition<ValueType>> terminationCondition) { |
||||
|
this->terminationCondition = std::move(terminationCondition); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::resetTerminationCondition() { |
||||
|
this->terminationCondition = nullptr; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
bool AbstractEquationSolver<ValueType>::hasCustomTerminationCondition() const { |
||||
|
return static_cast<bool>(this->terminationCondition); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
TerminationCondition<ValueType> const& AbstractEquationSolver<ValueType>::getTerminationCondition() const { |
||||
|
return *terminationCondition; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
bool AbstractEquationSolver<ValueType>::hasLowerBound(BoundType const& type) const { |
||||
|
if (type == BoundType::Any) { |
||||
|
return static_cast<bool>(lowerBound) || static_cast<bool>(lowerBounds); |
||||
|
} else if (type == BoundType::Global) { |
||||
|
return static_cast<bool>(lowerBound); |
||||
|
} else if (type == BoundType::Local) { |
||||
|
return static_cast<bool>(lowerBounds); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
bool AbstractEquationSolver<ValueType>::hasUpperBound(BoundType const& type) const { |
||||
|
if (type == BoundType::Any) { |
||||
|
return static_cast<bool>(upperBound) || static_cast<bool>(upperBounds); |
||||
|
} else if (type == BoundType::Global) { |
||||
|
return static_cast<bool>(upperBound); |
||||
|
} else if (type == BoundType::Local) { |
||||
|
return static_cast<bool>(upperBounds); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setLowerBound(ValueType const& value) { |
||||
|
lowerBound = value; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setUpperBound(ValueType const& value) { |
||||
|
upperBound = value; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setBounds(ValueType const& lower, ValueType const& upper) { |
||||
|
setLowerBound(lower); |
||||
|
setUpperBound(upper); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
ValueType const& AbstractEquationSolver<ValueType>::getLowerBound() const { |
||||
|
return lowerBound.get(); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
ValueType const& AbstractEquationSolver<ValueType>::getUpperBound() const { |
||||
|
return upperBound.get(); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
std::vector<ValueType> const& AbstractEquationSolver<ValueType>::getLowerBounds() const { |
||||
|
return lowerBounds.get(); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
std::vector<ValueType> const& AbstractEquationSolver<ValueType>::getUpperBounds() const { |
||||
|
return upperBounds.get(); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setLowerBounds(std::vector<ValueType> const& values) { |
||||
|
lowerBounds = values; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setUpperBounds(std::vector<ValueType> const& values) { |
||||
|
upperBounds = values; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setUpperBounds(std::vector<ValueType>&& values) { |
||||
|
upperBounds = std::move(values); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::setBounds(std::vector<ValueType> const& lower, std::vector<ValueType> const& upper) { |
||||
|
setLowerBounds(lower); |
||||
|
setUpperBounds(upper); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::createLowerBoundsVector(std::vector<ValueType>& lowerBoundsVector) const { |
||||
|
if (this->hasLowerBound(BoundType::Local)) { |
||||
|
lowerBoundsVector = this->getLowerBounds(); |
||||
|
} else { |
||||
|
STORM_LOG_THROW(this->hasLowerBound(BoundType::Global), storm::exceptions::UnmetRequirementException, "Cannot create lower bounds vector without lower bound."); |
||||
|
for (auto& e : lowerBoundsVector) { |
||||
|
e = this->getLowerBound(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void AbstractEquationSolver<ValueType>::createUpperBoundsVector(std::unique_ptr<std::vector<ValueType>>& upperBoundsVector, uint64_t length) const { |
||||
|
STORM_LOG_ASSERT(this->hasUpperBound(), "Expecting upper bound(s)."); |
||||
|
if (!upperBoundsVector) { |
||||
|
if (this->hasUpperBound(BoundType::Local)) { |
||||
|
STORM_LOG_ASSERT(length == this->getUpperBounds().size(), "Mismatching sizes."); |
||||
|
upperBoundsVector = std::make_unique<std::vector<ValueType>>(this->getUpperBounds()); |
||||
|
} else { |
||||
|
upperBoundsVector = std::make_unique<std::vector<ValueType>>(length, this->getUpperBound()); |
||||
|
} |
||||
|
} else { |
||||
|
if (this->hasUpperBound(BoundType::Global)) { |
||||
|
for (auto& e : *upperBoundsVector) { |
||||
|
e = this->getUpperBound(); |
||||
|
} |
||||
|
} else { |
||||
|
auto upperBoundsIt = this->getUpperBounds().begin(); |
||||
|
for (auto& e : *upperBoundsVector) { |
||||
|
e = *upperBoundsIt; |
||||
|
++upperBoundsIt; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template class AbstractEquationSolver<double>; |
||||
|
|
||||
|
#ifdef STORM_HAVE_CARL
|
||||
|
template class AbstractEquationSolver<storm::RationalNumber>; |
||||
|
template class AbstractEquationSolver<storm::RationalFunction>; |
||||
|
#endif
|
||||
|
|
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue