Skip to content

Commit

Permalink
Improve bounds for Pow() and quadratics
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Mar 1, 2023
1 parent 970405f commit 2615da3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
31 changes: 18 additions & 13 deletions include/mp/flat/constr_prepro.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,24 @@ class ConstraintPreprocessors {
auto& m = MP_DISPATCH( GetModel() );
auto lb = std::pow(m.lb(arg), pwr),
ub = std::pow(m.ub(arg), pwr);
if (MPD( is_integer_value(pwr) ) && pwr>=0.0) {
// result integer if arg is and integer, >=0 exponent
prepro.set_result_type( m.var_type(arg) );
if (MPD( is_integer_value(pwr / 2.0) )) { // exponent is even, >=0
bool lb_neg = m.lb(arg)<0.0;
bool ub_pos = m.ub(arg)>0.0;
if (lb_neg && ub_pos) {
ub = std::max(lb, ub); lb = 0.0;
} else if (lb_neg) {
std::swap(lb, ub);
}
}
}
if (MPD( is_integer_value(pwr) )) {
if (pwr>=0.0) {
// result integer if arg is and integer, >=0 exponent
prepro.set_result_type( m.var_type(arg) );
if (MPD( is_integer_value(pwr / 2.0) )) { // exponent is even, >=0
bool lb_neg = m.lb(arg)<0.0;
bool ub_pos = m.ub(arg)>0.0;
if (lb_neg && ub_pos) {
ub = std::max(lb, ub); lb = 0.0;
} else if (lb_neg) {
std::swap(lb, ub);
}
}
}
} else { // fractional power
if (lb<0.0)
lb = 0.0;
}
prepro.narrow_result_bounds( std::min(lb, ub),
std::max(lb, ub) );
}
Expand Down
6 changes: 4 additions & 2 deletions include/mp/flat/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,10 @@ class FlatConverter :
void FixUnusedDefinedVars() {
for (auto i=num_vars(); i--; ) {
if (HasInitExpression(i) &&
! VarUsageRef(i))
set_var_ub(i, lb(i));
! VarUsageRef(i)) {
set_var_lb(i, 0.0); // fix to 0
set_var_ub(i, 0.0);
}
}
}

Expand Down
13 changes: 10 additions & 3 deletions include/mp/flat/expr_bounds.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,16 @@ class BoundComputations {
std::pair<double, double> ProductBounds(Var x, Var y) const {
const auto& m = MPCD(GetModel());
auto lx=m.lb(x), ly=m.lb(y), ux=m.ub(x), uy=m.ub(y);
std::array<double, 4> pb{lx*ly, lx*uy, ux*ly, ux*uy};
return { *std::min_element(pb.begin(), pb.end()),
*std::max_element(pb.begin(), pb.end()) };
if (x!=y) { // different vars
std::array<double, 4> pb{lx*ly, lx*uy, ux*ly, ux*uy};
return { *std::min_element(pb.begin(), pb.end()),
*std::max_element(pb.begin(), pb.end()) };
}
return {
lx<=0.0 && ux>=0.0 ? // lb_result: 0 included?
0.0 : std::min(lx*lx, ux*ux),
std::max(lx*lx, ux*ux)
};
}

/// Add / merge bounds and type
Expand Down

1 comment on commit 2615da3

@glebbelov
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing unused defined variables: all to 0 #201

Please sign in to comment.