46 if (criteria.optimality_norm() != OPTIMALITY_NORM_L_INF &&
47 criteria.optimality_norm() != OPTIMALITY_NORM_L2 &&
48 criteria.optimality_norm() != OPTIMALITY_NORM_L_INF_COMPONENTWISE) {
49 return InvalidArgumentError(
"invalid value for optimality_norm");
51 if (criteria.has_detailed_optimality_criteria() ||
52 criteria.has_simple_optimality_criteria()) {
53 if (criteria.has_eps_optimal_absolute()) {
54 return InvalidArgumentError(
55 "eps_optimal_absolute should not be set if "
56 "detailed_optimality_criteria or simple_optimality_criteria is used");
58 if (criteria.has_eps_optimal_relative()) {
59 return InvalidArgumentError(
60 "eps_optimal_relative should not be set if "
61 "detailed_optimality_criteria or simple_optimality_criteria is used");
64 if (criteria.has_detailed_optimality_criteria()) {
66 criteria.detailed_optimality_criteria()
67 .eps_optimal_primal_residual_absolute(),
68 "detailed_optimality_criteria.eps_optimal_primal_residual_absolute"));
70 criteria.detailed_optimality_criteria()
71 .eps_optimal_primal_residual_relative(),
72 "detailed_optimality_criteria.eps_optimal_primal_residual_relative"));
74 criteria.detailed_optimality_criteria()
75 .eps_optimal_dual_residual_absolute(),
76 "detailed_optimality_criteria.eps_optimal_dual_residual_absolute"));
78 criteria.detailed_optimality_criteria()
79 .eps_optimal_dual_residual_relative(),
80 "detailed_optimality_criteria.eps_optimal_dual_residual_relative"));
82 criteria.detailed_optimality_criteria()
83 .eps_optimal_objective_gap_absolute(),
84 "detailed_optimality_criteria.eps_optimal_objective_gap_absolute"));
86 criteria.detailed_optimality_criteria()
87 .eps_optimal_objective_gap_relative(),
88 "detailed_optimality_criteria.eps_optimal_objective_gap_relative"));
89 }
else if (criteria.has_simple_optimality_criteria()) {
91 criteria.simple_optimality_criteria().eps_optimal_absolute(),
92 "simple_optimality_criteria.eps_optimal_absolute"));
94 criteria.simple_optimality_criteria().eps_optimal_relative(),
95 "simple_optimality_criteria.eps_optimal_relative"));
98 "eps_optimal_absolute"));
100 "eps_optimal_relative"));
103 "eps_primal_infeasible"));
111 if (criteria.iteration_limit() < 0) {
112 return InvalidArgumentError(
"iteration_limit must be non-negative");
115 "kkt_matrix_pass_limit"));
142 if (std::isnan(params.step_size_downscaling_factor())) {
143 return InvalidArgumentError(
"step_size_downscaling_factor is NAN");
145 if (params.step_size_downscaling_factor() <=
kTinyDouble ||
146 params.step_size_downscaling_factor() >= 1) {
147 return InvalidArgumentError(
148 absl::StrCat(
"step_size_downscaling_factor must be between ",
151 if (std::isnan(params.linesearch_contraction_factor())) {
152 return InvalidArgumentError(
"linesearch_contraction_factor is NAN");
154 if (params.linesearch_contraction_factor() <= 0 ||
155 params.linesearch_contraction_factor() >= 1) {
156 return InvalidArgumentError(
157 "linesearch_contraction_factor must be between 0 and 1 exclusive");
159 if (std::isnan(params.step_size_interpolation())) {
160 return InvalidArgumentError(
"step_size_interpolation is NAN");
162 if (params.step_size_interpolation() < 0 ||
164 return InvalidArgumentError(absl::StrCat(
165 "step_size_interpolation must be non-negative and less than ",
172 const PrimalDualHybridGradientParams& params) {
174 <<
"termination_criteria invalid";
175 if (params.num_threads() <= 0) {
176 return InvalidArgumentError(
"num_threads must be positive");
178 if (params.verbosity_level() < 0) {
179 return InvalidArgumentError(
"verbosity_level must be non-negative");
181 if (params.log_interval_seconds() < 0.0) {
182 return InvalidArgumentError(
"log_interval_seconds must be non-negative");
184 if (std::isnan(params.log_interval_seconds())) {
185 return InvalidArgumentError(
"log_interval_seconds is NAN");
187 if (params.major_iteration_frequency() <= 0) {
188 return InvalidArgumentError(
"major_iteration_frequency must be positive");
190 if (params.termination_check_frequency() <= 0) {
191 return InvalidArgumentError(
"termination_check_frequency must be positive");
193 if (params.restart_strategy() !=
194 PrimalDualHybridGradientParams::NO_RESTARTS &&
195 params.restart_strategy() !=
196 PrimalDualHybridGradientParams::EVERY_MAJOR_ITERATION &&
197 params.restart_strategy() !=
198 PrimalDualHybridGradientParams::ADAPTIVE_HEURISTIC &&
199 params.restart_strategy() !=
200 PrimalDualHybridGradientParams::ADAPTIVE_DISTANCE_BASED) {
201 return InvalidArgumentError(
"invalid restart_strategy");
203 if (std::isnan(params.primal_weight_update_smoothing())) {
204 return InvalidArgumentError(
"primal_weight_update_smoothing is NAN");
206 if (params.primal_weight_update_smoothing() < 0 ||
207 params.primal_weight_update_smoothing() > 1) {
208 return InvalidArgumentError(
209 "primal_weight_update_smoothing must be between 0 and 1 inclusive");
211 if (std::isnan(params.initial_primal_weight())) {
212 return InvalidArgumentError(
"initial_primal_weight is NAN");
214 if (params.has_initial_primal_weight() &&
217 return InvalidArgumentError(
218 absl::StrCat(
"initial_primal_weight must be between ",
kTinyDouble,
221 if (params.l_inf_ruiz_iterations() < 0) {
222 return InvalidArgumentError(
"l_inf_ruiz_iterations must be non-negative");
224 if (params.l_inf_ruiz_iterations() > 100) {
225 return InvalidArgumentError(
"l_inf_ruiz_iterations must be at most 100");
227 if (std::isnan(params.sufficient_reduction_for_restart())) {
228 return InvalidArgumentError(
"sufficient_reduction_for_restart is NAN");
230 if (params.sufficient_reduction_for_restart() <= 0 ||
231 params.sufficient_reduction_for_restart() >= 1) {
232 return InvalidArgumentError(
233 "sufficient_reduction_for_restart must be between 0 and 1 exclusive");
235 if (std::isnan(params.necessary_reduction_for_restart())) {
236 return InvalidArgumentError(
"necessary_reduction_for_restart is NAN");
238 if (params.necessary_reduction_for_restart() <
239 params.sufficient_reduction_for_restart() ||
240 params.necessary_reduction_for_restart() >= 1) {
241 return InvalidArgumentError(
242 "necessary_reduction_for_restart must be in the interval "
243 "[sufficient_reduction_for_restart, 1)");
245 if (params.linesearch_rule() !=
246 PrimalDualHybridGradientParams::ADAPTIVE_LINESEARCH_RULE &&
247 params.linesearch_rule() !=
248 PrimalDualHybridGradientParams::MALITSKY_POCK_LINESEARCH_RULE &&
249 params.linesearch_rule() !=
250 PrimalDualHybridGradientParams::CONSTANT_STEP_SIZE_RULE) {
251 return InvalidArgumentError(
"invalid linesearch_rule");
255 <<
"adaptive_linesearch_parameters invalid";
257 <<
"malitsky_pock_parameters invalid";
258 if (std::isnan(params.initial_step_size_scaling())) {
259 return InvalidArgumentError(
"initial_step_size_scaling is NAN");
261 if (params.initial_step_size_scaling() <=
kTinyDouble ||
262 params.initial_step_size_scaling() >=
kHugeDouble) {
263 return InvalidArgumentError(
264 absl::StrCat(
"initial_step_size_scaling must be between ",
kTinyDouble,
268 if (std::isnan(params.infinite_constraint_bound_threshold())) {
269 return InvalidArgumentError(
"infinite_constraint_bound_threshold is NAN");
271 if (params.infinite_constraint_bound_threshold() <= 0.0) {
272 return InvalidArgumentError(
273 "infinite_constraint_bound_threshold must be positive");
275 if (std::isnan(params.diagonal_qp_trust_region_solver_tolerance())) {
276 return InvalidArgumentError(
277 "diagonal_qp_trust_region_solver_tolerance is NAN");
279 if (params.diagonal_qp_trust_region_solver_tolerance() <
280 10 * std::numeric_limits<double>::epsilon()) {
281 return InvalidArgumentError(absl::StrCat(
282 "diagonal_qp_trust_region_solver_tolerance must be at least ",
283 10 * std::numeric_limits<double>::epsilon()));
285 if (params.use_feasibility_polishing() &&
286 params.handle_some_primal_gradients_on_finite_bounds_as_residuals()) {
287 return InvalidArgumentError(
288 "use_feasibility_polishing requires "
289 "!handle_some_primal_gradients_on_finite_bounds_as_residuals");
291 if (params.use_feasibility_polishing() &&
292 params.presolve_options().use_glop()) {
293 return InvalidArgumentError(
294 "use_feasibility_polishing and glop presolve can not be used "