pdlp: sync
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user