idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
AffExpr.h
1//
2// Created by henri on 21/10/22.
3//
4
5#ifndef IDOL_AFFEXPR_H
6#define IDOL_AFFEXPR_H
7
8#include "LinExpr.h"
9#include "idol/general/numericals.h"
10
11namespace idol {
12 class Var;
13
14 template<class KeyT, class ValueT>
15 class AffExpr;
16}
17
18template<class KeyT = idol::Var, class ValueT = double>
20 LinExpr<KeyT, ValueT> m_linear;
21 ValueT m_constant = 0.;
22public:
23 AffExpr();
24 AffExpr(ValueT t_constant); // NOLINT(google-explicit-constructor)
25 AffExpr(const KeyT& t_key); // NOLINT(google-explicit-constructor)
26 AffExpr(LinExpr<KeyT> t_expr); // NOLINT(google-explicit-constructor)
27
28 virtual ~AffExpr() = default;
29
30 AffExpr(const AffExpr& t_src) = default;
31 AffExpr(AffExpr&&) noexcept = default;
32
33 AffExpr& operator=(const AffExpr& t_rhs) = default;
34 AffExpr& operator=(AffExpr&&) noexcept = default;
35
36 AffExpr& operator+=(const AffExpr& t_rhs);
37
38 AffExpr& operator-=(const AffExpr& t_rhs);
39 AffExpr& operator*=(double t_rhs);
40 AffExpr& operator/=(double t_rhs);
41 AffExpr operator-() const;
42
43 LinExpr<KeyT, ValueT>& linear() { return m_linear; }
44 [[nodiscard]] const LinExpr<KeyT, ValueT>& linear() const { return m_linear; }
45
46 ValueT& constant() { return m_constant; }
47
48 [[nodiscard]] const ValueT& constant() const { return m_constant; }
49
50 [[nodiscard]] bool is_zero(double t_tolerance) const { return ::idol::is_zero(constant(), t_tolerance) && linear().is_zero(t_tolerance); }
51
52 void clear() {
53 constant() = 0;
54 m_linear.clear();
55 }
56
57 static const AffExpr<KeyT, ValueT> Zero;
58};
59
60template<class KeyT, class ValueT> const idol::AffExpr<KeyT, ValueT> idol::AffExpr<KeyT, ValueT>::Zero {};
61
62template<class KeyT, class ValueT>
63idol::AffExpr<KeyT, ValueT>::AffExpr(const KeyT &t_key) : m_linear(t_key) {
64
65}
66
67template<class Key1, class ValueT>
69 auto result = *this;
70 result.constant() = -result.constant();
71 result.linear() = -result.linear();
72 return result;
73}
74
75template<class Key1, class ValueT>
77
78}
79
80template<class Key1, class ValueT>
81idol::AffExpr<Key1, ValueT>::AffExpr(ValueT t_constant) : m_constant(std::move(t_constant)) {
82
83}
84
85template<class Key1, class ValueT>
86idol::AffExpr<Key1, ValueT>::AffExpr(LinExpr<Key1> t_expr) : m_linear(std::move(t_expr)) {
87
88}
89
90template<class Key1, class ValueT>
92 m_linear += t_rhs.m_linear;
93 m_constant += t_rhs.m_constant;
94 return *this;
95}
96
97template<class Key1, class ValueT>
99 m_linear -= t_rhs.m_linear;
100 m_constant -= t_rhs.m_constant;
101 return *this;
102}
103
104template<class Key1, class ValueT>
106 m_linear *= t_rhs;
107 m_constant *= t_rhs;
108 return *this;
109}
110
111template<class Key1, class ValueT>
113 m_linear /= t_rhs;
114 m_constant /= t_rhs;
115 return *this;
116}
117
118namespace idol {
119
120 template<class Key1, class ValueT>
121 std::ostream &operator<<(std::ostream &t_os, const idol::AffExpr<Key1, ValueT> &t_expr) {
122
123 if (std::abs(t_expr.constant()) < Tolerance::Sparsity) {
124
125 t_os << t_expr.linear();
126
127 return t_os;
128 }
129
130 t_os << t_expr.constant();
131
132 if (!t_expr.linear().empty()) {
133 t_os << " + " << t_expr.linear();
134 }
135
136 return t_os;
137 }
138
139}
140
141#endif //IDOL_AFFEXPR_H
static double Sparsity
Definition numericals.h:37