Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
LinearCoefficientVisitor.cpp
Go to the documentation of this file.
2
3#include <iterator>
4
6
12
13namespace storm {
14namespace expressions {
15
16template<typename ValueType>
18 : variableToCoefficientMapping(), constantPart(std::move(constantPart)) {
19 // Intentionally left empty.
20}
21
22template<typename ValueType>
23void LinearCoefficientVisitor<ValueType>::VariableCoefficients::removeZeroCoefficients() {
24 for (auto it = variableToCoefficientMapping.begin(); it != variableToCoefficientMapping.end();) {
25 it = storm::utility::isZero(it->second) ? variableToCoefficientMapping.erase(it) : std::next(it);
26 }
27}
28
29template<typename ValueType>
31 VariableCoefficients&& other) {
32 for (auto const& otherVariableCoefficientPair : other.variableToCoefficientMapping) {
33 auto [it, inserted] = this->variableToCoefficientMapping.try_emplace(otherVariableCoefficientPair.first, otherVariableCoefficientPair.second);
34 if (!inserted) {
35 it->second += otherVariableCoefficientPair.second;
36 }
37 }
38 constantPart += other.constantPart;
39 removeZeroCoefficients();
40 return *this;
41}
42
43template<typename ValueType>
49
50template<typename ValueType>
52 VariableCoefficients&& other) {
53 STORM_LOG_THROW(variableToCoefficientMapping.size() == 0 || other.variableToCoefficientMapping.size() == 0, storm::exceptions::InvalidArgumentException,
54 "Expression is non-linear.");
55 if (other.variableToCoefficientMapping.size() > 0) {
56 variableToCoefficientMapping = std::move(other.variableToCoefficientMapping);
57 std::swap(constantPart, other.constantPart);
58 }
59 for (auto& variableCoefficientPair : this->variableToCoefficientMapping) {
60 variableCoefficientPair.second *= other.constantPart;
61 }
62 constantPart *= other.constantPart;
63 removeZeroCoefficients();
64 return *this;
65}
66
67template<typename ValueType>
69 VariableCoefficients&& other) {
70 STORM_LOG_THROW(other.variableToCoefficientMapping.size() == 0 && !storm::utility::isZero(other.constantPart), storm::exceptions::InvalidArgumentException,
71 "Expression is non-linear or divides by zero.");
72 for (auto& variableCoefficientPair : this->variableToCoefficientMapping) {
73 variableCoefficientPair.second /= other.constantPart;
74 }
75 constantPart /= other.constantPart;
76 return *this;
77}
78
79template<typename ValueType>
81 for (auto& variableCoefficientPair : variableToCoefficientMapping) {
82 variableCoefficientPair.second = -variableCoefficientPair.second;
83 }
84 constantPart = -constantPart;
85}
86
87template<typename ValueType>
89 variableToCoefficientMapping.insert_or_assign(variable, coefficient);
90}
91
92template<typename ValueType>
94 auto it = variableToCoefficientMapping.find(variable);
95 return it == variableToCoefficientMapping.end() ? storm::utility::zero<ValueType>() : it->second;
96}
97
98template<typename ValueType>
100 return variableToCoefficientMapping.size();
101}
102
103template<typename ValueType>
105 return this->constantPart;
106}
107
108template<typename ValueType>
110 for (auto const& rhsVariableCoefficientPair : rhs.variableToCoefficientMapping) {
111 auto [it, inserted] = this->variableToCoefficientMapping.try_emplace(rhsVariableCoefficientPair.first, -rhsVariableCoefficientPair.second);
112 if (!inserted) {
113 it->second -= rhsVariableCoefficientPair.second;
114 }
115 }
116 removeZeroCoefficients();
117 rhs.variableToCoefficientMapping.clear();
118 rhs.constantPart -= this->constantPart;
119}
120
121template<typename ValueType>
122typename std::map<storm::expressions::Variable, ValueType>::const_iterator LinearCoefficientVisitor<ValueType>::VariableCoefficients::begin() const {
123 return this->variableToCoefficientMapping.begin();
124}
125
126template<typename ValueType>
127typename std::map<storm::expressions::Variable, ValueType>::const_iterator LinearCoefficientVisitor<ValueType>::VariableCoefficients::end() const {
128 return this->variableToCoefficientMapping.end();
129}
130
131template<typename ValueType>
132std::optional<typename LinearCoefficientVisitor<ValueType>::VariableCoefficients> LinearCoefficientVisitor<ValueType>::tryGetLinearCoefficients(
133 Expression const& expression) {
134 return boost::any_cast<Result>(expression.getBaseExpression().accept(*this, boost::none));
135}
136
137template<typename ValueType>
139 auto result = tryGetLinearCoefficients(expression);
140 STORM_LOG_THROW(result.has_value(), storm::exceptions::InvalidArgumentException, "Expression is non-linear.");
141 return std::move(result.value());
142}
143
144template<typename ValueType>
146 return Result{};
147}
148
149template<typename ValueType>
151 return Result{};
152}
153
154template<typename ValueType>
155boost::any LinearCoefficientVisitor<ValueType>::visit(BinaryNumericalFunctionExpression const& expression, boost::any const& data) {
156 Result left = boost::any_cast<Result>(expression.getFirstOperand()->accept(*this, data));
157 if (!left) {
158 return Result{};
159 }
160 Result right = boost::any_cast<Result>(expression.getSecondOperand()->accept(*this, data));
161 if (!right) {
162 return Result{};
163 }
164
165 switch (expression.getOperatorType()) {
167 *left += std::move(*right);
168 break;
170 *left -= std::move(*right);
171 break;
173 if (left->size() > 0 && right->size() > 0) {
174 return Result{};
175 }
176 *left *= std::move(*right);
177 break;
179 if (right->size() > 0 || storm::utility::isZero(right->getConstantPart())) {
180 return Result{};
181 }
182 *left /= std::move(*right);
183 break;
184 default:
185 return Result{};
186 }
187 return left;
188}
189
190template<typename ValueType>
192 return Result{};
193}
194
195template<typename ValueType>
196boost::any LinearCoefficientVisitor<ValueType>::visit(VariableExpression const& expression, boost::any const&) {
197 if (!expression.getType().isNumericalType()) {
198 return Result{};
199 }
200 VariableCoefficients coefficients;
201 coefficients.setCoefficient(expression.getVariable(), storm::utility::one<ValueType>());
202 return Result{std::move(coefficients)};
203}
204
205template<typename ValueType>
207 return Result{};
208}
209
210template<typename ValueType>
211boost::any LinearCoefficientVisitor<ValueType>::visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) {
212 Result child = boost::any_cast<Result>(expression.getOperand()->accept(*this, data));
214 return Result{};
215 }
216 child->negate();
217 return child;
218}
219
220template<typename ValueType>
222 return Result{};
223}
224
225template<typename ValueType>
226boost::any LinearCoefficientVisitor<ValueType>::visit(IntegerLiteralExpression const& expression, boost::any const&) {
228}
229
230template<typename ValueType>
231boost::any LinearCoefficientVisitor<ValueType>::visit(RationalLiteralExpression const& expression, boost::any const&) {
233}
234
237// The coefficients of rational functions use a different type if exact arithmetic and rational functions use different libraries.
238#if (defined(STORM_USE_CLN_EA) && !defined(STORM_USE_CLN_RF)) || (!defined(STORM_USE_CLN_EA) && defined(STORM_USE_CLN_RF))
240#endif
241} // namespace expressions
242} // namespace storm
virtual boost::any accept(ExpressionVisitor &visitor, boost::any const &data) const =0
Accepts the given visitor by calling its visit method.
Type const & getType() const
Retrieves the type of the expression.
std::shared_ptr< BaseExpression const > const & getSecondOperand() const
Retrieves the second operand of the expression.
std::shared_ptr< BaseExpression const > const & getFirstOperand() const
Retrieves the first operand of the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
BaseExpression const & getBaseExpression() const
Retrieves the base expression underlying this expression object.
int_fast64_t getValue() const
Retrieves the value of the integer literal.
Computes the coefficients of a linear expression.
std::optional< VariableCoefficients > tryGetLinearCoefficients(Expression const &expression)
As getLinearCoefficients, but returns std::nullopt instead of throwing if the expression is not linea...
virtual boost::any visit(IfThenElseExpression const &expression, boost::any const &data) override
VariableCoefficients getLinearCoefficients(Expression const &expression)
Computes the coefficients of all identifiers appearing in the expression if the expression was rewrit...
storm::RationalNumber getValue() const
Retrieves the value of the double literal.
bool isNumericalType() const
Checks whether this type is a numerical type.
Definition Type.cpp:206
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const override
Retrieves the given operand from the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
Variable const & getVariable() const
Retrieves the variable associated with this expression.
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
bool isZero(ValueType const &a)
Definition constants.cpp:44
ValueType zero()
Definition constants.cpp:26
ValueType one()
Definition constants.cpp:21
TargetType convertNumber(SourceType const &number)
VariableCoefficients & operator-=(VariableCoefficients &&other)
std::map< storm::expressions::Variable, ValueType >::const_iterator begin() const
VariableCoefficients & operator*=(VariableCoefficients &&other)
ValueType getCoefficient(storm::expressions::Variable const &variable)
std::map< storm::expressions::Variable, ValueType >::const_iterator end() const
VariableCoefficients & operator+=(VariableCoefficients &&other)
void separateVariablesFromConstantPart(VariableCoefficients &rhs)
Brings all variables of the right-hand side coefficients to the left-hand side by negating them and m...
VariableCoefficients & operator/=(VariableCoefficients &&other)
void setCoefficient(storm::expressions::Variable const &variable, ValueType const &coefficient)