idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
operators.h
1//
2// Created by henri on 26/10/22.
3//
4
5#ifndef IDOL_OPERATORS_H
6#define IDOL_OPERATORS_H
7
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>
13
14namespace idol {
15 template<class T>
16 double evaluate(const LinExpr<T, double>& t_expr, const Point<T>& t_values) {
17 double result = 0.;
18
19 for (const auto& [var, constant] : t_expr) {
20 result += constant * t_values.get(var);
21 }
22
23 return result;
24 }
25
26 template<class T>
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);
29 }
30
31 template<class T>
32 double evaluate(const QuadExpr<T, double>& t_expr, const Point<T>& t_values) {
33 double result = evaluate(t_expr.affine(), t_values);
34
35 for (const auto& [pair, constant] : t_expr) {
36 result += constant * t_values.get(pair.first) * t_values.get(pair.second);
37 }
38
39 return result;
40 }
41
42 template<class KeyT, class ValueT, class PointT>
43 LinExpr<KeyT> evaluate(const SparseVector<KeyT, ValueT>& t_pattern, const PointT& t_values) {
44 LinExpr<KeyT> result;
45 result.reserve(t_pattern.size());
46 for (const auto& [key, value] : t_pattern) {
47 result.set(key, evaluate(value, t_values));
48 }
49 return result;
50 }
51
52}
53
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); \
58 return result; \
59}
60
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); \
66 return result; \
67}
68
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); \
73 return result; \
74}
75
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); \
81 return result; \
82}
83
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>) \
88 \
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>) \
94 \
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>) \
98 \
99DEFINE_COMMUTATIVE_OPERATOR(+, +=, AffExpr<T>, QuadExpr<T>, QuadExpr<T>) \
100DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, AffExpr<T>, AffExpr<T>, AffExpr<T>) \
101 \
102DEFINE_COMMUTATIVE_OPERATOR_SINGLE(+, +=, QuadExpr<T>, QuadExpr<T>, QuadExpr<T>) \
103 \
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>) \
108 \
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>) \
113 \
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>) \
117 \
118DEFINE_OPERATOR_SINGLE(-, -=, AffExpr<T>, AffExpr<T>, AffExpr<T>) \
119DEFINE_OPERATOR(-, -=, AffExpr<T>, QuadExpr<T>, QuadExpr<T>) \
120 \
121DEFINE_OPERATOR_SINGLE(-, -=, QuadExpr<T>, QuadExpr<T>, QuadExpr<T>) \
122 \
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>) \
127\
128static QuadExpr<T> operator*(T t_a, T t_b) { return { t_a, t_b }; } \
129\
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);\
136 } \
137 return result; \
138} \
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; }
146
147namespace idol {
148 DEFINE_OPERATIONS(Var)
149 DEFINE_OPERATIONS(Ctr)
150}
151
152#endif //IDOL_OPERATORS_H