From fb121090be82c5618b16d8951d2e3afa1684e934 Mon Sep 17 00:00:00 2001 From: Charlie Vanaret Date: Thu, 17 Oct 2024 12:40:32 +0200 Subject: [PATCH] AMPLModel: write the solution in a *.sol file (this can be disabled with the option AMPL_write_solution_to_file) --- bindings/AMPL/AMPLModel.cpp | 30 ++++++++++++++++++++++++++---- bindings/AMPL/AMPLModel.hpp | 8 ++++++-- bindings/AMPL/uno_ampl.cpp | 2 +- uno.options | 3 +++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/bindings/AMPL/AMPLModel.cpp b/bindings/AMPL/AMPLModel.cpp index a1331af1..22b75d61 100644 --- a/bindings/AMPL/AMPLModel.cpp +++ b/bindings/AMPL/AMPLModel.cpp @@ -7,8 +7,10 @@ #include "linear_algebra/RectangularMatrix.hpp" #include "linear_algebra/SymmetricMatrix.hpp" #include "optimization/EvaluationErrors.hpp" +#include "optimization/Iterate.hpp" #include "tools/Logger.hpp" #include "tools/Infinity.hpp" +#include "tools/Options.hpp" #include "symbolic/Concatenation.hpp" namespace uno { @@ -34,12 +36,13 @@ namespace uno { } // generate the ASL object and call the private constructor - AMPLModel::AMPLModel(const std::string& file_name) : AMPLModel(file_name, generate_asl(file_name)) { + AMPLModel::AMPLModel(const std::string& file_name, const Options& options) : AMPLModel(file_name, generate_asl(file_name), options) { } - AMPLModel::AMPLModel(const std::string& file_name, ASL* asl) : + AMPLModel::AMPLModel(const std::string& file_name, ASL* asl, const Options& options) : Model(file_name, static_cast(asl->i.n_var_), static_cast(asl->i.n_con_), (asl->i.objtype_[0] == 1) ? -1. : 1.), asl(asl), + write_solution_to_file(options.get_bool("AMPL_write_solution_to_file")), // allocate vectors asl_gradient(this->number_variables), variable_lower_bounds(this->number_variables), @@ -350,8 +353,27 @@ namespace uno { std::copy(this->asl->i.pi0_, this->asl->i.pi0_ + this->number_constraints, multipliers.begin()); } - void AMPLModel::postprocess_solution(Iterate& /*iterate*/, TerminationStatus /*termination_status*/) const { - // do nothing + void AMPLModel::postprocess_solution(Iterate& iterate, TerminationStatus termination_status) const { + if (this->write_solution_to_file) { + // write the primal-dual solution and status into a *.sol file + this->asl->p.solve_code_ = 400; // limit + if (termination_status == TerminationStatus::FEASIBLE_KKT_POINT) { + this->asl->p.solve_code_ = 0; + } + if (termination_status == TerminationStatus::FEASIBLE_SMALL_STEP) { + this->asl->p.solve_code_ = 100; + } + else if (termination_status == TerminationStatus::INFEASIBLE_STATIONARY_POINT) { + this->asl->p.solve_code_ = 200; + } + else if (termination_status == TerminationStatus::UNBOUNDED) { + this->asl->p.solve_code_ = 300; + } + else if (termination_status == TerminationStatus::INFEASIBLE_SMALL_STEP) { + this->asl->p.solve_code_ = 500; + } + write_sol_ASL(this->asl, "", iterate.primals.data(), iterate.multipliers.constraints.data(), nullptr); + } } void AMPLModel::generate_constraints() { diff --git a/bindings/AMPL/AMPLModel.hpp b/bindings/AMPL/AMPLModel.hpp index ebfdbc32..c9d05b07 100644 --- a/bindings/AMPL/AMPLModel.hpp +++ b/bindings/AMPL/AMPLModel.hpp @@ -16,6 +16,9 @@ extern "C" { } namespace uno { + // forward reference + class Options; + /*! \class AMPLModel * \brief AMPL model * @@ -23,7 +26,7 @@ namespace uno { */ class AMPLModel: public Model { public: - explicit AMPLModel(const std::string& file_name); + AMPLModel(const std::string& file_name, const Options& options); ~AMPLModel() override; [[nodiscard]] double evaluate_objective(const Vector& x) const override; @@ -61,10 +64,11 @@ namespace uno { private: // private constructor to pass the dimensions to the Model base constructor - AMPLModel(const std::string& file_name, ASL* asl); + AMPLModel(const std::string& file_name, ASL* asl, const Options& options); // mutable: can be modified by const methods (internal state not seen by user) mutable ASL* asl; /*!< Instance of the AMPL Solver Library class */ + const bool write_solution_to_file; mutable std::vector asl_gradient{}; mutable std::vector asl_hessian{}; size_t number_asl_hessian_nonzeros{0}; /*!< Number of nonzero elements in the Hessian */ diff --git a/bindings/AMPL/uno_ampl.cpp b/bindings/AMPL/uno_ampl.cpp index 69552732..66ac1a15 100644 --- a/bindings/AMPL/uno_ampl.cpp +++ b/bindings/AMPL/uno_ampl.cpp @@ -25,7 +25,7 @@ namespace uno { void run_uno_ampl(const std::string& model_name, const Options& options) { try { // AMPL model - std::unique_ptr ampl_model = std::make_unique(model_name); + std::unique_ptr ampl_model = std::make_unique(model_name, options); // initialize initial primal and dual points Iterate initial_iterate(ampl_model->number_variables, ampl_model->number_constraints); diff --git a/uno.options b/uno.options index 849ec60c..552aa892 100644 --- a/uno.options +++ b/uno.options @@ -238,3 +238,6 @@ least_square_multiplier_max_norm 1e3 ##### BQPD options ##### BQPD_print_subproblem no BQPD_kmax 500 + +##### AMPL options ##### +AMPL_write_solution_to_file yes