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)