21namespace modelchecker {
22namespace multiobjective {
24template<
class SparseMaModelType>
31template<
class SparseMaModelType>
33 markovianStates = model.getMarkovianStates();
34 exitRates = model.getExitRates();
37 this->actionRewards.assign(this->objectives.size(), {});
38 this->stateRewards.assign(this->objectives.size(), {});
39 for (uint64_t objIndex = 0; objIndex < this->objectives.size(); ++objIndex) {
40 auto const& formula = *this->objectives[objIndex].formula;
41 STORM_LOG_THROW(formula.isRewardOperatorFormula() && formula.asRewardOperatorFormula().hasRewardModelName(), storm::exceptions::UnexpectedException,
42 "Unexpected type of operator formula: " << formula);
43 typename SparseMaModelType::RewardModelType
const& rewModel = model.getRewardModel(formula.asRewardOperatorFormula().getRewardModelName());
44 STORM_LOG_ASSERT(!rewModel.hasTransitionRewards(),
"Preprocessed Reward model has transition rewards which is not expected.");
45 this->actionRewards[objIndex] = rewModel.hasStateActionRewards()
46 ? rewModel.getStateActionRewardVector()
47 : std::vector<ValueType>(model.getTransitionMatrix().getRowCount(), storm::utility::zero<ValueType>());
48 if (formula.getSubformula().isTotalRewardFormula()) {
49 if (rewModel.hasStateRewards()) {
51 for (
auto markovianState : markovianStates) {
52 this->actionRewards[objIndex][model.getTransitionMatrix().getRowGroupIndices()[markovianState]] +=
53 rewModel.getStateReward(markovianState) / exitRates[markovianState];
56 }
else if (formula.getSubformula().isLongRunAverageRewardFormula()) {
58 if (rewModel.hasStateRewards()) {
59 this->stateRewards[objIndex] = rewModel.getStateRewardVector();
63 formula.getSubformula().asCumulativeRewardFormula().getTimeBoundReference().isTimeBound(),
64 storm::exceptions::UnexpectedException,
"Unexpected type of sub-formula: " << formula.getSubformula());
65 STORM_LOG_THROW(!rewModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
66 "Found state rewards for time bounded objective " << this->objectives[objIndex].originalFormula <<
". This is not supported.");
68 this->objectives[objIndex].originalFormula->isProbabilityOperatorFormula() &&
69 this->objectives[objIndex].originalFormula->asProbabilityOperatorFormula().getSubformula().isBoundedUntilFormula(),
70 "Objective " << this->objectives[objIndex].originalFormula
71 <<
" was simplified to a cumulative reward formula. Correctness of the algorithm is unknown for this type of property.");
75 if (storm::settings::getModule<storm::settings::modules::CoreSettings>().isShowStatisticsSet()) {
76 STORM_PRINT_AND_LOG(
"Final preprocessed model has " << markovianStates.getNumberOfSetBits() <<
" Markovian states.\n");
80template<
class SparseMdpModelType>
87template<
class SparseMdpModelType>
93 result.setOptimizationDirection(storm::solver::OptimizationDirection::Maximize);
97template<
class SparseMaModelType>
99 return this->getWeightedPrecision() - getWeightedPrecisionBoundedPhase();
102template<
class SparseMaModelType>
104 if (!this->objectivesWithNoUpperTimeBound.full()) {
107 return storm::utility::convertNumber<ValueType>(0.99) * this->getWeightedPrecision();
109 return storm::utility::zero<ValueType>();
112template<
class SparseMaModelType>
114 return !this->objectivesWithNoUpperTimeBound.full();
117template<
class SparseMaModelType>
119 std::vector<ValueType>& weightedRewardVector) {
121 SubModel MS = createSubModel(
true, weightedRewardVector);
122 SubModel PS = createSubModel(
false, weightedRewardVector);
125 ValueType digitizationConstant = getDigitizationConstant(weightVector);
126 digitize(MS, digitizationConstant);
129 TimeBoundMap upperTimeBounds;
130 digitizeTimeBounds(upperTimeBounds, digitizationConstant, weightVector);
137 std::unique_ptr<MinMaxSolverData> minMax = initMinMaxSolver(env, PS, acyclic, weightVector);
141 std::unique_ptr<LinEqSolverData> linEq = initLinEqSolver(env, PS, acyclic);
144 std::vector<uint_fast64_t> optimalChoicesAtCurrentEpoch(PS.getNumberOfStates(), std::numeric_limits<uint_fast64_t>::max());
149 auto upperTimeBoundIt = upperTimeBounds.
begin();
150 uint_fast64_t currentEpoch = upperTimeBounds.empty() ? 0 : upperTimeBoundIt->first;
153 updateDataToCurrentEpoch(MS, PS, *minMax, consideredObjectives, currentEpoch, weightVector, upperTimeBoundIt, upperTimeBounds);
156 performPSStep(env, PS, MS, *minMax, *linEq, optimalChoicesAtCurrentEpoch, consideredObjectives, weightVector);
160 if (currentEpoch > 0) {
161 performMSStep(env, MS, PS, consideredObjectives, weightVector);
172 for (uint_fast64_t objIndex = 0; objIndex < this->objectives.size(); ++objIndex) {
178template<
class SparseMaModelType>
179typename StandardMaPcaaWeightVectorChecker<SparseMaModelType>::SubModel StandardMaPcaaWeightVectorChecker<SparseMaModelType>::createSubModel(
180 bool createMS, std::vector<ValueType>
const& weightedRewardVector)
const {
184 result.states = createMS ? markovianStates : probabilisticStates;
185 result.choices = this->transitionMatrix.getRowFilter(result.states);
186 STORM_LOG_ASSERT(!createMS || result.states.getNumberOfSetBits() == result.choices.getNumberOfSetBits(),
187 "row groups for Markovian states should consist of exactly one row");
190 result.toMS = this->transitionMatrix.getSubmatrix(
true, result.states, markovianStates, createMS);
191 result.toPS = this->transitionMatrix.getSubmatrix(
true, result.states, probabilisticStates,
false);
192 STORM_LOG_ASSERT(result.getNumberOfStates() == result.states.getNumberOfSetBits() && result.getNumberOfStates() == result.toMS.getRowGroupCount() &&
193 result.getNumberOfStates() == result.toPS.getRowGroupCount(),
194 "Invalid state count for subsystem");
195 STORM_LOG_ASSERT(result.getNumberOfChoices() == result.choices.getNumberOfSetBits() && result.getNumberOfChoices() == result.toMS.getRowCount() &&
196 result.getNumberOfChoices() == result.toPS.getRowCount(),
197 "Invalid choice count for subsystem");
199 result.weightedRewardVector.resize(result.getNumberOfChoices());
201 for (uint_fast64_t objIndex = 0; objIndex < this->objectives.size(); ++objIndex) {
202 std::vector<ValueType>
const& objRewards = this->actionRewards[objIndex];
203 std::vector<ValueType> subModelObjRewards;
204 subModelObjRewards.reserve(result.getNumberOfChoices());
205 for (
auto choice : result.choices) {
206 subModelObjRewards.push_back(objRewards[choice]);
208 result.objectiveRewardVectors.push_back(std::move(subModelObjRewards));
211 result.weightedSolutionVector.resize(result.getNumberOfStates());
213 result.objectiveSolutionVectors.resize(this->objectives.size());
214 for (uint_fast64_t objIndex = 0; objIndex < this->objectives.size(); ++objIndex) {
215 result.objectiveSolutionVectors[objIndex].resize(result.weightedSolutionVector.size());
219 result.auxChoiceValues.resize(result.getNumberOfChoices());
224template<
class SparseMaModelType>
225template<typename VT, typename std::enable_if<storm::NumberTraits<VT>::SupportsExponential,
int>::type>
226VT StandardMaPcaaWeightVectorChecker<SparseMaModelType>::getDigitizationConstant(std::vector<ValueType>
const& weightVector)
const {
239 std::vector<VT> timeBounds;
240 std::vector<VT> eToPowerOfMinusMaxRateTimesBound;
241 VT smallestNonZeroBound = storm::utility::zero<VT>();
242 for (
auto const& obj : this->objectives) {
243 if (obj.formula->getSubformula().isCumulativeRewardFormula()) {
244 timeBounds.push_back(obj.formula->getSubformula().asCumulativeRewardFormula().template getBound<VT>());
246 "Got zero-valued upper time bound. This is not suppoted.");
247 eToPowerOfMinusMaxRateTimesBound.push_back(std::exp(-maxRate * timeBounds.back()));
248 smallestNonZeroBound =
storm::utility::isZero(smallestNonZeroBound) ? timeBounds.back() : std::min(smallestNonZeroBound, timeBounds.back());
250 timeBounds.push_back(storm::utility::zero<VT>());
251 eToPowerOfMinusMaxRateTimesBound.push_back(storm::utility::zero<VT>());
256 return storm::utility::one<VT>();
264 uint_fast64_t smallestStepBound = 1;
265 VT delta = smallestNonZeroBound / smallestStepBound;
267 bool deltaValid =
true;
268 for (
auto objIndex : objectivesWithTimeBound) {
269 auto const& timeBound = timeBounds[objIndex];
270 if (timeBound / delta != std::floor(timeBound / delta)) {
276 VT weightedPrecisionForCurrentDelta = storm::utility::zero<VT>();
277 for (uint_fast64_t objIndex = 0; objIndex < this->objectives.size(); ++objIndex) {
278 VT precisionOfObj = storm::utility::zero<VT>();
279 if (objectivesWithTimeBound.
get(objIndex)) {
281 storm::utility::one<VT>() - (eToPowerOfMinusMaxRateTimesBound[objIndex] *
282 storm::utility::pow(storm::utility::one<VT>() + maxRate * delta, timeBounds[objIndex] / delta));
284 weightedPrecisionForCurrentDelta += weightVector[objIndex] * precisionOfObj;
286 deltaValid &= weightedPrecisionForCurrentDelta <= weightedGoalPrecision;
292 STORM_LOG_ASSERT(delta > smallestNonZeroBound / smallestStepBound,
"Digitization constant is expected to become smaller in every iteration");
293 delta = smallestNonZeroBound / smallestStepBound;
295 STORM_LOG_DEBUG(
"Found digitization constant: " << delta <<
". At least " << smallestStepBound <<
" digitization steps will be necessarry");
299template<
class SparseMaModelType>
300template<typename VT, typename std::enable_if<!storm::NumberTraits<VT>::SupportsExponential,
int>::type>
301VT StandardMaPcaaWeightVectorChecker<SparseMaModelType>::getDigitizationConstant(std::vector<ValueType>
const& )
const {
302 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Computing bounded probabilities of MAs is unsupported for this value type.");
305template<
class SparseMaModelType>
306template<typename VT, typename std::enable_if<storm::NumberTraits<VT>::SupportsExponential,
int>::type>
307void StandardMaPcaaWeightVectorChecker<SparseMaModelType>::digitize(SubModel& MS, VT
const& digitizationConstant)
const {
308 std::vector<VT> rateVector(MS.getNumberOfChoices());
310 for (uint_fast64_t row = 0; row < rateVector.size(); ++row) {
311 VT
const eToMinusRateTimesDelta = std::exp(-rateVector[row] * digitizationConstant);
312 for (
auto& entry : MS.toMS.getRow(row)) {
313 entry.setValue((storm::utility::one<VT>() - eToMinusRateTimesDelta) * entry.getValue());
314 if (entry.getColumn() == row) {
315 entry.setValue(entry.getValue() + eToMinusRateTimesDelta);
318 for (
auto& entry : MS.toPS.getRow(row)) {
319 entry.setValue((storm::utility::one<VT>() - eToMinusRateTimesDelta) * entry.getValue());
321 MS.weightedRewardVector[row] *= storm::utility::one<VT>() - eToMinusRateTimesDelta;
322 for (
auto& objVector : MS.objectiveRewardVectors) {
323 objVector[row] *= storm::utility::one<VT>() - eToMinusRateTimesDelta;
328template<
class SparseMaModelType>
329template<typename VT, typename std::enable_if<!storm::NumberTraits<VT>::SupportsExponential,
int>::type>
330void StandardMaPcaaWeightVectorChecker<SparseMaModelType>::digitize(SubModel& , VT
const& )
const {
331 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Computing bounded probabilities of MAs is unsupported for this value type.");
334template<
class SparseMaModelType>
335void StandardMaPcaaWeightVectorChecker<SparseMaModelType>::digitizeTimeBounds(TimeBoundMap& upperTimeBounds, ValueType
const& digitizationConstant,
336 std::vector<ValueType>
const& weightVector) {
339 for (
auto objIndex : ~this->objectivesWithNoUpperTimeBound) {
340 auto const& obj = this->objectives[objIndex];
341 ValueType errorTowardsZero = storm::utility::zero<ValueType>();
342 ValueType errorAwayFromZero = storm::utility::zero<ValueType>();
343 if (obj.formula->getSubformula().isCumulativeRewardFormula()) {
344 ValueType timeBound = obj.formula->getSubformula().asCumulativeRewardFormula().template getBound<ValueType>();
345 uint_fast64_t digitizedBound = storm::utility::convertNumber<uint_fast64_t>(timeBound / digitizationConstant);
346 auto timeBoundIt = upperTimeBounds.insert(std::make_pair(digitizedBound,
storm::storage::BitVector(this->objectives.size(),
false))).first;
347 timeBoundIt->second.set(objIndex);
348 ValueType digitizationError = storm::utility::one<ValueType>();
350 std::exp(-maxRate * timeBound) *
storm::utility::pow(storm::utility::one<ValueType>() + maxRate * digitizationConstant, digitizedBound);
351 errorAwayFromZero += digitizationError;
354 this->offsetsToAchievablePoint[objIndex] = -errorTowardsZero;
355 this->offsetToWeightedSum += weightVector[objIndex] * errorAwayFromZero;
357 this->offsetsToAchievablePoint[objIndex] = errorAwayFromZero;
358 this->offsetToWeightedSum += weightVector[objIndex] * errorTowardsZero;
362 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Computing bounded probabilities of MAs is unsupported for this value type.");
366template<
class SparseMaModelType>
367std::unique_ptr<typename StandardMaPcaaWeightVectorChecker<SparseMaModelType>::MinMaxSolverData>
368StandardMaPcaaWeightVectorChecker<SparseMaModelType>::initMinMaxSolver(Environment
const& env, SubModel
const& PS,
bool acyclic,
369 std::vector<ValueType>
const& weightVector)
const {
370 std::unique_ptr<MinMaxSolverData> result(
new MinMaxSolverData());
371 result->env = std::make_unique<storm::Environment>(env);
374 result->env->solver().minMax().setMethod(storm::solver::MinMaxMethod::Acyclic);
377 result->solver = minMaxSolverFactory.
create(*result->env, PS.toPS);
378 result->solver->setHasUniqueSolution(
true);
379 result->solver->setHasNoEndComponents(
true);
380 result->solver->setTrackScheduler(
true);
381 result->solver->setCachingEnabled(
true);
382 auto req = result->solver->getRequirements(*result->env, storm::solver::OptimizationDirection::Maximize,
false);
383 boost::optional<ValueType> lowerBound = this->computeWeightedResultBound(
true, weightVector,
storm::storage::BitVector(weightVector.size(),
true));
385 result->solver->setLowerBound(lowerBound.get());
386 req.clearLowerBounds();
388 boost::optional<ValueType> upperBound = this->computeWeightedResultBound(
false, weightVector,
storm::storage::BitVector(weightVector.size(),
true));
390 result->solver->setUpperBound(upperBound.get());
391 req.clearUpperBounds();
396 STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
397 "Solver requirements " + req.getEnabledRequirementsAsString() +
" not checked.");
398 result->solver->setRequirementsChecked(
true);
399 result->solver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize);
401 result->b.resize(PS.getNumberOfChoices());
406template<
class SparseMaModelType>
407template<typename VT, typename std::enable_if<storm::NumberTraits<VT>::SupportsExponential,
int>::type>
408std::unique_ptr<typename StandardMaPcaaWeightVectorChecker<SparseMaModelType>::LinEqSolverData>
410 std::unique_ptr<LinEqSolverData> result(
new LinEqSolverData());
411 result->env = std::make_unique<Environment>(env);
412 result->acyclic = acyclic;
415 result->env->solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Acyclic);
417 result->factory = std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>();
418 result->b.resize(PS.getNumberOfStates());
422template<
class SparseMaModelType>
423template<typename VT, typename std::enable_if<!storm::NumberTraits<VT>::SupportsExponential,
int>::type>
424std::unique_ptr<typename StandardMaPcaaWeightVectorChecker<SparseMaModelType>::LinEqSolverData>
426 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Computing bounded probabilities of MAs is unsupported for this value type.");
429template<
class SparseMaModelType>
430void StandardMaPcaaWeightVectorChecker<SparseMaModelType>::updateDataToCurrentEpoch(
431 SubModel& MS, SubModel& PS, MinMaxSolverData& minMax,
storm::storage::BitVector& consideredObjectives, uint_fast64_t
const& currentEpoch,
432 std::vector<ValueType>
const& weightVector, TimeBoundMap::iterator& upperTimeBoundIt, TimeBoundMap
const& upperTimeBounds) {
433 if (upperTimeBoundIt != upperTimeBounds.end() && currentEpoch == upperTimeBoundIt->first) {
434 consideredObjectives |= upperTimeBoundIt->second;
435 for (
auto objIndex : upperTimeBoundIt->second) {
438 storm::solver::minimize(this->objectives[objIndex].formula->getOptimalityType()) ? -weightVector[objIndex] : weightVector[objIndex];
446 PS.toMS.multiplyWithVector(MS.weightedSolutionVector, minMax.b);
450template<
class SparseMaModelType>
451void StandardMaPcaaWeightVectorChecker<SparseMaModelType>::performPSStep(Environment
const& env, SubModel& PS, SubModel
const& MS, MinMaxSolverData& minMax,
452 LinEqSolverData& linEq, std::vector<uint_fast64_t>& optimalChoicesAtCurrentEpoch,
454 std::vector<ValueType>
const& weightVector)
const {
456 minMax.solver->solveEquations(*minMax.env, PS.weightedSolutionVector, minMax.b);
457 auto const& newChoices = minMax.solver->getSchedulerChoices();
460 optimalChoicesAtCurrentEpoch = newChoices;
461 PS.objectiveSolutionVectors[*consideredObjectives.
begin()] = PS.weightedSolutionVector;
467 if (linEq.solver ==
nullptr || newChoices != optimalChoicesAtCurrentEpoch) {
468 optimalChoicesAtCurrentEpoch = newChoices;
469 linEq.solver =
nullptr;
472 if (needEquationSystem) {
475 linEq.solver = linEq.factory->create(*linEq.env, std::move(linEqMatrix));
476 linEq.solver->setCachingEnabled(
true);
477 auto req = linEq.solver->getRequirements(*linEq.env);
481 STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
482 "Solver requirements " + req.getEnabledRequirementsAsString() +
" not checked.");
488 for (
auto objIndex : consideredObjectives) {
489 auto const& objectiveRewardVectorPS = PS.objectiveRewardVectors[objIndex];
490 auto const& objectiveSolutionVectorMS = MS.objectiveSolutionVectors[objIndex];
493 auto itGroupIndex = PS.toPS.getRowGroupIndices().begin();
494 auto itChoiceOffset = optimalChoicesAtCurrentEpoch.begin();
495 for (
auto& bValue : linEq.b) {
496 uint_fast64_t row = (*itGroupIndex) + (*itChoiceOffset);
497 bValue = objectiveRewardVectorPS[row];
498 for (
auto const& entry : PS.toMS.getRow(row)) {
499 bValue += entry.getValue() * objectiveSolutionVectorMS[entry.getColumn()];
504 linEq.solver->solveEquations(*linEq.env, PS.objectiveSolutionVectors[objIndex], linEq.b);
509template<
class SparseMaModelType>
510void StandardMaPcaaWeightVectorChecker<SparseMaModelType>::performMSStep(Environment
const& env, SubModel& MS, SubModel
const& PS,
512 std::vector<ValueType>
const& weightVector)
const {
513 MS.toMS.multiplyWithVector(MS.weightedSolutionVector, MS.auxChoiceValues);
515 MS.toPS.multiplyWithVector(PS.weightedSolutionVector, MS.auxChoiceValues);
519 MS.objectiveSolutionVectors[*consideredObjectives.
begin()] = MS.weightedSolutionVector;
524 for (
auto objIndex : consideredObjectives) {
525 MS.toMS.multiplyWithVector(MS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues);
527 MS.toPS.multiplyWithVector(PS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues);
533template class StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<double>>;
534template double StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<double>>::getDigitizationConstant<double>(
535 std::vector<double>
const& direction)
const;
536template void StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<double>>::digitize<double>(
538template std::unique_ptr<typename StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<double>>::LinEqSolverData>
539StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<double>>::initLinEqSolver<double>(
542template class StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>>;
543template storm::RationalNumber StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>>::getDigitizationConstant<
544 storm::RationalNumber>(std::vector<storm::RationalNumber>
const& direction)
const;
545template void StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>>::digitize<storm::RationalNumber>(
547 storm::RationalNumber
const& digitizationConstant)
const;
548template std::unique_ptr<typename StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>>::LinEqSolverData>
549StandardMaPcaaWeightVectorChecker<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>>::initLinEqSolver<storm::RationalNumber>(
Helper class for model checking queries that depend on the long run behavior of the (nondeterministic...
Helper Class that takes preprocessed Pcaa data and a weight vector and ...
StandardMaPcaaWeightVectorChecker(preprocessing::SparseMultiObjectivePreprocessorResult< SparseMaModelType > const &preprocessorResult)
virtual ValueType getWeightedPrecisionUnboundedPhase() const override
virtual ValueType getWeightedPrecisionBoundedPhase() const override
virtual void initializeModelTypeSpecificData(SparseMaModelType const &model) override
virtual bool smallPrecisionsAreChallenging() const override
Returns whether achieving precise values (i.e.
virtual storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper< ValueType > createNondetInfiniteHorizonHelper(storm::storage::SparseMatrix< ValueType > const &transitions) const override
virtual storm::modelchecker::helper::SparseNondeterministicInfiniteHorizonHelper< ValueType > createDetInfiniteHorizonHelper(storm::storage::SparseMatrix< ValueType > const &transitions) const override
Helper Class that takes preprocessed Pcaa data and a weight vector and ...
void initialize(preprocessing::SparseMultiObjectivePreprocessorResult< SparseMaModelType > const &preprocessorResult)
This class represents a Markov automaton.
virtual std::unique_ptr< MinMaxLinearEquationSolver< ValueType, SolutionType > > create(Environment const &env) const override
A bit vector that is internally represented as a vector of 64-bit values.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
A class that holds a possibly non-square matrix in the compressed row storage format.
void convertToEquationSystem()
Transforms the matrix into an equation system.
SparseMatrix selectRowsFromRowGroups(std::vector< index_type > const &rowGroupToRowIndexMapping, bool insertDiagonalEntries=true) const
Selects exactly one row from each row group of this matrix and returns the resulting matrix.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
#define STORM_PRINT_AND_LOG(message)
SFTBDDChecker::ValueType ValueType
bool constexpr maximize(OptimizationDirection d)
bool constexpr minimize(OptimizationDirection d)
bool hasCycle(storm::storage::SparseMatrix< T > const &transitionMatrix, boost::optional< storm::storage::BitVector > const &subsystem)
Returns true if the graph represented by the given matrix has a cycle.
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
void addVectors(std::vector< InValueType1 > const &firstOperand, std::vector< InValueType2 > const &secondOperand, std::vector< OutValueType > &target)
Adds the two given vectors and writes the result to the target vector.
T dotProduct(std::vector< T > const &firstOperand, std::vector< T > const &secondOperand)
Computes the dot product (aka scalar product) and returns the result.
VT max_if(std::vector< VT > const &values, storm::storage::BitVector const &filter)
Computes the maximum of the entries from the values that are selected by the (non-empty) filter.
void setVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Sets the provided values at the provided positions in the given vector.
void selectVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Selects the elements from a vector at the specified positions and writes them consecutively into anot...
void addScaledVector(std::vector< InValueType1 > &firstOperand, std::vector< InValueType2 > const &secondOperand, InValueType3 const &factor)
Computes x:= x + a*y, i.e., adds each element of the first vector and (the corresponding element of t...
void scaleVectorInPlace(std::vector< ValueType1 > &target, ValueType2 const &factor)
Multiplies each element of the given vector with the given factor and writes the result into the vect...
bool isOne(ValueType const &a)
bool isZero(ValueType const &a)
ValueType pow(ValueType const &value, int_fast64_t exponent)
ValueType sqrt(ValueType const &number)