[CoinUtils-tickets] [COIN-OR Common Utilities] #67: postsolve in CoinPresolve does not correctly handle slack variables at bounds
COIN-OR Common Utilities
coin-trac at coin-or.org
Sun May 29 17:52:10 EDT 2011
#67: postsolve in CoinPresolve does not correctly handle slack variables at
bounds
-----------------------+----------------------------------------------------
Reporter: stefan | Owner:
Type: defect | Status: new
Priority: critical | Version: trunk
Resolution: | Keywords:
-----------------------+----------------------------------------------------
Old description:
> Activating asserts in OsiPresolve::postsolve and running the Osi unittest
> shows issues with the postsolve routines of !CoinPresolve.
> It seems that slack variables may be set to status atLowerBound for rows
> with infinite right hand side or set to atUpperBound for rows with
> infinite left hand side.
>
> Lou had a look into it and reports:
> {{{
> For reference, the notion of logical variable and row status enforced
> by the OSI unit test is:
>
> <= 0 < s < infty logical atLowerBound when constraint tight
> >= -infty < s < 0 logical atUpperBound when constraint tight
>
> Which is nicely compatible with upper-bounded logicals for range
> constraints.
>
> I repaired CoinPresolvePsdebug (minor collateral damage from the
> config.h stuff) and added code to presolve_check_sol to check the row
> status. Turns out that forcing_constraint_action::postsolve and
> subst_constraint_action::postsolve were directly setting incorrect row
> status, and slack_doubleton_action::postsolve was indirectly getting it
> wrong via CoinPrePostsolveMatrix::setRowStatusUsingValue. All of these
> had the atLowerBound/atUpperBound convention reversed. Falls into the
> category of `why did anything work at all' because the relevant bits of
> code date back to 2004, probably earlier. Apparently none of the previous
> implementors using CoinPresolve were actually using the row status
> information? Or were using it and changes will break lots of code? I'm
> not looking forward to committing this.
>
> Which leads to the obvious question `So what's really wrong?' I don't
> have the solution yet, but right now the answer appears to be that row
> bounds are not properly restored. The instances I'm seeing are uniformly
> a value of 0 but should be ± infty. There is, of course, the possibility
> that I introduced this bug while fixing the row status.
> }}}
New description:
Activating asserts in OsiPresolve::postsolve and running the Osi unittest
shows issues with the postsolve routines of !CoinPresolve.
It seems that slack variables may be set to status atLowerBound for rows
with infinite right hand side or set to atUpperBound for rows with
infinite left hand side.
Lou had a look into it and reports:[[br]]
For reference, the notion of logical variable and row status enforced by
the OSI unit test is:
{{{
<= 0 < s < infty logical atLowerBound when constraint tight
>= -infty < s < 0 logical atUpperBound when constraint tight
}}}
Which is nicely compatible with upper-bounded logicals for range
constraints.
I repaired !CoinPresolvePsdebug (minor collateral damage from the
config.h stuff) and added code to presolve_check_sol to check the row
status. Turns out that forcing_constraint_action::postsolve and
subst_constraint_action::postsolve were directly setting incorrect row
status, and slack_doubleton_action::postsolve was indirectly getting it
wrong via CoinPrePostsolveMatrix::setRowStatusUsingValue. All of these had
the atLowerBound/atUpperBound convention reversed. Falls into the category
of `why did anything work at all' because the relevant bits of code date
back to 2004, probably earlier. Apparently none of the previous
implementors using !CoinPresolve were actually using the row status
information? Or were using it and changes will break lots of code? I'm not
looking forward to committing this.
Which leads to the obvious question `So what's really wrong?' I don't
have the solution yet, but right now the answer appears to be that row
bounds are not properly restored. The instances I'm seeing are uniformly a
value of 0 but should be ± infty. There is, of course, the possibility
that I introduced this bug while fixing the row status.
--
Comment (by lou):
A quick update: I can say that I didn't introduce the bug that causes the
failure to restore the row bounds, based on a test with a previous trunk
version. And I've found the same incorrect row status code in several
other postsolve methods. Looks like there was a change of convention at
some point that wasn't reflected back into !CoinPresolve code. So far it's
been a typical venture into !CoinPresolve. One thing leads to three more.
--
Ticket URL: <https://projects.coin-or.org/CoinUtils/ticket/67#comment:1>
COIN-OR Common Utilities <http://projects.coin-or.org/CoinUtils>
Common data structures and linear algebra functions for COIN-OR projects
More information about the CoinUtils-tickets
mailing list