32 if (entryIt->getColumn() >= column) {
33 if (entryIt->getColumn() == column) {
34 columnValue = entryIt->getValue();
35 hasEntryInColumn =
true;
40 entriesInRow.erase(entryIt);
49 STORM_LOG_TRACE((hasEntryInColumn ?
"State has entry in column." :
"State does not have entry in column."));
51 STORM_LOG_ASSERT(hasEntryInColumn,
"The scaling mode 'divide' requires an element in the given column.");
53 columnValue = storm::utility::one<ValueType>() / columnValue;
55 if (hasEntryInColumn) {
57 "The scaling mode 'divide-one-minus' requires a non-one value in the given column.");
58 columnValue = storm::utility::one<ValueType>() / (storm::utility::one<ValueType>() - columnValue);
63 if (hasEntryInColumn) {
64 for (
auto entryIt = entriesInRow.begin(), entryIte = entriesInRow.end(); entryIt != entryIte; ++entryIt) {
66 if (entryIt->getColumn() != column) {
70 updateValue(row, columnValue);
74 FlexibleRowType& elementsWithEntryInColumnEqualRow = transposedMatrix.getRow(column);
78 FlexibleRowType rowsKeepingEntryInColumnEqualRow;
82 std::vector<FlexibleRowType> newBackwardEntries(entriesInRow.size());
83 for (
auto& backwardEntry : newBackwardEntries) {
84 backwardEntry.reserve(elementsWithEntryInColumnEqualRow.size());
89 for (
auto const& predecessorEntry : elementsWithEntryInColumnEqualRow) {
90 uint_fast64_t predecessor = predecessorEntry.getColumn();
94 if (predecessor == row) {
95 assert(hasEntryInColumn);
100 if (isFilterPredecessor() && !filterPredecessor(predecessor)) {
101 rowsKeepingEntryInColumnEqualRow.emplace_back(predecessorEntry);
102 STORM_LOG_TRACE(
"Not eliminating predecessor " << predecessor <<
", because it does not fit the filter.");
109 FlexibleRowType& predecessorForwardTransitions = matrix.getRow(predecessor);
110 FlexibleRowIterator multiplyElement = std::find_if(predecessorForwardTransitions.begin(), predecessorForwardTransitions.end(),
111 [&](MatrixEntry
const& a) { return a.getColumn() == column; });
114 STORM_LOG_THROW(multiplyElement != predecessorForwardTransitions.end(), storm::exceptions::InvalidStateException,
115 "No probability for successor found.");
116 ValueType multiplyFactor = multiplyElement->getValue();
117 multiplyElement->setValue(storm::utility::zero<ValueType>());
120 FlexibleRowIterator first1 = predecessorForwardTransitions.begin();
121 FlexibleRowIterator last1 = predecessorForwardTransitions.end();
122 FlexibleRowIterator first2 = entriesInRow.begin();
123 FlexibleRowIterator last2 = entriesInRow.end();
125 FlexibleRowType newSuccessors;
126 newSuccessors.reserve((last1 - first1) + (last2 - first2));
127 std::insert_iterator<FlexibleRowType> result(newSuccessors, newSuccessors.end());
129 uint_fast64_t successorOffsetInNewBackwardTransitions = 0;
131 for (; first1 != last1; ++result) {
133 if (first1->getColumn() == column || (first2 != last2 && first2->getColumn() == column)) {
134 if (first1->getColumn() == column) {
137 if (first2 != last2 && first2->getColumn() == column) {
143 if (first2 == last2) {
144 std::copy_if(first1, last1, result, [&](MatrixEntry
const& a) {
return a.getColumn() != column; });
147 if (first2->getColumn() < first1->getColumn()) {
148 ValueType successorValue = storm::utility::simplify<ValueType>((first2->getValue() * multiplyFactor));
149 *result = MatrixEntry(first2->getColumn(), successorValue);
150 newBackwardEntries[successorOffsetInNewBackwardTransitions].emplace_back(predecessor, successorValue);
152 ++successorOffsetInNewBackwardTransitions;
153 }
else if (first1->getColumn() < first2->getColumn()) {
157 ValueType sprod = multiplyFactor * first2->getValue();
160 *result = MatrixEntry(first1->getColumn(), probability);
161 newBackwardEntries[successorOffsetInNewBackwardTransitions].emplace_back(predecessor, probability);
164 ++successorOffsetInNewBackwardTransitions;
167 for (; first2 != last2; ++first2) {
168 if (first2->getColumn() != column) {
169 ValueType probability = storm::utility::simplify<ValueType>(first2->getValue() * multiplyFactor);
170 *result = MatrixEntry(first2->getColumn(), probability);
171 newBackwardEntries[successorOffsetInNewBackwardTransitions].emplace_back(predecessor, probability);
172 ++successorOffsetInNewBackwardTransitions;
177 predecessorForwardTransitions = std::move(newSuccessors);
178 STORM_LOG_TRACE(
"Fixed new next-state probabilities of predecessor state " << predecessor <<
".");
180 updatePredecessor(predecessor, multiplyFactor, row);
183 updatePriority(predecessor);
187 uint_fast64_t successorOffsetInNewBackwardTransitions = 0;
188 for (
auto const& successorEntry : entriesInRow) {
189 if (successorEntry.getColumn() == column) {
193 FlexibleRowType& successorBackwardTransitions = transposedMatrix.getRow(successorEntry.getColumn());
198 FlexibleRowIterator elimIt = std::find_if(successorBackwardTransitions.begin(), successorBackwardTransitions.end(),
199 [&](MatrixEntry
const& a) { return a.getColumn() == row; });
201 "Expected a proper backward transition from " << successorEntry.getColumn() <<
" to " << column <<
", but found none.");
202 successorBackwardTransitions.erase(elimIt);
205 FlexibleRowIterator first1 = successorBackwardTransitions.begin();
206 FlexibleRowIterator last1 = successorBackwardTransitions.end();
207 FlexibleRowIterator first2 = newBackwardEntries[successorOffsetInNewBackwardTransitions].begin();
208 FlexibleRowIterator last2 = newBackwardEntries[successorOffsetInNewBackwardTransitions].end();
210 FlexibleRowType newPredecessors;
211 newPredecessors.reserve((last1 - first1) + (last2 - first2));
212 std::insert_iterator<FlexibleRowType> result(newPredecessors, newPredecessors.end());
214 for (; first1 != last1; ++result) {
215 if (first2 == last2) {
216 std::copy(first1, last1, result);
219 if (first2->getColumn() < first1->getColumn()) {
220 if (first2->getColumn() != row) {
224 }
else if (first1->getColumn() == first2->getColumn()) {
237 if (isFilterPredecessor()) {
238 std::copy_if(first2, last2, result, [&](MatrixEntry
const& a) {
return a.getColumn() != row && filterPredecessor(a.getColumn()); });
240 std::copy_if(first2, last2, result, [&](MatrixEntry
const& a) {
return a.getColumn() != row; });
243 successorBackwardTransitions = std::move(newPredecessors);
244 ++successorOffsetInNewBackwardTransitions;
250 entriesInRow.clear();
251 entriesInRow.shrink_to_fit();
255 if (isFilterPredecessor()) {
256 elementsWithEntryInColumnEqualRow = std::move(rowsKeepingEntryInColumnEqualRow);
258 elementsWithEntryInColumnEqualRow.clear();
259 elementsWithEntryInColumnEqualRow.shrink_to_fit();
263template<
typename ValueType, ScalingMode Mode>
266 bool hasEntryInColumn =
false;
267 ValueType columnValue = storm::utility::zero<ValueType>();
269 for (
auto entryIt = entriesInRow.begin(), entryIte = entriesInRow.end(); entryIt != entryIte; ++entryIt) {
270 if (entryIt->getColumn() == state) {
271 columnValue = entryIt->getValue();
272 hasEntryInColumn =
true;
278 STORM_LOG_TRACE((hasEntryInColumn ?
"State has entry in column." :
"State does not have entry in column."));
280 STORM_LOG_ASSERT(hasEntryInColumn,
"The scaling mode 'divide' requires an element in the given column.");
282 columnValue = storm::utility::one<ValueType>() / columnValue;
284 if (hasEntryInColumn) {
286 "The scaling mode 'divide-one-minus' requires a non-one value in the given column.");
287 columnValue = storm::utility::one<ValueType>() / (storm::utility::one<ValueType>() - columnValue);
292 if (hasEntryInColumn) {
293 for (
auto entryIt = entriesInRow.begin(), entryIte = entriesInRow.end(); entryIt != entryIte; ++entryIt) {
295 if (entryIt->getColumn() != state) {
298 entryIt->setValue(storm::utility::zero<ValueType>());
304template<
typename ValueType, ScalingMode Mode>
309template<
typename ValueType, ScalingMode Mode>
315template<
typename ValueType, ScalingMode Mode>
320template<
typename ValueType, ScalingMode Mode>
326template<
typename ValueType, ScalingMode Mode>