diff --git a/check/TestCAPI.c b/check/TestCAPI.c index 5dbfe05fb6..86135b6b78 100644 --- a/check/TestCAPI.c +++ b/check/TestCAPI.c @@ -1967,7 +1967,7 @@ void test_multiObjective() { free(col_value); } -void test_qp_indefinite_failure() { +void testQpIndefiniteFailure() { void* highs = Highs_create(); HighsInt ret; const double inf = Highs_getInfinity(highs); @@ -2051,7 +2051,7 @@ int main() { test_feasibilityRelaxation(); test_getModel(); test_multiObjective(); - test_qp_indefinite_failure(); + test_testQpIndefiniteFailure(); return 0; } // test_setSolution(); diff --git a/src/Highs.h b/src/Highs.h index a54304d94d..bbdf219fde 100644 --- a/src/Highs.h +++ b/src/Highs.h @@ -1661,8 +1661,7 @@ class Highs { bool aFormatOk(const HighsInt num_nz, const HighsInt format); bool qFormatOk(const HighsInt num_nz, const HighsInt format); void clearZeroHessian(); - HighsStatus checkOptimality(const std::string& solver_type, - HighsStatus return_status); + HighsStatus checkOptimality(const std::string& solver_type); HighsStatus invertRequirementError(std::string method_name) const; HighsStatus handleInfCost(); diff --git a/src/lp_data/Highs.cpp b/src/lp_data/Highs.cpp index 5e315373df..840b0225d6 100644 --- a/src/lp_data/Highs.cpp +++ b/src/lp_data/Highs.cpp @@ -3746,13 +3746,7 @@ HighsStatus Highs::callSolveLp(HighsLp& lp, const string message) { return_status = solveLp(solver_object, message); // Extract the model status model_status_ = solver_object.model_status_; - if (model_status_ == HighsModelStatus::kOptimal) { - HighsStatus check_status = checkOptimality("LP", return_status); - if (check_status == HighsStatus::kError) { - return_status = check_status; - solver_object.model_status_ = HighsModelStatus::kSolveError; - } - } + if (model_status_ == HighsModelStatus::kOptimal) return checkOptimality("LP"); return return_status; } @@ -3897,13 +3891,7 @@ HighsStatus Highs::callSolveQp() { info_.simplex_iteration_count += stats.phase1_iterations; info_.qp_iteration_count += stats.num_iterations; info_.valid = true; - if (model_status_ == HighsModelStatus::kOptimal) { - HighsStatus check_status = checkOptimality("QP", return_status); - if (check_status == HighsStatus::kError) { - return_status = check_status; - model_status_ = HighsModelStatus::kSolveError; - } - } + if (model_status_ == HighsModelStatus::kOptimal) return checkOptimality("QP"); return return_status; } @@ -3997,13 +3985,8 @@ HighsStatus Highs::callSolveMip() { ? -1 : HighsInt(mip_total_lp_iterations); info_.valid = true; - if (model_status_ == HighsModelStatus::kOptimal) { - HighsStatus check_status = checkOptimality("MIP", return_status); - if (check_status == HighsStatus::kError) { - return_status = check_status; - model_status_ = HighsModelStatus::kSolveError; - } - } + if (model_status_ == HighsModelStatus::kOptimal) + return_status = checkOptimality("MIP"); if (use_mip_feasibility_tolerance) { // Overwrite max infeasibility to include integrality if there is a solution if (solver.solution_objective_ != kHighsInf) { diff --git a/src/lp_data/HighsInterface.cpp b/src/lp_data/HighsInterface.cpp index 3029acfc1f..472ffb8705 100644 --- a/src/lp_data/HighsInterface.cpp +++ b/src/lp_data/HighsInterface.cpp @@ -2442,24 +2442,25 @@ void Highs::clearZeroHessian() { } } -HighsStatus Highs::checkOptimality(const std::string& solver_type, - HighsStatus return_status) { +HighsStatus Highs::checkOptimality(const std::string& solver_type) { // Check for infeasibility measures incompatible with optimality - assert(return_status != HighsStatus::kError); + assert(model_status_ == HighsModelStatus::kOptimal); // Cannot expect to have no dual_infeasibilities since the QP solver // (and, of course, the MIP solver) give no dual information if (info_.num_primal_infeasibilities == 0 && info_.num_dual_infeasibilities <= 0) return HighsStatus::kOk; HighsLogType log_type = HighsLogType::kWarning; - return_status = HighsStatus::kWarning; + model_status_ = HighsModelStatus::kUnknown; + HighsStatus return_status = HighsStatus::kWarning; + // Check for gross errors if (info_.max_primal_infeasibility > sqrt(options_.primal_feasibility_tolerance) || (info_.dual_solution_status != kSolutionStatusNone && info_.max_dual_infeasibility > sqrt(options_.dual_feasibility_tolerance))) { - // Check for gross errors log_type = HighsLogType::kError; + model_status_ = HighsModelStatus::kSolveError; return_status = HighsStatus::kError; } std::stringstream ss; @@ -2476,6 +2477,8 @@ HighsStatus Highs::checkOptimality(const std::string& solver_type, ss << " infeasibilities\n"; const std::string report_string = ss.str(); highsLogUser(options_.log_options, log_type, "%s", report_string.c_str()); + highsLogUser(options_.log_options, log_type, "Setting model status to %s\n", + modelStatusToString(model_status_).c_str()); return return_status; }