From f83464c3f3103e36ed9c387eba9e691be04c548b Mon Sep 17 00:00:00 2001 From: Gleb Belov Date: Tue, 20 Feb 2024 16:00:25 +1100 Subject: [PATCH] NLW C API: Ini guess, suffix input #30 --- nl-writer2/include/api/c/nl-model-c.h | 78 +++++++++++++++++++-------- nl-writer2/include/mp/nl-model.h | 16 +++--- nl-writer2/src/nl-model-c.cc | 19 +++++++ nl-writer2/src/nl-solver-c.cc | 1 + 4 files changed, 84 insertions(+), 30 deletions(-) diff --git a/nl-writer2/include/api/c/nl-model-c.h b/nl-writer2/include/api/c/nl-model-c.h index d5b7af9db..5172073df 100644 --- a/nl-writer2/include/api/c/nl-model-c.h +++ b/nl-writer2/include/api/c/nl-model-c.h @@ -118,9 +118,56 @@ void NLW2_SetHessian_C(NLW2_NLModel_C* , /// loading the model into NLW2_NLSolver_C. void NLW2_SetObjName_C(NLW2_NLModel_C* , const char* nm); + +/// Set initial solution. +/// +/// @note All pointers should stay valid until +/// loading the model into NLW2_NLSolver_C. +void NLW2_SetWarmstart_C(NLW2_NLModel_C* , + NLW2_SparseVector_C ini_x); + +/// Set dual initial solution. +/// +/// @note All pointers should stay valid until +/// loading the model into NLW2_NLSolver_C. +void NLW2_SetDualWarmstart_C(NLW2_NLModel_C* , + NLW2_SparseVector_C ini_y); + + +/// NL suffix type +typedef struct NLW2_Suffix_C { + /// Name + const char* name_; + /// Suffix table + const char* table_; + /// Kind. + /// + /// VAR = 0, /**< Applies to variables. */ + /// CON = 1, /**< Applies to constraints. */ + /// OBJ = 2, /**< Applies to objectives. */ + /// PROBLEM = 3 /**< Applies to problems. */ + /// + /// If the suffix should be delivered as real-valued, + /// the kind_ should be bitwise-OR'ed with 0x4. + int kind_; + /// Number of values. + /// Should correspond to the suffix kind. + int numval_; + /// Values. Always double precision. + const double* values_; +} NLW2_Suffix_C; + +/// Add suffix. +/// @return true iff new suffix added (vs replaced.) +/// @note SOS constraints can be modeled as suffixes +/// for some AMPL solvers. +int NLW2_AddSuffix_C(NLW2_NLModel_C* , + NLW2_Suffix_C suf_c); + + /// Compute objective value double NLW2_ComputeObjValue_C(NLW2_NLModel_C* , - const double* x); + const double* x); /// Get problem name @@ -159,35 +206,22 @@ NLW2_SparseMatrix_C NLW2_Hessian_C(NLW2_NLModel_C* ); const char* NLW2_ObjName_C(NLW2_NLModel_C* ); -/// NL suffix type -typedef struct NLW2_Suffix_C { - /// Name - const char* name_; - /// Suffix table - const char* table_; - /// Kind - int kind_; - /// Values. Always double precision. - const double* values_; -} NLW2_Suffix_C; - - /// NL solution typedef struct NLW2_Solution_C { /** Solve result. If >-2, solver interaction successful. Then: - - -1 **unknown** - unexpected termination - - 0- 99 **solved** - optimal solution found - - 100-199 **solved?** - optimal solution indicated, but error likely - - 200-299 **infeasible** - constraints cannot be satisfied - - 300-399 **unbounded** - objective can be improved without limit - - 400-499 **limit** - stopped by a limit that you set (such as on iterations) - - 500-999 **failure** - stopped by an error condition in the solver + - -1 *unknown* - unexpected termination + - 0- 99 *solved* - optimal solution found + - 100-199 *solved?* - optimal solution indicated, but error likely + - 200-299 *infeasible* - constraints cannot be satisfied + - 300-399 *unbounded* - objective can be improved without limit + - 400-499 *limit* - stopped by a limit that you set (such as on iterations) + - 500-999 *failure* - stopped by an error condition in the solver @note NLSolution is feasible (not proven optimal) - if **unbounded** or **limit** and \a x_ populated. + if *unbounded* or *limit* and \a x_ populated. @note Individual solvers may have more specific values, see https://ampl.com/products/solvers/solvers-we-sell/. diff --git a/nl-writer2/include/mp/nl-model.h b/nl-writer2/include/mp/nl-model.h index e58797f01..49ad38120 100644 --- a/nl-writer2/include/mp/nl-model.h +++ b/nl-writer2/include/mp/nl-model.h @@ -294,16 +294,16 @@ struct NLSolution { Solve result. If >-2, solver interaction successful. Then: - - -1 **unknown** - unexpected termination - - 0- 99 **solved** - optimal solution found - - 100-199 **solved?** - optimal solution indicated, but error likely - - 200-299 **infeasible** - constraints cannot be satisfied - - 300-399 **unbounded** - objective can be improved without limit - - 400-499 **limit** - stopped by a limit that you set (such as on iterations) - - 500-999 **failure** - stopped by an error condition in the solver + - -1 *unknown* - unexpected termination + - 0- 99 *solved* - optimal solution found + - 100-199 *solved?* - optimal solution indicated, but error likely + - 200-299 *infeasible* - constraints cannot be satisfied + - 300-399 *unbounded* - objective can be improved without limit + - 400-499 *limit* - stopped by a limit that you set (such as on iterations) + - 500-999 *failure* - stopped by an error condition in the solver @note NLSolution is feasible (not proven optimal) - if **unbounded** or **limit** and \a x_ populated. + if *unbounded* or *limit* and \a x_ populated. @note Individual solvers may have more specific values, see https://ampl.com/products/solvers/solvers-we-sell/. diff --git a/nl-writer2/src/nl-model-c.cc b/nl-writer2/src/nl-model-c.cc index 9d57bdac2..bf3292066 100644 --- a/nl-writer2/src/nl-model-c.cc +++ b/nl-writer2/src/nl-model-c.cc @@ -113,6 +113,25 @@ void NLW2_SetHessian_C(NLW2_NLModel_C* nlme, void NLW2_SetObjName_C(NLW2_NLModel_C* nlme, const char* nm) { CastNZ(nlme->p_data_)->SetObjName(nm); } + +void NLW2_SetWarmstart_C(NLW2_NLModel_C* nlme, + NLW2_SparseVector_C ini_x) +{ CastNZ(nlme->p_data_)->SetWarmstart(ini_x); } + +void NLW2_SetDualWarmstart_C(NLW2_NLModel_C* nlme, + NLW2_SparseVector_C ini_y) +{ CastNZ(nlme->p_data_)->SetWarmstart(ini_y); } + +int NLW2_AddSuffix_C(NLW2_NLModel_C* nlme, + NLW2_Suffix_C suf_c) { + mp::NLSuffix suf{ + suf_c.name_, suf_c.table_, suf_c.kind_, + {suf_c.values_, suf_c.values_+suf_c.numval_} + }; + return CastNZ(nlme->p_data_)->AddSuffix(suf); +} + + /// Compute objective value double NLW2_ComputeObjValue_C(NLW2_NLModel_C* nlme, const double* x) { diff --git a/nl-writer2/src/nl-solver-c.cc b/nl-writer2/src/nl-solver-c.cc index 022715480..3fe09c11b 100644 --- a/nl-writer2/src/nl-solver-c.cc +++ b/nl-writer2/src/nl-solver-c.cc @@ -767,6 +767,7 @@ static NLW2_Solution_C NLW2_WrapNLSOL_Solution_C suf_c.kind_ = suf.kind_; suf_c.name_ = suf.name_.c_str(); suf_c.table_ = suf.table_.c_str(); + suf_c.numval_ = suf.values_.size(); suf_c.values_ = suf.values_.data(); sol_data.suffixes_.push_back(std::move(suf_c)); }