use crate::expression::LinearExpression;
use crate::{Expression, Solution, Variable};
pub trait IntoAffineExpression {
type Iter: IntoIterator<Item = (Variable, f64)>;
fn linear_coefficients(self) -> Self::Iter;
#[inline]
fn constant(&self) -> f64 {
0.
}
fn into_expression(self) -> Expression
where
Self: Sized,
{
let constant = self.constant();
let coefficients = self.linear_coefficients().into_iter().collect();
Expression {
linear: LinearExpression { coefficients },
constant,
}
}
fn eval_with<S: Solution>(self, values: &S) -> f64
where
Self: Sized,
{
self.constant()
+ self
.linear_coefficients()
.into_iter()
.map(|(var, coefficient)| coefficient * values.value(var))
.sum::<f64>()
}
}
macro_rules! impl_affine_for_num {
($($num:ty),*) => {$(
impl IntoAffineExpression for $num {
type Iter = std::iter::Empty<(Variable, f64)>;
#[inline]
fn linear_coefficients(self) -> Self::Iter {
std::iter::empty()
}
#[inline]
fn constant(&self) -> f64 {
f64::from(*self)
}
fn into_expression(self) -> Expression {
Expression {
linear: LinearExpression { coefficients: std::default::Default::default() },
constant: f64::from(self),
}
}
}
)*};
}
impl_affine_for_num!(f64, f32, u32, u16, u8, i32, i16, i8);