Skip to content

Commit 5e2e821

Browse files
committed
Now using infeasibility() to compute primal_infeasibility in getVariableKktFailures
1 parent 0c5d6cb commit 5e2e821

File tree

3 files changed

+35
-21
lines changed

3 files changed

+35
-21
lines changed

highs/lp_data/HighsSolution.cpp

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

highs/lp_data/HighsSolution.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ void getVariableKktFailures(const double primal_feasibility_tolerance,
9090
const HighsVarType integrality,
9191
double& primal_infeasibility,
9292
double& dual_infeasibility, uint8_t& at_status,
93-
uint8_t& mid_status);
93+
uint8_t& mid_status,
94+
const HighsInt index = 0);
9495

9596
void getPrimalDualGlpsolErrors(const HighsOptions& options, const HighsLp& lp,
9697
const std::vector<double>& gradient,

highs/util/HighsUtils.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ inline std::pair<double, double> infeasibility(const double* lower,
228228
// Determine the infeasibility exceeding the tolerance used in
229229
// computing the number of infeasibilities - which defines
230230
// feasibility of a solution
231+
//
232+
// @primal_infeasibility calculation
231233
if (*value < *lower - *tolerance) {
232234
infeasibility = *lower - *value;
233235
}
@@ -277,7 +279,7 @@ inline std::pair<double, double> infeasibility(const double* lower,
277279
// so that values of maximum infeasibility defined by residual
278280
// doesn't exceed the tolerance
279281
//
280-
// if (infeasibility == 0) residual = min(residual, *tolerance);
282+
if (infeasibility == 0) residual = min(residual, *tolerance);
281283
return std::make_pair(infeasibility, residual);
282284
}
283285
#endif // UTIL_HIGHSUTILS_H_

0 commit comments

Comments
 (0)