5#ifndef IDOL_OPERATORS_H
6#define IDOL_OPERATORS_H
8#include "operators_utils.h"
9#include "idol/general/utils/Point.h"
10#include <idol/mixed-integer/modeling/expressions/QuadExpr.h>
11#include <idol/mixed-integer/modeling/variables/Var.h>
12#include <idol/mixed-integer/modeling/constraints/Ctr.h>
16 double evaluate(
const LinExpr<T, double>& t_expr,
const Point<T>& t_values) {
19 for (
const auto& [var, constant] : t_expr) {
20 result += constant * t_values.get(var);
27 double evaluate(
const AffExpr<T, double>& t_expr,
const Point<T>& t_values) {
28 return t_expr.constant() + evaluate(t_expr.linear(), t_values);
32 double evaluate(
const QuadExpr<T, double>& t_expr,
const Point<T>& t_values) {
33 double result = evaluate(t_expr.affine(), t_values);
35 for (
const auto& [pair, constant] : t_expr) {
36 result += constant * t_values.get(pair.first) * t_values.get(pair.second);
42 template<
class KeyT,
class ValueT,
class Po
intT>
43 LinExpr<KeyT> evaluate(
const SparseVector<KeyT, ValueT>& t_pattern,
const PointT& t_values) {
45 result.reserve(t_pattern.size());
46 for (
const auto& [key, value] : t_pattern) {
47 result.set(key, evaluate(value, t_values));
54#define DEFINE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \
55static ResultT operator OPERATOR(T t_a, U t_b) { \
56 ResultT result(std::move(t_a)); \
57 result OPERATOR_EQ std::move(t_b); \
61#define DEFINE_OPERATOR(OPERATOR, OPERATOR_EQ, T, U, ResultT) \
62DEFINE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \
63static ResultT operator OPERATOR(U t_a, T t_b) { \
64 ResultT result(std::move(t_a)); \
65 result OPERATOR_EQ std::move(t_b); \
69#define DEFINE_COMMUTATIVE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \
70static ResultT operator OPERATOR(T t_a, U t_b) { \
71 ResultT result(std::move(t_b)); \
72 result OPERATOR_EQ std::move(t_a); \
76#define DEFINE_COMMUTATIVE_OPERATOR(OPERATOR, OPERATOR_EQ, T, U, ResultT) \
77DEFINE_COMMUTATIVE_OPERATOR_SINGLE(OPERATOR, OPERATOR_EQ, T, U, ResultT) \
78static ResultT operator OPERATOR(U t_a, T t_b) { \
79 ResultT result(std::move(t_a)); \
80 result OPERATOR_EQ std::move(t_b); \
84#define DEFINE_OPERATIONS(T) \
85DEFINE_COMMUTATIVE_OPERATOR(+, +=, double, LinExpr<T>, AffExpr<T>) \
86DEFINE_COMMUTATIVE_OPERATOR(+, +=, double, AffExpr<T>, AffExpr<T>) \
87DEFINE_COMMUTATIVE_OPERATOR(+, +=, double, QuadExpr<T>, QuadExpr<T>) \
89DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, double, AffExpr<T>) \
90DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, T, T, LinExpr<T>) \
91DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, LinExpr<T>, LinExpr<T>) \
92DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, AffExpr<T>, AffExpr<T>) \
93DEFINE_COMMUTATIVE_OPERATOR(+, +=, T, QuadExpr<T>, QuadExpr<T>) \
95DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, LinExpr<T>, LinExpr<T>, LinExpr<T>) \
96DEFINE_COMMUTATIVE_OPERATOR(+, +=, LinExpr<T>, AffExpr<T>, AffExpr<T>) \
97DEFINE_COMMUTATIVE_OPERATOR(+, +=, LinExpr<T>, QuadExpr<T>, QuadExpr<T>) \
99DEFINE_COMMUTATIVE_OPERATOR(+, +=, AffExpr<T>, QuadExpr<T>, QuadExpr<T>) \
100DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, AffExpr<T>, AffExpr<T>, AffExpr<T>) \
102DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, QuadExpr<T>, QuadExpr<T>, QuadExpr<T>) \
104DEFINE_OPERATOR(-, -=, double, T, AffExpr<T>) \
105DEFINE_OPERATOR(-, -=, double, LinExpr<T>, AffExpr<T>) \
106DEFINE_OPERATOR(-, -=, double, AffExpr<T>, AffExpr<T>) \
107DEFINE_OPERATOR(-, -=, double, QuadExpr<T>, QuadExpr<T>) \
109DEFINE_OPERATOR_SINGLE(-, -=, T, T, LinExpr<T>) \
110DEFINE_OPERATOR(-, -=, T, LinExpr<T>, LinExpr<T>) \
111DEFINE_OPERATOR(-, -=, T, AffExpr<T>, AffExpr<T>) \
112DEFINE_OPERATOR(-, -=, T, QuadExpr<T>, QuadExpr<T>) \
114DEFINE_OPERATOR_SINGLE(-, -=, LinExpr<T>, LinExpr<T>, LinExpr<T>) \
115DEFINE_OPERATOR(-, -=, LinExpr<T>, AffExpr<T>, AffExpr<T>) \
116DEFINE_OPERATOR(-, -=, LinExpr<T>, QuadExpr<T>, QuadExpr<T>) \
118DEFINE_OPERATOR_SINGLE(-, -=, AffExpr<T>, AffExpr<T>, AffExpr<T>) \
119DEFINE_OPERATOR(-, -=, AffExpr<T>, QuadExpr<T>, QuadExpr<T>) \
121DEFINE_OPERATOR_SINGLE(-, -=, QuadExpr<T>, QuadExpr<T>, QuadExpr<T>) \
123DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, T, LinExpr<T>) \
124DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, LinExpr<T>, LinExpr<T>) \
125DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, AffExpr<T>, AffExpr<T>) \
126DEFINE_COMMUTATIVE_OPERATOR(*, *=, double, QuadExpr<T>, QuadExpr<T>) \
128static QuadExpr<T> operator*(T t_a, T t_b) { return { t_a, t_b }; } \
130static LinExpr<T, double> operator+(const T& t_a) { return t_a; } \
131static LinExpr<T, double> operator-(const T& t_a) { return { -1., t_a }; } \
132static QuadExpr<T> operator*(const T& t_a, const LinExpr<T>& t_b) { \
133 QuadExpr<T> result; \
134 for (const auto& [var, constant] : t_b) { \
135 result += constant * (var * t_a);\
139static QuadExpr<T> operator*(const LinExpr<T>& t_a, const T& t_b) { return t_b * t_a; } \
140static QuadExpr<T> operator*(const T& t_a, const AffExpr<T>& t_b) { return t_a * t_b.constant() + t_a * t_b.linear(); } \
141static QuadExpr<T> operator*(const AffExpr<T>& t_a, const T& t_b) { return t_b * t_a; } \
142static LinExpr<T> operator/(const T& t_a, double t_b) { return (1./t_b) * t_a; } \
143static LinExpr<T> operator/(const LinExpr<T>& t_a, double t_b) { return (1./t_b) * t_a; } \
144static AffExpr<T> operator/(const AffExpr<T>& t_a, double t_b) { return (1./t_b) * t_a; } \
145static QuadExpr<T> operator/(const QuadExpr<T>& t_a, double t_b) { return (1./t_b) * t_a; }
148 DEFINE_OPERATIONS(Var)
149 DEFINE_OPERATIONS(Ctr)