| 292 | } |
| 293 | |
| 294 | void AMPLModel::write_solution_to_file(Result& result) const { |
| 295 | // write the primal-dual solution and status into a *.sol file |
| 296 | this->asl->p.solve_code_ = 400; // limit |
| 297 | if (result.solution_status == SolutionStatus::FEASIBLE_KKT_POINT) { |
| 298 | this->asl->p.solve_code_ = 0; |
| 299 | } |
| 300 | else if (result.solution_status == SolutionStatus::FEASIBLE_SMALL_STEP) { |
| 301 | this->asl->p.solve_code_ = 100; |
| 302 | } |
| 303 | else if (result.solution_status == SolutionStatus::INFEASIBLE_STATIONARY_POINT) { |
| 304 | this->asl->p.solve_code_ = 200; |
| 305 | } |
| 306 | else if (result.solution_status == SolutionStatus::UNBOUNDED) { |
| 307 | this->asl->p.solve_code_ = 300; |
| 308 | } |
| 309 | else if (result.solution_status == SolutionStatus::INFEASIBLE_SMALL_STEP) { |
| 310 | this->asl->p.solve_code_ = 500; |
| 311 | } |
| 312 | |
| 313 | // include the bound duals in the .sol file, using suffixes |
| 314 | SufDecl lower_bound_suffix{const_cast<char*>("lower_bound_duals"), nullptr, ASL_Sufkind_var | ASL_Sufkind_real, 0}; |
| 315 | SufDecl upper_bound_suffix{const_cast<char*>("upper_bound_duals"), nullptr, ASL_Sufkind_var | ASL_Sufkind_real, 0}; |
| 316 | std::array<SufDecl, 2> suffixes{lower_bound_suffix, upper_bound_suffix}; |
| 317 | suf_declare_ASL(this->asl, suffixes.data(), suffixes.size()); |
| 318 | suf_rput_ASL(this->asl, "lower_bound_duals", ASL_Sufkind_var, result.lower_bound_dual_solution.data()); |
| 319 | suf_rput_ASL(this->asl, "upper_bound_duals", ASL_Sufkind_var, result.upper_bound_dual_solution.data()); |
| 320 | |
| 321 | Option_Info option_info{}; |
| 322 | option_info.wantsol = 9; // write the solution without printing the message to stdout |
| 323 | std::string message = "Uno "; |
| 324 | message.append(Uno::current_version()).append(": ").append(solution_status_to_message(result.solution_status)); |
| 325 | |
| 326 | // flip the signs of the constraint multipliers (different Lagrangian convention between ASL and Uno) |
| 327 | Vector<double> ampl_dual_solution = -result.constraint_dual_solution; |
| 328 | write_sol_ASL(this->asl, message.data(), result.primal_solution.data(), ampl_dual_solution.data(), &option_info); |
| 329 | } |
| 330 | |
| 331 | size_t AMPLModel::number_jacobian_nonzeros() const { |
| 332 | return static_cast<size_t>(this->asl->i.nzc_); |
no test coverage detected