Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions interfaces/AMPL/AMPLModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,6 @@ namespace uno {
return this->variables_upper_bounds;
}

const SparseVector<size_t>& AMPLModel::get_slacks() const {
return this->slacks;
}

const Vector<size_t>& AMPLModel::get_fixed_variables() const {
return this->fixed_variables;
}
Expand Down
3 changes: 0 additions & 3 deletions interfaces/AMPL/AMPLModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include <vector>
#include "model/Model.hpp"
#include "linear_algebra/SparseVector.hpp"
#include "linear_algebra/Vector.hpp"
#include "optimization/ProblemType.hpp"
#include "symbolic/CollectionAdapter.hpp"
Expand Down Expand Up @@ -62,7 +61,6 @@ namespace uno {

[[nodiscard]] const std::vector<double>& get_variables_lower_bounds() const override;
[[nodiscard]] const std::vector<double>& get_variables_upper_bounds() const override;
[[nodiscard]] const SparseVector<size_t>& get_slacks() const override;
[[nodiscard]] const Vector<size_t>& get_fixed_variables() const override;

[[nodiscard]] const std::vector<double>& get_constraints_lower_bounds() const override;
Expand Down Expand Up @@ -114,7 +112,6 @@ namespace uno {
CollectionAdapter<std::vector<size_t>&> equality_constraints_collection;
std::vector<size_t> inequality_constraints{};
CollectionAdapter<std::vector<size_t>&> inequality_constraints_collection;
SparseVector<size_t> slacks{};
Vector<size_t> fixed_variables;

mutable NumberModelEvaluations number_model_evaluations{};
Expand Down
6 changes: 0 additions & 6 deletions interfaces/C/Uno_C_API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "Uno_C_API.h"
#include "../UserModel.hpp"
#include "Uno.hpp"
#include "linear_algebra/SparseVector.hpp"
#include "linear_algebra/Vector.hpp"
#include "model/Model.hpp"
#include "options/DefaultOptions.hpp"
Expand Down Expand Up @@ -232,10 +231,6 @@ class UnoModel: public Model {
return this->user_model.variables_upper_bounds;
}

[[nodiscard]] const SparseVector<size_t>& get_slacks() const override {
return this->slacks;
}

[[nodiscard]] const Vector<size_t>& get_fixed_variables() const override {
return this->fixed_variables;
}
Expand Down Expand Up @@ -325,7 +320,6 @@ class UnoModel: public Model {
protected:
const CUserModel& user_model;
mutable NumberModelEvaluations number_model_evaluations{};
const SparseVector<size_t> slacks{};
Vector<size_t> fixed_variables{};
const IntegerRange linear_constraints{0};
const IntegerRange nonlinear_constraints;
Expand Down
4 changes: 0 additions & 4 deletions interfaces/Python/cpp_classes/PythonModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,6 @@ namespace uno {
return this->user_model.variables_upper_bounds;
}

const SparseVector<size_t>& PythonModel::get_slacks() const {
return this->slacks;
}

const Vector<size_t>& PythonModel::get_fixed_variables() const {
return this->fixed_variables;
}
Expand Down
2 changes: 0 additions & 2 deletions interfaces/Python/cpp_classes/PythonModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ namespace uno {
// purely functions
[[nodiscard]] const std::vector<double>& get_variables_lower_bounds() const override;
[[nodiscard]] const std::vector<double>& get_variables_upper_bounds() const override;
[[nodiscard]] const SparseVector<size_t>& get_slacks() const override;
[[nodiscard]] const Vector<size_t>& get_fixed_variables() const override;

[[nodiscard]] const std::vector<double>& get_constraints_lower_bounds() const override;
Expand All @@ -80,7 +79,6 @@ namespace uno {
protected:
const PythonUserModel& user_model;
mutable NumberModelEvaluations number_model_evaluations{};
const SparseVector<size_t> slacks{};
Vector<size_t> fixed_variables{};
const IntegerRange linear_constraints{0};
const IntegerRange nonlinear_constraints;
Expand Down
5 changes: 1 addition & 4 deletions uno/Uno.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "linear_algebra/Vector.hpp"
#include "model/BoundRelaxedModel.hpp"
#include "model/FixedBoundsConstraintsModel.hpp"
#include "model/HomogeneousEqualityConstrainedModel.hpp"
#include "model/Model.hpp"
#include "model/ScaledModel.hpp"
#include "optimization/EvaluationCache.hpp"
Expand Down Expand Up @@ -58,10 +57,8 @@ namespace uno {
const ScaledModel scaled_model(model, initial_primals, options);
// move the fixed variables to the set of general constraints
const FixedBoundsConstraintsModel fixed_bound_model(scaled_model);
// if an equality-constrained problem is required (e.g. interior points or AL), reformulate the model with slacks
const HomogeneousEqualityConstrainedModel homogeneous_model(fixed_bound_model);
// slightly relax the bound constraints
const BoundRelaxedModel bound_relaxed_model(homogeneous_model, options);
const BoundRelaxedModel bound_relaxed_model(fixed_bound_model, options);

Result result = uno_solve(bound_relaxed_model, options, user_callbacks);
// fix the dimensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,10 @@

#include "ConstraintRelaxationStrategy.hpp"
#include "ingredients/globalization_strategies/GlobalizationStrategy.hpp"
#include "ingredients/subproblem/Subproblem.hpp"
#include "linear_algebra/View.hpp"
#include "model/Model.hpp"
#include "optimization/Direction.hpp"
#include "optimization/EvaluationCache.hpp"
#include "optimization/Iterate.hpp"
#include "optimization/Multipliers.hpp"
#include "optimization/OptimizationProblem.hpp"
#include "options/Options.hpp"
#include "tools/Logger.hpp"

namespace uno {
ConstraintRelaxationStrategy::ConstraintRelaxationStrategy(const Options& options):
residual_norm(norm_from_string(options.get_string("residual_norm"))),
residual_scaling_threshold(options.get_double("residual_scaling_threshold")),
primal_tolerance(options.get_double("primal_tolerance")),
dual_tolerance(options.get_double("dual_tolerance")),
loose_primal_tolerance(options.get_double("loose_primal_tolerance")),
Expand All @@ -32,87 +21,4 @@ namespace uno {
size_t ConstraintRelaxationStrategy::get_number_subproblems_solved() const {
return this->number_subproblems_solved;
}

// protected member functions

// stationarity errors:
// - for KKT conditions: with standard multipliers and current objective multiplier
// - for FJ conditions: with standard multipliers and 0 objective multiplier
// - for feasibility problem: with feasibility multipliers and 0 objective multiplier
void ConstraintRelaxationStrategy::compute_residuals(const OptimizationProblem& problem, Iterate& iterate,
Evaluations& evaluations) const {
// stationarity error (norm of the Lagrangian gradient)
problem.evaluate_lagrangian_gradient(iterate, evaluations, iterate.residuals.lagrangian_gradient);
iterate.residuals.stationarity = norm(this->residual_norm, iterate.residuals.lagrangian_gradient);

// primal feasibility/constraint violation of the model
evaluations.evaluate_constraints(problem.model, iterate.primals);
iterate.primal_infeasibility = problem.model.constraint_violation(evaluations.constraints, this->residual_norm);

// complementarity error
// TODO preallocate constraints
Vector<double> constraints(problem.number_constraints);
problem.evaluate_constraints(iterate, constraints.view(), evaluations);
iterate.residuals.complementarity = problem.complementarity_error(iterate.primals, constraints,
iterate.multipliers, 0., this->residual_norm);

// scaling factors
iterate.residuals.stationarity_scaling = this->compute_stationarity_scaling(problem.model, iterate.multipliers);
iterate.residuals.complementarity_scaling = this->compute_complementarity_scaling(problem.model, iterate.multipliers);
}

double ConstraintRelaxationStrategy::compute_stationarity_scaling(const Model& model, const Multipliers& multipliers) const {
size_t number_lower_bounded_variables = 0;
size_t number_upper_bounded_variables = 0;
const auto& variables_lower_bounds = model.get_variables_lower_bounds();
const auto& variables_upper_bounds = model.get_variables_upper_bounds();
for (size_t variable_index: Range(model.number_variables)) {
if (is_finite(variables_lower_bounds[variable_index])) {
++number_lower_bounded_variables;
}
if (is_finite(variables_upper_bounds[variable_index])) {
++number_upper_bounded_variables;
}
}
const size_t total_size = number_lower_bounded_variables + number_upper_bounded_variables + model.number_constraints;
if (total_size == 0) {
return 1.;
}
else {
const double scaling_factor = this->residual_scaling_threshold * static_cast<double>(total_size);
const double multiplier_norm = norm_1(
view(multipliers.constraints, 0, model.number_constraints),
view(multipliers.lower_bounds, 0, model.number_variables),
view(multipliers.upper_bounds, 0, model.number_variables)
);
return std::max(1., multiplier_norm / scaling_factor);
}
}

double ConstraintRelaxationStrategy::compute_complementarity_scaling(const Model& model, const Multipliers& multipliers) const {
size_t number_lower_bounded_variables = 0;
size_t number_upper_bounded_variables = 0;
const auto& variables_lower_bounds = model.get_variables_lower_bounds();
const auto& variables_upper_bounds = model.get_variables_upper_bounds();
for (size_t variable_index: Range(model.number_variables)) {
if (is_finite(variables_lower_bounds[variable_index])) {
++number_lower_bounded_variables;
}
if (is_finite(variables_upper_bounds[variable_index])) {
++number_upper_bounded_variables;
}
}
const size_t total_size = number_lower_bounded_variables + number_upper_bounded_variables;
if (total_size == 0) {
return 1.;
}
else {
const double scaling_factor = this->residual_scaling_threshold * static_cast<double>(total_size);
const double bound_multiplier_norm = norm_1(
view(multipliers.lower_bounds, 0, model.number_variables),
view(multipliers.upper_bounds, 0, model.number_variables)
);
return std::max(1., bound_multiplier_norm / scaling_factor);
}
}
} // namespace
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ namespace uno {
[[nodiscard]] size_t get_number_subproblems_solved() const;

protected:
const Norm residual_norm;
const double residual_scaling_threshold;
const double primal_tolerance;
const double dual_tolerance;
const double loose_primal_tolerance;
Expand All @@ -73,10 +71,6 @@ namespace uno {
const double unbounded_objective_threshold;
size_t number_subproblems_solved{0};

void compute_residuals(const OptimizationProblem& problem, Iterate& iterate, Evaluations& evaluations) const;
[[nodiscard]] double compute_stationarity_scaling(const Model& model, const Multipliers& multipliers) const;
[[nodiscard]] double compute_complementarity_scaling(const Model& model, const Multipliers& multipliers) const;

template <typename Problem>
[[nodiscard]] SolutionStatus check_termination(const Problem& problem, Iterate& iterate, const Evaluations& evaluations);
};
Expand Down
Loading
Loading