Skip to content

Commit

Permalink
Merge pull request #69 from jcavat/lovasoa-better_lp_sum
Browse files Browse the repository at this point in the history
Lovasoa better lp sum
  • Loading branch information
jcavat authored Feb 10, 2021
2 parents 4ed69c6 5f59fef commit c622847
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 14 deletions.
28 changes: 17 additions & 11 deletions src/dsl/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 319,10 @@ impl LpExpression {
}
}

pub fn literal(value: f32) -> Self {
value.into()
}

#[cfg(test)]
fn build(root: LpExprArenaIndex, arena: Vec<LpExprNode>) -> Self {
LpExpression {
Expand Down Expand Up @@ -1344,19 1348,21 @@ impl ToTokens for LpConstraint {
/// problem = lp_sum(v).equal(10.0);
/// ```
///
pub fn lp_sum<T>(not_yet_lp_expr_arenas: &Vec<T>) -> LpExpression where T: Into<LpExpression> Clone {
match not_yet_lp_expr_arenas.first() {
Some(first) => {
let mut arena: LpExpression = first.clone().into();
for a in not_yet_lp_expr_arenas[1..].iter() {
arena = arena.merge_cloned_arenas(&a.clone().into(), Addition);
}
arena
},
None => {
panic!("vector should have at least one element")
pub fn lp_sum<T>(expr: &Vec<T>) -> LpExpression
where T: Into<LpExpression> Clone {
let mut results: Vec<LpExpression> = expr.iter().map(|e| e.clone().into()).collect();
let mut next = Vec::with_capacity(results.len() / 2);
while results.len() > 1 {
while results.len() >= 2 {
let right = results.pop().expect("impossible because len>2");
let left = results.pop().expect("impossible because len>2");
next.push(left right)
}
next.append(&mut results);
next.reverse(); // Required only if we want to maintain the order of operations
std::mem::swap(&mut results, &mut next)
}
results.into_iter().next().unwrap_or( LpExpression::literal(0.0) )
}

pub fn sum<'a, T: 'a,U: 'a>(expr: &'a Vec<T>, f: impl Fn(&'a T) -> U) -> LpExpression where U: Into<LpExpression> Clone {
Expand Down
7 changes: 4 additions & 3 deletions tests/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 175,10 @@ fn expression_with_lp_sum() {
lp_sum(expr3).le(5.5).to_lp_file_format(),
"a <= 5.5"
);
assert!(
std::panic::catch_unwind( || lp_sum(empty)).is_err(),
"should panic if empty vec"
assert_eq!(
lp_sum(empty).to_lp_file_format(),
"0",
"should not panic if empty vec"
);
}

Expand Down

0 comments on commit c622847

Please sign in to comment.