MCPcopy Create free account
hub / github.com/ERGO-Code/HiGHS / getVariableKktFailures

Function getVariableKktFailures

highs/lp_data/HighsSolution.cpp:567–661  ·  view source on GitHub ↗

Gets the KKT failures for a variable. Value and dual are used compute the primal and dual infeasibility It's up to the calling method to ignore these if the value or dual are not valid.

Source from the content-addressed store, hash-verified

565// It's up to the calling method to ignore these if the value or dual
566// are not valid.
567void getVariableKktFailures(const double primal_feasibility_tolerance,
568 const double dual_feasibility_tolerance,
569 const double mip_feasibility_tolerance,
570 const double lower, const double upper,
571 const double value, const double dual,
572 const HighsVarType integrality,
573 double& primal_infeasibility,
574 double& dual_infeasibility,
575 double& semi_infeasibility, uint8_t& at_status,
576 uint8_t& mid_status, const HighsInt index) {
577 // Return the primal residual (ie infeasibility with zero tolerance)
578 // as the primal infeasibility, ensuring (cf #2653) that it doesn't
579 // exceed the primal feasibility tolerance if the standard primal
580 // infeasibility (ie infeasibility exceeding the tolerance) is zero
581 auto infeasibility_residual =
582 infeasibility(lower, value, upper, primal_feasibility_tolerance);
583 primal_infeasibility = infeasibility_residual.second;
584 semi_infeasibility = 0;
585 // Determine whether this value is close to a bound
586 at_status = kHighsSolutionNo;
587 double bound_residual = std::fabs(lower - value);
588 if (bound_residual * bound_residual <= primal_feasibility_tolerance) {
589 // Close to lower bound
590 at_status = kHighsSolutionLo;
591 } else {
592 // Not close to lower bound: maybe close to upper bound
593 bound_residual = std::fabs(value - upper);
594 if (bound_residual * bound_residual <= primal_feasibility_tolerance)
595 at_status = kHighsSolutionUp;
596 }
597 // Look for dual sign errors that exceed the tolerance. For boxed
598 // variables the test is discontinuous at the midpoint, but any
599 // meaningful dual value on a meaningful interval will show up as a
600 // large complementarity error
601 mid_status = kHighsSolutionNo;
602 if (lower < upper) {
603 double length = upper - lower;
604 // Non-fixed variable
605 if (lower <= -kHighsInf && upper >= kHighsInf) {
606 // Free variable
607 dual_infeasibility = fabs(dual);
608 } else if (length * length > primal_feasibility_tolerance) {
609 // Interval length is meaningful
610 //
611 // Compute the mid-point of the bound interval. This will be
612 // +infinity for LB variables; -infinity for UB variables;
613 // finite for boxed and fixed variables
614 const double middle = (lower + upper) * 0.5;
615 if (value < middle) {
616 // Below the mid-point, so use lower bound optimality condition:
617 // feasibility is dual >= -tolerance
618 mid_status = kHighsSolutionLo;
619 dual_infeasibility = std::max(-dual, 0.);
620 } else {
621 // Below the mid-point, so use upper bound optimality condition:
622 // feasibility is dual <= tolerance
623 mid_status = kHighsSolutionUp;
624 dual_infeasibility = std::max(dual, 0.);

Callers 2

getKktFailuresFunction · 0.85

Calls 1

infeasibilityFunction · 0.85

Tested by

no test coverage detected