@@ -284,10 +284,12 @@ void getKktFailures(const HighsOptions& options, const bool is_qp,
284284 // one-sided variables. For free variables, fixed variables, or
285285 // variables with small positive bound interval lengths,
286286 // mid_status is returned as kHighsSolutionNo.
287+ const HighsInt index = pass == 0 ? 0 : (is_col ? iVar : -(1 +(iVar-lp.num_col_ )));
287288 getVariableKktFailures (primal_feasibility_tolerance,
288289 dual_feasibility_tolerance, lower, upper, value,
289290 dual, integrality, primal_infeasibility,
290- dual_infeasibility, at_status, mid_status);
291+ dual_infeasibility, at_status, mid_status,
292+ index);
291293 if (pass == 0 ) {
292294 // If the primal value is close to a bound then include the bound
293295 // in the active bound norm
@@ -549,34 +551,43 @@ void getVariableKktFailures(const double primal_feasibility_tolerance,
549551 const HighsVarType integrality,
550552 double & primal_infeasibility,
551553 double & dual_infeasibility, uint8_t & at_status,
552- uint8_t & mid_status) {
554+ uint8_t & mid_status,
555+ const HighsInt index) {
553556 const HighsInt feasibility_tolerance_mu = 0.0 ;
554- // @primal_infeasibility calculation
555- primal_infeasibility = 0 ;
556- if (value < lower - primal_feasibility_tolerance * feasibility_tolerance_mu) {
557- // Below lower
558- primal_infeasibility = lower - value;
559- } else if (value >
560- upper + primal_feasibility_tolerance * feasibility_tolerance_mu) {
561- // Above upper
562- primal_infeasibility = value - upper;
563- }
564557 std::pair<double , double > infeasibility_residual =
565558 infeasibility (&lower, &value, &upper, &primal_feasibility_tolerance);
566- // #2653
567- //
568- // assert(infeasibility_residual.second == primal_infeasibility);
559+ primal_infeasibility = infeasibility_residual.second ;
560+ bool infeasibility_ok = primal_infeasibility == infeasibility_residual.second ;
561+ if (!infeasibility_ok) {
562+ printf (" getVariableKktFailures: pr_ifs = %11.4g; ifs.infeasibility = %11.4g; dl = %11.4g\n " ,
563+ primal_infeasibility, infeasibility_residual.second ,
564+ primal_infeasibility- infeasibility_residual.second );
565+ assert (infeasibility_ok);
566+ }
567+ bool residual_error = primal_infeasibility > primal_feasibility_tolerance &&
568+ infeasibility_residual.first == 0 ;
569+ if (residual_error) {
570+ const bool is_col = index > 0 ;
571+ printf (" getVariableKktFailures: %2s %3d [%11.4g, %11.4g, %11.4g], pr_ifs = %11.4g; ifs.infeasibility = %11.4g; ifs.residual = %11.4g\n " ,
572+ is_col ? " Col" : " Row" ,
573+ is_col ? index : -index-1 ,
574+ lower, value, upper,
575+ primal_infeasibility,
576+ infeasibility_residual.first ,
577+ infeasibility_residual.second );
578+ assert (!residual_error);
579+ }
569580
570581 // Determine whether this value is close to a bound
571582 at_status = kHighsSolutionNo ;
572- double residual = std::fabs (lower - value);
573- if (residual * residual <= primal_feasibility_tolerance) {
583+ double bound_residual = std::fabs (lower - value);
584+ if (bound_residual * bound_residual <= primal_feasibility_tolerance) {
574585 // Close to lower bound
575586 at_status = kHighsSolutionLo ;
576587 } else {
577588 // Not close to lower bound: maybe close to upper bound
578- residual = std::fabs (value - upper);
579- if (residual * residual <= primal_feasibility_tolerance)
589+ bound_residual = std::fabs (value - upper);
590+ if (bound_residual * bound_residual <= primal_feasibility_tolerance)
580591 at_status = kHighsSolutionUp ;
581592 }
582593 // Look for dual sign errors that exceed the tolerance. For boxed
0 commit comments