OR-Tools  9.3
solvers_proto_validation.cc
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include "absl/status/status.h"
18#include "ortools/pdlp/solvers.pb.h"
19
21
22using ::absl::InvalidArgumentError;
23using ::absl::OkStatus;
24
25absl::Status ValidateTerminationCriteria(const TerminationCriteria& criteria) {
26 if (criteria.optimality_norm() != OPTIMALITY_NORM_L_INF &&
27 criteria.optimality_norm() != OPTIMALITY_NORM_L2) {
28 return InvalidArgumentError("invalid value for optimality_norm");
29 }
30 if (criteria.eps_optimal_absolute() < 0) {
31 return InvalidArgumentError("eps_optimal_absolute must be non-negative");
32 }
33 if (criteria.eps_optimal_relative() < 0) {
34 return InvalidArgumentError("eps_optimal_relative must be non-negative");
35 }
36 if (criteria.eps_primal_infeasible() < 0) {
37 return InvalidArgumentError("eps_primal_infeasible must be non-negative");
38 }
39 if (criteria.eps_dual_infeasible() < 0) {
40 return InvalidArgumentError("eps_dual_infeasible must be non-negative");
41 }
42 if (criteria.time_sec_limit() < 0) {
43 return InvalidArgumentError("time_sec_limit must be non-negative");
44 }
45 if (criteria.iteration_limit() < 0) {
46 return InvalidArgumentError("iteration_limit must be non-negative");
47 }
48 if (criteria.kkt_matrix_pass_limit() < 0) {
49 return InvalidArgumentError("kkt_matrix_pass_limit must be non-negative");
50 }
51 return OkStatus();
52}
53
55 const AdaptiveLinesearchParams& params) {
56 if (params.step_size_reduction_exponent() <= 0) {
57 return InvalidArgumentError(
58 "step_size_reduction_exponent must be positive");
59 }
60 if (params.step_size_growth_exponent() <= 0) {
61 return InvalidArgumentError("step_size_growth_exponent must be positive");
62 }
63 return OkStatus();
64}
65
66absl::Status ValidateMalitskyPockParams(const MalitskyPockParams& params) {
67 if (params.step_size_downscaling_factor() <= 0 ||
68 params.step_size_downscaling_factor() >= 1) {
69 return InvalidArgumentError(
70 "step_size_downscaling_factor must be between 0 and 1 exclusive");
71 }
72 if (params.linesearch_contraction_factor() <= 0 ||
73 params.linesearch_contraction_factor() >= 1) {
74 return InvalidArgumentError(
75 "linesearch_contraction_factor must be between 0 and 1 exclusive");
76 }
77 if (params.step_size_interpolation() < 0) {
78 return InvalidArgumentError("step_size_interpolation must be non-negative");
79 }
80 return OkStatus();
81}
82
84 const PrimalDualHybridGradientParams& params) {
85 RETURN_IF_ERROR(ValidateTerminationCriteria(params.termination_criteria()))
86 << "termination_criteria invalid";
87 if (params.num_threads() <= 0) {
88 return InvalidArgumentError("num_threads must be positive");
89 }
90 if (params.verbosity_level() < 0) {
91 return InvalidArgumentError("verbosity_level must be non-negative");
92 }
93 if (params.major_iteration_frequency() <= 0) {
94 return InvalidArgumentError("major_iteration_frequency must be positive");
95 }
96 if (params.termination_check_frequency() <= 0) {
97 return InvalidArgumentError("termination_check_frequency must be positive");
98 }
99 if (params.restart_strategy() !=
100 PrimalDualHybridGradientParams::NO_RESTARTS &&
101 params.restart_strategy() !=
102 PrimalDualHybridGradientParams::EVERY_MAJOR_ITERATION &&
103 params.restart_strategy() !=
104 PrimalDualHybridGradientParams::ADAPTIVE_HEURISTIC &&
105 params.restart_strategy() !=
106 PrimalDualHybridGradientParams::ADAPTIVE_DISTANCE_BASED) {
107 return InvalidArgumentError("invalid restart_strategy");
108 }
109 if (params.primal_weight_update_smoothing() < 0 ||
110 params.primal_weight_update_smoothing() > 1) {
111 return InvalidArgumentError(
112 "primal_weight_update_smoothing must be between 0 and 1 inclusive");
113 }
114 if (params.has_initial_primal_weight() &&
115 params.initial_primal_weight() <= 0) {
116 return InvalidArgumentError(
117 "initial_primal_weight must be positive if specified");
118 }
119 if (params.l_inf_ruiz_iterations() < 0) {
120 return InvalidArgumentError("l_inf_ruiz_iterations must be non-negative");
121 }
122 if (params.sufficient_reduction_for_restart() <= 0 ||
123 params.sufficient_reduction_for_restart() >= 1) {
124 return InvalidArgumentError(
125 "sufficient_reduction_for_restart must be between 0 and 1 exclusive");
126 }
127 if (params.necessary_reduction_for_restart() <
128 params.sufficient_reduction_for_restart() ||
129 params.necessary_reduction_for_restart() >= 1) {
130 return InvalidArgumentError(
131 "necessary_reduction_for_restart must be in the interval "
132 "[sufficient_reduction_for_restart, 1)");
133 }
134 if (params.linesearch_rule() !=
135 PrimalDualHybridGradientParams::ADAPTIVE_LINESEARCH_RULE &&
136 params.linesearch_rule() !=
137 PrimalDualHybridGradientParams::MALITSKY_POCK_LINESEARCH_RULE &&
138 params.linesearch_rule() !=
139 PrimalDualHybridGradientParams::CONSTANT_STEP_SIZE_RULE) {
140 return InvalidArgumentError("invalid linesearch_rule");
141 }
143 ValidateAdaptiveLinesearchParams(params.adaptive_linesearch_parameters()))
144 << "adaptive_linesearch_parameters invalid";
145 RETURN_IF_ERROR(ValidateMalitskyPockParams(params.malitsky_pock_parameters()))
146 << "malitsky_pock_parameters invalid";
147 if (params.initial_step_size_scaling() <= 0.0) {
148 return InvalidArgumentError("initial_step_size_scaling must be positive");
149 }
150
151 if (params.infinite_constraint_bound_threshold() < 0.0) {
152 return InvalidArgumentError(
153 "infinite_constraint_bound_threshold must be non-negative");
154 }
155 if (params.diagonal_qp_trust_region_solver_tolerance() < 0.0) {
156 return InvalidArgumentError(
157 "diagonal_qp_trust_region_solver_tolerance must be non-negative");
158 }
159 return OkStatus();
160}
161
162} // namespace operations_research::pdlp
#define RETURN_IF_ERROR(expr)
absl::Status ValidateTerminationCriteria(const TerminationCriteria &criteria)
absl::Status ValidateMalitskyPockParams(const MalitskyPockParams &params)
absl::Status ValidateAdaptiveLinesearchParams(const AdaptiveLinesearchParams &params)
absl::Status ValidatePrimalDualHybridGradientParams(const PrimalDualHybridGradientParams &params)