27 #include <antares/optimisation/linear-problem-api/ILinearProblemData.h>
28 #include "antares/expressions/visitors/NodeVisitor.h"
29 #include "antares/modeler-optimisation-container/EvaluationContext.h"
30 #include "antares/modeler-optimisation-container/OptimEntityContainer.h"
31 #include "antares/solver/optim-model-filler/Dimensions.h"
32 #include "antares/study/system-model/component.h"
34 #include "VariadicNodeFunctionVisit.h"
36 namespace Antares::Expressions::Visitors
51 static constexpr
double DEFAULT_THRESHOLD = 1e-16;
62 return evaluateBinaryOperation(right, std::plus<>());
67 *
this = *
this + right;
73 return evaluateBinaryOperation(right, std::minus<>());
78 return evaluateBinaryOperation(right, std::multiplies<>());
83 return evaluateBinaryOperation(right, std::equal_to<>());
88 return evaluateBinaryOperation(right, std::less_equal<>());
93 return evaluateBinaryOperation(right, std::greater_equal<>());
97 double value(
unsigned i)
const;
101 explicit SafeDivides(
double threshold = DEFAULT_THRESHOLD):
102 threshold_(threshold)
106 double operator()(
double lhs,
double rhs)
const
108 if (std::abs(rhs) <= threshold_)
121 return evaluateBinaryOperation(right,
SafeDivides{});
124 EvaluationResult operator-()
const
126 return evaluateUnaryOperation(std::negate<>());
129 [[nodiscard]]
const std::variant<double, std::vector<double>>& value()
const
137 using std::runtime_error::runtime_error;
143 using std::out_of_range::out_of_range;
146 double valueAsDouble()
const
148 if (!std::holds_alternative<double>(value_))
152 return std::get<double>(value_);
155 [[nodiscard]] std::vector<double> valuesAsVector()
const
157 if (
const auto* v = std::get_if<std::vector<double>>(&value_))
161 throw EvalResultTypeError(
"Expected a vector but found a double.");
164 [[nodiscard]]
double getValueInVector(
unsigned index)
const
166 if (
const auto* v = std::get_if<std::vector<double>>(&value_))
170 throw EvalResultTypeError(
"Expected a vector but found a double.");
173 EvaluationResult operator[](
int timeIndex)
const;
174 EvaluationResult timeShift(
int time_shift)
const;
175 EvaluationResult timeSum(
int from,
int to)
const;
176 EvaluationResult alltimeSum(
int numberOfTimeStep)
const;
178 template<
typename Op>
179 EvaluationResult evaluateBinaryOperation(
const EvaluationResult& right, Op op)
const;
182 std::variant<double, std::vector<double>> value_;
183 explicit EvaluationResult(
const std::variant<
double, std::vector<double>>& value);
185 template<
typename Op>
186 EvaluationResult evaluateUnaryOperation(Op op)
const;
188 static double shift(
double value,
int)
193 static std::vector<double> shift(
const std::vector<double>& values,
int shiftValue);
196 template<
typename BinaryOp>
197 double computeBinaryOperation(
double lhs,
double rhs, BinaryOp op)
202 template<
typename BinaryOp>
203 std::vector<double> computeBinaryOperation(
const std::vector<double>& lhs,
double rhs, BinaryOp op)
206 for (
double& value: result)
208 value = op(value, rhs);
213 template<
typename BinaryOp>
214 std::vector<double> computeBinaryOperation(
double lhs,
const std::vector<double>& rhs, BinaryOp op)
216 std::vector<double> result(rhs.size());
217 for (
size_t i = 0; i < rhs.size(); ++i)
219 result[i] = op(lhs, rhs[i]);
227 using std::runtime_error::runtime_error;
230 template<
typename BinaryOp>
231 std::vector<double> computeBinaryOperation(
const std::vector<double>& lhs,
232 const std::vector<double>& rhs,
235 if (lhs.size() != rhs.size())
237 std::ostringstream errorMsg;
238 errorMsg <<
"Failed to compute binary operation: vectors have different sizes ("
239 << lhs.size() <<
" and " << rhs.size() <<
").";
243 std::vector<double> result(lhs.size());
244 for (
size_t i = 0; i < lhs.size(); ++i)
246 result[i] = op(lhs[i], rhs[i]);
251 template<
typename Op>
252 EvaluationResult EvaluationResult::evaluateBinaryOperation(
const EvaluationResult& right,
255 return EvaluationResult(
256 std::visit([&op](
const auto& l,
const auto& r) -> std::variant<
double, std::vector<double>>
257 {
return computeBinaryOperation(l, r, op); },
262 template<
typename UnaryOp>
263 std::vector<double> computeUnaryOperation(
const std::vector<double>& values, UnaryOp op)
266 for (
double& v: result)
273 template<
typename UnaryOp>
274 double computeUnaryOperation(
double value, UnaryOp op)
279 template<
typename Op>
280 EvaluationResult EvaluationResult::evaluateUnaryOperation(Op op)
const
282 return EvaluationResult(
283 std::visit([&op](
const auto& v) -> std::variant<
double, std::vector<double>>
284 {
return computeUnaryOperation(v, op); },
288 template<
class Operation>
289 EvaluationResult applyOperation(
const std::vector<EvaluationResult>& in, Operation op)
293 throw std::invalid_argument(
"Expected at least two EvaluationResult");
295 const size_t size = getMaxSize(in);
296 std::vector<double> values(size);
297 std::vector<double> row(in.size());
299 for (
size_t timeIndex = 0; timeIndex < size; ++timeIndex)
301 for (
size_t evalIndex = 0; evalIndex < in.size(); ++evalIndex)
303 const auto& evalResult = in[evalIndex];
304 row[evalIndex] = evalResult.value(timeIndex);
306 values[timeIndex] = op(row);
310 return EvaluationResult(values);
313 return EvaluationResult(values.at(0));
333 std::string name()
const override;
Represents a AllTimeSumNode node in a syntax tree.
Definition: AllTimeSumNode.h:31
Represents a division node in a syntax tree.
Definition: DivisionNode.h:31
Represents an equality comparison node in a syntax tree.
Definition: EqualNode.h:31
AST node representing a function expression (max, min, pow, ...).
Definition: FunctionNode.h:63
Represents a greater than or equal comparison node in a syntax tree.
Definition: GreaterThanOrEqualNode.h:31
Represents a less than or equal comparison node in a syntax tree.
Definition: LessThanOrEqualNode.h:31
Represents a literal node in a syntax tree, storing a double value.
Definition: LiteralNode.h:11
Represents a multiplication node in a syntax tree.
Definition: MultiplicationNode.h:31
Represents a negation node in a syntax tree.
Definition: NegationNode.h:31
Represents a parameter node in a syntax tree, storing a string value.
Definition: ParameterNode.h:14
Represents a port field node in a syntax tree.
Definition: PortFieldNode.h:32
Represents a port field node where the expression is a sum.
Definition: PortFieldSumNode.h:32
Represents a subtraction node in a syntax tree.
Definition: SubtractionNode.h:31
Definition: TimeIndexNode.h:28
Definition: TimeShiftNode.h:29
Definition: TimeSumNode.h:28
Represents a variable node in a syntax tree, storing a string value.
Definition: VariableNode.h:20
Definition: EvalVisitor.h:40
Definition: EvalVisitor.h:46
Represents a visitor for evaluating expressions within a given context.
Definition: EvalVisitor.h:320
EvalVisitor(const Optimisation::OptimEntityContainer &optimContainer, const Optimisation::LinearProblemApi::FillContext &fillContext, const ModelerStudy::SystemModel::Component &component)
Constructs an evaluation visitor with the specified context.
Definition: EvalVisitor.cpp:35
Definition: EvalVisitor.h:141
Definition: EvalVisitor.h:135
Definition: EvalVisitor.h:54
Definition: NodeVisitor.h:76
Definition: EvalVisitor.h:225
Definition: component.h:69
Represents the context for evaluating expressions.
Definition: EvaluationContext.h:25
Context for filling linear problem data. Contains temporal information.
Definition: ILinearProblemData.h:35
Definition: OptimEntityContainer.h:46
Definition: EvalVisitor.h:100