| 3438 | } |
| 3439 | |
| 3440 | HPresolve::Result HPresolve::rowPresolve(HighsPostsolveStack& postsolve_stack, |
| 3441 | HighsInt row) { |
| 3442 | assert(!rowDeleted[row]); |
| 3443 | |
| 3444 | const bool logging_on = analysis_.logging_on_; |
| 3445 | |
| 3446 | auto checkRowInfeasible = [&](HighsInt row) { |
| 3447 | if (impliedRowBounds.getSumLower(row) > |
| 3448 | model->row_upper_[row] + primal_feastol || |
| 3449 | impliedRowBounds.getSumUpper(row) < |
| 3450 | model->row_lower_[row] - primal_feastol) |
| 3451 | return Result::kPrimalInfeasible; |
| 3452 | return Result::kOk; |
| 3453 | }; |
| 3454 | |
| 3455 | auto checkRowRedundant = [&](HighsInt row) { |
| 3456 | if (isRedundant(row)) { |
| 3457 | // row is redundant |
| 3458 | int presolveRule = |
| 3459 | rowsize[row] != 0 ? kPresolveRuleRedundantRow : kPresolveRuleEmptyRow; |
| 3460 | if (logging_on) analysis_.startPresolveRuleLog(presolveRule); |
| 3461 | postsolve_stack.redundantRow(row); |
| 3462 | removeRow(row); |
| 3463 | analysis_.logging_on_ = logging_on; |
| 3464 | if (logging_on) analysis_.stopPresolveRuleLog(presolveRule); |
| 3465 | return checkLimits(postsolve_stack); |
| 3466 | } |
| 3467 | return Result::kOk; |
| 3468 | }; |
| 3469 | |
| 3470 | // printf("row presolve: "); |
| 3471 | // debugPrintRow(row); |
| 3472 | |
| 3473 | // check for infeasibility |
| 3474 | HPRESOLVE_CHECKED_CALL(checkRowInfeasible(row)); |
| 3475 | |
| 3476 | // handle special cases directly via a call to the specialized procedure |
| 3477 | switch (rowsize[row]) { |
| 3478 | default: |
| 3479 | break; |
| 3480 | case 1: |
| 3481 | return singletonRow(postsolve_stack, row); |
| 3482 | } |
| 3483 | |
| 3484 | // check for redundancy |
| 3485 | HPRESOLVE_CHECKED_CALL(checkRowRedundant(row)); |
| 3486 | if (rowDeleted[row]) return Result::kOk; |
| 3487 | |
| 3488 | if (rowsizeInteger[row] != 0 || rowsizeImplInt[row] != 0) { |
| 3489 | // check if setting variable to opposite bound (with respect to bound used |
| 3490 | // in calculation of bounds on row activity) makes row infeasible. |
| 3491 | // this is a special case of bound tightening, but only performed once for |
| 3492 | // binary variables here (see Suhl, Szymanski: Supernode processing of |
| 3493 | // mixed-integer models. Comput. Optim. Appl. 3(4): 317-331 (1994)). |
| 3494 | |
| 3495 | for (const HighsSliceNonzero& nonzero : getRowVector(row)) { |
| 3496 | // get column index and coefficient |
| 3497 | HighsInt col = nonzero.index(); |
nothing calls this directly
no test coverage detected