pdlp: sync

This commit is contained in:
Corentin Le Molgat
2023-06-02 13:18:34 +02:00
parent f9dad81ff7
commit 9a0c66c80c
5 changed files with 31 additions and 5 deletions

View File

@@ -2808,6 +2808,12 @@ SolverResult PrimalDualHybridGradient(
return ErrorSolverResult(TERMINATION_REASON_INVALID_PROBLEM,
"The objective scaling factor cannot be zero.");
}
if (qp.objective_matrix.has_value() &&
qp.objective_matrix->diagonal().minCoeff() < 0.0) {
return ErrorSolverResult(TERMINATION_REASON_INVALID_PROBLEM,
"The objective is not convex (i.e., the objective "
"matrix contains negative entries).");
}
if (params.use_feasibility_polishing() && !IsLinearProgram(qp)) {
return ErrorSolverResult(
TERMINATION_REASON_INVALID_PARAMETER,

View File

@@ -1052,6 +1052,15 @@ TEST(PrimalDualHybridGradientTest, DetectsProblemWithInconsistentBounds) {
TERMINATION_REASON_INVALID_PROBLEM);
}
TEST(PrimalDualHybridGradientTest, DetectsNonconvexQp) {
QuadraticProgram qp = TestDiagonalQp1();
qp.objective_matrix->diagonal()[0] = -1.0;
SolverResult output =
PrimalDualHybridGradient(qp, PrimalDualHybridGradientParams());
EXPECT_EQ(output.solve_log.termination_reason(),
TERMINATION_REASON_INVALID_PROBLEM);
}
TEST(PrimalDualHybridGradientTest, DetectsProblemWithInconsistentSizes) {
QuadraticProgram qp = TinyLp();
qp.objective_vector.resize(0);

View File

@@ -18,7 +18,6 @@
#include <limits>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include "Eigen/Core"
@@ -205,7 +204,7 @@ absl::StatusOr<QuadraticProgram> QpFromMpModelProto(
}
qp.objective_scaling_factor = -1;
}
return std::move(qp);
return qp;
}
absl::Status CanFitInMpModelProto(const QuadraticProgram& qp) {

View File

@@ -14,6 +14,7 @@
#include "ortools/pdlp/solvers_proto_validation.h"
#include <cmath>
#include <limits>
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
@@ -271,9 +272,11 @@ absl::Status ValidatePrimalDualHybridGradientParams(
return InvalidArgumentError(
"diagonal_qp_trust_region_solver_tolerance is NAN");
}
if (params.diagonal_qp_trust_region_solver_tolerance() < 0.0) {
return InvalidArgumentError(
"diagonal_qp_trust_region_solver_tolerance must be non-negative");
if (params.diagonal_qp_trust_region_solver_tolerance() <
10 * std::numeric_limits<double>::epsilon()) {
return InvalidArgumentError(absl::StrCat(
"diagonal_qp_trust_region_solver_tolerance must be at least ",
10 * std::numeric_limits<double>::epsilon()));
}
if (params.use_feasibility_polishing() &&
params.handle_some_primal_gradients_on_finite_bounds_as_residuals()) {

View File

@@ -652,6 +652,15 @@ TEST(ValidatePrimalDualHybridGradientParams,
EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(status_nan.message(),
HasSubstr("diagonal_qp_trust_region_solver_tolerance"));
PrimalDualHybridGradientParams params_tiny;
params_tiny.set_diagonal_qp_trust_region_solver_tolerance(
std::numeric_limits<double>::epsilon());
const absl::Status status_tiny =
ValidatePrimalDualHybridGradientParams(params_tiny);
EXPECT_EQ(status_tiny.code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(status_tiny.message(),
HasSubstr("diagonal_qp_trust_region_solver_tolerance"));
}
TEST(ValidatePrimalDualHybridGradientParams, FeasibilityPolishingValidOptions) {