@@ -194,7 +194,7 @@ bool HPresolve::isImpliedFree(HighsInt col) const {
194194}
195195
196196bool HPresolve::isDualImpliedFree (HighsInt row) const {
197- return model-> row_lower_ [ row] == model-> row_upper_ [row] ||
197+ return isEquation ( row) ||
198198 (model->row_upper_ [row] != kHighsInf &&
199199 implRowDualUpper[row] <= options->dual_feasibility_tolerance ) ||
200200 (model->row_lower_ [row] != -kHighsInf &&
@@ -205,7 +205,7 @@ void HPresolve::dualImpliedFreeGetRhsAndRowType(
205205 HighsInt row, double & rhs, HighsPostsolveStack::RowType& rowType,
206206 bool relaxRowDualBounds) {
207207 assert (isDualImpliedFree (row));
208- if (model-> row_lower_ [ row] == model-> row_upper_ [row] ) {
208+ if (isEquation ( row) ) {
209209 rowType = HighsPostsolveStack::RowType::kEq ;
210210 rhs = model->row_upper_ [row];
211211 } else if (model->row_upper_ [row] != kHighsInf &&
@@ -220,6 +220,10 @@ void HPresolve::dualImpliedFreeGetRhsAndRowType(
220220 }
221221}
222222
223+ bool HPresolve::isEquation (HighsInt row) const {
224+ return (model->row_lower_ [row] == model->row_upper_ [row]);
225+ }
226+
223227bool HPresolve::isImpliedEquationAtLower (HighsInt row) const {
224228 // if the implied lower bound on a row dual is strictly positive then the row
225229 // is an implied equation (using its lower bound) due to complementary
@@ -267,9 +271,10 @@ HPresolve::StatusResult HPresolve::isImpliedIntegral(HighsInt col) {
267271 // if there is an equation the dual detection does not need to be tried
268272 runDualDetection = false ;
269273 double scale = 1.0 / nz.value ();
274+
270275 if (!rowCoefficientsIntegral (nz.index (), scale)) continue ;
271276
272- if (fractionality (model-> row_lower_ [nz. index ()] * scale) > primal_feastol)
277+ if (fractionality (rowLower * scale) > primal_feastol)
273278 return StatusResult (Result::kPrimalInfeasible );
274279
275280 return StatusResult (true );
@@ -344,8 +349,7 @@ HPresolve::StatusResult HPresolve::isImpliedInteger(HighsInt col) const {
344349 runDualDetection = false ;
345350 double scale = 1.0 / nz.value ();
346351
347- if (fractionality (model->row_lower_ [nz.index ()] * scale) > primal_feastol)
348- return StatusResult (Result::kPrimalInfeasible );
352+ if (fractionality (rowLower * scale) > primal_feastol) continue ;
349353
350354 if (!rowCoefficientsIntegral (nz.index (), scale)) continue ;
351355
@@ -917,8 +921,7 @@ void HPresolve::shrinkProblem(HighsPostsolveStack& postsolve_stack) {
917921 equations.clear ();
918922 eqiters.assign (model->num_row_ , equations.end ());
919923 for (HighsInt i = 0 ; i != model->num_row_ ; ++i) {
920- if (model->row_lower_ [i] == model->row_upper_ [i])
921- eqiters[i] = equations.emplace (rowsize[i], i).first ;
924+ if (isEquation (i)) eqiters[i] = equations.emplace (rowsize[i], i).first ;
922925 }
923926
924927 if (mipsolver != nullptr ) {
@@ -1968,8 +1971,7 @@ void HPresolve::markRowDeleted(HighsInt row) {
19681971 assert (!rowDeleted[row]);
19691972
19701973 // remove equations from set of equations
1971- if (model->row_lower_ [row] == model->row_upper_ [row] &&
1972- eqiters[row] != equations.end ()) {
1974+ if (isEquation (row) && eqiters[row] != equations.end ()) {
19731975 equations.erase (eqiters[row]);
19741976 eqiters[row] = equations.end ();
19751977 }
@@ -2396,8 +2398,7 @@ bool HPresolve::okFromCSC(const std::vector<double>& Aval,
23962398 }
23972399 for (HighsInt i = 0 ; i != model->num_row_ ; ++i) {
23982400 // register equation
2399- if (model->row_lower_ [i] == model->row_upper_ [i])
2400- eqiters[i] = equations.emplace (rowsize[i], i).first ;
2401+ if (isEquation (i)) eqiters[i] = equations.emplace (rowsize[i], i).first ;
24012402 }
24022403 }
24032404 return true ;
@@ -2460,8 +2461,7 @@ bool HPresolve::okFromCSR(const std::vector<double>& ARval,
24602461 }
24612462 for (HighsInt i = 0 ; i != nrow; ++i) {
24622463 // register equation
2463- if (model->row_lower_ [i] == model->row_upper_ [i])
2464- eqiters[i] = equations.emplace (rowsize[i], i).first ;
2464+ if (isEquation (i)) eqiters[i] = equations.emplace (rowsize[i], i).first ;
24652465 }
24662466 }
24672467 return true ;
@@ -2538,8 +2538,8 @@ bool HPresolve::checkFillin(HighsHashTable<HighsInt, HighsInt>& fillinCache,
25382538
25392539void HPresolve::reinsertEquation (HighsInt row) {
25402540 // check if this is an equation row and it now has a different size
2541- if (model-> row_lower_ [ row] == model-> row_upper_ [row] &&
2542- eqiters[row] != equations. end () && eqiters[row] ->first != rowsize[row]) {
2541+ if (isEquation ( row) && eqiters [row] != equations. end () &&
2542+ eqiters[row]->first != rowsize[row]) {
25432543 // if that is the case reinsert it into the equation set that is ordered
25442544 // by sparsity
25452545 equations.erase (eqiters[row]);
@@ -2826,7 +2826,7 @@ HPresolve::Result HPresolve::doubletonEq(HighsPostsolveStack& postsolve_stack,
28262826 analysis_.startPresolveRuleLog (kPresolveRuleDoubletonEquation );
28272827 assert (!rowDeleted[row]);
28282828 assert (rowsize[row] == 2 );
2829- assert (model-> row_lower_ [ row] == model-> row_upper_ [row] );
2829+ assert (isEquation ( row) );
28302830
28312831 // printf("doubleton equation: ");
28322832 // debugPrintRow(row);
@@ -3276,7 +3276,7 @@ HPresolve::Result HPresolve::rowPresolve(HighsPostsolveStack& postsolve_stack,
32763276 double origRowUpper = model->row_upper_ [row];
32773277 double origRowLower = model->row_lower_ [row];
32783278
3279- if (model-> row_lower_ [row] != model-> row_upper_ [ row] ) {
3279+ if (! isEquation ( row) ) {
32803280 if (isImpliedEquationAtLower (row)) {
32813281 // Convert to equality constraint (note that currently postsolve will not
32823282 // know about this conversion)
@@ -4553,7 +4553,7 @@ HPresolve::Result HPresolve::removeSlacks(
45534553 HighsInt iRow = Arow[coliter];
45544554 assert (Acol[coliter] == iCol);
45554555 assert (!rowDeleted[iRow]);
4556- if (model-> row_lower_ [iRow] != model-> row_upper_ [ iRow] ) continue ;
4556+ if (! isEquation ( iRow) ) continue ;
45574557 double lower = model->col_lower_ [iCol];
45584558 double upper = model->col_upper_ [iCol];
45594559 double cost = model->col_cost_ [iCol];
@@ -5405,7 +5405,7 @@ HPresolve::Result HPresolve::removeDoubletonEquations(
54055405 HighsInt eqrow = eq->second ;
54065406 assert (!rowDeleted[eqrow]);
54075407 assert (eq->first == rowsize[eqrow]);
5408- assert (model-> row_lower_ [ eqrow] == model-> row_upper_ [eqrow] );
5408+ assert (isEquation ( eqrow) );
54095409 if (rowsize[eqrow] > 2 ) return Result::kOk ;
54105410 HPRESOLVE_CHECKED_CALL (rowPresolve (postsolve_stack, eqrow));
54115411 if (rowDeleted[eqrow])
@@ -6166,8 +6166,7 @@ HPresolve::Result HPresolve::detectParallelRowsAndCols(
61666166
61676167 for (HighsInt i = 0 ; i != model->num_row_ ; ++i) {
61686168 if (rowDeleted[i]) continue ;
6169- if (rowsize[i] <= 1 ||
6170- (rowsize[i] == 2 && model->row_lower_ [i] == model->row_upper_ [i])) {
6169+ if (rowsize[i] <= 1 || (rowsize[i] == 2 && isEquation (i))) {
61716170 HPRESOLVE_CHECKED_CALL (rowPresolve (postsolve_stack, i));
61726171 continue ;
61736172 }
@@ -6210,22 +6209,16 @@ HPresolve::Result HPresolve::detectParallelRowsAndCols(
62106209 // equation. In that case we sparsify the other row by adding the
62116210 // equation and can subsequently solve it as an individual component as
62126211 // it is a row which only contains singletons
6213- if ((numSingleton != 0 ||
6214- model->row_lower_ [i] != model->row_upper_ [i]) &&
6215- (numSingletonCandidate != 0 ||
6216- model->row_lower_ [parallelRowCand] !=
6217- model->row_upper_ [parallelRowCand]))
6212+ if ((numSingleton != 0 || !isEquation (i)) &&
6213+ (numSingletonCandidate != 0 || !isEquation (parallelRowCand)))
62186214 continue ;
62196215 } else if (numSingletonCandidate != numSingleton) {
62206216 // if only one of the two constraints has an extra singleton,
62216217 // we require at least one of the constraints to be an equation
62226218 // if that is the case we can add that equation to the other row
62236219 // and will make it into either a row singleton or a doubleton equation
62246220 // which is removed afterwards
6225- if (model->row_lower_ [i] != model->row_upper_ [i] &&
6226- model->row_lower_ [parallelRowCand] !=
6227- model->row_upper_ [parallelRowCand])
6228- continue ;
6221+ if (!isEquation (i) && !isEquation (parallelRowCand)) continue ;
62296222 }
62306223
62316224 double rowScale = rowMax[parallelRowCand].first / rowMax[i].first ;
@@ -6325,7 +6318,7 @@ HPresolve::Result HPresolve::detectParallelRowsAndCols(
63256318 markRowDeleted (i);
63266319 for (HighsInt rowiter : rowpositions) unlink (rowiter);
63276320 break ;
6328- } else if (model-> row_lower_ [i] == model-> row_upper_ [i] ) {
6321+ } else if (isEquation (i) ) {
63296322 // row i is equation and parallel (except for singletons)
63306323 // add to the row parallelRowCand
63316324 // printf(
@@ -6337,8 +6330,7 @@ HPresolve::Result HPresolve::detectParallelRowsAndCols(
63376330 HPRESOLVE_CHECKED_CALL (equalityRowAddition (
63386331 postsolve_stack, i, parallelRowCand, -rowScale, getStoredRow ()));
63396332 delRow = parallelRowCand;
6340- } else if (model->row_lower_ [parallelRowCand] ==
6341- model->row_upper_ [parallelRowCand]) {
6333+ } else if (isEquation (parallelRowCand)) {
63426334 // printf(
63436335 // "nearly parallel case with %" HIGHSINT_FORMAT " singletons in eq
63446336 // row and %" HIGHSINT_FORMAT " " "singletons in other inequality
@@ -6644,7 +6636,7 @@ HPresolve::Result HPresolve::sparsify(HighsPostsolveStack& postsolve_stack) {
66446636 if (rowDeleted[eqrow]) continue ;
66456637
66466638 assert (!rowDeleted[eqrow]);
6647- assert (model-> row_lower_ [ eqrow] == model-> row_upper_ [eqrow] );
6639+ assert (isEquation ( eqrow) );
66486640
66496641 storeRow (eqrow);
66506642
0 commit comments