otspot_model/
expression.rs1use std::collections::HashMap;
4use std::ops::{Add, Mul, Neg, Sub};
5
6use super::constraint::{Constraint, ConstraintSense};
7use super::variable::Variable;
8
9#[derive(Debug, Clone, Default)]
14pub struct Expression {
15 pub(crate) coefficients: HashMap<Variable, f64>,
16 pub(crate) constant: f64,
17}
18
19impl Expression {
20 pub fn from_constant(c: f64) -> Self {
22 Expression {
23 coefficients: HashMap::new(),
24 constant: c,
25 }
26 }
27
28 pub(crate) fn coefficient(&self, var: Variable) -> f64 {
30 self.coefficients.get(&var).copied().unwrap_or(0.0)
31 }
32
33 fn merge_add(&mut self, rhs: Expression) {
35 for (var, coeff) in rhs.coefficients {
36 *self.coefficients.entry(var).or_insert(0.0) += coeff;
37 }
38 self.constant += rhs.constant;
39 }
40
41 pub fn leq(self, rhs: impl Into<Expression>) -> Constraint {
45 let mut lhs = self;
46 let mut rhs_expr = rhs.into();
47 for (var, coeff) in rhs_expr.coefficients.drain() {
51 *lhs.coefficients.entry(var).or_insert(0.0) -= coeff;
52 }
53 let rhs_val = rhs_expr.constant - lhs.constant;
54 lhs.constant = 0.0;
55 Constraint {
56 lhs,
57 rhs: rhs_val,
58 sense: ConstraintSense::Le,
59 }
60 }
61
62 pub fn geq(self, rhs: impl Into<Expression>) -> Constraint {
64 let mut lhs = self;
65 let mut rhs_expr = rhs.into();
66 for (var, coeff) in rhs_expr.coefficients.drain() {
67 *lhs.coefficients.entry(var).or_insert(0.0) -= coeff;
68 }
69 let rhs_val = rhs_expr.constant - lhs.constant;
70 lhs.constant = 0.0;
71 Constraint {
72 lhs,
73 rhs: rhs_val,
74 sense: ConstraintSense::Ge,
75 }
76 }
77
78 pub fn eq_constraint(self, rhs: impl Into<Expression>) -> Constraint {
80 let mut lhs = self;
81 let mut rhs_expr = rhs.into();
82 for (var, coeff) in rhs_expr.coefficients.drain() {
83 *lhs.coefficients.entry(var).or_insert(0.0) -= coeff;
84 }
85 let rhs_val = rhs_expr.constant - lhs.constant;
86 lhs.constant = 0.0;
87 Constraint {
88 lhs,
89 rhs: rhs_val,
90 sense: ConstraintSense::Eq,
91 }
92 }
93}
94
95impl From<Variable> for Expression {
98 fn from(var: Variable) -> Self {
99 let mut coefficients = HashMap::new();
100 coefficients.insert(var, 1.0);
101 Expression {
102 coefficients,
103 constant: 0.0,
104 }
105 }
106}
107
108impl From<f64> for Expression {
109 fn from(c: f64) -> Self {
110 Expression::from_constant(c)
111 }
112}
113
114impl From<i32> for Expression {
115 fn from(c: i32) -> Self {
116 Expression::from_constant(c as f64)
117 }
118}
119
120impl Neg for Expression {
123 type Output = Expression;
124 fn neg(mut self) -> Expression {
125 for coeff in self.coefficients.values_mut() {
126 *coeff = -*coeff;
127 }
128 self.constant = -self.constant;
129 self
130 }
131}
132
133impl Neg for Variable {
134 type Output = Expression;
135 fn neg(self) -> Expression {
136 -Expression::from(self)
137 }
138}
139
140impl Add for Expression {
143 type Output = Expression;
144 fn add(mut self, rhs: Expression) -> Expression {
145 self.merge_add(rhs);
146 self
147 }
148}
149
150impl Sub for Expression {
153 type Output = Expression;
154 fn sub(self, rhs: Expression) -> Expression {
155 self + (-rhs)
156 }
157}
158
159impl Mul<Expression> for f64 {
162 type Output = Expression;
163 fn mul(self, mut rhs: Expression) -> Expression {
164 for coeff in rhs.coefficients.values_mut() {
165 *coeff *= self;
166 }
167 rhs.constant *= self;
168 rhs
169 }
170}
171
172impl Mul<f64> for Expression {
173 type Output = Expression;
174 fn mul(self, rhs: f64) -> Expression {
175 rhs * self
176 }
177}
178
179impl Mul<Variable> for f64 {
182 type Output = Expression;
183 fn mul(self, rhs: Variable) -> Expression {
184 let mut coefficients = HashMap::new();
185 coefficients.insert(rhs, self);
186 Expression {
187 coefficients,
188 constant: 0.0,
189 }
190 }
191}
192
193impl Mul<f64> for Variable {
194 type Output = Expression;
195 fn mul(self, rhs: f64) -> Expression {
196 rhs * self
197 }
198}
199
200impl Add<Variable> for Variable {
203 type Output = Expression;
204 fn add(self, rhs: Variable) -> Expression {
205 Expression::from(self) + Expression::from(rhs)
206 }
207}
208
209impl Sub<Variable> for Variable {
210 type Output = Expression;
211 fn sub(self, rhs: Variable) -> Expression {
212 Expression::from(self) - Expression::from(rhs)
213 }
214}
215
216impl Add<Expression> for Variable {
219 type Output = Expression;
220 fn add(self, rhs: Expression) -> Expression {
221 Expression::from(self) + rhs
222 }
223}
224
225impl Add<Variable> for Expression {
226 type Output = Expression;
227 fn add(mut self, rhs: Variable) -> Expression {
228 *self.coefficients.entry(rhs).or_insert(0.0) += 1.0;
229 self
230 }
231}
232
233impl Sub<Expression> for Variable {
234 type Output = Expression;
235 fn sub(self, rhs: Expression) -> Expression {
236 Expression::from(self) - rhs
237 }
238}
239
240impl Sub<Variable> for Expression {
241 type Output = Expression;
242 fn sub(mut self, rhs: Variable) -> Expression {
243 *self.coefficients.entry(rhs).or_insert(0.0) -= 1.0;
244 self
245 }
246}
247
248impl Add<f64> for Expression {
251 type Output = Expression;
252 fn add(mut self, rhs: f64) -> Expression {
253 self.constant += rhs;
254 self
255 }
256}
257
258impl Add<Expression> for f64 {
259 type Output = Expression;
260 fn add(self, mut rhs: Expression) -> Expression {
261 rhs.constant += self;
262 rhs
263 }
264}
265
266impl Sub<f64> for Expression {
267 type Output = Expression;
268 fn sub(mut self, rhs: f64) -> Expression {
269 self.constant -= rhs;
270 self
271 }
272}
273
274impl Sub<Expression> for f64 {
275 type Output = Expression;
276 fn sub(self, rhs: Expression) -> Expression {
277 self + (-rhs)
278 }
279}
280
281impl Add<f64> for Variable {
284 type Output = Expression;
285 fn add(self, rhs: f64) -> Expression {
286 Expression::from(self) + rhs
287 }
288}
289
290impl Add<Variable> for f64 {
291 type Output = Expression;
292 fn add(self, rhs: Variable) -> Expression {
293 self + Expression::from(rhs)
294 }
295}
296
297impl Sub<f64> for Variable {
298 type Output = Expression;
299 fn sub(self, rhs: f64) -> Expression {
300 Expression::from(self) - rhs
301 }
302}
303
304impl Sub<Variable> for f64 {
305 type Output = Expression;
306 fn sub(self, rhs: Variable) -> Expression {
307 self - Expression::from(rhs)
308 }
309}