idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
GenerationPattern.h
1//
2// Created by henri on 20.11.24.
3//
4
5#ifndef IDOL_GENERATIONPATTERN_H
6#define IDOL_GENERATIONPATTERN_H
7
8#include "idol/mixed-integer/modeling/expressions/AffExpr.h"
9#include "Point.h"
10#include "idol/mixed-integer/modeling/expressions/operations/operators.h"
11
12namespace idol {
13 template<class, class> class GenerationPattern;
14}
15
16template<class GeneratedT,
17 class CoefficientT = idol::Var
18 >
20public:
21 using KeyT = std::conditional_t<std::is_same_v<GeneratedT, Var>, Ctr, Var>;
22
23 GenerationPattern() = default;
24
26 : m_constant(std::move(t_constant)), m_linear(std::move(t_linear)) {}
27
28 auto& constant() { return m_constant; }
29
30 [[nodiscard]] const auto& constant() const { return m_constant; }
31
32 auto& linear() { return m_linear; }
33
34 [[nodiscard]] const auto& linear() const { return m_linear; }
35
36 [[nodiscard]] double generate_constant(const Point<CoefficientT>& t_values) const {
37 return evaluate(m_constant, t_values);
38 }
39
40 [[nodiscard]] LinExpr<KeyT> generate_linear(const Point<CoefficientT>& t_values) const {
41 LinExpr<KeyT> result;
42
43 for (const auto& [key, value] : m_linear) {
44 result += key * evaluate(value, t_values);
45 }
46
47 return result;
48 }
49
50 AffExpr<KeyT> operator()(const Point<CoefficientT>& t_values) const {
51 AffExpr<KeyT> result(generate_linear(t_values));
52 result.constant() = generate_constant(t_values);
53 return result;
54 }
55
56 GenerationPattern operator+=(const AffExpr<CoefficientT>& t_other) {
57 m_constant += t_other.constant();
58 for (const auto& [var, coeff] : t_other.linear()) {
59 m_linear.set(var, m_linear.get(var) + coeff);
60 }
61 return *this;
62 }
63
64 GenerationPattern operator-=(const AffExpr<CoefficientT>& t_other) {
65 m_constant -= t_other;
66 for (const auto& [var, coeff] : t_other.linear()) {
67 m_linear.set(var, m_linear.get(var) - coeff);
68 }
69 return *this;
70 }
71
72 GenerationPattern operator+=(const GenerationPattern& t_other) {
73 m_constant += t_other.m_constant;
74 m_linear += t_other.m_linear;
75 return *this;
76 }
77
78 GenerationPattern operator+=(double t_scalar) {
79 m_constant += t_scalar;
80 return *this;
81 }
82
83 GenerationPattern operator-=(const GenerationPattern& t_other) {
84 m_constant -= t_other.m_constant;
85 m_linear -= t_other.m_linear;
86 return *this;
87 }
88
89 GenerationPattern operator*=(const double t_scalar) {
90 m_constant *= t_scalar;
91 m_linear *= t_scalar;
92 return *this;
93 }
94
95 GenerationPattern operator/=(const double t_scalar) {
96 m_constant /= t_scalar;
97 m_linear /= t_scalar;
98 return *this;
99 }
100
101 GenerationPattern operator*=(const KeyT& t_key) {
102 if (!m_linear.empty()) {
103 throw Exception("Trying to build a quadratic generation pattern.");
104 }
105 if (m_constant.is_zero(Tolerance::Sparsity)) {
106 return *this;
107 }
108 m_linear.set(t_key, m_constant);
109 m_constant.clear();
110 return *this;
111 }
112
113protected:
116};
117
118namespace idol {
119
120 template<class GeneratedT, class CoefficientT>
121 std::ostream& operator<<(std::ostream& t_os, const idol::GenerationPattern<GeneratedT, CoefficientT>& t_gen) {
122 const auto print_constant = [&](const idol::AffExpr<CoefficientT>& t_constant) {
123
124 t_os << t_constant.constant();
125
126 for (const auto& [key, value] : t_constant.linear()) {
127 t_os << " + " << value << " !" << key;
128 }
129
130 };
131
132 print_constant(t_gen.constant());
133 for (const auto& [key, value] : t_gen.linear()) {
134 t_os << " + ";
135 if (value.linear().empty()) {
136 print_constant(value);
137 } else {
138 t_os << "(";
139 print_constant(value);
140 t_os << ")";
141 }
142 t_os << " " << key;
143 }
144
145 return t_os;
146 }
147
148 template<class GeneratedT, class CoefficientT>
150 operator+(const CoefficientT &t_gen, const idol::GenerationPattern<GeneratedT, CoefficientT> &t_other) {
151 auto result = t_other;
152 result += idol::AffExpr<CoefficientT>(t_gen);
153 return result;
154 }
155
156 template<class GeneratedT, class CoefficientT>
158 operator+(const idol::GenerationPattern<GeneratedT, CoefficientT> &t_other, const CoefficientT &t_gen) {
159 auto result = t_other;
160 result += idol::AffExpr<CoefficientT>(t_gen);
161 return result;
162 }
163
164 template<class GeneratedT, class CoefficientT>
167 auto result = t_other;
168 result += idol::AffExpr<CoefficientT>(t_gen);
169 return result;
170 }
171
172 template<class GeneratedT, class CoefficientT>
174 const idol::LinExpr<CoefficientT> &t_gen) {
175 auto result = t_other;
176 result += idol::AffExpr<CoefficientT>(t_gen);
177 return result;
178 }
179
180 template<class GeneratedT, class CoefficientT>
183 auto result = t_other;
184 result += t_gen;
185 return result;
186 }
187
188 template<class GeneratedT, class CoefficientT>
191 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
192 result -= t_other;
193 return result;
194 }
195
196 template<class GeneratedT, class CoefficientT>
199 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
200 result -= t_other;
201 return result;
202 }
203
204 template<class GeneratedT, class CoefficientT>
206 const idol::LinExpr<CoefficientT> &t_other) {
207 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
208 result -= t_other;
209 return result;
210 }
211
212 template<class GeneratedT, class CoefficientT>
214 const idol::AffExpr<CoefficientT> &t_other) {
215 GenerationPattern<GeneratedT, CoefficientT> result = t_gen;
216 result -= t_other;
217 return result;
218 }
219
220 template<class GeneratedT, class CoefficientT>
222 const idol::AffExpr<CoefficientT> &t_gen) {
223 auto result = t_other;
224 result += t_gen;
225 return result;
226 }
227
228 template<class GeneratedT, class CoefficientT>
231 const typename idol::GenerationPattern<GeneratedT, CoefficientT>::KeyT &t_key) {
232 auto result = t_gen;
233 result *= t_key;
234 return result;
235 }
236
237 template<class GeneratedT, class CoefficientT>
239 operator*(const typename idol::GenerationPattern<GeneratedT, CoefficientT>::KeyT &t_key,
241 auto result = t_gen;
242 result *= t_key;
243 return result;
244 }
245
246 template<class GeneratedT, class CoefficientT>
250 auto result = t_gen1;
251 result += t_gen2;
252 return result;
253 }
254
255 template<class GeneratedT, class CoefficientT>
259 auto result = t_gen1;
260 result -= t_gen2;
261 return result;
262 }
263
264 template<class GeneratedT, class CoefficientT>
266 operator-(const CoefficientT& t_gen1,
268 GenerationPattern<GeneratedT, CoefficientT> result;
269 result.linear().set(t_gen1, 1);
270 result -= t_gen2;
271 return result;
272 }
273
274 template<class GeneratedT, class CoefficientT>
277 const CoefficientT& t_gen2) {
278 GenerationPattern<GeneratedT, CoefficientT> result = t_gen1;
279 result -= t_gen2;
280 return result;
281 }
282
283 template<class GeneratedT, class CoefficientT>
285 operator+(const idol::GenerationPattern<GeneratedT, CoefficientT> &t_gen, double t_scalar) {
286 auto result = t_gen;
287 result += t_scalar;
288 return result;
289 }
290
291 template<class GeneratedT, class CoefficientT>
293 operator-(const idol::GenerationPattern<GeneratedT, CoefficientT> &t_gen, double t_scalar) {
294 auto result = t_gen;
295 result -= t_scalar;
296 return result;
297 }
298
299 template<class GeneratedT, class CoefficientT>
301 operator+(double t_scalar, const idol::GenerationPattern<GeneratedT, CoefficientT> &t_gen) {
302 auto result = t_gen;
303 result += t_scalar;
304 return result;
305 }
306
307 template<class GeneratedT, class CoefficientT>
309 operator-(double t_scalar, const idol::GenerationPattern<GeneratedT, CoefficientT> &t_gen) {
310 auto result = t_gen;
311 result -= t_scalar;
312 return result;
313 }
314
315 template<class GeneratedT, class CoefficientT>
317 operator*(const double t_scalar, const idol::GenerationPattern<GeneratedT, CoefficientT> &t_gen) {
318 auto result = t_gen;
319 result *= t_scalar;
320 return result;
321 }
322
323 template<class GeneratedT, class CoefficientT>
325 operator*(const idol::GenerationPattern<GeneratedT, CoefficientT> &t_gen, const double t_scalar) {
326 auto result = t_gen;
327 result *= t_scalar;
328 return result;
329 }
330
331 template<class GeneratedT, class CoefficientT>
333 operator/(const idol::GenerationPattern<GeneratedT, CoefficientT> &t_gen, const double t_scalar) {
334 auto result = t_gen;
335 result /= t_scalar;
336 return result;
337 }
338
339 static idol::GenerationPattern<idol::Ctr> operator!(const idol::Var &t_var) {
341 cut.constant().linear().set(t_var, 1);
342 return cut;
343 }
344
345 template<class GeneratedT, class CoefficientT>
349 result.constant().constant() = t_gen.constant().constant();
350 for (const auto &[key, value]: t_gen.constant().linear()) {
351 result.linear().set(key, result.linear().get(key) + value);
352 }
353 for (const auto &[key, coefficient]: t_gen.linear()) {
354 result.constant().linear().set(key, result.constant().linear().get(key) + coefficient.constant());
355 for (const auto &[key2, value]: coefficient.linear()) {
356 result.linear().set(key2, result.linear().get(key2) + value * key);
357 }
358 }
359 return result;
360 }
361}
362
363#endif //IDOL_GENERATIONPATTERN_H
static double Sparsity
Definition numericals.h:37