From 1306c9b76ea8e59a2feedece1aa48162679502b8 Mon Sep 17 00:00:00 2001 From: Francesco Cavaliere Date: Thu, 4 Dec 2025 15:16:26 +0100 Subject: [PATCH 1/8] Linear, Quadratic, NLP and Callbacks (#1) - added status enums - added support for string attribute/controls ids - kept int attribute/controls id for internal use - fixed broken defaults in binded arguments - added missing _add_linear_constraint overloads - added missing get_value overloads - added missing pprint overloads - added missing set_objective overloads - fixed a whole lot of defect during initial testing - implemented xpress.py model - added a simple partial implementation of the tsp example - callback system - license error message - default message cb - OUTPUTLOG 1 by default - CB from main thread to avoid issues with Python GIL - Made XpressModel CALLBACK mode more explicit and checked - cb_get_* queries - Lazy and usercut mapped to XPRSaddcuts - Auto submit solution after CB end - xpress.Model wrap of RawModel in python CB - XpressModel move ctor to enable wrapping-unwrapping - Removed deprecated attribute - Flatten out XpressModel fields - Fixed repeated set_callback calls - Removed mutex (not used) - Original XpressModel used also in cbs - Added forgotte cb bindings - Complete tsp_xpress.py callback test - xpress_model.hpp comments - Cleaned up xpress_model*.cpp - NLP objective + SOC + Exp Cones - Postsolve and minor fixing - Version check - Ptr ownership bugfix + stream flushing --- CMakeLists.txt | 32 + README.md | 1 + docs/source/api/pyoptinterface.rst | 1 + docs/source/api/pyoptinterface.xpress.rst | 8 + docs/source/attribute/xpress.md | 123 + docs/source/callback.md | 45 +- docs/source/constraint.md | 4 +- docs/source/getting_started.md | 22 +- docs/source/index.md | 1 + docs/source/infeasibility.md | 2 +- docs/source/model.md | 12 +- docs/source/nonlinear.md | 2 +- docs/source/xpress.md | 163 ++ include/pyoptinterface/core.hpp | 5 +- include/pyoptinterface/nlexpr.hpp | 5 +- include/pyoptinterface/xpress_model.hpp | 759 +++++++ lib/nlexpr.cpp | 4 + lib/xpress_model.cpp | 2528 +++++++++++++++++++++ lib/xpress_model_ext.cpp | 286 +++ lib/xpress_model_ext_constants.cpp | 935 ++++++++ optimizer_version.toml | 1 + src/pyoptinterface/_src/xpress.py | 655 ++++++ src/pyoptinterface/xpress.py | 22 + tests/conftest.py | 7 +- tests/simple_cb.py | 42 +- tests/test_close.py | 6 +- tests/test_nlp_expression.py | 10 +- tests/test_qp.py | 2 +- tests/test_soc.py | 16 +- tests/tsp_cb.py | 327 ++- tests/tsp_xpress.py | 437 ++++ 31 files changed, 6318 insertions(+), 145 deletions(-) create mode 100644 docs/source/api/pyoptinterface.xpress.rst create mode 100644 docs/source/attribute/xpress.md create mode 100644 docs/source/xpress.md create mode 100644 include/pyoptinterface/xpress_model.hpp create mode 100644 lib/xpress_model.cpp create mode 100644 lib/xpress_model_ext.cpp create mode 100644 lib/xpress_model_ext_constants.cpp create mode 100644 src/pyoptinterface/_src/xpress.py create mode 100644 src/pyoptinterface/xpress.py create mode 100644 tests/tsp_xpress.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 2619d848..74ccdcae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,6 +239,31 @@ nanobind_add_module( target_link_libraries(ipopt_model_ext PUBLIC ipopt_model) install(TARGETS ipopt_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR}) +# XPRESS +add_library(xpress_model STATIC) +target_sources(xpress_model PRIVATE + include/pyoptinterface/xpress_model.hpp + lib/xpress_model.cpp +) +target_link_libraries(xpress_model PUBLIC core nlexpr nleval) + +nanobind_add_module( + xpress_model_ext + + STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface + + lib/xpress_model_ext.cpp + lib/xpress_model_ext_constants.cpp +) +target_link_libraries(xpress_model_ext PUBLIC xpress_model) +install(TARGETS xpress_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR}) + +if(DEFINED ENV{XPRESSDIR}) + message(STATUS "Detected Xpress header file: $ENV{XPRESSDIR}/include") + target_include_directories(xpress_model PRIVATE $ENV{XPRESSDIR}/include) + target_include_directories(xpress_model_ext PRIVATE $ENV{XPRESSDIR}/include) +endif() + # stub nanobind_add_stub( core_ext_stub @@ -310,6 +335,13 @@ nanobind_add_stub( OUTPUT ${POI_INSTALL_DIR}/ipopt_model_ext.pyi ) +nanobind_add_stub( + xpress_model_ext_stub + INSTALL_TIME + MODULE pyoptinterface._src.xpress_model_ext + OUTPUT ${POI_INSTALL_DIR}/xpress_model_ext.pyi +) + set(ENABLE_TEST_MAIN OFF BOOL "Enable test c++ function with a main.cpp") if(ENABLE_TEST_MAIN) add_executable(test_main lib/main.cpp) diff --git a/README.md b/README.md index 5e53b9fc..ab4140ac 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ It currently supports the following problem types: It currently supports the following optimizers: - [COPT](https://shanshu.ai/copt) ( Commercial ) - [Gurobi](https://www.gurobi.com/) ( Commercial ) +- [Xpress](https://www.fico.com/en/products/fico-xpress-optimization) ( Commercial ) - [HiGHS](https://github.com/ERGO-Code/HiGHS) ( Open source ) - [Mosek](https://www.mosek.com/) ( Commercial ) - [Ipopt](https://github.com/coin-or/Ipopt) ( Open source ) diff --git a/docs/source/api/pyoptinterface.rst b/docs/source/api/pyoptinterface.rst index d81e18c9..f1bb5d54 100644 --- a/docs/source/api/pyoptinterface.rst +++ b/docs/source/api/pyoptinterface.rst @@ -14,5 +14,6 @@ Submodules pyoptinterface.gurobi.rst pyoptinterface.copt.rst + pyoptinterface.xpress.rst pyoptinterface.mosek.rst pyoptinterface.highs.rst diff --git a/docs/source/api/pyoptinterface.xpress.rst b/docs/source/api/pyoptinterface.xpress.rst new file mode 100644 index 00000000..035825c7 --- /dev/null +++ b/docs/source/api/pyoptinterface.xpress.rst @@ -0,0 +1,8 @@ +pyoptinterface.xpress package +==================================== + +.. automodule:: pyoptinterface.xpress + :members: + :inherited-members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/attribute/xpress.md b/docs/source/attribute/xpress.md new file mode 100644 index 00000000..9e30c584 --- /dev/null +++ b/docs/source/attribute/xpress.md @@ -0,0 +1,123 @@ +### Supported [model attribute](#pyoptinterface.ModelAttribute) + +:::{list-table} +:header-rows: 1 + +* - Attribute + - Get + - Set +* - Name + - ✅ + - ✅ +* - ObjectiveSense + - ✅ + - ✅ +* - DualStatus + - ✅ + - ❌ +* - PrimalStatus + - ✅ + - ❌ +* - RawStatusString + - ✅ + - ❌ +* - TerminationStatus + - ✅ + - ❌ +* - BarrierIterations + - ✅ + - ❌ +* - DualObjectiveValue + - ✅ + - ❌ +* - NodeCount + - ✅ + - ❌ +* - NumberOfThreads + - ✅ + - ✅ +* - ObjectiveBound + - ✅ + - ❌ +* - ObjectiveValue + - ✅ + - ❌ +* - RelativeGap + - ✅ + - ✅ +* - Silent + - ✅ + - ✅ +* - SimplexIterations + - ✅ + - ❌ +* - SolverName + - ✅ + - ❌ +* - SolverVersion + - ✅ + - ❌ +* - SolveTimeSec + - ✅ + - ❌ +* - TimeLimitSec + - ✅ + - ✅ +::: + +### Supported [variable attribute](#pyoptinterface.VariableAttribute) + +:::{list-table} +:header-rows: 1 + +* - Attribute + - Get + - Set +* - Value + - ✅ + - ❌ +* - LowerBound + - ✅ + - ✅ +* - UpperBound + - ✅ + - ✅ +* - Domain + - ✅ + - ✅ +* - PrimalStart + - ✅ + - ✅ +* - Name + - ✅ + - ✅ +* - IISLowerBound + - ✅ + - ❌ +* - IISUpperBound + - ✅ + - ❌ +::: + +### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute) + +:::{list-table} +:header-rows: 1 + +* - Attribute + - Get + - Set +* - Name + - ✅ + - ✅ +* - Primal + - ✅ + - ❌ +* - Dual + - ✅ + - ❌ +* - IIS + - ✅ + - ❌ +::: + diff --git a/docs/source/callback.md b/docs/source/callback.md index 754a1e5b..1d9e5172 100644 --- a/docs/source/callback.md +++ b/docs/source/callback.md @@ -6,26 +6,28 @@ The behavior of callback function highly depends on the optimizer and the specif In most optimization problems, we build the model, set the parameters, and then call the optimizer to solve the problem. However, in some cases, we may want to monitor the optimization process and intervene in the optimization process. For example, we may want to stop the optimization process when a certain condition is met, or we may want to record the intermediate results of the optimization process. In these cases, we can use the callback function. The callback function is a user-defined function that is called by the optimizer at specific points during the optimization process. Callback is especially useful for mixed-integer programming problems, where we can control the branch and bound process in callback functions. -Callback is not supported for all optimizers. Currently, we only support callback for Gurobi and COPT optimizer. Because callback is tightly coupled with the optimizer, we choose not to implement a strictly unified API for callback. Instead, we try to unify the common parts of the callback API of Gurobi and COPT and aims to provide all callback features included in vendored Python bindings of Gurobi and COPT. +Callback is not supported for all optimizers. Currently, we only support callback for Gurobi, COPT, and Xpress optimizer. Because callback is tightly coupled with the optimizer, we choose not to implement a strictly unified API for callback. Instead, we try to unify the common parts of the callback API and aim to provide all callback features included in the vendored Python bindings. In PyOptInterface, the callback function is simply a Python function that takes two arguments: - `model`: The instance of the [optimization model](model.md) -- `where`: The flag indicates the stage of optimization process when our callback function is invoked. For Gurobi, the value of `where` is [CallbackCodes](https://www.gurobi.com/documentation/current/refman/cb_codes.html#sec:CallbackCodes). For COPT, the value of `where` is called as [callback contexts](https://guide.coap.online/copt/en-doc/callback.html) such as `COPT.CBCONTEXT_MIPNODE` and `COPT.CBCONTEXT_MIPRELAX`. +- `where`: The flag indicates the stage of optimization process when our callback function is invoked. For Gurobi, the value of `where` is [CallbackCodes](https://www.gurobi.com/documentation/current/refman/cb_codes.html#sec:CallbackCodes). For COPT, the value of `where` is called as [callback contexts](https://guide.coap.online/copt/en-doc/callback.html) such as `COPT.CBCONTEXT_MIPNODE` and `COPT.CBCONTEXT_MIPRELAX`. For Xpress, the `where` value corresponds to specific callback points such as `XPRS.CB_CONTEXT.PREINTSOL` or `XPRS.CB_CONTEXT.OPTNODE`. A description of supported Xpress callbacks can be found [here](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/chapter5.html?scroll=section5002). In the function body of the callback function, we can do the following four kinds of things: -- Query the current information of the optimization process. For scalar information, we can use `model.cb_get_info` function to get the information, and its argument is the value of [`what`](https://www.gurobi.com/documentation/current/refman/cb_codes.html) in Gurobi and the value of [callback information](https://guide.coap.online/copt/en-doc/information.html#chapinfo-cbc) in COPT. For array information such as the MIP solution or relaxation, PyOptInterface provides special functions such as `model.cb_get_solution` and `model.cb_get_relaxation`. +- Query the current information of the optimization process. For scalar information, we can use `model.cb_get_info` function to get the information, and its argument is the value of [`what`](https://www.gurobi.com/documentation/current/refman/cb_codes.html) in Gurobi and the value of [callback information](https://guide.coap.online/copt/en-doc/information.html#chapinfo-cbc) in COPT. For Xpress, use regular attribute access methods such as `model.get_raw_attribute`. For array information such as the MIP solution or relaxation, PyOptInterface provides special functions such as `model.cb_get_solution` and `model.cb_get_relaxation`. - Add lazy constraint: Use `model.cb_add_lazy_constraint` just like `model.add_linear_constraint` except for the `name` argument. - Add user cut: Use `model.cb_add_user_cut` just like `model.add_linear_constraint` except for the `name` argument. -- Set a heuristic solution: Use `model.set_solution` to set individual values of variables and use `model.cb_submit_solution` to submit the solution to the optimizer immediately (`model.cb_submit_solution` will be called automatically in the end of callback if `model.set_solution` is called). +- Set a heuristic solution: Use `model.cb_set_solution` to set individual values of variables and use `model.cb_submit_solution` to submit the solution to the optimizer immediately (`model.cb_submit_solution` will be called automatically in the end of callback if `model.cb_set_solution` is called). - Terminate the optimizer: Use `model.cb_exit`. Here is an example of a callback function that stops the optimization process when the objective value reaches a certain threshold: ```python import pyoptinterface as poi -from pyoptinterface import gurobi, copt +from pyoptinterface import gurobi, copt, xpress + GRB = gurobi.GRB COPT = copt.COPT +XPRS = xpress.XPRS def cb_gurobi(model, where): if where == GRB.Callback.MIPSOL: @@ -38,9 +40,15 @@ def cb_copt(model, where): obj = model.cb_get_info("MipCandObj") if obj < 10: model.cb_exit() + +def cb_xpress(model, where): + if where == XPRS.CB_CONTEXT.PREINTSOL: + obj = model.get_raw_attribute("LPOBJVAL") + if obj < 10: + model.cb_exit() ``` -To use the callback function, we need to call `model.set_callback(cb)` to pass the callback function to the optimizer. For COPT, `model.set_callback` needs an additional argument `where` to specify the context where the callback function is invoked. For Gurobi, the `where` argument is not needed. +To use the callback function, we need to call `model.set_callback(cb)` to pass the callback function to the optimizer. For COPT and Xpress, `model.set_callback` needs an additional argument `where` to specify the context where the callback function is invoked. For Gurobi, the `where` argument is not needed. ```python model_gurobi = gurobi.Model() @@ -50,9 +58,14 @@ model_copt = copt.Model() model_copt.set_callback(cb_copt, COPT.CBCONTEXT_MIPSOL) # callback can also be registered for multiple contexts model_copt.set_callback(cb_copt, COPT.CBCONTEXT_MIPSOL + COPT.CBCONTEXT_MIPNODE) + +model_xpress = xpress.Model() +model_xpress.set_callback(cb_xpress, XPRS.CB_CONTEXT.PREINTSOL) +# callback can also be registered for multiple contexts +model_xpress.set_callback(cb_xpress, XPRS.CB_CONTEXT.PREINTSOL + XPRS.CB_CONTEXT.CUTROUND) ``` -In order to help users to migrate code using gurobipy and/or coptpy to PyOptInterface, we list a translation table as follows. +In order to help users to migrate code using gurobipy, coptpy, and Xpress Python to PyOptInterface, we list a translation table as follows. :::{table} Callback in gurobipy and PyOptInterface :align: left @@ -68,9 +81,9 @@ In order to help users to migrate code using gurobipy and/or coptpy to PyOptInte | `model.cbSetSolution(x, 1.0)` | `model.cb_set_solution(x, 1.0)` | | `objval = model.cbUseSolution()` | `objval = model.cb_submit_solution()` | | `model.termimate()` | `model.cb_exit()` | - ::: + :::{table} Callback in coptpy and PyOptInterface :align: left @@ -86,7 +99,21 @@ In order to help users to migrate code using gurobipy and/or coptpy to PyOptInte | `CallbackBase.setSolution(x, 1.0) ` | `model.cb_set_solution(x, 1.0)` | | `CallbackBase.loadSolution()` | `model.cb_submit_solution()` | | `CallbackBase.interrupt()` | `model.cb_exit()` | +::: +:::{table} Callback in Xpress Python and PyOptInterface +:align: left +| Xpress Python | PyOptInterface | +| ------------------------------------------------------ | ------------------------------------------------------------- | +| `model.addPreIntsolCallback(cb)` | `model.set_callback(cb, XPRS.CB_CONTEXT.PREINTSOL)` | +| `model.attributes.bestbound` | `model.get_raw_attribute("BESTBOUND")` | +| `model.getCallbackSolution(var)` | `model.cb_get_solution(var)` | +| `model.getCallbackSolution(var)` | `model.cb_get_relaxation(var)` | +| `model.getSolution(var)` | `model.cb_get_incumbent(var)` | +| `model.addCuts(0, 'L', 3, [0], [0, 1], [1, 1])` | `model.cb_add_lazy_constraint(x[0] + x[1], poi.Leq, 3)` | +| `model.addManagedCuts(1, 'L', 3, [0], [0, 1], [1, 1])` | `model.cb_add_user_cut(x[0] + x[1], poi.Leq, 3)` | +| `model.addMipSol([x], [1.0])` | `model.cb_set_solution(x, 1.0)` + `model.cb_submit_solution()` | +| `model.interrupt()` | `model.cb_exit()` | ::: -For a detailed example to use callbacks in PyOptInterface, we provide a [concrete callback example](https://github.com/metab0t/PyOptInterface/blob/master/tests/tsp_cb.py) to solve the Traveling Salesman Problem (TSP) with callbacks in PyOptInterface, gurobipy and coptpy. The example is adapted from the official Gurobi example [tsp.py](https://www.gurobi.com/documentation/current/examples/tsp_py.html). +For a detailed example to use callbacks in PyOptInterface, we provide a [concrete callback example](https://github.com/metab0t/PyOptInterface/blob/master/tests/tsp_cb.py) to solve the Traveling Salesman Problem (TSP) with callbacks in PyOptInterface, gurobipy, coptpy, and Xpress Python. The example is adapted from the official Gurobi example [tsp.py](https://www.gurobi.com/documentation/current/examples/tsp_py.html). diff --git a/docs/source/constraint.md b/docs/source/constraint.md index 3a62d1bf..8f3bbd91 100644 --- a/docs/source/constraint.md +++ b/docs/source/constraint.md @@ -197,7 +197,9 @@ $$ variables=(t,s,r) \in \mathbb{R}^{3} : t \ge -r \exp(\frac{s}{r} - 1), r \le 0 $$ -Currently, only COPT(after 7.1.4), Mosek support exponential cone constraint. It can be added to the model using the `add_exp_cone_constraint` method of the `Model` class. +Currently, only COPT(after 7.1.4), Mosek support exponential cone constraint natively. +Xpress supports exponential cones by mapping them into generic NLP formulas at the API level. +It can be added to the model using the `add_exp_cone_constraint` method of the `Model` class. ```{py:function} model.add_exp_cone_constraint(variables, [name="", dual=False]) diff --git a/docs/source/getting_started.md b/docs/source/getting_started.md index 37aa91a4..4c45f36d 100644 --- a/docs/source/getting_started.md +++ b/docs/source/getting_started.md @@ -81,6 +81,11 @@ The typical paths where the dynamic library of optimizers are located are as fol - `/opt/gurobi1100/linux64/lib` - `/opt/gurobi1100/macos_universal2/lib` - `/opt/gurobi1100/macos_universal2/lib` +* - Xpress + - TODO add windows path + - TODO add linux path + - `/Applications/FICO Xpress/xpressmp/lib/libxprs.dylib` + - TODO add mac intel path * - COPT - `C:\Program Files\copt71\bin` - `/opt/copt72/lib` @@ -108,6 +113,14 @@ For Gurobi, the automatic detection looks for the following things in order: 2. The installation of `gurobipy` 3. `gurobi110.dll`/`libgurobi110.so`/`libgurobi110.dylib` in the system loadable path +### Xpress + +The currently supported version is **9.8**. Other versions may work but are not tested. + +For Xpress, the automatic detection looks for the following things in order: +1. The environment variable `XPRESSDIR` set by the installer of Xpress +2. `xprs.dll`/`libxprs.so`/`libxprs.dylib` int the system loadable path + ### COPT The currently supported version is **7.2.x**. Other versions may work but are not tested. @@ -175,7 +188,7 @@ ret = highs.autoload_library() print(f"Loading from automatically detected location: {ret}") ``` -For other optimizers, just replace `highs` with the corresponding optimizer name like `gurobi`, `copt`, `mosek`. +For other optimizers, just replace `highs` with the corresponding optimizer name like `gurobi`, `xpress`, `copt`, `mosek`. The typical paths where the dynamic library of optimizers are located are as follows: @@ -197,6 +210,11 @@ The typical paths where the dynamic library of optimizers are located are as fol - `/opt/copt72/lib/libcopt.so` - `/opt/copt72/lib/libcopt.dylib` - `/opt/copt72/lib/libcopt.dylib` +* - Xpress + - `C:\xpressmp\bin\xprs.dll` + - `/opt/xpressmp/lib/libxprs.so` + - `/Applications/FICO Xpress/xpressmp/lib/libxprs.dylib` + - `/Applications/FICO Xpress/xpressmp/lib/libxprs.dylib` * - Mosek - `C:\Program Files\Mosek\10.2\tools\platform\win64x86\bin\mosek64_10_1.dll` - `/opt/mosek/10.2/tools/platform/linux64x86/bin/libmosek64.so` @@ -225,7 +243,7 @@ First, we need to create a model object: ```{code-cell} import pyoptinterface as poi from pyoptinterface import highs -# from pyoptinterface import copt, gurobi, mosek (if you want to use other optimizers) +# from pyoptinterface import copt, gurobi, xpress, mosek (if you want to use other optimizers) model = highs.Model() ``` diff --git a/docs/source/index.md b/docs/source/index.md index 4131361f..40fb7a15 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -23,6 +23,7 @@ common_model_interface.md infeasibility.md callback.md gurobi.md +xpress.md copt.md mosek.md highs.md diff --git a/docs/source/infeasibility.md b/docs/source/infeasibility.md index ea60dc61..b456f17a 100644 --- a/docs/source/infeasibility.md +++ b/docs/source/infeasibility.md @@ -11,7 +11,7 @@ The optimization model is not ways feasible, and the optimizer may tell us some - Find the IIS (Irreducible Infeasible Set) to identify the minimal set of constraints that cause the infeasibility. - Relax the constraints and solve a weaker problem to find out which constraints are violated and how much. -PyOptInterface currently supports the first method to find the IIS (only with Gurobi and COPT). The following code snippet shows how to find the IIS of an infeasible model: +PyOptInterface currently supports the first method to find the IIS (only with Gurobi, Xpress, and COPT). The following code snippet shows how to find the IIS of an infeasible model: ```{code-cell} import pyoptinterface as poi diff --git a/docs/source/model.md b/docs/source/model.md index d66520e6..a9cbb69b 100644 --- a/docs/source/model.md +++ b/docs/source/model.md @@ -24,7 +24,7 @@ You can replace `highs` with the name of the solver you want to use. The availab Most commercial solvers require a `Environment`-like object to be initialized before creating a model in order to manage the license. -By default, PyOptInterface creates the global environment for each solver. If you want to create a model in a specific environment, you can pass the environment object to the constructor of the model class. The details can be found on the documentation of the corresponding optimizer: [Gurobi](gurobi.md), [HiGHS](highs.md), [COPT](copt.md), [MOSEK](mosek.md). +By default, PyOptInterface creates the global environment for each solver. If you want to create a model in a specific environment, you can pass the environment object to the constructor of the model class. The details can be found on the documentation of the corresponding optimizer: [Gurobi](gurobi.md), [HiGHS](highs.md), [COPT](copt.md), [Xpress](xpress.md), [MOSEK](mosek.md). ```python env = gurobi.Env() @@ -116,6 +116,8 @@ Besides the standard attributes, we can also set/get the solver-specific attribu model.set_raw_parameter("OutputFlag", 0) # COPT model.set_raw_parameter("Presolve", 0) +# Xpress +model.set_raw_control("XPRS_OUTPUTLOG", 0) # MOSEK model.set_raw_parameter("MSK_IPAR_INTPNT_BASIS", 0) ``` @@ -159,3 +161,11 @@ The file format is determined by the file extension. Because we use the native I - Gurobi: [Doc](https://www.gurobi.com/documentation/current/refman/c_write.html) - HiGHS: [Doc](https://ergo-code.github.io/HiGHS/stable/interfaces/c/#Highs_writeModel-Tuple{Any,%20Any}) - Mosek: [Doc](https://docs.mosek.com/latest/capi/supported-file-formats.html) +- Xpress: [`.lp`, `.mps`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeProb.html), + [`.svf`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.saveAs.html), + [`.bss`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeBasis.html), + [`.asc`, `.hdr`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeSol.html), + [`.sol`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeBinSol.html), + [`.prt`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writePrtSol.html), + [`.slx`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeSlxSol.html), + diff --git a/docs/source/nonlinear.md b/docs/source/nonlinear.md index 0e26292c..7564a7e3 100644 --- a/docs/source/nonlinear.md +++ b/docs/source/nonlinear.md @@ -11,7 +11,7 @@ Compared with the linear and quadratic expressions and objectives we have discus :::{note} -Before trying out the code snippets, please ensure that you have completed the installation of PyOptInterface with correct dependencies via `pip install pyoptinterface[nlp]` and solvers that support nonlinear programming (IPOPT, COPT, Gurobi) as described in the [Getting Started](getting_started.md) section. +Before trying out the code snippets, please ensure that you have completed the installation of PyOptInterface with correct dependencies via `pip install pyoptinterface[nlp]` and solvers that support nonlinear programming (IPOPT, COPT, Xpress, Gurobi) as described in the [Getting Started](getting_started.md) section. ::: ## Construct nonlinear expressions diff --git a/docs/source/xpress.md b/docs/source/xpress.md new file mode 100644 index 00000000..e7793223 --- /dev/null +++ b/docs/source/xpress.md @@ -0,0 +1,163 @@ +# Xpress + +## Initial setup + +```python +from pyoptinterface import xpress +model = xpress.Model() +``` + +You need to follow the instructions in [Getting Started](getting_started.md#xpress) to set up the optimizer correctly. + +If you want to manage the license of Xpress manually, you can create a `xpress.Env` object and pass it to the constructor of the `xpress.Model` object, otherwise we will initialize an implicit global `xpress.Env` object automatically and use it. + +```python +env = xpress.Env() +model = xpress.Model(env) +``` + +For users who want to release the license immediately after the optimization, you can call the `close` method of all models created and the `xpress.Env` object. + +```python +env = xpress.Env() +model = xpress.Model(env) +# do something with the model +model.close() +env.close() +``` + +## The capability of `xpress.Model` + +### Supported constraints + +:::{list-table} +:header-rows: 1 +* - Constraint + - Supported +* - + - ✅ +* - + - ✅ +* - + - ✅ +* - + - ✅ +* - + - ✅ +* - + - ✅ +::: + +```{include} attribute/xpress.md +``` + +## Solver-specific operations + +### Controls and Attributes + +Xpress uses different terminology than PyOptInterface: +- **Controls** govern the solution procedure and output format (similar to PyOptInterface parameters) +- **Attributes** are read-only properties of the problem and solution + +PyOptInterface maps these as follows: +- PyOptInterface **parameters** correspond to Xpress controls +- PyOptInterface **attributes** may access Xpress controls, attributes, or variable/constraint properties through dedicated methods + +### Controls (Parameters) + +For [solver-specific controls](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/chapter7.html), we provide `get_raw_control` and `set_raw_control` methods. + +```python +model = xpress.Model() +# Get the value of a control +value = model.get_raw_control("XPRS_TIMELIMIT") +# Set the value of a control +model.set_raw_control("XPRS_TIMELIMIT", 10.0) +``` + +### Attributes + +For [problem attributes](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/chapter8.html), we provide `get_raw_attribute` method. + +```python +# Get number of columns in the problem +cols = model.get_raw_attribute("XPRS_COLS") +``` + +We also provide `xpress.XPRS` to contain common constants from the Xpress C API. + +```python +# Using constants +value = model.get_raw_control_dbl_by_id(xpress.XPRS.TIMELIMIT) +``` + +### Variable and Constraint Properties + +Common variable and constraint properties are provided through PyOptInterface dedicated methods: + +**Variable methods:** +- **Bounds**: `set_variable_lowerbound`, `get_variable_lowerbound`, `set_variable_upperbound`, `get_variable_upperbound`, `set_variable_bounds` +- **Objective**: `set_objective_coefficient`, `get_objective_coefficient` +- **Type and name**: `set_variable_type`, `get_variable_type`, `set_variable_name`, `get_variable_name` +- **Solution values**: `get_variable_value`, `get_variable_rc`, `get_variable_primal_ray` +- **Basis status**: `is_variable_basic`, `is_variable_nonbasic_lb`, `is_variable_nonbasic_ub`, `is_variable_superbasic` +- **IIS information**: `is_variable_lowerbound_IIS`, `is_variable_upperbound_IIS` + +**Constraint methods:** +- **Definition**: `set_constraint_sense`, `get_constraint_sense`, `set_constraint_rhs`, `get_constraint_rhs`, `set_constraint_name`, `get_constraint_name` +- **Coefficients**: `set_normalized_coefficient`, `get_normalized_coefficient`, `set_normalized_rhs`, `get_normalized_rhs` +- **Solution values**: `get_constraint_dual`, `get_constraint_slack`, `get_constraint_dual_ray` +- **Basis status**: `is_constraint_basic`, `is_constraint_nonbasic_lb`, `is_constraint_nonbasic_ub`, `is_constraint_superbasic` +- **IIS information**: `is_constraint_in_IIS` + +**Usage examples:** + +Variable properties: +```python +# Bounds +model.set_variable_lowerbound(variable, 0.0) +lb = model.get_variable_lowerbound(variable) +model.set_variable_upperbound(variable, 10.0) +ub = model.get_variable_upperbound(variable) + +# Objective coefficient +model.set_objective_coefficient(variable, 2.0) +coef = model.get_objective_coefficient(variable) + +# Type and name +model.set_variable_type(variable, VariableDomain.Integer) +vtype = model.get_variable_type(variable) +model.set_variable_name(variable, "x") +name = model.get_variable_name(variable) + +# Solution values +value = model.get_variable_value(variable) +rc = model.get_variable_rc(variable) +ray = model.get_variable_primal_ray(variable) + +# Basis status +if model.is_variable_basic(variable): + ... +``` + +Constraint properties: +```python +# Sense and RHS +model.set_constraint_sense(constraint, ConstraintSense.LessEqual) +sense = model.get_constraint_sense(constraint) +model.set_constraint_rhs(constraint, 5.0) +rhs = model.get_constraint_rhs(constraint) + +# Name +model.set_constraint_name(constraint, "c1") +name = model.get_constraint_name(constraint) + +# Solution values +dual = model.get_constraint_dual(constraint) +slack = model.get_constraint_slack(constraint) +ray = model.get_constraint_dual_ray(constraint) + +# Basis status +if model.is_constraint_basic(constraint): + ... +``` diff --git a/include/pyoptinterface/core.hpp b/include/pyoptinterface/core.hpp index 206d453f..b2cfce8a 100644 --- a/include/pyoptinterface/core.hpp +++ b/include/pyoptinterface/core.hpp @@ -229,7 +229,7 @@ auto operator-(const ScalarQuadraticFunction &a) -> ScalarQuadraticFunction; auto operator-(const ExprBuilder &a) -> ExprBuilder; // Operator overloading for ExprBuilder -// Sadly, they are inefficient than the +=-=,*=,/= functions but they are important for a +// Sadly, they are inefficient than the +=,-=,*=,/= functions but they are important for a // user-friendly interface // The functions are like ScalarQuadraticFunction but returns a ExprBuilder auto operator+(const ExprBuilder &a, CoeffT b) -> ExprBuilder; @@ -273,7 +273,8 @@ enum class ConstraintType Gurobi_General, COPT_ExpCone, COPT_NL, - IPOPT_NL + IPOPT_NL, + Xpress_Nlp }; enum class SOSType diff --git a/include/pyoptinterface/nlexpr.hpp b/include/pyoptinterface/nlexpr.hpp index 2d370dd3..eeb0e9e2 100644 --- a/include/pyoptinterface/nlexpr.hpp +++ b/include/pyoptinterface/nlexpr.hpp @@ -54,7 +54,8 @@ enum class BinaryOperator GreaterEqual, GreaterThan, - // Compability issue where some solvers only accepts two-arg multiplication + // Compatibility issue where some solvers only accepts two-arg multiplication + Add2, Mul2 }; @@ -214,4 +215,4 @@ struct ExpressionGraph }; void unpack_comparison_expression(ExpressionGraph &graph, const ExpressionHandle &expr, - ExpressionHandle &real_expr, double &lb, double &ub); \ No newline at end of file + ExpressionHandle &real_expr, double &lb, double &ub); diff --git a/include/pyoptinterface/xpress_model.hpp b/include/pyoptinterface/xpress_model.hpp new file mode 100644 index 00000000..94f463b3 --- /dev/null +++ b/include/pyoptinterface/xpress_model.hpp @@ -0,0 +1,759 @@ +#pragma + +#include +#include +#include + +#include + +#include "pyoptinterface/core.hpp" +#include "pyoptinterface/container.hpp" +#define USE_NLMIXIN +#include "pyoptinterface/solver_common.hpp" +#include "pyoptinterface/dylib.hpp" + +// PyOptInterface has been compiled and tested with Xpress version 46.1.1 +#define XPRS_VER_MAJOR 46 +#define XPRS_VER_MINOR 1 +#define XPRS_VER_BUILD 1 + +#if XPVERSION_MAJOR < XPRS_VER_MAJOR +#warning "System Xpress library major version is older than the officially supported version. " \ + "Some features may not work correctly." +#endif + +// Xpress Callback Abstraction Layer +// +// Xpress supports multiple callbacks that we want to expose to PyOptInterface as "contexts" to +// match the design of other solver interfaces. To bridge Xpress's multiple-callback system to +// PyOptInterface's single-callback-with-context model, we need to repeat the same setup for each +// callback: define the low-level C function, register it with Xpress, handle its arguments, and +// bind everything through Nanobind. +// +// Rather than copy-paste this boilerplate for each callback (error-prone and hard to maintain), we +// use macros to generate everything from a single list. +// +// How does it work: +// We define XPRSCB_LIST below with all supported callbacks and their signatures. This list is +// parameterized by two macros that let us generate different code from the same data: +// +// MACRO - Receives callback metadata (ID, name, return type, arguments) and expands to whatever +// we're generating (function declarations, enum values, registration code, etc.) +// +// ARG - Formats each callback *optional* argument. MACRO receives arguments wrapped by ARG, so it +// can extract type/name information as needed. +// +// When we need to do something with all callbacks (e.g., declare wrapper functions), we pass +// specific MACRO and ARG definitions to XPRSCB_LIST, and it generates the code. +// +// MACRO is invoked with: +// 1. ID - Unique number for enum bit-flags (0-63, used for callback identification) +// 2. NAME - Xpress callback name (e.g., "optnode" for XPRSaddcboptnode) +// 3. RET - Return type of the Xpress callback function +// 4. ...ARGS - Callback arguments (excluding XPRSprob and void* which are always first), +// each wrapped in ARG(TYPE, NAME) +// +// ARG is invoked with: +// 1. TYPE - Argument type from Xpress documentation +// 2. NAME - Argument name from Xpress documentation +// +// Example: To declare all callback wrappers, define MACRO to generate a function declaration and +// ARG to format parameters, then invoke XPRSCB_LIST(MACRO, ARG). + +// clang-format off +#define XPRSCB_LIST(MACRO, ARG) \ + MACRO(0, bariteration, void, \ + ARG(int *, p_action)) \ + MACRO(1, barlog, int) \ + MACRO(2, afterobjective, void) \ + MACRO(3, beforeobjective, void) \ + MACRO(5, presolve, void) \ + MACRO(6, checktime,int) \ + MACRO(7, chgbranchobject, void, \ + ARG(XPRSbranchobject, obranch) \ + ARG(XPRSbranchobject *, p_newobject)) \ + MACRO(8, cutlog, int) \ + MACRO(9, cutround, void, \ + ARG(int, ifxpresscuts) \ + ARG(int*, p_action)) \ + MACRO(10, destroymt, void) \ + MACRO(11, gapnotify, void, \ + ARG(double*, p_relgapnotifytarget) \ + ARG(double*, p_absgapnotifytarget) \ + ARG(double*, p_absgapnotifyobjtarget) \ + ARG(double*, p_absgapnotifyboundtarget)) \ + MACRO(12, miplog, int) \ + MACRO(13, infnode, void) \ + MACRO(14, intsol, void) \ + MACRO(15, lplog, int) \ + MACRO(16, message, void, \ + ARG(const char*, msg) \ + ARG(int, msglen) \ + ARG(int, msgtype)) \ + /* This CB is currently incompatible with this wapper design + MACRO(17, mipthread, void, \ + ARG(XPRSprob, threadprob)) */ \ + MACRO(18, newnode, void, \ + ARG(int, parentnode) \ + ARG(int, node) \ + ARG(int, branch)) \ + MACRO(19, nodecutoff, void, \ + ARG(int, node)) \ + MACRO(20, nodelpsolved, void) \ + MACRO(21, optnode, void, \ + ARG(int*, p_infeasible)) \ + MACRO(22, preintsol, void, \ + ARG(int, soltype) \ + ARG(int*, p_reject) \ + ARG(double*, p_cutoff)) \ + MACRO(23, prenode, void, \ + ARG(int*, p_infeasible)) \ + MACRO(24, usersolnotify, void, \ + ARG(const char*, solname) \ + ARG(int, status)) +// clang-format on + +// Common callbacks optional arguments formatting macros: +#define XPRSCB_ARG_IGNORE(TYPE, NAME) // Ingore arguments +#define XPRSCB_ARG_FN(TYPE, NAME) , TYPE NAME // As args of a function +#define XPRSCB_ARG_TYPE(TYPE, NAME) , TYPE // As args of a template + +// Expand to 2 elements of APILIST +#define XPRSCB_ADDREMOVE_FN(ID, NAME, ...) \ + B(XPRSaddcb##NAME); \ + B(XPRSremovecb##NAME); + +// Define Xpress C APIs list. +// Similar idea to the CBs list, here the B macro is externally provided as in the other solvers +// interface implementation. +#define APILIST \ + B(XPRSaddcols64); \ + B(XPRSaddcuts64); \ + B(XPRSaddmanagedcuts64); \ + B(XPRSaddmipsol); \ + B(XPRSaddnames); \ + B(XPRSaddqmatrix64); \ + B(XPRSaddrows64); \ + B(XPRSaddsets64); \ + B(XPRSbeginlicensing); \ + B(XPRSchgbounds); \ + B(XPRSchgcoef); \ + B(XPRSchgcoltype); \ + B(XPRSchgmqobj64); \ + B(XPRSchgobj); \ + B(XPRSchgobjsense); \ + B(XPRSchgrhs); \ + B(XPRSchgrowtype); \ + B(XPRScreateprob); \ + B(XPRSdelcols); \ + B(XPRSdelobj); \ + B(XPRSdelqmatrix); \ + B(XPRSdelrows); \ + B(XPRSdelsets); \ + B(XPRSdestroyprob); \ + B(XPRSendlicensing); \ + B(XPRSfree); \ + B(XPRSgetattribinfo); \ + B(XPRSgetbasisval); \ + B(XPRSgetcallbacksolution); \ + B(XPRSgetcoef); \ + B(XPRSgetcoltype); \ + B(XPRSgetcontrolinfo); \ + B(XPRSgetdblattrib); \ + B(XPRSgetdblcontrol); \ + B(XPRSgetdualray); \ + B(XPRSgetduals); \ + B(XPRSgetiisdata); \ + B(XPRSgetintattrib64); \ + B(XPRSgetintcontrol64); \ + B(XPRSgetlasterror); \ + B(XPRSgetlb); \ + B(XPRSgetlicerrmsg); \ + B(XPRSgetlpsol); \ + B(XPRSgetnamelist); \ + B(XPRSgetobj); \ + B(XPRSgetprimalray); \ + B(XPRSgetprobname); \ + B(XPRSgetredcosts); \ + B(XPRSgetrhs); \ + B(XPRSgetrowtype); \ + B(XPRSgetslacks); \ + B(XPRSgetsolution); \ + B(XPRSgetstrattrib); \ + B(XPRSgetstrcontrol); \ + B(XPRSgetstringattrib); \ + B(XPRSgetstringcontrol); \ + B(XPRSgetub); \ + B(XPRSgetversion); \ + B(XPRSgetversionnumbers); \ + B(XPRSiisall); \ + B(XPRSiisfirst); \ + B(XPRSinit); \ + B(XPRSinterrupt); \ + B(XPRSlicense); \ + B(XPRSnlpaddformulas); \ + B(XPRSnlploadformulas); \ + B(XPRSnlppostsolve); \ + B(XPRSoptimize); \ + B(XPRSpostsolve); \ + B(XPRSpresolverow); \ + B(XPRSsaveas); \ + B(XPRSsetdblcontrol); \ + B(XPRSsetintcontrol); \ + B(XPRSsetintcontrol64); \ + B(XPRSsetlogfile); \ + B(XPRSsetprobname); \ + B(XPRSsetstrcontrol); \ + B(XPRSwritebasis); \ + B(XPRSwritebinsol); \ + B(XPRSwriteprob); \ + B(XPRSwriteprtsol); \ + B(XPRSwriteslxsol); \ + B(XPRSwritesol); \ + XPRSCB_LIST(XPRSCB_ADDREMOVE_FN, XPRSCB_ARG_IGNORE); + +namespace xpress +{ +// Define xpress function inside the xpress namespace +#define B DYLIB_EXTERN_DECLARE +APILIST +#undef B + +// Libray loading functions +bool is_library_loaded(); +bool load_library(const std::string &path); +std::pair license(int p_i, const char *p_c); +bool beginlicensing(); +void endlicensing(); + +// Xpress doesn't have an Env pointer, however, POI manages environment +// initialization with an OOP interface. +struct Env +{ + Env(const char *path = nullptr); + ~Env(); + void close(); + + static inline std::mutex mtx; + static inline int init_count = 0; + bool initialized = false; +}; + +// Some of the Xpress enums are here re-defined to enforce type safety +// Types associated with Xpress attribute and controls +enum class CATypes : int +{ + NOTDEFINED = XPRS_TYPE_NOTDEFINED, + INT = XPRS_TYPE_INT, + INT64 = XPRS_TYPE_INT64, + DOUBLE = XPRS_TYPE_DOUBLE, + STRING = XPRS_TYPE_STRING, +}; + +enum class SOLSTATUS : int +{ + NOTFOUND = XPRS_SOLSTATUS_NOTFOUND, + OPTIMAL = XPRS_SOLSTATUS_OPTIMAL, + FEASIBLE = XPRS_SOLSTATUS_FEASIBLE, + INFEASIBLE = XPRS_SOLSTATUS_INFEASIBLE, + UNBOUNDED = XPRS_SOLSTATUS_UNBOUNDED +}; + +enum class SOLVESTATUS : int +{ + UNSTARTED = XPRS_SOLVESTATUS_UNSTARTED, + STOPPED = XPRS_SOLVESTATUS_STOPPED, + FAILED = XPRS_SOLVESTATUS_FAILED, + COMPLETED = XPRS_SOLVESTATUS_COMPLETED +}; + +enum class LPSTATUS : int +{ + UNSTARTED = XPRS_LP_UNSTARTED, + OPTIMAL = XPRS_LP_OPTIMAL, + INFEAS = XPRS_LP_INFEAS, + CUTOFF = XPRS_LP_CUTOFF, + UNFINISHED = XPRS_LP_UNFINISHED, + UNBOUNDED = XPRS_LP_UNBOUNDED, + CUTOFF_IN_DUAL = XPRS_LP_CUTOFF_IN_DUAL, + UNSOLVED = XPRS_LP_UNSOLVED, + NONCONVEX = XPRS_LP_NONCONVEX +}; + +enum class MIPSTATUS : int +{ + NOT_LOADED = XPRS_MIP_NOT_LOADED, + LP_NOT_OPTIMAL = XPRS_MIP_LP_NOT_OPTIMAL, + LP_OPTIMAL = XPRS_MIP_LP_OPTIMAL, + NO_SOL_FOUND = XPRS_MIP_NO_SOL_FOUND, + SOLUTION = XPRS_MIP_SOLUTION, + INFEAS = XPRS_MIP_INFEAS, + OPTIMAL = XPRS_MIP_OPTIMAL, + UNBOUNDED = XPRS_MIP_UNBOUNDED +}; + +enum class NLPSTATUS : int +{ + UNSTARTED = XPRS_NLPSTATUS_UNSTARTED, + SOLUTION = XPRS_NLPSTATUS_SOLUTION, + LOCALLY_OPTIMAL = XPRS_NLPSTATUS_LOCALLY_OPTIMAL, + OPTIMAL = XPRS_NLPSTATUS_OPTIMAL, + NOSOLUTION = XPRS_NLPSTATUS_NOSOLUTION, + LOCALLY_INFEASIBLE = XPRS_NLPSTATUS_LOCALLY_INFEASIBLE, + INFEASIBLE = XPRS_NLPSTATUS_INFEASIBLE, + UNBOUNDED = XPRS_NLPSTATUS_UNBOUNDED, + UNFINISHED = XPRS_NLPSTATUS_UNFINISHED, + UNSOLVED = XPRS_NLPSTATUS_UNSOLVED, +}; + +enum class IISSOLSTATUS : int +{ + UNSTARTED = XPRS_IIS_UNSTARTED, + FEASIBLE = XPRS_IIS_FEASIBLE, + COMPLETED = XPRS_IIS_COMPLETED, + UNFINISHED = XPRS_IIS_UNFINISHED +}; + +enum class SOLAVAILABLE : int +{ + NOTFOUND = XPRS_SOLAVAILABLE_NOTFOUND, + OPTIMAL = XPRS_SOLAVAILABLE_OPTIMAL, + FEASIBLE = XPRS_SOLAVAILABLE_FEASIBLE +}; + +enum class OPTIMIZETYPE : int +{ + NONE = XPRS_OPTIMIZETYPE_NONE, + LP = XPRS_OPTIMIZETYPE_LP, + MIP = XPRS_OPTIMIZETYPE_MIP, + LOCAL = XPRS_OPTIMIZETYPE_LOCAL, + GLOBAL = XPRS_OPTIMIZETYPE_GLOBAL +}; + +//////////////////////////////////////////////////////////////////////////////// +// CALLBACKS TYPES AND DEFINITIONS // +//////////////////////////////////////////////////////////////////////////////// + +// Callback contexts enum. Defines an unique id for each callback/context. +// The values of this enum class are defined as bitflags, to allow for multiple context manipulation +// using a single uint64 value. +enum class CB_CONTEXT : unsigned long long +{ +// Define a enum element +#define XPRSCB_ENUM(ID, NAME, ...) NAME = (1ULL << ID), + XPRSCB_LIST(XPRSCB_ENUM, XPRSCB_ARG_IGNORE) +#undef XPRSCB_ENUM +}; + +class Model; // Define later in this file +using Callback = std::function; // Callback opaque container + +// xpress::Model operates in two modes to handle callback local XPRSprob objects: +// +// MAIN mode - The model owns its XPRSprob and manages all optimization state normally. +// CALLBACK mode - A temporary, non-owning wrapper around Xpress's thread-local problem clone that +// gets passed to callbacks. Since Xpress creates separate problem clones for callbacks, we need to +// temporarily "borrow" this clone while preserving xpress::Model's internal state +// (variable/constraint indexers, etc.) without copies. +// +// During a callback, we swap the XPRSprob pointer from the main model into the callback pointer, +// execute the user's callback with a full xpress::Model object, then swap it back. +// +// Thread safety: This swap-based design assumes callbacks execute sequentially. Python's GIL +// enforces this anyway (only one callback can execute Python code at a time), and we configure +// Xpress to mutex callbacks invocations, so concurrent callback execution isn't an issue. +enum class XPRESS_MODEL_MODE +{ + MAIN, // Owns XPRSprob; holds global callback state + CALLBACK, // Non-owning wrapper around Xpress's callback problem clone +}; + +// Simple conditional struct that define the ret_code field only if it is not void +template +struct ReturnValue +{ + T ret_code; + T get_return_value() const + { + return ret_code; + } +}; + +template <> +struct ReturnValue +{ + void get_return_value() const {}; +}; + +// Since we use the CB macro list, we get the original types passed at the low-level CBs +// This helper struct is used to inject type-exceptions on the callback struct field types. In most +// cases this is not required, except when dealing with pointers to opaque objects, which Nanobind +// doesn't handle automatically. +template +struct StructFieldType +{ + using type = T; // Default behavior: just use the original type +}; + +// (At the best of my knowledge) Nanobind does not support binding for opaque types (pointers to +// declared structs but whose definition is not available in that point). Some callbacks works with +// opaque objects that are passed around (e.g., branch object), we don't need to access them, +// just to pass them back to other Xpress APIs. + +// XPRSbranchobject is a pointer to an opaque type, which nanobind struggle with. So we pass it +// as an opaque void*, which nanobind knows how to handle. +template <> +struct StructFieldType +{ + using type = void *; +}; + +template <> +struct StructFieldType +{ + using type = void *; +}; + +// Callback Argument Structs +// +// PyOptInterface callbacks have a uniform signature: callback(model, context). On the other hand, +// Xpress callbacks have varying signatures with callback-specific arguments (e.g., node IDs, +// branching info, solution status). To bridge this gap, we generate a struct for each callback type +// that holds its specific arguments. +// +// During a callback, we populate the appropriate struct with the current arguments, and we provide +// it to the CB through the "Model.cb_get_arguments" function. The Python callback can then access +// these arguments as named fields. +// +// For example, the 'optnode' callback receives an int* p_infeasible parameter. We generate: +// struct optnode_struct { int* p_infeasible; }; +// The Python callback accesses this as: model.cb_get_arguments().p_infeasible + +#define XPRSCB_ARG_STRUCT(TYPE, NAME) StructFieldType::type NAME; +#define XPRSCB_STRUCT(ID, NAME, RET, ...) \ + struct NAME##_struct : ReturnValue \ + { \ + __VA_ARGS__ \ + }; +XPRSCB_LIST(XPRSCB_STRUCT, XPRSCB_ARG_STRUCT) +#undef XPRSCB_STRUCT + +// Callback Data Variant +// +// We use std::variant to store pointers to callback-specific argument structs, rather than +// a generic void*. This provides two benefits: +// +// 1. Type safety - The variant ensures we can only store pointers to known callback structs, +// catching type errors at compile time. +// +// 2. Automatic Python binding - Nanobind automatically converts std::variant to Python union +// types, giving Python callbacks properly-typed access to callback arguments without manual +// type casting or wrapper code. +// +// The variant contains nullptr_t plus a pointer type for each callback struct (e.g., +// optnode_struct*, intsol_struct*, etc.) +#define XPRSCB_STRUCT_NAME(ID, NAME, RET, ...) , NAME##_struct * +using xpress_cbs_data = + std::variant; +#undef XPRSCB_STRUCT_NAME + +// Type-value pair mainly used for NLP formulas +struct Tvp +{ + int type; + double value; +}; + +// xpress::Model - Main solver interface for building and solving Xpress optimization models. +// Inherits standard PyOptInterface modeling API through CRTP mixins for constraints, objectives, +// and solution queries. +class Model : public OnesideLinearConstraintMixin, + public TwosideLinearConstraintMixin, + public OnesideQuadraticConstraintMixin, + public TwosideNLConstraintMixin, + public LinearObjectiveMixin, + public PPrintMixin, + public GetValueMixin +{ + + public: + Model() = default; + ~Model(); + + // Avoid involuntary copies + Model(const Model &) = delete; + Model &operator=(const Model &) = delete; + + // Move is fine, and we need it to wrap callback XPRSprob + Model(Model &&) noexcept = default; + Model &operator=(Model &&) noexcept = default; + + Model(const Env &env); + void init(const Env &env); + void close(); + + void optimize(); + bool _is_mip(); + static double get_infinity(); + void write(const std::string &filename); + std::string get_problem_name(); + void set_problem_name(const std::string &probname); + void add_mip_start(const std::vector &variables, + const std::vector &values); + void *get_raw_model(); + void computeIIS(); + std::string version_string(); + + // Index mappings + int _constraint_index(ConstraintIndex constraint); + int _variable_index(VariableIndex variable); + int _checked_constraint_index(ConstraintIndex constraint); + int _checked_variable_index(VariableIndex variable); + + // Variables + VariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous, + double lb = XPRS_MINUSINFINITY, double ub = XPRS_PLUSINFINITY, + const char *name = nullptr); + void delete_variable(VariableIndex variable); + void delete_variables(const Vector &variables); + void set_objective_coefficient(VariableIndex variable, double value); + void set_variable_bounds(VariableIndex variable, double lb, double ub); + void set_variable_lowerbound(VariableIndex variable, double lb); + void set_variable_name(VariableIndex variable, const char *name); + void set_variable_type(VariableIndex variable, VariableDomain vtype); + void set_variable_upperbound(VariableIndex variable, double ub); + bool is_variable_active(VariableIndex variable); + bool is_variable_basic(VariableIndex variable); + bool is_variable_lowerbound_IIS(VariableIndex variable); + bool is_variable_nonbasic_lb(VariableIndex variable); + bool is_variable_nonbasic_ub(VariableIndex variable); + bool is_variable_superbasic(VariableIndex variable); + bool is_variable_upperbound_IIS(VariableIndex variable); + double get_objective_coefficient(VariableIndex variable); + double get_variable_lowerbound(VariableIndex variable); + double get_variable_primal_ray(VariableIndex variable); + double get_variable_rc(VariableIndex variable); + double get_variable_upperbound(VariableIndex variable); + double get_variable_value(VariableIndex variable); + std::string get_variable_name(VariableIndex variable); + std::string pprint_variable(VariableIndex variable); + VariableDomain get_variable_type(VariableIndex variable); + + // Constraints + ConstraintIndex add_exp_cone_constraint(const Vector &variables, + const char *name, bool dual); + ConstraintIndex add_linear_constraint(const ScalarAffineFunction &function, + const std::tuple &interval, + const char *name); + ConstraintIndex add_linear_constraint(const ScalarAffineFunction &function, + ConstraintSense sense, CoeffT rhs, + const char *name = nullptr); + ConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &function, + ConstraintSense sense, CoeffT rhs, + const char *name = nullptr); + ConstraintIndex add_second_order_cone_constraint(const Vector &variables, + const char *name, bool rotated); + ConstraintIndex add_single_nl_constraint(ExpressionGraph &graph, const ExpressionHandle &result, + const std::tuple &interval, + const char *name = nullptr); + ConstraintIndex add_sos_constraint(const Vector &variables, SOSType sos_type, + const Vector &weights); + ConstraintIndex add_sos_constraint(const Vector &variables, SOSType sos_type); + void delete_constraint(ConstraintIndex constraint); + void set_constraint_name(ConstraintIndex constraint, const char *name); + void set_constraint_rhs(ConstraintIndex constraint, CoeffT rhs); + void set_constraint_sense(ConstraintIndex constraint, ConstraintSense sense); + void set_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable, + double value); + void set_normalized_rhs(ConstraintIndex constraint, double value); + bool is_constraint_active(ConstraintIndex constraint); + bool is_constraint_basic(ConstraintIndex constraint); + bool is_constraint_in_IIS(ConstraintIndex constraint); + bool is_constraint_nonbasic_lb(ConstraintIndex constraint); + bool is_constraint_nonbasic_ub(ConstraintIndex constraint); + bool is_constraint_superbasic(ConstraintIndex constraint); + double get_constraint_dual_ray(ConstraintIndex constraint); + double get_constraint_dual(ConstraintIndex constraint); + double get_constraint_slack(ConstraintIndex constraint); + double get_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable); + double get_normalized_rhs(ConstraintIndex constraint); + CoeffT get_constraint_rhs(ConstraintIndex constraint); + std::string get_constraint_name(ConstraintIndex constraint); + ConstraintSense get_constraint_sense(ConstraintIndex constraint); + + // Objective function + void set_objective(const ScalarAffineFunction &function, ObjectiveSense sense); + void set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense); + void set_objective(const ExprBuilder &function, ObjectiveSense sense); + void add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result); + + // Xpress->POI exit status mappings + LPSTATUS get_lp_status(); + MIPSTATUS get_mip_status(); + NLPSTATUS get_nlp_status(); + SOLSTATUS get_sol_status(); + SOLVESTATUS get_solve_status(); + OPTIMIZETYPE get_optimize_type(); + IISSOLSTATUS get_iis_sol_status(); + + // Native Attribute/Control access using integer IDs + void set_raw_control_dbl_by_id(int control, double value); + void set_raw_control_int_by_id(int control, XPRSint64 value); + void set_raw_control_str_by_id(int control, const char *value); + XPRSint64 get_raw_control_int_by_id(int control); + double get_raw_control_dbl_by_id(int control); + std::string get_raw_control_str_by_id(int control); + + XPRSint64 get_raw_attribute_int_by_id(int attrib); + double get_raw_attribute_dbl_by_id(int attrib); + std::string get_raw_attribute_str_by_id(int attrib); + + // Attribute/Control access through string IDs (converted to integer IDs) + void set_raw_control_int(const char *control, XPRSint64 value); + void set_raw_control_dbl(const char *control, double value); + void set_raw_control_str(const char *control, const char *value); + XPRSint64 get_raw_control_int(const char *control); + double get_raw_control_dbl(const char *control); + std::string get_raw_control_str(const char *control); + + XPRSint64 get_raw_attribute_int(const char *attrib); + double get_raw_attribute_dbl(const char *attrib); + std::string get_raw_attribute_str(const char *attrib); + + // Type generic Attribute/Control access through string IDs + using xprs_type_variant_t = std::variant; + void set_raw_control(const char *control, xprs_type_variant_t &value); + xprs_type_variant_t get_raw_attribute(const char *attrib); + xprs_type_variant_t get_raw_control(const char *control); + + // Callback + void set_callback(const Callback &callback, unsigned long long cbctx); + xpress_cbs_data cb_get_arguments(); + + double cb_get_solution(VariableIndex variable); + double cb_get_relaxation(VariableIndex variable); + double cb_get_incumbent(VariableIndex variable); + void cb_set_solution(VariableIndex variable, double value); + void cb_submit_solution(); + + void cb_exit(); + + // NOTE: Xpress only provive ways to add local cuts, so, all these functions map to the same + // XPRSaddcuts operation + void cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense, + CoeffT rhs); + void cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs); + void cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs); + void cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs); + + private: // HELPER FUNCTIONS + void _check(int error); + void _clear_caches(); + + // Modeling helpers + void _set_entity_name(int etype, int index, const char *name); + ConstraintIndex _add_sos_constraint(const Vector &variables, SOSType sos_type, + const Vector &weights); + std::string _get_entity_name(int etype, int eidx); + char _get_variable_bound_IIS(VariableIndex variable); + int _get_basis_stat(int entity_idx, bool is_row = false); + + // NLP helpers + Tvp _decode_expr(const ExpressionGraph &graph, const ExpressionHandle &expr); + std::pair, std::vector> _decode_graph_postfix_order( + ExpressionGraph &graph, const ExpressionHandle &result); + + // Attributes/Controls helpers + int _get_checked_attribute_id(const char *attrib, CATypes expected, + CATypes backup = CATypes::NOTDEFINED); + int _get_checked_control_id(const char *control, CATypes expected, + CATypes backup = CATypes::NOTDEFINED); + std::pair _get_attribute_info(const char *attrib); + std::pair _get_control_info(const char *control); + + // Callback/Mode helpers + void _check_expected_mode(XPRESS_MODEL_MODE mode); + void _ensure_postsolved(); + double _cb_get_context_solution(VariableIndex variable); + void _cb_add_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs); + XPRSprob _toggle_model_mode(XPRSprob model); + + private: // TYPES + // Helper struct used to spawn lower level C callbacks with matching signature + template + struct CbWrap; + + // XPRSprob deleter to automatically RAII using unique_ptr + struct ProbDeleter + { + void operator()(XPRSprob prob) + { + if (xpress::XPRSdestroyprob(prob) != 0) + { + throw std::runtime_error("Error while destroying Xpress problem object"); + } + } + }; + + private: // MEMBER VARIABLES + // Xpress problem pointer + std::unique_ptr m_model; + + // Current operating mode (MAIN or CALLBACK) - enables runtime validation that + // callback-only methods aren't called outside callbacks and vice versa + XPRESS_MODEL_MODE m_mode; + + // Index management for variables and constraints + // Note that Xpress uses the same index set to refer to almost all its constraint types. The + // only exception are SOS which are handled in a separate pool. + MonotoneIndexer m_variable_index; + MonotoneIndexer m_constraint_index; + MonotoneIndexer m_sos_constraint_index; + + // Tracks whether the model requires postsolving before queries can be made. + // When optimization is interrupted, the model remains in a presolved state where variable + // and constraint indices don't match the original problem structure. Querying model data + // in this state would return incorrect results. Postsolving restores the original index + // mappings but discards all optimization progress, forcing any subsequent optimization + // to restart from scratch. + bool m_need_postsolve = false; + + // Any non-linear or non-convex quadratic constraint is handled with Xpress non linear solver. + // We keep count of all the non-linear (strictly speaking) constraints. + int m_quad_nl_constr_num = 0; + bool has_quad_objective = false; + + bool has_nlp_objective = false; + VariableIndex m_nlp_obj_variable; + ConstraintIndex m_nlp_obj_constraint; + + // Cached vectors + std::vector m_primal_ray; + std::vector m_dual_ray; + std::vector m_iis_cols; + std::vector m_iss_rows; + std::vector m_iis_bound_types; + + // Message callback state - we register a default handler but allow user override + bool is_default_message_cb_set; + + // User callback and active contexts + Callback m_callback = nullptr; + unsigned long long m_curr_contexts = 0; // Bitwise OR of enabled callback contexts + + // Exception propagation - if a callback throws, we capture it here to let Xpress + // complete cleanup gracefully before rethrowing to Python + std::vector m_captured_exceptions; + + // Current callback context being executed + CB_CONTEXT cb_where; + + // Heuristic solution builder - accumulates (variable, value) pairs during callback; + // submitted to Xpress when callback completes + std::vector> cb_sol_cache; + + // Callback-specific arguments - variant holding pointers to context-specific structs + // (e.g., optnode_struct*, intsol_struct*) based on current callback type + xpress_cbs_data cb_args = nullptr; +}; +} // namespace xpress diff --git a/lib/nlexpr.cpp b/lib/nlexpr.cpp index 7ee8a70d..9227feec 100644 --- a/lib/nlexpr.cpp +++ b/lib/nlexpr.cpp @@ -444,6 +444,10 @@ std::string binary_operator_to_string(BinaryOperator op) return "GreaterEqual"; case BinaryOperator::GreaterThan: return "GreaterThan"; + case BinaryOperator::Add2: + return "Add2"; + case BinaryOperator::Mul2: + return "Mul2"; } } diff --git a/lib/xpress_model.cpp b/lib/xpress_model.cpp new file mode 100644 index 00000000..34f56620 --- /dev/null +++ b/lib/xpress_model.cpp @@ -0,0 +1,2528 @@ +#include "pyoptinterface/xpress_model.hpp" +#include "fmt/core.h" +#include "pyoptinterface/core.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace xpress +{ + +// Simple helper to have a Go-like defer functionality. +// Mainly used to move resource release closer to its acquisition. +template +struct Defer : LmdT +{ + Defer(LmdT l) : LmdT(l) {}; + ~Defer() noexcept + { + (*this)(); + } +}; + +// Mimics what is done to load the other solvers. +#define B DYLIB_DECLARE +APILIST +#undef B + +static DynamicLibrary lib; +static bool is_loaded = false; + +bool is_library_loaded() +{ + return is_loaded; +} + +bool load_library(const std::string &path) +{ + bool success = lib.try_load(path.c_str()); + if (!success) + { + return false; + } + + DYLIB_LOAD_INIT; + +#define B DYLIB_LOAD_FUNCTION + APILIST +#undef B + + if (IS_DYLIB_LOAD_SUCCESS) + { +#define B DYLIB_SAVE_FUNCTION + APILIST +#undef B + is_loaded = true; + int major = {}; + int minor = {}; + int build = {}; + XPRSgetversionnumbers(&major, &minor, &build); + // Use tuple comparison operator + if (std::make_tuple(major, minor, build) < + std::make_tuple(XPRS_VER_MAJOR, XPRS_VER_MINOR, XPRS_VER_BUILD)) + { + fmt::print( + stderr, + "Warning: loaded Xpress version is older than the officially supported one.\n"); + } + } + return is_loaded; +} + +static void check_license(int error) +{ + if (error == 0) + { + return; + } + + char buffer[XPRS_MAXMESSAGELENGTH]; + if (XPRSgetlicerrmsg(buffer, sizeof buffer) != 0) + { + throw std::runtime_error("Error while getting the Xpress license error message"); + } + throw std::runtime_error( + fmt::format("Error while initializing Xpress Environment: {}", buffer)); +} + +Env::Env(const char *path) +{ + if (!xpress::is_library_loaded()) + { + throw std::runtime_error("Xpress library is not loaded"); + } + + auto lg = std::lock_guard(mtx); + assert(init_count >= 0); + + if (init_count <= 0) + { + check_license(XPRSinit(path)); + } + ++init_count; + initialized = true; +} + +Env::~Env() +{ + try + { + close(); + } + catch (std::exception e) + { + fmt::print(stderr, "{}\n", e.what()); + fflush(stderr); + } +} + +void Env::close() +{ + if (!initialized) + { + return; + } + initialized = false; + + auto lg = std::lock_guard(mtx); + --init_count; + assert(init_count >= 0); + + if (init_count <= 0 && XPRSfree() != 0) + { + throw std::runtime_error("Error while freeing Xpress environment"); + } +} + +std::pair license(int p_i, const char *p_c) +{ + int i = p_i; + std::string c(p_c); + check_license(XPRSlicense(&i, c.data())); + c.resize(strlen(c.data())); + return std::make_pair(i, c); +} + +bool beginlicensing() +{ + int notyet = {}; + check_license(XPRSbeginlicensing(¬yet)); + return notyet != 0; +} + +void endlicensing() +{ + check_license(XPRSendlicensing()); +} + +static char poi_to_xprs_cons_sense(ConstraintSense sense) +{ + switch (sense) + { + case ConstraintSense::LessEqual: + return 'L'; + case ConstraintSense::Equal: + return 'E'; + case ConstraintSense::GreaterEqual: + return 'G'; + default: + throw std::runtime_error("Unknown constraint sense"); + } +} + +static ConstraintSense xprs_to_poi_cons_sense(int ctype) +{ + switch (ctype) + { + case 'L': + return ConstraintSense::LessEqual; + case 'E': + return ConstraintSense::Equal; + case 'G': + return ConstraintSense::GreaterEqual; + case 'R': // Range constraints + case 'N': // Free constraints + default: + throw std::runtime_error("Unsupported constraint sense"); + } +} +static int poi_to_xprs_obj_sense(ObjectiveSense sense) +{ + switch (sense) + { + case ObjectiveSense::Minimize: + return XPRS_OBJ_MINIMIZE; + case ObjectiveSense::Maximize: + return XPRS_OBJ_MAXIMIZE; + default: + throw std::runtime_error("Unknown objective function sense"); + } +} + +static char poi_to_xprs_var_type(VariableDomain domain) +{ + switch (domain) + { + case VariableDomain::Continuous: + return 'C'; + case VariableDomain::Integer: + return 'I'; + case VariableDomain::Binary: + return 'B'; + case VariableDomain::SemiContinuous: + return 'S'; + default: + throw std::runtime_error("Unknown variable domain"); + } +} + +static VariableDomain xprs_to_poi_var_type(char vtype) +{ + switch (vtype) + { + case 'C': + return VariableDomain::Continuous; + case 'I': + return VariableDomain::Integer; + case 'B': + return VariableDomain::Binary; + case 'S': + return VariableDomain::SemiContinuous; + default: + throw std::runtime_error("Unknown variable domain"); + } +} + +static char poi_to_xprs_sos_type(SOSType type) +{ + switch (type) + { + case SOSType::SOS1: + return '1'; + case SOSType::SOS2: + return '2'; + default: + throw std::runtime_error("Unknown SOS type"); + } +} + +// Check Xpress APIs return value for error and throws in case it is non-zero +void Model::_check(int error) +{ + // We allow users to define custom message callbacks which may throw exceptions. Since + // Xpress APIs can trigger messages at any point, exceptions might be thrown even from + // apparently "safe" operations. We always check for captured exceptions before returning. + if (m_mode == XPRESS_MODEL_MODE::MAIN && !m_captured_exceptions.empty()) + { + Defer exceptions_clear = [&] { m_captured_exceptions.clear(); }; + + // Single exception - rethrow directly + if (m_captured_exceptions.size() == 1) + { + std::rethrow_exception(m_captured_exceptions[0]); + } + + // Multiple exceptions - aggregate into single message + std::string new_what = "Multiple exceptions raised:\n"; + for (int i = 0; const auto &exc : m_captured_exceptions) + { + try + { + std::rethrow_exception(exc); + } + catch (const std::exception &e) + { + fmt::format_to(std::back_inserter(new_what), "{}. {}\n", ++i, e.what()); + } + catch (...) + { + fmt::format_to(std::back_inserter(new_what), "{}. Unknown exception\n", ++i); + } + } + throw std::runtime_error(new_what); + } + + if (error == 0) + { + return; + } + + char error_buffer[XPRS_MAXMESSAGELENGTH]; + if (XPRSgetlasterror(m_model.get(), error_buffer) != 0) + { + throw std::runtime_error("Error while getting Xpress message error"); + } + throw std::runtime_error(error_buffer); +} + +// The default behavior of Xpress C APIs is to don't print anything unless a message CB is +// registered. Thus, this is the default print callback that redirect to standard streams. +static void default_print(XPRSprob prob, void *, char const *msg, int msgsize, int msgtype) +{ + if (msgtype < 0) + { + // Negative values are used to signal output end, and can be use as flush trigger + // But we flush at every message, so no problem need to flush again. + return; + } + + FILE *out = (msgtype == 1 ? stdout : stderr); + fmt::print(out, "{}\n", msgsize > 0 ? msg : ""); + fflush(out); +} + +Model::Model(const Env &env) +{ + init(env); + + // The default behavior expected by POI differ a bit from Xpress default behavior. Here we + // adjust some controls: + + // Verbose by default, the user can silence if needed + set_raw_control_int_by_id(XPRS_OUTPUTLOG, 1); + + // Register a message callback (can be overridden) + _check(XPRSaddcbmessage(m_model.get(), &default_print, nullptr, 0)); + is_default_message_cb_set = true; + + // We do not support concurrent CBs invocation since each callback have to acquire Python GIL + _check(XPRSsetintcontrol64(m_model.get(), XPRS_MUTEXCALLBACKS, 1)); + + // Use global solver if the model contains non linear formulas + set_raw_control_int_by_id(XPRS_NLPSOLVER, XPRS_NLPSOLVER_GLOBAL); +} + +void Model::init(const Env &env) +{ + if (!xpress::is_library_loaded()) + { + throw std::runtime_error("Xpress library is not loaded"); + } + if (auto lg = std::lock_guard(Env::mtx); Env::init_count <= 0) + { + throw std::runtime_error("Xpress environment is not initialized"); + } + XPRSprob prob = nullptr; + _check(XPRScreateprob(&prob)); + m_model.reset(prob); + _clear_caches(); +} + +XPRSprob Model::_toggle_model_mode(XPRSprob model) +{ + if (m_mode == XPRESS_MODEL_MODE::MAIN) + { + m_mode = XPRESS_MODEL_MODE::CALLBACK; + } + else + { + m_mode = XPRESS_MODEL_MODE::MAIN; + } + XPRSprob old = m_model.release(); + m_model.reset(model); + return old; +} + +Model::~Model() +try +{ + close(); +} +catch (std::exception e) +{ + fmt::print(stderr, "{}\n", e.what()); + fflush(stderr); +} + +void Model::close() +{ + // In CALLBACK mode we cannot destroy the problem, we release the unique_ptr instead + if (m_mode == XPRESS_MODEL_MODE::CALLBACK) + { + [[maybe_unused]] auto _ = m_model.release(); + } + else + { + m_model.reset(); + } +} + +void Model::_clear_caches() +{ + m_primal_ray.clear(); + m_dual_ray.clear(); + m_iis_cols.clear(); + m_iss_rows.clear(); + m_iis_bound_types.clear(); +} + +double Model::get_infinity() +{ + return XPRS_PLUSINFINITY; +} + +void Model::write(const std::string &filename) +{ + // Detect if the file should be compressed by looking at the last file + // extension. We exploit short-circuiting and fold expressions to avoid long + // else if branches. + auto find_compress_ext_len = [&](auto &...extensions) { + size_t ext_len = 0; + ((filename.ends_with(extensions) && (ext_len = sizeof extensions - 1)) || ...); + return ext_len; + }; + size_t compress_ext_len = find_compress_ext_len(".gz", ".zip", ".tar", ".tgz", ".bz2", ".bzip", + ".7z", ".xz", ".lz4", ".Z"); + std::string_view fname = filename; + fname.remove_suffix(compress_ext_len); + + // Based on the second last extension, we deduce what the user wants. + if (fname.ends_with(".mps")) + { + _check(XPRSwriteprob(m_model.get(), filename.c_str(), "v")); + } + else if (fname.ends_with(".lp")) + { + _check(XPRSwriteprob(m_model.get(), filename.c_str(), "lv")); + } + else if (fname.ends_with(".bss")) + { + _check(XPRSwritebasis(m_model.get(), filename.c_str(), "v")); + } + else if (fname.ends_with(".hdr") || fname.ends_with(".asc")) + { + _check(XPRSwritesol(m_model.get(), filename.c_str(), "v")); + } + else if (fname.ends_with(".sol")) + { + _check(XPRSwritebinsol(m_model.get(), filename.c_str(), "v")); + } + else if (fname.ends_with(".prt")) + { + _check(XPRSwriteprtsol(m_model.get(), filename.c_str(), "v")); + } + else if (fname.ends_with(".slx")) + { + _check(XPRSwriteslxsol(m_model.get(), filename.c_str(), "v")); + } + else if (fname.ends_with(".svf")) + { + _check(XPRSsaveas(m_model.get(), filename.c_str())); + } + else + { + throw std::runtime_error("Unknow file extension"); + } +} + +std::string Model::get_problem_name() +{ + int size = get_raw_attribute_int_by_id(XPRS_MAXPROBNAMELENGTH) + 1; + std::string probname; + probname.resize(size); + _check(XPRSgetprobname(m_model.get(), probname.data())); + // Align string size with string length + probname.resize(strlen(probname.c_str())); + return probname; +} + +void Model::set_problem_name(const std::string &probname) +{ + _check(XPRSsetprobname(m_model.get(), probname.c_str())); +} + +VariableIndex Model::add_variable(VariableDomain domain, double lb, double ub, const char *name) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + IndexT index = m_variable_index.add_index(); + VariableIndex variable(index); + + double zero[] = {0.0}; + int colidx = get_raw_attribute_int_by_id(XPRS_COLS); + _check(XPRSaddcols64(m_model.get(), 1, 0, zero, nullptr, nullptr, nullptr, &lb, &ub)); + _set_entity_name(XPRS_NAMES_COLUMN, colidx, name); + char vtype = poi_to_xprs_var_type(domain); + if (domain != VariableDomain::Continuous) + { + char vtype = poi_to_xprs_var_type(domain); + int icol = colidx; + _check(XPRSchgcoltype(m_model.get(), 1, &icol, &vtype)); + } + return variable; +} + +void Model::delete_variable(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + if (!is_variable_active(variable)) + { + throw std::runtime_error("Variable does not exist"); + } + int colidx = _variable_index(variable); + _check(XPRSdelcols(m_model.get(), 1, &colidx)); + m_variable_index.delete_index(variable.index); +} + +void Model::delete_variables(const Vector &variables) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int n_variables = variables.size(); + if (n_variables == 0) + return; + + std::vector columns; + columns.reserve(n_variables); + for (int i = {}; i < n_variables; i++) + { + if (!is_variable_active(variables[i])) + { + continue; + } + auto column = _variable_index(variables[i]); + columns.push_back(column); + } + _check(XPRSdelcols(m_model.get(), columns.size(), columns.data())); + + for (int i = {}; i < n_variables; i++) + { + m_variable_index.delete_index(variables[i].index); + } +} + +bool Model::is_variable_active(VariableIndex variable) +{ + return m_variable_index.has_index(variable.index); +} + +std::string Model::pprint_variable(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + return get_variable_name(variable); +} + +std::string Model::_get_entity_name(int etype, int eidx) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int req_size = {}; + _check(XPRSgetnamelist(m_model.get(), etype, nullptr, 0, &req_size, eidx, eidx)); + + // Small string opt for temporary string + char buffer[64]; + char *value = buffer; + if (req_size > sizeof buffer) + { + value = (char *)malloc(req_size); + } + Defer value_cleanup = [&] { + if (req_size > sizeof buffer) + { + free(value); + } + }; + + _check(XPRSgetnamelist(m_model.get(), etype, value, req_size, &req_size, eidx, eidx)); + + assert(value[req_size - 1] == '\0'); + std::string res(value); + return res; +} + +std::string Model::get_variable_name(VariableIndex variable) +{ + int colidx = _checked_variable_index(variable); + return _get_entity_name(XPRS_NAMES_COLUMN, colidx); +} + +std::string Model::get_constraint_name(ConstraintIndex constraint) +{ + int rowidx = _checked_constraint_index(constraint); + return _get_entity_name(XPRS_NAMES_ROW, rowidx); +} + +void Model::set_variable_bounds(VariableIndex variable, double lb, double ub) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int column = _checked_variable_index(variable); + int columns[] = {column, column}; + char btypes[] = "LU"; + double bounds[] = {lb, ub}; + _check(XPRSchgbounds(m_model.get(), 2, columns, btypes, bounds)); +} + +void Model::set_variable_lowerbound(VariableIndex variable, double lb) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int colidx = _checked_variable_index(variable); + _check(XPRSchgbounds(m_model.get(), 1, &colidx, "L", &lb)); +} + +void Model::set_variable_upperbound(VariableIndex variable, double ub) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int colidx = _checked_variable_index(variable); + _check(XPRSchgbounds(m_model.get(), 1, &colidx, "U", &ub)); +} + +void Model::set_variable_type(VariableIndex variable, VariableDomain vdomain) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int colidx = _checked_variable_index(variable); + char vtype = poi_to_xprs_var_type(vdomain); + _check(XPRSchgcoltype(m_model.get(), 1, &colidx, &vtype)); +} + +void Model::_set_entity_name(int etype, int index, const char *name) +{ + if (name == nullptr || name[0] == '\0') + { + return; + } + _check(XPRSaddnames(m_model.get(), etype, name, index, index)); +} + +void Model::add_mip_start(const std::vector &variables, + const std::vector &values) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + if (variables.size() != values.size()) + { + throw std::runtime_error("Number of variables and values do not match"); + } + int numnz = variables.size(); + if (numnz == 0) + { + return; + } + + std::vector ind_v(numnz); + for (int i = {}; i < numnz; i++) + { + ind_v[i] = _checked_variable_index(variables[i].index); + } + _check(XPRSaddmipsol(m_model.get(), numnz, values.data(), ind_v.data(), nullptr)); +} + +void Model::set_variable_name(VariableIndex variable, const char *name) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int column = _checked_variable_index(variable); + _set_entity_name(XPRS_NAMES_COLUMN, column, name); +} + +void Model::set_constraint_name(ConstraintIndex constraint, const char *name) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int row = _checked_constraint_index(constraint); + _set_entity_name(XPRS_NAMES_ROW, row, name); +} + +ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &function, + const std::tuple &interval, + const char *name) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + auto [lb, ub] = interval; + double constant = static_cast(function.constant.value_or(CoeffT{})); + lb = std::clamp(lb - constant, XPRS_MINUSINFINITY, XPRS_PLUSINFINITY); + ub = std::clamp(ub - constant, XPRS_MINUSINFINITY, XPRS_PLUSINFINITY); + if (lb > ub - 1e-10) + { + throw std::runtime_error("LB > UB in the provieded interval."); + } + + // Handle infinity bounds + bool lb_inf = lb <= XPRS_MINUSINFINITY; + bool ub_inf = ub >= XPRS_PLUSINFINITY; + + // Determine constraint type and parameters + char g_sense = {}; + double g_rhs = {}; + double range_val = {}; + const double *g_range = {}; + + if (lb_inf && ub_inf) + { + g_sense = 'N'; // Free row + g_rhs = 0.0; + } + else if (lb_inf) + { + g_sense = 'L'; + g_rhs = ub; + } + else if (ub_inf) + { + g_sense = 'G'; + g_rhs = lb; + } + else if (std::abs(ub - lb) < 1e-10) + { + g_sense = 'E'; + g_rhs = ub; + } + else + { + g_sense = 'R'; + g_rhs = ub; + range_val = ub - lb; + g_range = &range_val; + } + + IndexT index = m_constraint_index.add_index(); + ConstraintIndex constraint_index(ConstraintType::Linear, index); + int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + + AffineFunctionPtrForm ptr_form; + ptr_form.make(this, function); + int numnz = ptr_form.numnz; + XPRSint64 beg[] = {0}; + const int *cind = ptr_form.index; + const double *cval = ptr_form.value; + + _check(XPRSaddrows64(m_model.get(), 1, numnz, &g_sense, &g_rhs, g_range, beg, cind, cval)); + _set_entity_name(XPRS_NAMES_ROW, rowidx, name); + + return constraint_index; +} + +ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &function, + ConstraintSense sense, CoeffT rhs, const char *name) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + IndexT index = m_constraint_index.add_index(); + ConstraintIndex constraint_index(ConstraintType::Linear, index); + int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + + AffineFunctionPtrForm ptr_form; + ptr_form.make(this, function); + int numnz = ptr_form.numnz; + + double g_rhs = static_cast(rhs - function.constant.value_or(CoeffT{})); + g_rhs = std::clamp(g_rhs, XPRS_MINUSINFINITY, XPRS_PLUSINFINITY); + + // Map expr >= -inf and expr <= +inf to free rows + char g_sense = poi_to_xprs_cons_sense(sense); + if ((g_sense == 'G' && g_rhs <= XPRS_MINUSINFINITY) || + (g_sense == 'L' && g_rhs >= XPRS_PLUSINFINITY)) + { + g_sense = 'N'; // Free row + g_rhs = 0.0; + } + + XPRSint64 beg[] = {0}; + const int *cind = ptr_form.index; + const double *cval = ptr_form.value; + _check(XPRSaddrows64(m_model.get(), 1, numnz, &g_sense, &g_rhs, nullptr, beg, cind, cval)); + _set_entity_name(XPRS_NAMES_ROW, rowidx, name); + + return constraint_index; +} + +static QuadraticFunctionPtrForm poi_to_xprs_quad_formula( + Model &model, const ScalarQuadraticFunction &function, bool is_objective) +{ + QuadraticFunctionPtrForm ptr_form; + ptr_form.make(&model, function); + int numqnz = ptr_form.numnz; + + // Xpress uses different quadratic representations for objectives vs constraints: + // + // OBJECTIVES: Use 0.5*x'Qx form with automatic symmetry. + // - Diagonal terms (i,i): Need 2× multiplication to compensate for the 0.5 factor + // - Off-diagonal terms (i,j): Used as-is; Xpress automatically mirrors to (j,i) + // + // CONSTRAINTS: Use x'Qx form with upper-triangular specification. + // - Diagonal terms (i,i): Used as-is + // - Off-diagonal terms (i,j): Need 0.5× division; Xpress expects coefficients + // for the upper triangular part only, which will be mirrored + // + // PyOptInterface provides coefficients in the standard x'Qx form through + // QuadraticFunctionPtrForm, so we adjust based on whether this is for an objective function or + // a constraint. + + // Copy coefficients (ptr_form.value may reference function.coefficients directly) + if (ptr_form.value_storage.empty()) + { + ptr_form.value_storage.reserve(numqnz); + for (CoeffT c : function.coefficients) + { + ptr_form.value_storage.push_back(static_cast(c)); + } + } + + // Apply Xpress-specific coefficient adjustments + for (int i = 0; i < numqnz; ++i) + { + if (is_objective && (ptr_form.row[i] == ptr_form.col[i])) + { + // Objective diagonal terms: multiply by 2 for 0.5*x'Qx convention + ptr_form.value_storage[i] *= 2.0; + } + if (!is_objective && (ptr_form.row[i] != ptr_form.col[i])) + { + // Constraint off-diagonal terms: divide by 2 for upper-triangular specification + ptr_form.value_storage[i] /= 2.0; + } + } + + ptr_form.value = ptr_form.value_storage.data(); + return ptr_form; +} + +// Quadratic constraints are regular rows with a quadratic term. +ConstraintIndex Model::add_quadratic_constraint(const ScalarQuadraticFunction &function, + ConstraintSense sense, CoeffT rhs, const char *name) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + + const auto &affine_part = function.affine_part.value_or(ScalarAffineFunction{}); + ConstraintIndex constraint_index = add_linear_constraint(affine_part, sense, rhs, name); + constraint_index.type = ConstraintType::Quadratic; // Fix constraint type + + // Add quadratic term + QuadraticFunctionPtrForm ptr_form = + poi_to_xprs_quad_formula(*this, function, false); + int numqnz = ptr_form.numnz; + const int *qrow = ptr_form.row; + const int *qcol = ptr_form.col; + const double *qval = ptr_form.value; + + _check(XPRSaddqmatrix64(m_model.get(), rowidx, numqnz, qrow, qcol, qval)); + ++m_quad_nl_constr_num; + return constraint_index; +} + +ConstraintIndex Model::add_second_order_cone_constraint(const Vector &variables, + const char *name, bool rotated) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int rot_offset = rotated ? 1 : 0; + if (variables.size() <= rot_offset) + { + throw std::runtime_error("Not enough variables in SOC constraint."); + } + + // SOC: 1 x_0 x_0 >= \sum_{i : [1,N)} x_i^2 + // Rotated SOC: 2 x_0 x_1 >= \sum_{i : [2,N)} x_i^2 + ScalarQuadraticFunction quadconstr; + quadconstr.add_quadratic_term(variables[0], variables[rot_offset], 1.0 + rot_offset); + for (int i = 1 + rot_offset; i < variables.size(); ++i) + { + quadconstr.add_quadratic_term(variables[i], variables[i], -1.0); + } + ConstraintIndex constraint_index = + add_quadratic_constraint(quadconstr, ConstraintSense::GreaterEqual, 0.0, name); + constraint_index.type = ConstraintType::Cone; + return constraint_index; +} + +namespace +{ +template +struct NlpArrays +{ + int types[N]; + double values[N]; +}; +} // namespace + +ConstraintIndex Model::add_exp_cone_constraint(const Vector &variables, + const char *name, bool dual) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + if (variables.size() != 3) + { + throw std::runtime_error("Exponential cone constraint must have 3 variables"); + } + + // Add affine part + auto constraint_index = + add_linear_constraint_from_var(variables[0], ConstraintSense::GreaterEqual, 0.0); + constraint_index.type = ConstraintType::Xpress_Nlp; // Fix constraint type + + int nnz = 0; + const int *types = {}; + const double *values = {}; + double var1_idx = static_cast(_checked_variable_index(variables[1])); + double var2_idx = static_cast(_checked_variable_index(variables[2])); + + int rowidx = _constraint_index(constraint_index); + + // Syntactic sugar to make hand written NLP formulas more readable + auto make_type_value_arrays = [](auto... terms) { + return NlpArrays{{terms.type...}, {terms.value...}}; + }; + if (dual) + { + // linear_term + x_2 * exp(x_1 / x_2 - 1) >= 0 + auto [types, values] = make_type_value_arrays( // + Tvp{XPRS_TOK_COL, var2_idx}, // x_2 + Tvp{XPRS_TOK_RB, {}}, // ) + Tvp{XPRS_TOK_COL, var1_idx}, // x_1 + Tvp{XPRS_TOK_COL, var2_idx}, // x_2 + Tvp{XPRS_TOK_OP, XPRS_OP_DIVIDE}, // / + Tvp{XPRS_TOK_CON, 1.0}, // 1.0 + Tvp{XPRS_TOK_OP, XPRS_OP_MINUS}, // - + Tvp{XPRS_TOK_IFUN, XPRS_IFUN_EXP}, // exp( + Tvp{XPRS_TOK_OP, XPRS_OP_MULTIPLY}, // * + Tvp{XPRS_TOK_EOF, {}}); // EOF + + int begs[] = {0, std::ssize(types)}; + _check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types, values)); + } + else + { + // linear_term - x_1 * exp(x_2 / x_1) >= 0 + auto [types, values] = make_type_value_arrays( // + Tvp{XPRS_TOK_COL, var1_idx}, // x_1 + Tvp{XPRS_TOK_RB, {}}, // ) + Tvp{XPRS_TOK_COL, var2_idx}, // x_2 + Tvp{XPRS_TOK_COL, var1_idx}, // x_1 + Tvp{XPRS_TOK_OP, XPRS_OP_DIVIDE}, // / + Tvp{XPRS_TOK_IFUN, XPRS_IFUN_EXP}, // exp( + Tvp{XPRS_TOK_OP, XPRS_OP_MULTIPLY}, // * + Tvp{XPRS_TOK_OP, XPRS_OP_UMINUS}, // - + Tvp{XPRS_TOK_EOF, {}}); // EOF + + int begs[] = {0, std::ssize(types)}; + _check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types, values)); + } + + ++m_quad_nl_constr_num; + return constraint_index; +} + +ConstraintIndex Model::_add_sos_constraint(const Vector &variables, SOSType sos_type, + const Vector &weights) +{ + IndexT index = m_sos_constraint_index.add_index(); + ConstraintIndex constraint_index(ConstraintType::SOS, index); + + const int nnz = variables.size(); + const char type[] = {poi_to_xprs_sos_type(sos_type)}; + const XPRSint64 beg[] = {0}; + std::vector ind_v(nnz); + for (int i = 0; i < nnz; i++) + { + ind_v[i] = _checked_variable_index(variables[i]); + } + _check(XPRSaddsets64(m_model.get(), 1, nnz, type, beg, ind_v.data(), weights.data())); + return constraint_index; +} + +ConstraintIndex Model::add_sos_constraint(const Vector &variables, SOSType sos_type) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + Vector weights(variables.size()); + std::iota(weights.begin(), weights.end(), 1.0); + return _add_sos_constraint(variables, sos_type, weights); +} + +ConstraintIndex Model::add_sos_constraint(const Vector &variables, SOSType sos_type, + const Vector &weights) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + // If CoeffT will ever be not a double, we need to convert weights + if constexpr (std::is_same_v) + { + std::vector double_weights; + double_weights.reserve(weights.size()); + for (CoeffT w : weights) + { + double_weights.push_back(static_cast(w)); + } + return _add_sos_constraint(variables, sos_type, double_weights); + } + else + { + return _add_sos_constraint(variables, sos_type, weights); + } +} + +Tvp to_xprs_opcode(UnaryOperator opcode_enum) +{ + switch (opcode_enum) + { + case UnaryOperator::Neg: + return {XPRS_TOK_OP, XPRS_OP_UMINUS}; + case UnaryOperator::Sin: + return {XPRS_TOK_IFUN, XPRS_IFUN_SIN}; + case UnaryOperator::Cos: + return {XPRS_TOK_IFUN, XPRS_IFUN_COS}; + case UnaryOperator::Tan: + return {XPRS_TOK_IFUN, XPRS_IFUN_TAN}; + case UnaryOperator::Asin: + return {XPRS_TOK_IFUN, XPRS_IFUN_ARCSIN}; + case UnaryOperator::Acos: + return {XPRS_TOK_IFUN, XPRS_IFUN_ARCCOS}; + case UnaryOperator::Atan: + return {XPRS_TOK_IFUN, XPRS_IFUN_ARCTAN}; + case UnaryOperator::Abs: + return {XPRS_TOK_IFUN, XPRS_IFUN_ABS}; + case UnaryOperator::Sqrt: + return {XPRS_TOK_IFUN, XPRS_IFUN_SQRT}; + case UnaryOperator::Exp: + return {XPRS_TOK_IFUN, XPRS_IFUN_EXP}; + case UnaryOperator::Log: + return {XPRS_TOK_IFUN, XPRS_IFUN_LOG}; + case UnaryOperator::Log10: + return {XPRS_TOK_IFUN, XPRS_IFUN_LOG10}; + default: { + auto opname = unary_operator_to_string(opcode_enum); + auto msg = fmt::format("Unknown unary operator for Xpress: {}", opname); + throw std::runtime_error(msg); + } + } +} + +Tvp to_xprs_opcode(BinaryOperator opcode_enum) +{ + switch (opcode_enum) + { + case BinaryOperator::Sub: + return {XPRS_TOK_OP, XPRS_OP_MINUS}; + case BinaryOperator::Div: + return {XPRS_TOK_OP, XPRS_OP_DIVIDE}; + case BinaryOperator::Pow: + return {XPRS_TOK_OP, XPRS_OP_EXPONENT}; + case BinaryOperator::Add2: + return {XPRS_TOK_OP, XPRS_OP_PLUS}; + case BinaryOperator::Mul2: + return {XPRS_TOK_OP, XPRS_OP_MULTIPLY}; + default: + auto opname = binary_operator_to_string(opcode_enum); + auto msg = fmt::format("Unknown unary operator for Xpress: {}", opname); + throw std::runtime_error(msg); + } +} + +Tvp to_xprs_opcode(TernaryOperator opcode_enum) +{ + auto opname = ternary_operator_to_string(opcode_enum); + auto msg = fmt::format("Unknown unary operator for Xpress: {}", opname); + throw std::runtime_error(msg); +} + +Tvp to_xprs_opcode(NaryOperator opcode_enum) +{ + switch (opcode_enum) + { + case NaryOperator::Add: + return {XPRS_TOK_OP, XPRS_OP_PLUS}; + case NaryOperator::Mul: + return {XPRS_TOK_OP, XPRS_OP_MULTIPLY}; + default: + auto opname = nary_operator_to_string(opcode_enum); + auto msg = fmt::format("Unknown nary operator for Xpress: {}", opname); + throw std::runtime_error(msg); + } +} + +BinaryOperator nary_to_binary_op(NaryOperator opcode_enum) +{ + switch (opcode_enum) + { + case NaryOperator::Add: + return BinaryOperator::Add2; + case NaryOperator::Mul: + return BinaryOperator::Mul2; + default: { + auto opname = nary_operator_to_string(opcode_enum); + auto msg = fmt::format("Unknown nary operator for Xpress: {}", opname); + throw std::runtime_error(msg); + } + } +} + +Tvp Model::_decode_expr(const ExpressionGraph &graph, const ExpressionHandle &expr) +{ + auto array_type = expr.array; + auto index = expr.id; + + switch (array_type) + { + case ArrayType::Constant: + return {XPRS_TOK_CON, static_cast(graph.m_constants[index])}; + case ArrayType::Variable: + return {XPRS_TOK_COL, + static_cast(_checked_variable_index(graph.m_variables[index]))}; + case ArrayType::Parameter: + break; + case ArrayType::Unary: + return to_xprs_opcode(graph.m_unaries[index].op); + case ArrayType::Binary: + return to_xprs_opcode(graph.m_binaries[index].op); + case ArrayType::Ternary: + return to_xprs_opcode(graph.m_ternaries[index].op); + case ArrayType::Nary: + return to_xprs_opcode(graph.m_naries[index].op); + defaut: + break; + } + throw std::runtime_error("Not supported expression."); +} + +ExpressionHandle nary_to_binary(ExpressionGraph &graph, const ExpressionHandle &expr) +{ + auto &nary = graph.m_naries[expr.id]; + NaryOperator n_op = nary.op; + BinaryOperator bin_opcode = nary_to_binary_op(n_op); + int n_operands = nary.operands.size(); + if (n_operands == 0 || (n_op != NaryOperator::Add && n_op != NaryOperator::Mul)) + { + return expr; + } + + auto new_expr = nary.operands[0]; + for (int i = 1; i < n_operands; ++i) + { + new_expr = graph.add_binary(bin_opcode, new_expr, nary.operands[i]); + } + return new_expr; +} + +std::pair, std::vector> Model::_decode_graph_postfix_order( + ExpressionGraph &graph, const ExpressionHandle &result) +{ + std::vector types; + std::vector values; + + // Xpress uses a reversed Polish notation (post fix). So we need to visit the expression tree + // in post-order depth first. We keep a stack to go depth first and visit each element + // twice. First time process its children, second time decode it. + std::stack> expr_stack; + expr_stack.emplace(result, true); + + while (!expr_stack.empty()) + { + auto &[expr, visit_children] = expr_stack.top(); + auto [type, value] = _decode_expr(graph, expr); + + // If its children have already been processed and we can add it to the expression + if (!visit_children) + { + types.push_back(type); + values.push_back(value); + expr_stack.pop(); + continue; + } + + // Xpress requires a parenthesis to start an internal or user function + if (type == XPRS_TOK_IFUN || type == XPRS_TOK_FUN) + { + types.push_back(XPRS_TOK_RB); + values.push_back({}); + } + + switch (expr.array) + { + case ArrayType::Constant: + case ArrayType::Variable: + break; + case ArrayType::Unary: + expr_stack.emplace(graph.m_unaries[expr.id].operand, true); + break; + case ArrayType::Nary: + // Xpress does not have nary operators out of the box, we have to translate them into a + // sequence of binary operators + expr = nary_to_binary(graph, expr); + [[fallthrough]]; + case ArrayType::Binary: + expr_stack.emplace(graph.m_binaries[expr.id].right, true); + expr_stack.emplace(graph.m_binaries[expr.id].left, true); + break; + default: + throw std::runtime_error("Unrecognized token."); + } + + // Children has been processed and added to the stack, next time we'll add it to the + // expression. + visit_children = false; + } + + types.push_back(XPRS_TOK_EOF); + values.push_back({}); + return {std::move(types), std::move(values)}; +} + +ConstraintIndex Model::add_single_nl_constraint(ExpressionGraph &graph, + const ExpressionHandle &result, + const std::tuple &interval, + const char *name) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + ConstraintIndex constraint = add_linear_constraint(ScalarAffineFunction{}, interval, name); + constraint.type = ConstraintType::Xpress_Nlp; + + auto [types, values] = _decode_graph_postfix_order(graph, result); + + int nnz = values.size(); + int begs[] = {0, nnz}; + _check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types.data(), values.data())); + ++m_quad_nl_constr_num; + return constraint; +} + +void Model::delete_constraint(ConstraintIndex constraint) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + if (!is_constraint_active(constraint)) + { + throw std::runtime_error("Constraint does not exist"); + } + + int constraint_row = _checked_constraint_index(constraint); + if (constraint_row >= 0) + { + switch (constraint.type) + { + case ConstraintType::Quadratic: + case ConstraintType::Cone: + case ConstraintType::Xpress_Nlp: + --m_quad_nl_constr_num; + [[fallthrough]]; + case ConstraintType::Linear: + m_constraint_index.delete_index(constraint.index); + _check(XPRSdelrows(m_model.get(), 1, &constraint_row)); + break; + case ConstraintType::SOS: + m_sos_constraint_index.delete_index(constraint.index); + _check(XPRSdelsets(m_model.get(), 1, &constraint_row)); + break; + default: + throw std::runtime_error("Unknown constraint type"); + } + } +} + +bool Model::is_constraint_active(ConstraintIndex constraint) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + switch (constraint.type) + { + case ConstraintType::Linear: + case ConstraintType::Quadratic: + case ConstraintType::Cone: + case ConstraintType::Xpress_Nlp: + return m_constraint_index.has_index(constraint.index); + case ConstraintType::SOS: + return m_sos_constraint_index.has_index(constraint.index); + default: + throw std::runtime_error("Unknown constraint type"); + } + return false; +} + +void Model::set_objective(const ScalarAffineFunction &function, ObjectiveSense sense) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + // Delete linear and quadratic term of the objective function + _check(XPRSdelobj(m_model.get(), 0)); + _check(XPRSdelqmatrix(m_model.get(), -1)); + has_quad_objective = false; + if (has_nlp_objective) + { + delete_constraint(m_nlp_obj_constraint); + delete_variable(m_nlp_obj_variable); + has_nlp_objective = false; + } + + if (function.size() > 0) + { + AffineFunctionPtrForm ptr_form; + ptr_form.make(this, function); + int numnz = ptr_form.numnz; + const int *cind = ptr_form.index; + const double *cval = ptr_form.value; + _check(XPRSchgobj(m_model.get(), numnz, cind, cval)); + } + if (function.constant.has_value()) + { + int obj_constant_magic_index = -1; + double obj_constant = -static_cast(function.constant.value()); + _check(XPRSchgobj(m_model.get(), 1, &obj_constant_magic_index, &obj_constant)); + } + int stype = poi_to_xprs_obj_sense(sense); + _check(XPRSchgobjsense(m_model.get(), stype)); +} + +// Set quadratic objective function, replacing any previous objective. +// Handles Xpress's symmetric matrix convention where off-diagonal terms are doubled. +void Model::set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense) +{ + // Set affine part (also clears any previous quadratic terms) + const auto &affine_part = function.affine_part.value_or(ScalarAffineFunction{}); + set_objective(affine_part, sense); + + // Add quadratic terms if present + if (function.size() > 0) + { + QuadraticFunctionPtrForm ptr_form = + poi_to_xprs_quad_formula(*this, function, true); + int numqnz = ptr_form.numnz; + const int *qrow = ptr_form.row; + const int *qcol = ptr_form.col; + const double *qval = ptr_form.value; + _check(XPRSchgmqobj64(m_model.get(), numqnz, qrow, qcol, qval)); + has_quad_objective = true; + } +} + +void Model::set_objective(const ExprBuilder &function, ObjectiveSense sense) +{ + auto deg = function.degree(); + if (deg <= 1) + { + ScalarAffineFunction f(function); + set_objective(f, sense); + } + else if (deg == 2) + { + ScalarQuadraticFunction f(function); + set_objective(f, sense); + } + else + { + throw std::runtime_error("Objective must be linear or quadratic"); + } +} + +void Model::add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + if (!has_nlp_objective) + { + has_nlp_objective = true; + m_nlp_obj_variable = add_variable(); + m_nlp_obj_constraint = add_linear_constraint(ScalarAffineFunction(m_nlp_obj_variable, -1.0), + ConstraintSense::Equal, 0.0, NULL); + set_objective_coefficient(m_nlp_obj_variable, 1.0); + } + + auto [types, values] = _decode_graph_postfix_order(graph, result); + int nnz = values.size(); + int begs[] = {0, nnz}; + int rowidx = _constraint_index(m_nlp_obj_constraint); + _check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types.data(), values.data())); +} + +double Model::get_normalized_rhs(ConstraintIndex constraint) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + double rhs = {}; + int rowidx = _checked_constraint_index(constraint); + _check(XPRSgetrhs(m_model.get(), &rhs, rowidx, rowidx)); + return rhs; +} + +void Model::set_normalized_rhs(ConstraintIndex constraint, double value) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int rowidx = _checked_constraint_index(constraint); + _check(XPRSchgrhs(m_model.get(), 1, &rowidx, &value)); +} + +double Model::get_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int rowidx = _checked_constraint_index(constraint); + int colidx = _checked_variable_index(variable); + double coeff = {}; + _check(XPRSgetcoef(m_model.get(), rowidx, colidx, &coeff)); + return coeff; +} +void Model::set_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable, + double value) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int rowidx = _checked_constraint_index(constraint); + int colidx = _checked_variable_index(variable); + _check(XPRSchgcoef(m_model.get(), rowidx, colidx, value)); +} + +double Model::get_objective_coefficient(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int colidx = _checked_variable_index(variable); + double coeff = {}; + _check(XPRSgetobj(m_model.get(), &coeff, colidx, colidx)); + return coeff; +} +void Model::set_objective_coefficient(VariableIndex variable, double value) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + _clear_caches(); + + int colidx = _checked_variable_index(variable); + _check(XPRSchgobj(m_model.get(), 1, &colidx, &value)); +} + +int Model::_constraint_index(ConstraintIndex constraint) +{ + switch (constraint.type) + { + case ConstraintType::Linear: + case ConstraintType::Quadratic: + case ConstraintType::Cone: + case ConstraintType::Xpress_Nlp: + return m_constraint_index.get_index(constraint.index); + case ConstraintType::SOS: + return m_sos_constraint_index.get_index(constraint.index); + default: + throw std::runtime_error("Unknown constraint type"); + } +} + +int Model::_variable_index(VariableIndex variable) +{ + return m_variable_index.get_index(variable.index); +} + +int Model::_checked_constraint_index(ConstraintIndex constraint) +{ + int rowidx = _constraint_index(constraint); + if (rowidx < 0) + { + throw std::runtime_error("Constraint does not exists"); + } + return rowidx; +} + +int Model::_checked_variable_index(VariableIndex variable) +{ + int colidx = _variable_index(variable); + if (colidx < 0) + { + throw std::runtime_error("Variable does not exists"); + } + return colidx; +} + +bool Model::_is_mip() +{ + return get_raw_attribute_int_by_id(XPRS_MIPENTS) > 0 || + get_raw_attribute_int_by_id(XPRS_SETS) > 0; +} + +void Model::optimize() +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _clear_caches(); + + int stop_status = 0; + _check(XPRSoptimize(m_model.get(), "", &stop_status, nullptr)); + m_need_postsolve = (stop_status == XPRS_SOLVESTATUS_STOPPED); +} + +double Model::get_variable_value(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + int colidx = _checked_variable_index(variable); + int status = XPRS_SOLAVAILABLE_NOTFOUND; + double value = {}; + _check(XPRSgetsolution(m_model.get(), &status, &value, colidx, colidx)); + if (status == XPRS_SOLAVAILABLE_NOTFOUND) + { + throw std::runtime_error("No solution found"); + } + return value; +} + +double Model::get_variable_rc(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + int colidx = _checked_variable_index(variable); + int status = XPRS_SOLAVAILABLE_NOTFOUND; + double value = {}; + _check(XPRSgetredcosts(m_model.get(), &status, &value, colidx, colidx)); + if (status == XPRS_SOLAVAILABLE_NOTFOUND) + { + throw std::runtime_error("No solution found"); + } + return value; +} + +double Model::get_variable_primal_ray(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + if (m_primal_ray.empty()) + { + int has_ray = 0; + _check(XPRSgetprimalray(m_model.get(), nullptr, &has_ray)); + if (has_ray == 0) + { + throw std::runtime_error("Primal ray not available"); + } + m_primal_ray.resize(get_raw_attribute_int_by_id(XPRS_COLS)); + _check(XPRSgetprimalray(m_model.get(), m_primal_ray.data(), &has_ray)); + assert(has_ray != 0); + } + + int colidx = _checked_variable_index(variable); + return m_primal_ray[colidx]; +} + +int Model::_get_basis_stat(int entity_idx, bool is_row) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int entity_stat = {}; + if (is_row) + { + _check(XPRSgetbasisval(m_model.get(), entity_idx, 0, &entity_stat, nullptr)); + } + else + { + _check(XPRSgetbasisval(m_model.get(), 0, entity_idx, nullptr, &entity_stat)); + } + return entity_stat; +} + +bool Model::is_variable_basic(VariableIndex variable) +{ + return _get_basis_stat(_checked_variable_index(variable), false) == XPRS_BASISSTATUS_BASIC; +} + +bool Model::is_variable_nonbasic_lb(VariableIndex variable) +{ + return _get_basis_stat(_checked_variable_index(variable), false) == + XPRS_BASISSTATUS_NONBASIC_LOWER; +} + +bool Model::is_variable_nonbasic_ub(VariableIndex variable) +{ + return _get_basis_stat(_checked_variable_index(variable), false) == + XPRS_BASISSTATUS_NONBASIC_UPPER; +} +bool Model::is_variable_superbasic(VariableIndex variable) +{ + return _get_basis_stat(_checked_variable_index(variable), false) == XPRS_BASISSTATUS_SUPERBASIC; +} + +double Model::get_variable_lowerbound(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + double lb = {}; + int colidx = _checked_variable_index(variable); + _check(XPRSgetlb(m_model.get(), &lb, colidx, colidx)); + return lb; +} + +double Model::get_variable_upperbound(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + double ub = {}; + int colidx = _checked_variable_index(variable); + _check(XPRSgetub(m_model.get(), &ub, colidx, colidx)); + return ub; +} + +VariableDomain Model::get_variable_type(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int colidex = _checked_variable_index(variable); + char vtype = {}; + _check(XPRSgetcoltype(m_model.get(), &vtype, colidex, colidex)); + return xprs_to_poi_var_type(vtype); +} + +char Model::_get_variable_bound_IIS(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + if (m_iis_cols.empty() || m_iis_bound_types.empty()) + { + int m_nrows = {}; + int m_ncols = {}; + _check(XPRSgetiisdata(m_model.get(), 1, &m_nrows, &m_ncols, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr)); + + m_iis_cols.resize(m_ncols); + m_iis_bound_types.resize(m_ncols); + _check(XPRSgetiisdata(m_model.get(), 1, &m_nrows, &m_ncols, nullptr, m_iis_cols.data(), + nullptr, m_iis_bound_types.data(), nullptr, nullptr, nullptr, + nullptr)); + } + + int colidx = _checked_variable_index(variable); + for (int j = 0; j < m_iis_cols.size(); ++j) + { + if (m_iis_cols[j] == colidx) + { + return m_iis_bound_types[j]; + } + } + return '\0'; +} + +bool Model::is_variable_lowerbound_IIS(VariableIndex variable) +{ + return _get_variable_bound_IIS(variable) == 'L'; +} + +bool Model::is_variable_upperbound_IIS(VariableIndex variable) +{ + return _get_variable_bound_IIS(variable) == 'U'; +} + +void Model::set_constraint_sense(ConstraintIndex constraint, ConstraintSense sense) +{ + const int rowidx = _checked_constraint_index(constraint); + const char rowtype = poi_to_xprs_cons_sense(sense); + _check(XPRSchgrowtype(m_model.get(), 1, &rowidx, &rowtype)); +} + +ConstraintSense Model::get_constraint_sense(ConstraintIndex constraint) +{ + const int rowidx = _checked_constraint_index(constraint); + char rowtype = {}; + _check(XPRSgetrowtype(m_model.get(), &rowtype, rowidx, rowidx)); + return xprs_to_poi_cons_sense(rowtype); +} + +void Model::set_constraint_rhs(ConstraintIndex constraint, CoeffT rhs) +{ + const int rowidx = _checked_constraint_index(constraint); + const double g_rhs[] = {static_cast(rhs)}; + _check(XPRSchgrhs(m_model.get(), 1, &rowidx, g_rhs)); +} + +CoeffT Model::get_constraint_rhs(ConstraintIndex constraint) +{ + const int rowidx = _checked_constraint_index(constraint); + double rhs = {}; + _check(XPRSgetrhs(m_model.get(), &rhs, rowidx, rowidx)); + return static_cast(rhs); +} + +double Model::get_constraint_slack(ConstraintIndex constraint) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int rowidx = _checked_constraint_index(constraint); + int status = XPRS_SOLAVAILABLE_NOTFOUND; + double value = {}; + _check(XPRSgetslacks(m_model.get(), &status, &value, rowidx, rowidx)); + if (status == XPRS_SOLAVAILABLE_NOTFOUND) + { + throw std::runtime_error("No solution found"); + } + return value; +} + +double Model::get_constraint_dual(ConstraintIndex constraint) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + int rowidx = _checked_constraint_index(constraint); + int status = XPRS_SOLAVAILABLE_NOTFOUND; + double value = {}; + _check(XPRSgetduals(m_model.get(), &status, &value, rowidx, rowidx)); + if (status == XPRS_SOLAVAILABLE_NOTFOUND) + { + throw std::runtime_error("No solution found"); + } + return value; +} + +double Model::get_constraint_dual_ray(ConstraintIndex constraint) +{ + + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + if (m_dual_ray.empty()) + { + int has_ray = 0; + _check(XPRSgetdualray(m_model.get(), nullptr, &has_ray)); + if (has_ray == 0) + { + throw std::runtime_error("Dual ray not available"); + } + m_dual_ray.resize(get_raw_attribute_int_by_id(XPRS_ROWS)); + _check(XPRSgetdualray(m_model.get(), m_dual_ray.data(), &has_ray)); + assert(has_ray != 0); + } + + int rowidx = _checked_constraint_index(constraint); + return m_dual_ray[rowidx]; +} + +bool Model::is_constraint_basic(ConstraintIndex constraint) +{ + return _get_basis_stat(_checked_constraint_index(constraint), true) == XPRS_BASISSTATUS_BASIC; +} + +bool Model::is_constraint_nonbasic_lb(ConstraintIndex constraint) +{ + return _get_basis_stat(_checked_constraint_index(constraint), true) == + XPRS_BASISSTATUS_NONBASIC_LOWER; +} + +bool Model::is_constraint_nonbasic_ub(ConstraintIndex constraint) +{ + return _get_basis_stat(_checked_constraint_index(constraint), true) == + XPRS_BASISSTATUS_NONBASIC_UPPER; +} + +bool Model::is_constraint_superbasic(ConstraintIndex constraint) +{ + return _get_basis_stat(_checked_constraint_index(constraint), true) == + XPRS_BASISSTATUS_SUPERBASIC; +} + +bool Model::is_constraint_in_IIS(ConstraintIndex constraint) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _ensure_postsolved(); + + if (m_iss_rows.empty()) + { + int nrow = {}; + int ncol = {}; + _check(XPRSgetiisdata(m_model.get(), 1, &nrow, &ncol, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr)); + + m_iss_rows.resize(nrow); + _check(XPRSgetiisdata(m_model.get(), 1, &nrow, &ncol, m_iss_rows.data(), nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr)); + } + + int rowidx = _constraint_index(constraint); + for (int ridx : m_iss_rows) + { + if (ridx == rowidx) + { + return true; + } + } + return false; +} + +void *Model::get_raw_model() +{ + return m_model.get(); +} + +std::string Model::version_string() +{ + char buffer[32]; + XPRSgetversion(buffer); + return buffer; +} + +void Model::computeIIS() +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + int status = 0; + + // passing 1 emphasizes simplicity of the IIS + // passing 2 emphasizes a quick result + _check(XPRSiisfirst(m_model.get(), 2, &status)); + switch (status) + { + case 0: + return; + case 1: + throw std::runtime_error("IIS: problem is feasible"); + case 2: + throw std::runtime_error("IIS: generic error"); + case 3: + throw std::runtime_error("IIS: timeout or interruption"); + default: + throw std::runtime_error(fmt::format("IIS: unknown exit status {}", status)); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// ATTRIBUTES AND CONTROLS ACCESS // +//////////////////////////////////////////////////////////////////////////////// + +static const char *xpress_type_to_string(CATypes type) +{ + switch (type) + { + case CATypes::INT: + return "int"; + case CATypes::INT64: + return "int64"; + case CATypes::DOUBLE: + return "double"; + case CATypes::STRING: + return "string"; + default: + return "unknown"; + } +} + +std::pair Model::_get_control_info(const char *control) +{ + int control_id = {}; + int control_type = {}; + _check(XPRSgetcontrolinfo(m_model.get(), control, &control_id, &control_type)); + return std::make_pair(control_id, static_cast(control_type)); +} + +std::pair Model::_get_attribute_info(const char *attrib) +{ + int attrib_id = {}; + int attrib_type = {}; + _check(XPRSgetattribinfo(m_model.get(), attrib, &attrib_id, &attrib_type)); + return std::make_pair(attrib_id, static_cast(attrib_type)); +} + +int Model::_get_checked_control_id(const char *control, CATypes expected, CATypes backup) +{ + auto [id, type] = _get_control_info(control); + if (type == CATypes::NOTDEFINED) + { + throw std::runtime_error("Error, unknown control type."); + } + if (type != expected && type != backup) + { + auto error_msg = fmt::format( + "Error retriving control '{}'. Control type is '{}', but '{}' was expected.", control, + xpress_type_to_string(type), xpress_type_to_string(expected)); + throw std::runtime_error(error_msg); + } + return id; +} + +int Model::_get_checked_attribute_id(const char *attrib, CATypes expected, CATypes backup) +{ + auto [id, type] = _get_attribute_info(attrib); + if (type == CATypes::NOTDEFINED) + { + throw std::runtime_error("Error, unknown attribute type."); + } + if (type != expected) + { + auto error_msg = fmt::format( + "Error retriving attribute '{}'. Attribute type is '{}', but '{}' was expected.", + attrib, xpress_type_to_string(type), xpress_type_to_string(expected)); + throw std::runtime_error(error_msg); + } + return id; +} + +// Generic access to attributes and controls +Model::xprs_type_variant_t Model::get_raw_attribute(const char *attrib) +{ + auto [id, type] = _get_attribute_info(attrib); + switch (type) + { + case CATypes::INT: + case CATypes::INT64: + return get_raw_attribute_int_by_id(id); + case CATypes::DOUBLE: + return get_raw_attribute_dbl_by_id(id); + case CATypes::STRING: + return get_raw_attribute_str_by_id(id); + default: + throw std::runtime_error("Unknown attribute type"); + } +} + +Model::xprs_type_variant_t Model::get_raw_control(const char *control) +{ + auto [id, type] = _get_control_info(control); + switch (type) + { + case CATypes::INT: + case CATypes::INT64: + return get_raw_control_int_by_id(id); + case CATypes::DOUBLE: + return get_raw_control_dbl_by_id(id); + case CATypes::STRING: + return get_raw_control_str_by_id(id); + default: + throw std::runtime_error("Unknown attribute type"); + } +} + +// Helper struct to achieve a sort of pattern matching with the visitor pattern. +// It basically exploit the overload resolution to get the equivalent of a series of +// if constexpr(std::is_same_v) +template +struct OverloadSet : public Ts... +{ + using Ts::operator()...; +}; + +void Model::set_raw_control(const char *control, Model::xprs_type_variant_t &value) +{ + std::visit(OverloadSet{[&](double d) { set_raw_control_dbl(control, d); }, + [&](std::integral auto i) { set_raw_control_int(control, i); }, + [&](const std::string &s) { set_raw_control_str(control, s.c_str()); }}, + value); +} + +void Model::set_raw_control_int(const char *control, XPRSint64 value) +{ + int id = _get_checked_control_id(control, CATypes::INT64, CATypes::INT); + return set_raw_control_int_by_id(id, value); +} + +void Model::set_raw_control_dbl(const char *control, double value) +{ + int id = _get_checked_control_id(control, CATypes::DOUBLE); + return set_raw_control_dbl_by_id(id, value); +} + +void Model::set_raw_control_str(const char *control, const char *value) +{ + int id = _get_checked_control_id(control, CATypes::STRING); + return set_raw_control_str_by_id(id, value); +} + +XPRSint64 Model::get_raw_control_int(const char *control) +{ + int id = _get_checked_control_id(control, CATypes::INT64, CATypes::INT); + return get_raw_control_int_by_id(id); +} + +double Model::get_raw_control_dbl(const char *control) +{ + int id = _get_checked_control_id(control, CATypes::DOUBLE); + return get_raw_control_dbl_by_id(id); +} + +std::string Model::get_raw_control_str(const char *control) +{ + int id = _get_checked_control_id(control, CATypes::STRING); + return get_raw_control_str_by_id(id); +} + +XPRSint64 Model::get_raw_attribute_int(const char *attrib) +{ + int id = _get_checked_attribute_id(attrib, CATypes::INT64, CATypes::INT); + return get_raw_attribute_int_by_id(id); +} + +double Model::get_raw_attribute_dbl(const char *attrib) +{ + int id = _get_checked_attribute_id(attrib, CATypes::DOUBLE); + return get_raw_attribute_dbl_by_id(id); +} + +std::string Model::get_raw_attribute_str(const char *attrib) +{ + int id = _get_checked_attribute_id(attrib, CATypes::STRING); + return get_raw_attribute_str_by_id(id); +} + +void Model::set_raw_control_int_by_id(int control, XPRSint64 value) +{ + // Disabling Xpress internal callback mutex is forbidden since this could easily create race + // condition and deadlocks since it's used in conjunction with Python GIL. + if (control == XPRS_MUTEXCALLBACKS) + { + throw std::runtime_error( + "Changing Xpress callback mutex setting is currently not supported."); + } + _check(XPRSsetintcontrol64(m_model.get(), control, value)); +} + +void Model::set_raw_control_dbl_by_id(int control, double value) +{ + _check(XPRSsetdblcontrol(m_model.get(), control, value)); +} + +void Model::set_raw_control_str_by_id(int control, const char *value) +{ + _check(XPRSsetstrcontrol(m_model.get(), control, value)); +} + +XPRSint64 Model::get_raw_control_int_by_id(int control) +{ + XPRSint64 value = {}; + _check(XPRSgetintcontrol64(m_model.get(), control, &value)); + return value; +} + +double Model::get_raw_control_dbl_by_id(int control) +{ + double value = {}; + _check(XPRSgetdblcontrol(m_model.get(), control, &value)); + return value; +} + +std::string Model::get_raw_control_str_by_id(int control) +{ + int req_size = {}; + _check(XPRSgetstringcontrol(m_model.get(), control, nullptr, 0, &req_size)); + std::string value = {}; + value.resize(req_size); + _check(XPRSgetstringcontrol(m_model.get(), control, value.data(), req_size, &req_size)); + if (value.size() != req_size) + { + throw std::runtime_error("Error while getting control string"); + } + // Align string size with string length + value.resize(strlen(value.c_str())); + return value; +} + +XPRSint64 Model::get_raw_attribute_int_by_id(int attrib) +{ + XPRSint64 value = {}; + _check(XPRSgetintattrib64(m_model.get(), attrib, &value)); + return value; +} + +double Model::get_raw_attribute_dbl_by_id(int attrib) +{ + double value = {}; + _check(XPRSgetdblattrib(m_model.get(), attrib, &value)); + return value; +} + +std::string Model::get_raw_attribute_str_by_id(int attrib) +{ + int req_size = {}; + _check(XPRSgetstringattrib(m_model.get(), attrib, nullptr, 0, &req_size)); + std::string value = {}; + value.resize(req_size); + _check(XPRSgetstringattrib(m_model.get(), attrib, value.data(), req_size, &req_size)); + if (value.size() != req_size) + { + throw std::runtime_error("Error while getting control string"); + } + return value; +} + +LPSTATUS Model::get_lp_status() +{ + return static_cast(get_raw_attribute_int_by_id(XPRS_LPSTATUS)); +} + +MIPSTATUS Model::get_mip_status() +{ + return static_cast(get_raw_attribute_int_by_id(XPRS_MIPSTATUS)); +} + +NLPSTATUS Model::get_nlp_status() +{ + return static_cast(get_raw_attribute_int_by_id(XPRS_NLPSTATUS)); +} + +SOLVESTATUS Model::get_solve_status() +{ + return static_cast(get_raw_attribute_int_by_id(XPRS_SOLVESTATUS)); +} + +SOLSTATUS Model::get_sol_status() +{ + return static_cast(get_raw_attribute_int_by_id(XPRS_SOLSTATUS)); +} + +IISSOLSTATUS Model::get_iis_sol_status() +{ + return static_cast(get_raw_attribute_int_by_id(XPRS_IISSOLSTATUS)); +} + +OPTIMIZETYPE Model::get_optimize_type() +{ + return static_cast(get_raw_attribute_int_by_id(XPRS_OPTIMIZETYPEUSED)); +} + +void Model::_ensure_postsolved() +{ + if (m_need_postsolve) + { + _check(XPRSpostsolve(m_model.get())); + + // Non-convex quadratic constraint might be solved with the non linear solver, so we have to + // make sure that the problem is nl-postsolved, even if it is not always strictly necessary + // and could introduce minor overhead. + if (m_quad_nl_constr_num >= 0 || has_quad_objective || has_nlp_objective) + { + _check(XPRSnlppostsolve(m_model.get())); + } + m_need_postsolve = false; + } +} + +void Model::_check_expected_mode(XPRESS_MODEL_MODE mode) +{ + if (mode == XPRESS_MODEL_MODE::MAIN && m_mode == XPRESS_MODEL_MODE::CALLBACK) + { + throw std::runtime_error("Cannot call this function from within a callback. " + "This operation is only available on the main model."); + } + if (mode == XPRESS_MODEL_MODE::CALLBACK && m_mode == XPRESS_MODEL_MODE::MAIN) + { + throw std::runtime_error("This function can only be called from within a callback. " + "It is not available on the main model."); + } +} + +xpress_cbs_data Model::cb_get_arguments() +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + return cb_args; +} + +// NOTE: XPRSgetcallbacksolution return a context dependent solution +double Model::_cb_get_context_solution(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + // Xpress already caches solutions internally + int p_available = 0; + int colidx = _checked_variable_index(variable); + double value[] = {0.0}; + _check(XPRSgetcallbacksolution(m_model.get(), &p_available, value, colidx, colidx)); + if (p_available == 0) + { + throw std::runtime_error("No solution available"); + } + return value[0]; +} + +// Get MIP solution value for a variable in callback context. +// Returns the callback's candidate integer solution if available (intsol, preintsol contexts), +// otherwise falls back to the current incumbent solution. +double Model::cb_get_solution(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + if (cb_where == CB_CONTEXT::intsol || cb_where == CB_CONTEXT::preintsol) + { + // Context provides a candidate integer solution - return it directly + return _cb_get_context_solution(variable); + } + + // No integer solution in current context - return best known incumbent instead + return cb_get_incumbent(variable); +} + +// Get LP relaxation solution value for a variable in callback context. Returns the callback's LP +// relaxation solution when available in contexts that solve LPs (bariteration, cutround, +// chgbranchobject, nodelpsolved, optnode). It throws in other contexts. +double Model::cb_get_relaxation(VariableIndex variable) +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + if (cb_where != CB_CONTEXT::bariteration && cb_where != CB_CONTEXT::cutround && + cb_where != CB_CONTEXT::chgbranchobject && cb_where != CB_CONTEXT::nodelpsolved && + cb_where != CB_CONTEXT::optnode) + { + throw std::runtime_error("LP relaxation solution not available."); + } + return _cb_get_context_solution(variable); +} + +double Model::cb_get_incumbent(VariableIndex variable) +{ + return get_variable_value(variable); +} + +void Model::cb_set_solution(VariableIndex variable, double value) +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + cb_sol_cache.emplace_back(_checked_variable_index(variable), value); +} + +void Model::cb_submit_solution() +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + + auto &sol = cb_sol_cache; + if (sol.empty()) + { + return; + } + + // Merge together coefficient of duplicated indices + std::ranges::sort(sol); + std::vector indices; + std::vector values; + int curr_idx = std::numeric_limits::lowest(); + for (auto [idx, val] : sol) + { + if (curr_idx != idx) + { + curr_idx = idx; + indices.push_back(idx); + values.emplace_back(); + } + values.back() += val; + } + + int ncol = static_cast(indices.size()); + _check(XPRSaddmipsol(m_model.get(), ncol, values.data(), indices.data(), nullptr)); +} + +void Model::cb_exit() +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + _check(XPRSinterrupt(m_model.get(), XPRS_STOP_USER)); +} + +void Model::_cb_add_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs) +{ + AffineFunctionPtrForm ptr_form; + ptr_form.make(this, function); + int numnz = ptr_form.numnz; + char g_sense = poi_to_xprs_cons_sense(sense); + double g_rhs = static_cast(rhs - function.constant.value_or(CoeffT{})); + const int *cind = ptr_form.index; + const double *cval = ptr_form.value; + + // Before adding the cut, we must translate it to the presolved model. If this translation fails + // then we cannot continue. The translation can only fail if we have presolve operations enabled + // that should be disabled in case of dynamically separated constraints. + int ncols = get_raw_attribute_int_by_id(XPRS_COLS); + int ps_numnz = 0; + std::vector ps_cind(ncols); + std::vector ps_cval(ncols); + double ps_rhs = 0.0; + int ps_status = 0; + _check(XPRSpresolverow(m_model.get(), g_sense, numnz, cind, cval, g_rhs, ncols, &ps_numnz, + ps_cind.data(), ps_cval.data(), &ps_rhs, &ps_status)); + if (ps_status != 0) + { + throw std::runtime_error("Failed to presolve new cut."); + } + + XPRSint64 start[] = {0, ps_numnz}; + int ctype = 1; + if (cb_where == CB_CONTEXT::cutround) + { + // NOTE: we assume cuts to be global since other solvers only support those + _check(XPRSaddmanagedcuts64(m_model.get(), 1, 1, &g_sense, &ps_rhs, start, ps_cind.data(), + ps_cval.data())); + } + else + { + _check(XPRSaddcuts64(m_model.get(), 1, &ctype, &g_sense, &ps_rhs, start, ps_cind.data(), + ps_cval.data())); + } +} + +// Tries to add a lazy constraints. If the context is right, but we are not in a node of the tree, +// it fallbacks to simply rejecting the solution, since no cut can be added at that moment. +void Model::cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense, + CoeffT rhs) +{ + _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + if (cb_where != CB_CONTEXT::nodelpsolved && cb_where != CB_CONTEXT::optnode && + cb_where != CB_CONTEXT::preintsol && cb_where != CB_CONTEXT::prenode) + { + throw std::runtime_error("New constraints can be added only in NODELPSOLVED, OPTNODE, " + "PREINTSOL, and PRENODE callbacks."); + } + + if (cb_where != CB_CONTEXT::preintsol) + { + _cb_add_cut(function, sense, rhs); + return; + } + + auto *args = std::get(cb_args); + if (args->soltype == 0) + { + _cb_add_cut(function, sense, rhs); + return; + } + + // If the solution didn't originated from a node of the tree, we can't reject it with a cut. + // However, if the user cut makes the solution infeasible, we have to reject it. + double pos_activity = 0.0; + double neg_anctivity = 0.0; + const int nnz = function.size(); + for (int i = 0; i < nnz; ++i) + { + double col_val = _cb_get_context_solution(function.variables[i]); + double term_val = col_val * function.coefficients[i]; + (term_val > 0.0 ? pos_activity : neg_anctivity) += term_val; + } + const double activity = pos_activity + neg_anctivity; + const double real_rhs = static_cast(rhs - function.constant.value_or(0.0)); + double infeas = 0.0; // > 0 if solution violates constraint + if (sense == ConstraintSense::Equal || sense == ConstraintSense::LessEqual) + { + infeas = std::max(infeas, activity - real_rhs); + } + if (sense == ConstraintSense::Equal || sense == ConstraintSense::GreaterEqual) + { + infeas = std::max(infeas, real_rhs - activity); + } + const double feastol = get_raw_control_dbl_by_id(XPRS_FEASTOL); + if (infeas > feastol) + { + // The user added a cut, but we are not in a context where it can be added. So, the only + // thing we can reasonably do is to reject the solution iff it is made infeasible by the + // user provided cut. + *args->p_reject = 1; + } +} + +void Model::cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs) +{ + ScalarAffineFunction f(function); + cb_add_lazy_constraint(f, sense, rhs); +} + +void Model::cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs) +{ + _cb_add_cut(function, sense, rhs); +} + +void Model::cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs) +{ + ScalarAffineFunction f(function); + cb_add_user_cut(f, sense, rhs); +} + +// Helper struct that defines a static function when instantiated. +// The defined static function is the actual Xpress CB that will be registered to the context +// selected by the Where argument. +// It collects the due-diligence common to all CBs, to minimize code duplication. +template +struct Model::CbWrap +{ + static RetT cb(XPRSprob cb_prob, void *user_data, ArgsT... args) noexcept + { + auto *model = reinterpret_cast(user_data); + assert(model->m_mode == XPRESS_MODEL_MODE::MAIN); + + auto cb_args = CbStruct{{/*ret_code*/}, args...}; // Store additional arguments + + // Temporarily swap the XpressModel's problem pointer with the callback's thread-local + // clone. This allows reusing the model's indexers and helper data without copying. + // + // Current design assumes serialized callback invocation (enforced by Python GIL). The swap + // is safe because only one callback executes at a time. + // + // NOTE: Free-threading compatibility will require redesign. The approach would be to split + // Model state into: + // - Immutable shared state (indexers, problem structure) shared through a common pointer, + // read-only when in callbacks + // - Thread-local state (callback context, temporary buffers) + // + // Instead of swapping problem pointers, create lightweight callback problem objects that + // reference the shared state. This is conceptually simple but requires refactoring all + // Model methods to access shared state through indirection. + XPRSprob main_prob = model->_toggle_model_mode(cb_prob); + // Ensure restoration on all exit paths + Defer main_prob_restore = [&] { model->_toggle_model_mode(main_prob); }; + + try + { + model->_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); + model->cb_sol_cache.clear(); + model->cb_where = static_cast(Where); + model->cb_args = &cb_args; + model->m_callback(model, static_cast(Where)); + model->cb_submit_solution(); + } + catch (...) + { + // We cannot let any exception slip through a callback, we have to catch it, + // terminate Xpress gracefully and then we can throw it again. + if (XPRSinterrupt(cb_prob, XPRS_STOP_USER) != 0) + { + std::rethrow_exception(std::current_exception()); // We have to terminate somehow + } + model->m_captured_exceptions.push_back(std::current_exception()); + } + + return cb_args.get_return_value(); + } +}; + +static constexpr unsigned long long as_flag(int ID) +{ + assert("ID must be in the [0, 63] range" && ID >= 0 && ID < 63); + return (1ULL << ID); +} + +static constexpr bool test_ctx(CB_CONTEXT dest_ctx, unsigned long long curr_ctx) +{ + auto ctx = static_cast(dest_ctx); + return (curr_ctx & ctx) != 0; // The context matches the ID +} + +void Model::set_callback(const Callback &cb, unsigned long long new_contexts) +{ + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + + // Default message callback management - we always register a default message handler + // unless the user explicitly registers their own. When the user callback is removed, + // restore the default handler. + if (is_default_message_cb_set && test_ctx(CB_CONTEXT::message, new_contexts)) + { + _check(XPRSremovecbmessage(m_model.get(), &default_print, nullptr)); + is_default_message_cb_set = false; + } + if (!is_default_message_cb_set && !test_ctx(CB_CONTEXT::message, new_contexts)) + { + _check(XPRSaddcbmessage(m_model.get(), &default_print, nullptr, 0)); + is_default_message_cb_set = true; + } + + // Register/unregister Xpress callbacks based on context changes. For each callback type, + // compare the old context set (m_curr_contexts) with the new one. If a context needs to be + // added or removed, register/unregister the corresponding low-level wrapper function. + // + // Note: The wrapper functions are stateless - they just forward to the user callback pointer. + // Updating the callback for an already-registered context only requires updating m_callback; + // the wrapper stays registered. + +#define XPRSCB_SET_CTX(ID, NAME, RET, ...) \ + { \ + bool has_cb = test_ctx(CB_CONTEXT::NAME, m_curr_contexts); \ + bool needs_cb = test_ctx(CB_CONTEXT::NAME, new_contexts); \ + if (has_cb != needs_cb) \ + { \ + auto *cb = &CbWrap::cb; \ + if (has_cb) \ + { \ + _check(XPRSremovecb##NAME(m_model.get(), cb, this)); \ + } \ + else /* needs_cb */ \ + { \ + _check(XPRSaddcb##NAME(m_model.get(), cb, this, 0)); \ + } \ + } \ + } + XPRSCB_LIST(XPRSCB_SET_CTX, XPRSCB_ARG_TYPE) +#undef XPRSCB_SET_CTX + + m_curr_contexts = new_contexts; + m_callback = cb; +} +} // namespace xpress diff --git a/lib/xpress_model_ext.cpp b/lib/xpress_model_ext.cpp new file mode 100644 index 00000000..d46da5ed --- /dev/null +++ b/lib/xpress_model_ext.cpp @@ -0,0 +1,286 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "pyoptinterface/core.hpp" +#include "pyoptinterface/xpress_model.hpp" + +namespace nb = nanobind; + +using namespace nb::literals; +using namespace xpress; + +extern void bind_xpress_constants(nb::module_ &m); + +NB_MODULE(xpress_model_ext, m) +{ + m.import_("pyoptinterface._src.core_ext"); + + m.def("is_library_loaded", &xpress::is_library_loaded); + m.def("load_library", &xpress::load_library); + m.def("license", &xpress::license, "i"_a, "c"_a); + m.def("beginlicensing", &xpress::beginlicensing); + m.def("endlicensing", &xpress::endlicensing); + + bind_xpress_constants(m); + + nb::class_(m, "Env") + .def(nb::init<>()) + .def(nb::init(), "path"_a = nullptr) + .def("close", &Env::close); + + nb::class_(m, "RawModel") + .def(nb::init<>()) + .def(nb::init(), nb::keep_alive<1, 2>()) + + // Model management + .def("init", &Model::init, "env"_a) + .def("close", &Model::close) + .def("optimize", &Model::optimize, nb::call_guard()) + .def("computeIIS", &Model::computeIIS, nb::call_guard()) + .def("write", &Model::write, "filename"_a, nb::call_guard()) + .def("_is_mip", &Model::_is_mip) + .def_static("get_infinity", &Model::get_infinity) + .def("get_problem_name", &Model::get_problem_name) + .def("set_problem_name", &Model::set_problem_name, "probname"_a) + .def("add_mip_start", &Model::add_mip_start, "variables"_a, "values"_a) + .def("get_raw_model", &Model::get_raw_model) + .def("version_string", &Model::version_string) + + // Index mappings + .def("_constraint_index", &Model::_constraint_index, "constraint"_a) + .def("_variable_index", &Model::_variable_index, "variable"_a) + .def("_checked_constraint_index", &Model::_checked_constraint_index, "constraint"_a) + .def("_checked_variable_index", &Model::_checked_variable_index, "variable"_a) + + // Variables + .def("add_variable", &Model::add_variable, "domain"_a = VariableDomain::Continuous, + "lb"_a = XPRS_MINUSINFINITY, "ub"_a = XPRS_PLUSINFINITY, "name"_a = "") + .def("delete_variable", &Model::delete_variable, "variable"_a) + .def("delete_variables", &Model::delete_variables, "variables"_a) + .def("set_objective_coefficient", &Model::set_objective_coefficient, "variable"_a, + "value"_a) + .def("set_variable_bounds", &Model::set_variable_bounds, "variable"_a, "lb"_a, "ub"_a) + .def("set_variable_lowerbound", &Model::set_variable_lowerbound, "variable"_a, "lb"_a) + .def("set_variable_name", &Model::set_variable_name, "variable"_a, "name"_a) + .def("set_variable_type", &Model::set_variable_type, "variable"_a, "vtype"_a) + .def("set_variable_upperbound", &Model::set_variable_upperbound, "variable"_a, "ub"_a) + .def("is_variable_active", &Model::is_variable_active, "variable"_a) + .def("is_variable_basic", &Model::is_variable_basic, "variable"_a) + .def("get_variable_lowerbound_IIS", &Model::is_variable_lowerbound_IIS, "variable"_a) + .def("is_variable_nonbasic_lb", &Model::is_variable_nonbasic_lb, "variable"_a) + .def("is_variable_nonbasic_ub", &Model::is_variable_nonbasic_ub, "variable"_a) + .def("is_variable_superbasic", &Model::is_variable_superbasic, "variable"_a) + .def("get_variable_upperbound_IIS", &Model::is_variable_upperbound_IIS, "variable"_a) + .def("get_objective_coefficient", &Model::get_objective_coefficient, "variable"_a) + .def("get_variable_lowerbound", &Model::get_variable_lowerbound, "variable"_a) + .def("get_variable_primal_ray", &Model::get_variable_primal_ray, "variable"_a) + .def("get_variable_rc", &Model::get_variable_rc, "variable"_a) + .def("get_variable_upperbound", &Model::get_variable_upperbound, "variable"_a) + .def("get_variable_value", &Model::get_variable_value, "variable"_a) + .def("get_variable_name", &Model::get_variable_name, "variable"_a) + .def("pprint", &Model::pprint_variable, "variable"_a) + .def("get_variable_type", &Model::get_variable_type, "variable"_a) + + // Constraints + .def("add_exp_cone_constraint", &Model::add_exp_cone_constraint, "variables"_a, + "name"_a = "", "dual"_a = false) + .def("_add_linear_constraint", + nb::overload_cast &, + const char *>(&Model::add_linear_constraint), + "function"_a, "interval"_a, "name"_a = "") + .def("_add_linear_constraint", + nb::overload_cast( + &Model::add_linear_constraint), + "function"_a, "sense"_a, "rhs"_a, "name"_a = "") + .def("add_quadratic_constraint", &Model::add_quadratic_constraint, "function"_a, "sense"_a, + "rhs"_a, "name"_a = "") + .def("_add_quadratic_constraint", &Model::add_quadratic_constraint, "function"_a, "sense"_a, + "rhs"_a, "name"_a = "") + .def("add_second_order_cone_constraint", &Model::add_second_order_cone_constraint, + "variables"_a, "name"_a = "", "rotated"_a = false) + .def("_add_single_nl_constraint", &Model::add_single_nl_constraint, "graph"_a, "result"_a, + + "interval"_a, "name"_a = "") + .def("add_sos_constraint", + nb::overload_cast &, SOSType, const Vector &>( + &Model::add_sos_constraint), + "variables"_a, "sos_type"_a, "weights"_a) + .def("add_sos_constraint", + nb::overload_cast &, SOSType>(&Model::add_sos_constraint), + "variables"_a, "sos_type"_a) + .def("delete_constraint", &Model::delete_constraint, "constraint"_a) + .def("set_constraint_name", &Model::set_constraint_name, "constraint"_a, "name"_a) + .def("set_constraint_rhs", &Model::set_constraint_rhs, "constraint"_a, "rhs"_a) + .def("set_constraint_sense", &Model::set_constraint_sense, "constraint"_a, "sense"_a) + .def("set_normalized_coefficient", &Model::set_normalized_coefficient, "constraint"_a, + "variable"_a, "value"_a) + .def("set_normalized_rhs", &Model::set_normalized_rhs, "constraint"_a, "value"_a) + .def("is_constraint_active", &Model::is_constraint_active, "constraint"_a) + .def("is_constraint_basic", &Model::is_constraint_basic, "constraint"_a) + .def("is_constraint_in_IIS", &Model::is_constraint_in_IIS, "constraint"_a) + .def("is_constraint_nonbasic_lb", &Model::is_constraint_nonbasic_lb, "constraint"_a) + .def("is_constraint_nonbasic_ub", &Model::is_constraint_nonbasic_ub, "constraint"_a) + .def("is_constraint_superbasic", &Model::is_constraint_superbasic, "constraint"_a) + .def("get_constraint_dual_ray", &Model::get_constraint_dual_ray, "constraint"_a) + .def("get_constraint_dual", &Model::get_constraint_dual, "constraint"_a) + .def("get_constraint_slack", &Model::get_constraint_slack, "constraint"_a) + .def("get_normalized_coefficient", &Model::get_normalized_coefficient, "constraint"_a, + "variable"_a) + .def("get_normalized_rhs", &Model::get_normalized_rhs, "constraint"_a) + .def("get_constraint_rhs", &Model::get_constraint_rhs, "constraint"_a) + .def("get_constraint_name", &Model::get_constraint_name, "constraint"_a) + .def("get_constraint_sense", &Model::get_constraint_sense, "constraint"_a) + + // Objective function + .def("set_objective", + nb::overload_cast(&Model::set_objective), + "function"_a, "sense"_a = ObjectiveSense::Minimize) + .def("set_objective", + nb::overload_cast( + &Model::set_objective), + "function"_a, "sense"_a = ObjectiveSense::Minimize) + .def("set_objective", + nb::overload_cast(&Model::set_objective), + "function"_a, "sense"_a = ObjectiveSense::Minimize) + .def("_add_single_nl_objective", &Model::add_single_nl_objective, "graph"_a, "result"_a) + + // Status queries + .def("get_lp_status", &Model::get_lp_status) + .def("get_mip_status", &Model::get_mip_status) + .def("get_nlp_status", &Model::get_nlp_status) + .def("get_sol_status", &Model::get_sol_status) + .def("get_solve_status", &Model::get_solve_status) + .def("get_optimize_type", &Model::get_optimize_type) + .def("get_iis_sol_status", &Model::get_iis_sol_status) + + // Raw control/attribute access by ID + .def("set_raw_control_dbl_by_id", &Model::set_raw_control_dbl_by_id, "control"_a, "value"_a) + .def("set_raw_control_int_by_id", &Model::set_raw_control_int_by_id, "control"_a, "value"_a) + .def("set_raw_control_str_by_id", &Model::set_raw_control_str_by_id, "control"_a, "value"_a) + .def("get_raw_control_int_by_id", &Model::get_raw_control_int_by_id, "control"_a) + .def("get_raw_control_dbl_by_id", &Model::get_raw_control_dbl_by_id, "control"_a) + .def("get_raw_control_str_by_id", &Model::get_raw_control_str_by_id, "control"_a) + .def("get_raw_attribute_int_by_id", &Model::get_raw_attribute_int_by_id, "attrib"_a) + .def("get_raw_attribute_dbl_by_id", &Model::get_raw_attribute_dbl_by_id, "attrib"_a) + .def("get_raw_attribute_str_by_id", &Model::get_raw_attribute_str_by_id, "attrib"_a) + + // Raw control/attribute access by string + .def("set_raw_control_int", &Model::set_raw_control_int, "control"_a, "value"_a) + .def("set_raw_control_dbl", &Model::set_raw_control_dbl, "control"_a, "value"_a) + .def("set_raw_control_str", &Model::set_raw_control_str, "control"_a, "value"_a) + .def("get_raw_control_int", &Model::get_raw_control_int, "control"_a) + .def("get_raw_control_dbl", &Model::get_raw_control_dbl, "control"_a) + .def("get_raw_control_str", &Model::get_raw_control_str, "control"_a) + .def("get_raw_attribute_int", &Model::get_raw_attribute_int, "attrib"_a) + .def("get_raw_attribute_dbl", &Model::get_raw_attribute_dbl, "attrib"_a) + .def("get_raw_attribute_str", &Model::get_raw_attribute_str, "attrib"_a) + + // Generic variant access + .def("set_raw_control", &Model::set_raw_control, "control"_a, "value"_a) + .def("get_raw_attribute", &Model::get_raw_attribute, "attrib"_a) + .def("get_raw_control", &Model::get_raw_control, "control"_a) + + // Callback methods + .def("set_callback", &Model::set_callback, "callback"_a, "cbctx"_a) + .def("cb_get_arguments", &Model::cb_get_arguments, nb::rv_policy::reference) + .def("cb_get_solution", &Model::cb_get_solution, "variable"_a) + .def("cb_get_relaxation", &Model::cb_get_relaxation, "variable"_a) + .def("cb_get_incumbent", &Model::cb_get_incumbent, "variable"_a) + .def("cb_set_solution", &Model::cb_set_solution, "variable"_a, "value"_a) + .def("cb_submit_solution", &Model::cb_submit_solution) + .def("cb_exit", &Model::cb_exit) + .def("cb_add_lazy_constraint", + nb::overload_cast( + &Model::cb_add_lazy_constraint), + "function"_a, "sense"_a, "rhs"_a) + .def("cb_add_lazy_constraint", + nb::overload_cast( + &Model::cb_add_lazy_constraint), + "function"_a, "sense"_a, "rhs"_a) + .def("cb_add_user_cut", + nb::overload_cast( + &Model::cb_add_user_cut), + "function"_a, "sense"_a, "rhs"_a) + .def("cb_add_user_cut", + nb::overload_cast( + &Model::cb_add_user_cut), + "function"_a, "sense"_a, "rhs"_a) + + // Functions defined in CRTP Mixins + .def("pprint", + nb::overload_cast(&Model::pprint_expression), + "expr"_a, "precision"_a = 4) + .def("pprint", + nb::overload_cast(&Model::pprint_expression), + "expr"_a, "precision"_a = 4) + .def("pprint", nb::overload_cast(&Model::pprint_expression), + "expr"_a, "precision"_a = 4) + + .def("get_value", nb::overload_cast(&Model::get_variable_value)) + .def("get_value", + nb::overload_cast(&Model::get_expression_value)) + .def("get_value", + nb::overload_cast(&Model::get_expression_value)) + .def("get_value", nb::overload_cast(&Model::get_expression_value)) + + .def("_add_linear_constraint", &Model::add_linear_constraint_from_var, "expr"_a, "sense"_a, + "rhs"_a, "name"_a = "") + .def("_add_linear_constraint", &Model::add_linear_interval_constraint_from_var, "expr"_a, + "interval"_a, "name"_a = "") + .def("_add_linear_constraint", &Model::add_linear_constraint_from_expr, "expr"_a, "sense"_a, + "rhs"_a, "name"_a = "") + .def("_add_linear_constraint", &Model::add_linear_interval_constraint_from_expr, "expr"_a, + "interval"_a, "name"_a = "") + .def("_add_linear_constraint", &Model::add_linear_constraint_from_var, "expr"_a, "sense"_a, + "rhs"_a, "name"_a = "") + .def("_add_linear_constraint", &Model::add_linear_interval_constraint_from_var, "expr"_a, + "interval"_a, "name"_a = "") + .def("_add_linear_constraint", &Model::add_linear_constraint_from_expr, "expr"_a, "sense"_a, + "rhs"_a, "name"_a = "") + .def("_add_linear_constraint", &Model::add_linear_interval_constraint_from_expr, "expr"_a, + "interval"_a, "name"_a = "") + + .def("_add_single_nl_constraint", &Model::add_single_nl_constraint_sense_rhs, "graph"_a, + "result"_a, "sense"_a, "rhs"_a, "name"_a = "") + .def("_add_single_nl_constraint", &Model::add_single_nl_constraint_from_comparison, + "graph"_a, "expr"_a, "name"_a = "") + + .def("set_objective", &Model::set_objective_as_variable, "expr"_a, + "sense"_a = ObjectiveSense::Minimize) + .def("set_objective", &Model::set_objective_as_constant, "expr"_a, + "sense"_a = ObjectiveSense::Minimize); + + // Bind the return value only it the CB has one + auto bind_ret_code = [](nb::class_ s) { + // "if constexpr + templates" conditionally instantiates only the true branch. + if constexpr (requires { &S::ret_code; }) + s.def_rw("ret_code", &S::ret_code); + }; + +// When callbacks provide pointer arguments, those are usually meant as output arguments. +// An exception is with pointer to structs, which usually are just opaque objects passed around +// between API calls. +// We define pointer arguments as read-write, while all the other arguments stays read-only +#define XPRSCB_ARG_NB_FIELD(TYPE, NAME) \ + if constexpr (std::is_pointer_v) \ + s.def_rw(#NAME, &struct_t::NAME); \ + else \ + s.def_ro(#NAME, &struct_t::NAME); + +// Define the binding for the argument struct of each CB. In this way, Nanobind will be able to +// translate our std::variant of CB-struct pointers into the proper Python union object +#define XPRSCB_NB_STRUCTS(ID, NAME, RET, ...) \ + { \ + using struct_t = NAME##_struct; \ + auto s = nb::class_(m, #NAME "_struct"); \ + __VA_ARGS__ \ + bind_ret_code(s); \ + } + XPRSCB_LIST(XPRSCB_NB_STRUCTS, XPRSCB_ARG_NB_FIELD) +#undef XPRSCB_NB_STRUCTS +} diff --git a/lib/xpress_model_ext_constants.cpp b/lib/xpress_model_ext_constants.cpp new file mode 100644 index 00000000..c2cae68b --- /dev/null +++ b/lib/xpress_model_ext_constants.cpp @@ -0,0 +1,935 @@ +#include + +#include "pyoptinterface/xpress_model.hpp" + +namespace nb = nanobind; +using namespace xpress; + +void bind_xpress_constants(nb::module_ &m) +{ + nb::module_ XPRS = m.def_submodule("XPRS"); + /* useful constants */ + XPRS.attr("PLUSINFINITY") = XPRS_PLUSINFINITY; + XPRS.attr("MINUSINFINITY") = XPRS_MINUSINFINITY; + XPRS.attr("MAXINT") = XPRS_MAXINT; + XPRS.attr("MAXBANNERLENGTH") = XPRS_MAXBANNERLENGTH; + XPRS.attr("VERSION") = XPVERSION; + XPRS.attr("VERSION_MAJOR") = XPVERSION_FULL; + XPRS.attr("VERSION_MINOR") = XPVERSION_BUILD; + XPRS.attr("VERSION_BUILD") = XPVERSION_MINOR; + XPRS.attr("VERSION_FULL") = XPVERSION_MAJOR; + XPRS.attr("MAXMESSAGELENGTH") = XPRS_MAXMESSAGELENGTH; + + /* control parameters for XPRSprob */ + /* String control parameters */ + XPRS.attr("MPSRHSNAME") = XPRS_MPSRHSNAME; + XPRS.attr("MPSOBJNAME") = XPRS_MPSOBJNAME; + XPRS.attr("MPSRANGENAME") = XPRS_MPSRANGENAME; + XPRS.attr("MPSBOUNDNAME") = XPRS_MPSBOUNDNAME; + XPRS.attr("OUTPUTMASK") = XPRS_OUTPUTMASK; + XPRS.attr("TUNERMETHODFILE") = XPRS_TUNERMETHODFILE; + XPRS.attr("TUNEROUTPUTPATH") = XPRS_TUNEROUTPUTPATH; + XPRS.attr("TUNERSESSIONNAME") = XPRS_TUNERSESSIONNAME; + XPRS.attr("COMPUTEEXECSERVICE") = XPRS_COMPUTEEXECSERVICE; + /* Double control parameters */ + XPRS.attr("MAXCUTTIME") = XPRS_MAXCUTTIME; + XPRS.attr("MAXSTALLTIME") = XPRS_MAXSTALLTIME; + XPRS.attr("TUNERMAXTIME") = XPRS_TUNERMAXTIME; + XPRS.attr("MATRIXTOL") = XPRS_MATRIXTOL; + XPRS.attr("PIVOTTOL") = XPRS_PIVOTTOL; + XPRS.attr("FEASTOL") = XPRS_FEASTOL; + XPRS.attr("OUTPUTTOL") = XPRS_OUTPUTTOL; + XPRS.attr("SOSREFTOL") = XPRS_SOSREFTOL; + XPRS.attr("OPTIMALITYTOL") = XPRS_OPTIMALITYTOL; + XPRS.attr("ETATOL") = XPRS_ETATOL; + XPRS.attr("RELPIVOTTOL") = XPRS_RELPIVOTTOL; + XPRS.attr("MIPTOL") = XPRS_MIPTOL; + XPRS.attr("MIPTOLTARGET") = XPRS_MIPTOLTARGET; + XPRS.attr("BARPERTURB") = XPRS_BARPERTURB; + XPRS.attr("MIPADDCUTOFF") = XPRS_MIPADDCUTOFF; + XPRS.attr("MIPABSCUTOFF") = XPRS_MIPABSCUTOFF; + XPRS.attr("MIPRELCUTOFF") = XPRS_MIPRELCUTOFF; + XPRS.attr("PSEUDOCOST") = XPRS_PSEUDOCOST; + XPRS.attr("PENALTY") = XPRS_PENALTY; + XPRS.attr("BIGM") = XPRS_BIGM; + XPRS.attr("MIPABSSTOP") = XPRS_MIPABSSTOP; + XPRS.attr("MIPRELSTOP") = XPRS_MIPRELSTOP; + XPRS.attr("CROSSOVERACCURACYTOL") = XPRS_CROSSOVERACCURACYTOL; + XPRS.attr("PRIMALPERTURB") = XPRS_PRIMALPERTURB; + XPRS.attr("DUALPERTURB") = XPRS_DUALPERTURB; + XPRS.attr("BAROBJSCALE") = XPRS_BAROBJSCALE; + XPRS.attr("BARRHSSCALE") = XPRS_BARRHSSCALE; + XPRS.attr("CHOLESKYTOL") = XPRS_CHOLESKYTOL; + XPRS.attr("BARGAPSTOP") = XPRS_BARGAPSTOP; + XPRS.attr("BARDUALSTOP") = XPRS_BARDUALSTOP; + XPRS.attr("BARPRIMALSTOP") = XPRS_BARPRIMALSTOP; + XPRS.attr("BARSTEPSTOP") = XPRS_BARSTEPSTOP; + XPRS.attr("ELIMTOL") = XPRS_ELIMTOL; + XPRS.attr("MARKOWITZTOL") = XPRS_MARKOWITZTOL; + XPRS.attr("MIPABSGAPNOTIFY") = XPRS_MIPABSGAPNOTIFY; + XPRS.attr("MIPRELGAPNOTIFY") = XPRS_MIPRELGAPNOTIFY; + XPRS.attr("BARLARGEBOUND") = XPRS_BARLARGEBOUND; + XPRS.attr("PPFACTOR") = XPRS_PPFACTOR; + XPRS.attr("REPAIRINDEFINITEQMAX") = XPRS_REPAIRINDEFINITEQMAX; + XPRS.attr("BARGAPTARGET") = XPRS_BARGAPTARGET; + XPRS.attr("DUMMYCONTROL") = XPRS_DUMMYCONTROL; + XPRS.attr("BARSTARTWEIGHT") = XPRS_BARSTARTWEIGHT; + XPRS.attr("BARFREESCALE") = XPRS_BARFREESCALE; + XPRS.attr("SBEFFORT") = XPRS_SBEFFORT; + XPRS.attr("HEURDIVERANDOMIZE") = XPRS_HEURDIVERANDOMIZE; + XPRS.attr("HEURSEARCHEFFORT") = XPRS_HEURSEARCHEFFORT; + XPRS.attr("CUTFACTOR") = XPRS_CUTFACTOR; + XPRS.attr("EIGENVALUETOL") = XPRS_EIGENVALUETOL; + XPRS.attr("INDLINBIGM") = XPRS_INDLINBIGM; + XPRS.attr("TREEMEMORYSAVINGTARGET") = XPRS_TREEMEMORYSAVINGTARGET; + XPRS.attr("INDPRELINBIGM") = XPRS_INDPRELINBIGM; + XPRS.attr("RELAXTREEMEMORYLIMIT") = XPRS_RELAXTREEMEMORYLIMIT; + XPRS.attr("MIPABSGAPNOTIFYOBJ") = XPRS_MIPABSGAPNOTIFYOBJ; + XPRS.attr("MIPABSGAPNOTIFYBOUND") = XPRS_MIPABSGAPNOTIFYBOUND; + XPRS.attr("PRESOLVEMAXGROW") = XPRS_PRESOLVEMAXGROW; + XPRS.attr("HEURSEARCHTARGETSIZE") = XPRS_HEURSEARCHTARGETSIZE; + XPRS.attr("CROSSOVERRELPIVOTTOL") = XPRS_CROSSOVERRELPIVOTTOL; + XPRS.attr("CROSSOVERRELPIVOTTOLSAFE") = XPRS_CROSSOVERRELPIVOTTOLSAFE; + XPRS.attr("DETLOGFREQ") = XPRS_DETLOGFREQ; + XPRS.attr("MAXIMPLIEDBOUND") = XPRS_MAXIMPLIEDBOUND; + XPRS.attr("FEASTOLTARGET") = XPRS_FEASTOLTARGET; + XPRS.attr("OPTIMALITYTOLTARGET") = XPRS_OPTIMALITYTOLTARGET; + XPRS.attr("PRECOMPONENTSEFFORT") = XPRS_PRECOMPONENTSEFFORT; + XPRS.attr("LPLOGDELAY") = XPRS_LPLOGDELAY; + XPRS.attr("HEURDIVEITERLIMIT") = XPRS_HEURDIVEITERLIMIT; + XPRS.attr("BARKERNEL") = XPRS_BARKERNEL; + XPRS.attr("FEASTOLPERTURB") = XPRS_FEASTOLPERTURB; + XPRS.attr("CROSSOVERFEASWEIGHT") = XPRS_CROSSOVERFEASWEIGHT; + XPRS.attr("LUPIVOTTOL") = XPRS_LUPIVOTTOL; + XPRS.attr("MIPRESTARTGAPTHRESHOLD") = XPRS_MIPRESTARTGAPTHRESHOLD; + XPRS.attr("NODEPROBINGEFFORT") = XPRS_NODEPROBINGEFFORT; + XPRS.attr("INPUTTOL") = XPRS_INPUTTOL; + XPRS.attr("MIPRESTARTFACTOR") = XPRS_MIPRESTARTFACTOR; + XPRS.attr("BAROBJPERTURB") = XPRS_BAROBJPERTURB; + XPRS.attr("CPIALPHA") = XPRS_CPIALPHA; + XPRS.attr("GLOBALSPATIALBRANCHPROPAGATIONEFFORT") = XPRS_GLOBALSPATIALBRANCHPROPAGATIONEFFORT; + XPRS.attr("GLOBALSPATIALBRANCHCUTTINGEFFORT") = XPRS_GLOBALSPATIALBRANCHCUTTINGEFFORT; + XPRS.attr("GLOBALBOUNDINGBOX") = XPRS_GLOBALBOUNDINGBOX; + XPRS.attr("TIMELIMIT") = XPRS_TIMELIMIT; + XPRS.attr("SOLTIMELIMIT") = XPRS_SOLTIMELIMIT; + XPRS.attr("REPAIRINFEASTIMELIMIT") = XPRS_REPAIRINFEASTIMELIMIT; + XPRS.attr("BARHGEXTRAPOLATE") = XPRS_BARHGEXTRAPOLATE; + XPRS.attr("WORKLIMIT") = XPRS_WORKLIMIT; + XPRS.attr("CALLBACKCHECKTIMEWORKDELAY") = XPRS_CALLBACKCHECKTIMEWORKDELAY; + XPRS.attr("PREROOTWORKLIMIT") = XPRS_PREROOTWORKLIMIT; + XPRS.attr("PREROOTEFFORT") = XPRS_PREROOTEFFORT; + /* Integer control parameters */ + XPRS.attr("EXTRAROWS") = XPRS_EXTRAROWS; + XPRS.attr("EXTRACOLS") = XPRS_EXTRACOLS; + XPRS.attr("LPITERLIMIT") = XPRS_LPITERLIMIT; + XPRS.attr("LPLOG") = XPRS_LPLOG; + XPRS.attr("SCALING") = XPRS_SCALING; + XPRS.attr("PRESOLVE") = XPRS_PRESOLVE; + XPRS.attr("CRASH") = XPRS_CRASH; + XPRS.attr("PRICINGALG") = XPRS_PRICINGALG; + XPRS.attr("INVERTFREQ") = XPRS_INVERTFREQ; + XPRS.attr("INVERTMIN") = XPRS_INVERTMIN; + XPRS.attr("MAXNODE") = XPRS_MAXNODE; + XPRS.attr("MAXMIPSOL") = XPRS_MAXMIPSOL; + XPRS.attr("SIFTPASSES") = XPRS_SIFTPASSES; + XPRS.attr("DEFAULTALG") = XPRS_DEFAULTALG; + XPRS.attr("VARSELECTION") = XPRS_VARSELECTION; + XPRS.attr("NODESELECTION") = XPRS_NODESELECTION; + XPRS.attr("BACKTRACK") = XPRS_BACKTRACK; + XPRS.attr("MIPLOG") = XPRS_MIPLOG; + XPRS.attr("KEEPNROWS") = XPRS_KEEPNROWS; + XPRS.attr("MPSECHO") = XPRS_MPSECHO; + XPRS.attr("MAXPAGELINES") = XPRS_MAXPAGELINES; + XPRS.attr("OUTPUTLOG") = XPRS_OUTPUTLOG; + XPRS.attr("BARSOLUTION") = XPRS_BARSOLUTION; + XPRS.attr("CROSSOVER") = XPRS_CROSSOVER; + XPRS.attr("BARITERLIMIT") = XPRS_BARITERLIMIT; + XPRS.attr("CHOLESKYALG") = XPRS_CHOLESKYALG; + XPRS.attr("BAROUTPUT") = XPRS_BAROUTPUT; + XPRS.attr("EXTRAMIPENTS") = XPRS_EXTRAMIPENTS; + XPRS.attr("REFACTOR") = XPRS_REFACTOR; + XPRS.attr("BARTHREADS") = XPRS_BARTHREADS; + XPRS.attr("KEEPBASIS") = XPRS_KEEPBASIS; + XPRS.attr("CROSSOVEROPS") = XPRS_CROSSOVEROPS; + XPRS.attr("VERSION") = XPRS_VERSION; + XPRS.attr("CROSSOVERTHREADS") = XPRS_CROSSOVERTHREADS; + XPRS.attr("BIGMMETHOD") = XPRS_BIGMMETHOD; + XPRS.attr("MPSNAMELENGTH") = XPRS_MPSNAMELENGTH; + XPRS.attr("ELIMFILLIN") = XPRS_ELIMFILLIN; + XPRS.attr("PRESOLVEOPS") = XPRS_PRESOLVEOPS; + XPRS.attr("MIPPRESOLVE") = XPRS_MIPPRESOLVE; + XPRS.attr("MIPTHREADS") = XPRS_MIPTHREADS; + XPRS.attr("BARORDER") = XPRS_BARORDER; + XPRS.attr("BREADTHFIRST") = XPRS_BREADTHFIRST; + XPRS.attr("AUTOPERTURB") = XPRS_AUTOPERTURB; + XPRS.attr("DENSECOLLIMIT") = XPRS_DENSECOLLIMIT; + XPRS.attr("CALLBACKFROMMASTERTHREAD") = XPRS_CALLBACKFROMMASTERTHREAD; + XPRS.attr("MAXMCOEFFBUFFERELEMS") = XPRS_MAXMCOEFFBUFFERELEMS; + XPRS.attr("REFINEOPS") = XPRS_REFINEOPS; + XPRS.attr("LPREFINEITERLIMIT") = XPRS_LPREFINEITERLIMIT; + XPRS.attr("MIPREFINEITERLIMIT") = XPRS_MIPREFINEITERLIMIT; + XPRS.attr("DUALIZEOPS") = XPRS_DUALIZEOPS; + XPRS.attr("CROSSOVERITERLIMIT") = XPRS_CROSSOVERITERLIMIT; + XPRS.attr("PREBASISRED") = XPRS_PREBASISRED; + XPRS.attr("PRESORT") = XPRS_PRESORT; + XPRS.attr("PREPERMUTE") = XPRS_PREPERMUTE; + XPRS.attr("PREPERMUTESEED") = XPRS_PREPERMUTESEED; + XPRS.attr("MAXMEMORYSOFT") = XPRS_MAXMEMORYSOFT; + XPRS.attr("CUTFREQ") = XPRS_CUTFREQ; + XPRS.attr("SYMSELECT") = XPRS_SYMSELECT; + XPRS.attr("SYMMETRY") = XPRS_SYMMETRY; + XPRS.attr("MAXMEMORYHARD") = XPRS_MAXMEMORYHARD; + XPRS.attr("MIQCPALG") = XPRS_MIQCPALG; + XPRS.attr("QCCUTS") = XPRS_QCCUTS; + XPRS.attr("QCROOTALG") = XPRS_QCROOTALG; + XPRS.attr("PRECONVERTSEPARABLE") = XPRS_PRECONVERTSEPARABLE; + XPRS.attr("ALGAFTERNETWORK") = XPRS_ALGAFTERNETWORK; + XPRS.attr("TRACE") = XPRS_TRACE; + XPRS.attr("MAXIIS") = XPRS_MAXIIS; + XPRS.attr("CPUTIME") = XPRS_CPUTIME; + XPRS.attr("COVERCUTS") = XPRS_COVERCUTS; + XPRS.attr("GOMCUTS") = XPRS_GOMCUTS; + XPRS.attr("LPFOLDING") = XPRS_LPFOLDING; + XPRS.attr("MPSFORMAT") = XPRS_MPSFORMAT; + XPRS.attr("CUTSTRATEGY") = XPRS_CUTSTRATEGY; + XPRS.attr("CUTDEPTH") = XPRS_CUTDEPTH; + XPRS.attr("TREECOVERCUTS") = XPRS_TREECOVERCUTS; + XPRS.attr("TREEGOMCUTS") = XPRS_TREEGOMCUTS; + XPRS.attr("CUTSELECT") = XPRS_CUTSELECT; + XPRS.attr("TREECUTSELECT") = XPRS_TREECUTSELECT; + XPRS.attr("DUALIZE") = XPRS_DUALIZE; + XPRS.attr("DUALGRADIENT") = XPRS_DUALGRADIENT; + XPRS.attr("SBITERLIMIT") = XPRS_SBITERLIMIT; + XPRS.attr("SBBEST") = XPRS_SBBEST; + XPRS.attr("BARINDEFLIMIT") = XPRS_BARINDEFLIMIT; + XPRS.attr("HEURFREQ") = XPRS_HEURFREQ; + XPRS.attr("HEURDEPTH") = XPRS_HEURDEPTH; + XPRS.attr("HEURMAXSOL") = XPRS_HEURMAXSOL; + XPRS.attr("HEURNODES") = XPRS_HEURNODES; + XPRS.attr("LNPBEST") = XPRS_LNPBEST; + XPRS.attr("LNPITERLIMIT") = XPRS_LNPITERLIMIT; + XPRS.attr("BRANCHCHOICE") = XPRS_BRANCHCHOICE; + XPRS.attr("BARREGULARIZE") = XPRS_BARREGULARIZE; + XPRS.attr("SBSELECT") = XPRS_SBSELECT; + XPRS.attr("IISLOG") = XPRS_IISLOG; + XPRS.attr("LOCALCHOICE") = XPRS_LOCALCHOICE; + XPRS.attr("LOCALBACKTRACK") = XPRS_LOCALBACKTRACK; + XPRS.attr("DUALSTRATEGY") = XPRS_DUALSTRATEGY; + XPRS.attr("HEURDIVESTRATEGY") = XPRS_HEURDIVESTRATEGY; + XPRS.attr("HEURSELECT") = XPRS_HEURSELECT; + XPRS.attr("BARSTART") = XPRS_BARSTART; + XPRS.attr("PRESOLVEPASSES") = XPRS_PRESOLVEPASSES; + XPRS.attr("BARORDERTHREADS") = XPRS_BARORDERTHREADS; + XPRS.attr("EXTRASETS") = XPRS_EXTRASETS; + XPRS.attr("FEASIBILITYPUMP") = XPRS_FEASIBILITYPUMP; + XPRS.attr("PRECOEFELIM") = XPRS_PRECOEFELIM; + XPRS.attr("PREDOMCOL") = XPRS_PREDOMCOL; + XPRS.attr("HEURSEARCHFREQ") = XPRS_HEURSEARCHFREQ; + XPRS.attr("HEURDIVESPEEDUP") = XPRS_HEURDIVESPEEDUP; + XPRS.attr("SBESTIMATE") = XPRS_SBESTIMATE; + XPRS.attr("BARCORES") = XPRS_BARCORES; + XPRS.attr("MAXCHECKSONMAXTIME") = XPRS_MAXCHECKSONMAXTIME; + XPRS.attr("MAXCHECKSONMAXCUTTIME") = XPRS_MAXCHECKSONMAXCUTTIME; + XPRS.attr("HISTORYCOSTS") = XPRS_HISTORYCOSTS; + XPRS.attr("ALGAFTERCROSSOVER") = XPRS_ALGAFTERCROSSOVER; + XPRS.attr("MUTEXCALLBACKS") = XPRS_MUTEXCALLBACKS; + XPRS.attr("BARCRASH") = XPRS_BARCRASH; + XPRS.attr("HEURDIVESOFTROUNDING") = XPRS_HEURDIVESOFTROUNDING; + XPRS.attr("HEURSEARCHROOTSELECT") = XPRS_HEURSEARCHROOTSELECT; + XPRS.attr("HEURSEARCHTREESELECT") = XPRS_HEURSEARCHTREESELECT; + XPRS.attr("MPS18COMPATIBLE") = XPRS_MPS18COMPATIBLE; + XPRS.attr("ROOTPRESOLVE") = XPRS_ROOTPRESOLVE; + XPRS.attr("CROSSOVERDRP") = XPRS_CROSSOVERDRP; + XPRS.attr("FORCEOUTPUT") = XPRS_FORCEOUTPUT; + XPRS.attr("PRIMALOPS") = XPRS_PRIMALOPS; + XPRS.attr("DETERMINISTIC") = XPRS_DETERMINISTIC; + XPRS.attr("PREPROBING") = XPRS_PREPROBING; + XPRS.attr("TREEMEMORYLIMIT") = XPRS_TREEMEMORYLIMIT; + XPRS.attr("TREECOMPRESSION") = XPRS_TREECOMPRESSION; + XPRS.attr("TREEDIAGNOSTICS") = XPRS_TREEDIAGNOSTICS; + XPRS.attr("MAXTREEFILESIZE") = XPRS_MAXTREEFILESIZE; + XPRS.attr("PRECLIQUESTRATEGY") = XPRS_PRECLIQUESTRATEGY; + XPRS.attr("IFCHECKCONVEXITY") = XPRS_IFCHECKCONVEXITY; + XPRS.attr("PRIMALUNSHIFT") = XPRS_PRIMALUNSHIFT; + XPRS.attr("REPAIRINDEFINITEQ") = XPRS_REPAIRINDEFINITEQ; + XPRS.attr("MIPRAMPUP") = XPRS_MIPRAMPUP; + XPRS.attr("MAXLOCALBACKTRACK") = XPRS_MAXLOCALBACKTRACK; + XPRS.attr("USERSOLHEURISTIC") = XPRS_USERSOLHEURISTIC; + XPRS.attr("PRECONVERTOBJTOCONS") = XPRS_PRECONVERTOBJTOCONS; + XPRS.attr("FORCEPARALLELDUAL") = XPRS_FORCEPARALLELDUAL; + XPRS.attr("BACKTRACKTIE") = XPRS_BACKTRACKTIE; + XPRS.attr("BRANCHDISJ") = XPRS_BRANCHDISJ; + XPRS.attr("MIPFRACREDUCE") = XPRS_MIPFRACREDUCE; + XPRS.attr("CONCURRENTTHREADS") = XPRS_CONCURRENTTHREADS; + XPRS.attr("MAXSCALEFACTOR") = XPRS_MAXSCALEFACTOR; + XPRS.attr("HEURTHREADS") = XPRS_HEURTHREADS; + XPRS.attr("THREADS") = XPRS_THREADS; + XPRS.attr("HEURBEFORELP") = XPRS_HEURBEFORELP; + XPRS.attr("PREDOMROW") = XPRS_PREDOMROW; + XPRS.attr("BRANCHSTRUCTURAL") = XPRS_BRANCHSTRUCTURAL; + XPRS.attr("QUADRATICUNSHIFT") = XPRS_QUADRATICUNSHIFT; + XPRS.attr("BARPRESOLVEOPS") = XPRS_BARPRESOLVEOPS; + XPRS.attr("QSIMPLEXOPS") = XPRS_QSIMPLEXOPS; + XPRS.attr("MIPRESTART") = XPRS_MIPRESTART; + XPRS.attr("CONFLICTCUTS") = XPRS_CONFLICTCUTS; + XPRS.attr("PREPROTECTDUAL") = XPRS_PREPROTECTDUAL; + XPRS.attr("CORESPERCPU") = XPRS_CORESPERCPU; + XPRS.attr("RESOURCESTRATEGY") = XPRS_RESOURCESTRATEGY; + XPRS.attr("CLAMPING") = XPRS_CLAMPING; + XPRS.attr("PREDUPROW") = XPRS_PREDUPROW; + XPRS.attr("CPUPLATFORM") = XPRS_CPUPLATFORM; + XPRS.attr("BARALG") = XPRS_BARALG; + XPRS.attr("SIFTING") = XPRS_SIFTING; + XPRS.attr("BARKEEPLASTSOL") = XPRS_BARKEEPLASTSOL; + XPRS.attr("LPLOGSTYLE") = XPRS_LPLOGSTYLE; + XPRS.attr("RANDOMSEED") = XPRS_RANDOMSEED; + XPRS.attr("TREEQCCUTS") = XPRS_TREEQCCUTS; + XPRS.attr("PRELINDEP") = XPRS_PRELINDEP; + XPRS.attr("DUALTHREADS") = XPRS_DUALTHREADS; + XPRS.attr("PREOBJCUTDETECT") = XPRS_PREOBJCUTDETECT; + XPRS.attr("PREBNDREDQUAD") = XPRS_PREBNDREDQUAD; + XPRS.attr("PREBNDREDCONE") = XPRS_PREBNDREDCONE; + XPRS.attr("PRECOMPONENTS") = XPRS_PRECOMPONENTS; + XPRS.attr("MAXMIPTASKS") = XPRS_MAXMIPTASKS; + XPRS.attr("MIPTERMINATIONMETHOD") = XPRS_MIPTERMINATIONMETHOD; + XPRS.attr("PRECONEDECOMP") = XPRS_PRECONEDECOMP; + XPRS.attr("HEURFORCESPECIALOBJ") = XPRS_HEURFORCESPECIALOBJ; + XPRS.attr("HEURSEARCHROOTCUTFREQ") = XPRS_HEURSEARCHROOTCUTFREQ; + XPRS.attr("PREELIMQUAD") = XPRS_PREELIMQUAD; + XPRS.attr("PREIMPLICATIONS") = XPRS_PREIMPLICATIONS; + XPRS.attr("TUNERMODE") = XPRS_TUNERMODE; + XPRS.attr("TUNERMETHOD") = XPRS_TUNERMETHOD; + XPRS.attr("TUNERTARGET") = XPRS_TUNERTARGET; + XPRS.attr("TUNERTHREADS") = XPRS_TUNERTHREADS; + XPRS.attr("TUNERHISTORY") = XPRS_TUNERHISTORY; + XPRS.attr("TUNERPERMUTE") = XPRS_TUNERPERMUTE; + XPRS.attr("TUNERVERBOSE") = XPRS_TUNERVERBOSE; + XPRS.attr("TUNEROUTPUT") = XPRS_TUNEROUTPUT; + XPRS.attr("PREANALYTICCENTER") = XPRS_PREANALYTICCENTER; + XPRS.attr("LPFLAGS") = XPRS_LPFLAGS; + XPRS.attr("MIPKAPPAFREQ") = XPRS_MIPKAPPAFREQ; + XPRS.attr("OBJSCALEFACTOR") = XPRS_OBJSCALEFACTOR; + XPRS.attr("TREEFILELOGINTERVAL") = XPRS_TREEFILELOGINTERVAL; + XPRS.attr("IGNORECONTAINERCPULIMIT") = XPRS_IGNORECONTAINERCPULIMIT; + XPRS.attr("IGNORECONTAINERMEMORYLIMIT") = XPRS_IGNORECONTAINERMEMORYLIMIT; + XPRS.attr("MIPDUALREDUCTIONS") = XPRS_MIPDUALREDUCTIONS; + XPRS.attr("GENCONSDUALREDUCTIONS") = XPRS_GENCONSDUALREDUCTIONS; + XPRS.attr("PWLDUALREDUCTIONS") = XPRS_PWLDUALREDUCTIONS; + XPRS.attr("BARFAILITERLIMIT") = XPRS_BARFAILITERLIMIT; + XPRS.attr("AUTOSCALING") = XPRS_AUTOSCALING; + XPRS.attr("GENCONSABSTRANSFORMATION") = XPRS_GENCONSABSTRANSFORMATION; + XPRS.attr("COMPUTEJOBPRIORITY") = XPRS_COMPUTEJOBPRIORITY; + XPRS.attr("PREFOLDING") = XPRS_PREFOLDING; + XPRS.attr("COMPUTE") = XPRS_COMPUTE; + XPRS.attr("NETSTALLLIMIT") = XPRS_NETSTALLLIMIT; + XPRS.attr("SERIALIZEPREINTSOL") = XPRS_SERIALIZEPREINTSOL; + XPRS.attr("NUMERICALEMPHASIS") = XPRS_NUMERICALEMPHASIS; + XPRS.attr("PWLNONCONVEXTRANSFORMATION") = XPRS_PWLNONCONVEXTRANSFORMATION; + XPRS.attr("MIPCOMPONENTS") = XPRS_MIPCOMPONENTS; + XPRS.attr("MIPCONCURRENTNODES") = XPRS_MIPCONCURRENTNODES; + XPRS.attr("MIPCONCURRENTSOLVES") = XPRS_MIPCONCURRENTSOLVES; + XPRS.attr("OUTPUTCONTROLS") = XPRS_OUTPUTCONTROLS; + XPRS.attr("SIFTSWITCH") = XPRS_SIFTSWITCH; + XPRS.attr("HEUREMPHASIS") = XPRS_HEUREMPHASIS; + XPRS.attr("BARREFITER") = XPRS_BARREFITER; + XPRS.attr("COMPUTELOG") = XPRS_COMPUTELOG; + XPRS.attr("SIFTPRESOLVEOPS") = XPRS_SIFTPRESOLVEOPS; + XPRS.attr("CHECKINPUTDATA") = XPRS_CHECKINPUTDATA; + XPRS.attr("ESCAPENAMES") = XPRS_ESCAPENAMES; + XPRS.attr("IOTIMEOUT") = XPRS_IOTIMEOUT; + XPRS.attr("AUTOCUTTING") = XPRS_AUTOCUTTING; + XPRS.attr("GLOBALNUMINITNLPCUTS") = XPRS_GLOBALNUMINITNLPCUTS; + XPRS.attr("CALLBACKCHECKTIMEDELAY") = XPRS_CALLBACKCHECKTIMEDELAY; + XPRS.attr("MULTIOBJOPS") = XPRS_MULTIOBJOPS; + XPRS.attr("MULTIOBJLOG") = XPRS_MULTIOBJLOG; + XPRS.attr("BACKGROUNDMAXTHREADS") = XPRS_BACKGROUNDMAXTHREADS; + XPRS.attr("GLOBALLSHEURSTRATEGY") = XPRS_GLOBALLSHEURSTRATEGY; + XPRS.attr("GLOBALSPATIALBRANCHIFPREFERORIG") = XPRS_GLOBALSPATIALBRANCHIFPREFERORIG; + XPRS.attr("PRECONFIGURATION") = XPRS_PRECONFIGURATION; + XPRS.attr("FEASIBILITYJUMP") = XPRS_FEASIBILITYJUMP; + XPRS.attr("IISOPS") = XPRS_IISOPS; + XPRS.attr("RLTCUTS") = XPRS_RLTCUTS; + XPRS.attr("ALTERNATIVEREDCOSTS") = XPRS_ALTERNATIVEREDCOSTS; + XPRS.attr("HEURSHIFTPROP") = XPRS_HEURSHIFTPROP; + XPRS.attr("HEURSEARCHCOPYCONTROLS") = XPRS_HEURSEARCHCOPYCONTROLS; + XPRS.attr("GLOBALNLPCUTS") = XPRS_GLOBALNLPCUTS; + XPRS.attr("GLOBALTREENLPCUTS") = XPRS_GLOBALTREENLPCUTS; + XPRS.attr("BARHGOPS") = XPRS_BARHGOPS; + XPRS.attr("BARHGMAXRESTARTS") = XPRS_BARHGMAXRESTARTS; + XPRS.attr("MCFCUTSTRATEGY") = XPRS_MCFCUTSTRATEGY; + XPRS.attr("PREROOTTHREADS") = XPRS_PREROOTTHREADS; + XPRS.attr("BARITERATIVE") = XPRS_BARITERATIVE; + /* Integer control parameters that support 64-bit values */ + XPRS.attr("EXTRAELEMS") = XPRS_EXTRAELEMS; + XPRS.attr("EXTRASETELEMS") = XPRS_EXTRASETELEMS; + XPRS.attr("BACKGROUNDSELECT") = XPRS_BACKGROUNDSELECT; + XPRS.attr("HEURSEARCHBACKGROUNDSELECT") = XPRS_HEURSEARCHBACKGROUNDSELECT; + + /* attributes for XPRSprob */ + /* String attributes */ + XPRS.attr("MATRIXNAME") = XPRS_MATRIXNAME; + XPRS.attr("BOUNDNAME") = XPRS_BOUNDNAME; + XPRS.attr("RHSNAME") = XPRS_RHSNAME; + XPRS.attr("RANGENAME") = XPRS_RANGENAME; + XPRS.attr("XPRESSVERSION") = XPRS_XPRESSVERSION; + XPRS.attr("UUID") = XPRS_UUID; + /* Double attributes */ + XPRS.attr("MIPSOLTIME") = XPRS_MIPSOLTIME; + XPRS.attr("TIME") = XPRS_TIME; + XPRS.attr("LPOBJVAL") = XPRS_LPOBJVAL; + XPRS.attr("SUMPRIMALINF") = XPRS_SUMPRIMALINF; + XPRS.attr("MIPOBJVAL") = XPRS_MIPOBJVAL; + XPRS.attr("BESTBOUND") = XPRS_BESTBOUND; + XPRS.attr("OBJRHS") = XPRS_OBJRHS; + XPRS.attr("MIPBESTOBJVAL") = XPRS_MIPBESTOBJVAL; + XPRS.attr("OBJSENSE") = XPRS_OBJSENSE; + XPRS.attr("BRANCHVALUE") = XPRS_BRANCHVALUE; + XPRS.attr("PENALTYVALUE") = XPRS_PENALTYVALUE; + XPRS.attr("CURRMIPCUTOFF") = XPRS_CURRMIPCUTOFF; + XPRS.attr("BARCONDA") = XPRS_BARCONDA; + XPRS.attr("BARCONDD") = XPRS_BARCONDD; + XPRS.attr("MAXABSPRIMALINFEAS") = XPRS_MAXABSPRIMALINFEAS; + XPRS.attr("MAXRELPRIMALINFEAS") = XPRS_MAXRELPRIMALINFEAS; + XPRS.attr("MAXABSDUALINFEAS") = XPRS_MAXABSDUALINFEAS; + XPRS.attr("MAXRELDUALINFEAS") = XPRS_MAXRELDUALINFEAS; + XPRS.attr("PRIMALDUALINTEGRAL") = XPRS_PRIMALDUALINTEGRAL; + XPRS.attr("MAXMIPINFEAS") = XPRS_MAXMIPINFEAS; + XPRS.attr("ATTENTIONLEVEL") = XPRS_ATTENTIONLEVEL; + XPRS.attr("MAXKAPPA") = XPRS_MAXKAPPA; + XPRS.attr("TREECOMPLETION") = XPRS_TREECOMPLETION; + XPRS.attr("PREDICTEDATTLEVEL") = XPRS_PREDICTEDATTLEVEL; + XPRS.attr("OBSERVEDPRIMALINTEGRAL") = XPRS_OBSERVEDPRIMALINTEGRAL; + XPRS.attr("CPISCALEFACTOR") = XPRS_CPISCALEFACTOR; + XPRS.attr("OBJVAL") = XPRS_OBJVAL; + XPRS.attr("WORK") = XPRS_WORK; + XPRS.attr("BARPRIMALOBJ") = XPRS_BARPRIMALOBJ; + XPRS.attr("BARDUALOBJ") = XPRS_BARDUALOBJ; + XPRS.attr("BARPRIMALINF") = XPRS_BARPRIMALINF; + XPRS.attr("BARDUALINF") = XPRS_BARDUALINF; + XPRS.attr("BARCGAP") = XPRS_BARCGAP; + /* Integer attributes */ + XPRS.attr("ROWS") = XPRS_ROWS; + XPRS.attr("SETS") = XPRS_SETS; + XPRS.attr("PRIMALINFEAS") = XPRS_PRIMALINFEAS; + XPRS.attr("DUALINFEAS") = XPRS_DUALINFEAS; + XPRS.attr("SIMPLEXITER") = XPRS_SIMPLEXITER; + XPRS.attr("LPSTATUS") = XPRS_LPSTATUS; + XPRS.attr("MIPSTATUS") = XPRS_MIPSTATUS; + XPRS.attr("CUTS") = XPRS_CUTS; + XPRS.attr("NODES") = XPRS_NODES; + XPRS.attr("NODEDEPTH") = XPRS_NODEDEPTH; + XPRS.attr("ACTIVENODES") = XPRS_ACTIVENODES; + XPRS.attr("MIPSOLNODE") = XPRS_MIPSOLNODE; + XPRS.attr("MIPSOLS") = XPRS_MIPSOLS; + XPRS.attr("COLS") = XPRS_COLS; + XPRS.attr("SPAREROWS") = XPRS_SPAREROWS; + XPRS.attr("SPARECOLS") = XPRS_SPARECOLS; + XPRS.attr("SPAREMIPENTS") = XPRS_SPAREMIPENTS; + XPRS.attr("ERRORCODE") = XPRS_ERRORCODE; + XPRS.attr("MIPINFEAS") = XPRS_MIPINFEAS; + XPRS.attr("PRESOLVESTATE") = XPRS_PRESOLVESTATE; + XPRS.attr("PARENTNODE") = XPRS_PARENTNODE; + XPRS.attr("NAMELENGTH") = XPRS_NAMELENGTH; + XPRS.attr("QELEMS") = XPRS_QELEMS; + XPRS.attr("NUMIIS") = XPRS_NUMIIS; + XPRS.attr("MIPENTS") = XPRS_MIPENTS; + XPRS.attr("BRANCHVAR") = XPRS_BRANCHVAR; + XPRS.attr("MIPTHREADID") = XPRS_MIPTHREADID; + XPRS.attr("ALGORITHM") = XPRS_ALGORITHM; + XPRS.attr("CROSSOVERITER") = XPRS_CROSSOVERITER; + XPRS.attr("SOLSTATUS") = XPRS_SOLSTATUS; + XPRS.attr("CUTROUNDS") = XPRS_CUTROUNDS; + XPRS.attr("ORIGINALROWS") = XPRS_ORIGINALROWS; + XPRS.attr("CALLBACKCOUNT_OPTNODE") = XPRS_CALLBACKCOUNT_OPTNODE; + XPRS.attr("ORIGINALQELEMS") = XPRS_ORIGINALQELEMS; + XPRS.attr("MAXPROBNAMELENGTH") = XPRS_MAXPROBNAMELENGTH; + XPRS.attr("STOPSTATUS") = XPRS_STOPSTATUS; + XPRS.attr("ORIGINALMIPENTS") = XPRS_ORIGINALMIPENTS; + XPRS.attr("ORIGINALSETS") = XPRS_ORIGINALSETS; + XPRS.attr("SPARESETS") = XPRS_SPARESETS; + XPRS.attr("CHECKSONMAXTIME") = XPRS_CHECKSONMAXTIME; + XPRS.attr("CHECKSONMAXCUTTIME") = XPRS_CHECKSONMAXCUTTIME; + XPRS.attr("ORIGINALCOLS") = XPRS_ORIGINALCOLS; + XPRS.attr("QCELEMS") = XPRS_QCELEMS; + XPRS.attr("QCONSTRAINTS") = XPRS_QCONSTRAINTS; + XPRS.attr("ORIGINALQCELEMS") = XPRS_ORIGINALQCELEMS; + XPRS.attr("ORIGINALQCONSTRAINTS") = XPRS_ORIGINALQCONSTRAINTS; + XPRS.attr("PEAKTOTALTREEMEMORYUSAGE") = XPRS_PEAKTOTALTREEMEMORYUSAGE; + XPRS.attr("CURRENTNODE") = XPRS_CURRENTNODE; + XPRS.attr("TREEMEMORYUSAGE") = XPRS_TREEMEMORYUSAGE; + XPRS.attr("TREEFILESIZE") = XPRS_TREEFILESIZE; + XPRS.attr("TREEFILEUSAGE") = XPRS_TREEFILEUSAGE; + XPRS.attr("INDICATORS") = XPRS_INDICATORS; + XPRS.attr("ORIGINALINDICATORS") = XPRS_ORIGINALINDICATORS; + XPRS.attr("CORESPERCPUDETECTED") = XPRS_CORESPERCPUDETECTED; + XPRS.attr("CPUSDETECTED") = XPRS_CPUSDETECTED; + XPRS.attr("CORESDETECTED") = XPRS_CORESDETECTED; + XPRS.attr("PHYSICALCORESDETECTED") = XPRS_PHYSICALCORESDETECTED; + XPRS.attr("PHYSICALCORESPERCPUDETECTED") = XPRS_PHYSICALCORESPERCPUDETECTED; + XPRS.attr("OPTIMIZETYPEUSED") = XPRS_OPTIMIZETYPEUSED; + XPRS.attr("BARSING") = XPRS_BARSING; + XPRS.attr("BARSINGR") = XPRS_BARSINGR; + XPRS.attr("PRESOLVEINDEX") = XPRS_PRESOLVEINDEX; + XPRS.attr("CONES") = XPRS_CONES; + XPRS.attr("CONEELEMS") = XPRS_CONEELEMS; + XPRS.attr("PWLCONS") = XPRS_PWLCONS; + XPRS.attr("GENCONS") = XPRS_GENCONS; + XPRS.attr("TREERESTARTS") = XPRS_TREERESTARTS; + XPRS.attr("ORIGINALPWLS") = XPRS_ORIGINALPWLS; + XPRS.attr("ORIGINALGENCONS") = XPRS_ORIGINALGENCONS; + XPRS.attr("COMPUTEEXECUTIONS") = XPRS_COMPUTEEXECUTIONS; + XPRS.attr("RESTARTS") = XPRS_RESTARTS; + XPRS.attr("SOLVESTATUS") = XPRS_SOLVESTATUS; + XPRS.attr("GLOBALBOUNDINGBOXAPPLIED") = XPRS_GLOBALBOUNDINGBOXAPPLIED; + XPRS.attr("OBJECTIVES") = XPRS_OBJECTIVES; + XPRS.attr("SOLVEDOBJS") = XPRS_SOLVEDOBJS; + XPRS.attr("OBJSTOSOLVE") = XPRS_OBJSTOSOLVE; + XPRS.attr("GLOBALNLPINFEAS") = XPRS_GLOBALNLPINFEAS; + XPRS.attr("IISSOLSTATUS") = XPRS_IISSOLSTATUS; + XPRS.attr("INPUTROWS") = XPRS_INPUTROWS; + XPRS.attr("INPUTCOLS") = XPRS_INPUTCOLS; + XPRS.attr("BARITER") = XPRS_BARITER; + XPRS.attr("BARDENSECOL") = XPRS_BARDENSECOL; + XPRS.attr("BARCROSSOVER") = XPRS_BARCROSSOVER; + /* Integer attributes that support 64-bit values */ + XPRS.attr("SETMEMBERS") = XPRS_SETMEMBERS; + XPRS.attr("ELEMS") = XPRS_ELEMS; + XPRS.attr("SPAREELEMS") = XPRS_SPAREELEMS; + XPRS.attr("SYSTEMMEMORY") = XPRS_SYSTEMMEMORY; + XPRS.attr("ORIGINALSETMEMBERS") = XPRS_ORIGINALSETMEMBERS; + XPRS.attr("SPARESETELEMS") = XPRS_SPARESETELEMS; + XPRS.attr("CURRENTMEMORY") = XPRS_CURRENTMEMORY; + XPRS.attr("PEAKMEMORY") = XPRS_PEAKMEMORY; + XPRS.attr("TOTALMEMORY") = XPRS_TOTALMEMORY; + XPRS.attr("AVAILABLEMEMORY") = XPRS_AVAILABLEMEMORY; + XPRS.attr("PWLPOINTS") = XPRS_PWLPOINTS; + XPRS.attr("GENCONCOLS") = XPRS_GENCONCOLS; + XPRS.attr("GENCONVALS") = XPRS_GENCONVALS; + XPRS.attr("ORIGINALPWLPOINTS") = XPRS_ORIGINALPWLPOINTS; + XPRS.attr("ORIGINALGENCONCOLS") = XPRS_ORIGINALGENCONCOLS; + XPRS.attr("ORIGINALGENCONVALS") = XPRS_ORIGINALGENCONVALS; + XPRS.attr("MEMORYLIMITDETECTED") = XPRS_MEMORYLIMITDETECTED; + XPRS.attr("BARAASIZE") = XPRS_BARAASIZE; + XPRS.attr("BARLSIZE") = XPRS_BARLSIZE; + + // Nonlinear solver related controls and attributes + XPRS.attr("NLPFUNCEVAL") = XPRS_NLPFUNCEVAL; + XPRS.attr("NLPLOG") = XPRS_NLPLOG; + XPRS.attr("NLPKEEPEQUALSCOLUMN") = XPRS_NLPKEEPEQUALSCOLUMN; + XPRS.attr("NLPEVALUATE") = XPRS_NLPEVALUATE; + XPRS.attr("NLPPRESOLVE") = XPRS_NLPPRESOLVE; + XPRS.attr("SLPLOG") = XPRS_SLPLOG; + XPRS.attr("LOCALSOLVER") = XPRS_LOCALSOLVER; + XPRS.attr("NLPSTOPOUTOFRANGE") = XPRS_NLPSTOPOUTOFRANGE; + XPRS.attr("NLPTHREADSAFEUSERFUNC") = XPRS_NLPTHREADSAFEUSERFUNC; + XPRS.attr("NLPJACOBIAN") = XPRS_NLPJACOBIAN; + XPRS.attr("NLPHESSIAN") = XPRS_NLPHESSIAN; + XPRS.attr("MULTISTART") = XPRS_MULTISTART; + XPRS.attr("MULTISTART_THREADS") = XPRS_MULTISTART_THREADS; + XPRS.attr("MULTISTART_MAXSOLVES") = XPRS_MULTISTART_MAXSOLVES; + XPRS.attr("MULTISTART_MAXTIME") = XPRS_MULTISTART_MAXTIME; + XPRS.attr("NLPMAXTIME") = XPRS_NLPMAXTIME; + XPRS.attr("NLPDERIVATIVES") = XPRS_NLPDERIVATIVES; + XPRS.attr("NLPREFORMULATE") = XPRS_NLPREFORMULATE; + XPRS.attr("NLPPRESOLVEOPS") = XPRS_NLPPRESOLVEOPS; + XPRS.attr("MULTISTART_LOG") = XPRS_MULTISTART_LOG; + XPRS.attr("MULTISTART_SEED") = XPRS_MULTISTART_SEED; + XPRS.attr("MULTISTART_POOLSIZE") = XPRS_MULTISTART_POOLSIZE; + XPRS.attr("NLPPOSTSOLVE") = XPRS_NLPPOSTSOLVE; + XPRS.attr("NLPDETERMINISTIC") = XPRS_NLPDETERMINISTIC; + XPRS.attr("NLPPRESOLVELEVEL") = XPRS_NLPPRESOLVELEVEL; + XPRS.attr("NLPPROBING") = XPRS_NLPPROBING; + XPRS.attr("NLPCALCTHREADS") = XPRS_NLPCALCTHREADS; + XPRS.attr("NLPTHREADS") = XPRS_NLPTHREADS; + XPRS.attr("NLPFINDIV") = XPRS_NLPFINDIV; + XPRS.attr("NLPLINQUADBR") = XPRS_NLPLINQUADBR; + XPRS.attr("NLPSOLVER") = XPRS_NLPSOLVER; + // SLP related integer controls + XPRS.attr("SLPALGORITHM") = XPRS_SLPALGORITHM; + XPRS.attr("SLPAUGMENTATION") = XPRS_SLPAUGMENTATION; + XPRS.attr("SLPBARLIMIT") = XPRS_SLPBARLIMIT; + XPRS.attr("SLPCASCADE") = XPRS_SLPCASCADE; + XPRS.attr("SLPCASCADENLIMIT") = XPRS_SLPCASCADENLIMIT; + XPRS.attr("SLPDAMPSTART") = XPRS_SLPDAMPSTART; + XPRS.attr("SLPCUTSTRATEGY") = XPRS_SLPCUTSTRATEGY; + XPRS.attr("SLPDELTAZLIMIT") = XPRS_SLPDELTAZLIMIT; + XPRS.attr("SLPINFEASLIMIT") = XPRS_SLPINFEASLIMIT; + XPRS.attr("SLPITERLIMIT") = XPRS_SLPITERLIMIT; + XPRS.attr("SLPSAMECOUNT") = XPRS_SLPSAMECOUNT; + XPRS.attr("SLPSAMEDAMP") = XPRS_SLPSAMEDAMP; + XPRS.attr("SLPSBSTART") = XPRS_SLPSBSTART; + XPRS.attr("SLPXCOUNT") = XPRS_SLPXCOUNT; + XPRS.attr("SLPXLIMIT") = XPRS_SLPXLIMIT; + XPRS.attr("SLPDELAYUPDATEROWS") = XPRS_SLPDELAYUPDATEROWS; + XPRS.attr("SLPAUTOSAVE") = XPRS_SLPAUTOSAVE; + XPRS.attr("SLPANALYZE") = XPRS_SLPANALYZE; + XPRS.attr("SLPOCOUNT") = XPRS_SLPOCOUNT; + XPRS.attr("SLPMIPALGORITHM") = XPRS_SLPMIPALGORITHM; + XPRS.attr("SLPMIPRELAXSTEPBOUNDS") = XPRS_SLPMIPRELAXSTEPBOUNDS; + XPRS.attr("SLPMIPFIXSTEPBOUNDS") = XPRS_SLPMIPFIXSTEPBOUNDS; + XPRS.attr("SLPMIPITERLIMIT") = XPRS_SLPMIPITERLIMIT; + XPRS.attr("SLPMIPCUTOFFLIMIT") = XPRS_SLPMIPCUTOFFLIMIT; + XPRS.attr("SLPMIPOCOUNT") = XPRS_SLPMIPOCOUNT; + XPRS.attr("SLPMIPDEFAULTALGORITHM") = XPRS_SLPMIPDEFAULTALGORITHM; + XPRS.attr("SLPMIPLOG") = XPRS_SLPMIPLOG; + XPRS.attr("SLPDELTAOFFSET") = XPRS_SLPDELTAOFFSET; + XPRS.attr("SLPUPDATEOFFSET") = XPRS_SLPUPDATEOFFSET; + XPRS.attr("SLPERROROFFSET") = XPRS_SLPERROROFFSET; + XPRS.attr("SLPSBROWOFFSET") = XPRS_SLPSBROWOFFSET; + XPRS.attr("SLPVCOUNT") = XPRS_SLPVCOUNT; + XPRS.attr("SLPVLIMIT") = XPRS_SLPVLIMIT; + XPRS.attr("SLPSCALE") = XPRS_SLPSCALE; + XPRS.attr("SLPSCALECOUNT") = XPRS_SLPSCALECOUNT; + XPRS.attr("SLPECFCHECK") = XPRS_SLPECFCHECK; + XPRS.attr("SLPMIPCUTOFFCOUNT") = XPRS_SLPMIPCUTOFFCOUNT; + XPRS.attr("SLPWCOUNT") = XPRS_SLPWCOUNT; + XPRS.attr("SLPUNFINISHEDLIMIT") = XPRS_SLPUNFINISHEDLIMIT; + XPRS.attr("SLPCONVERGENCEOPS") = XPRS_SLPCONVERGENCEOPS; + XPRS.attr("SLPZEROCRITERION") = XPRS_SLPZEROCRITERION; + XPRS.attr("SLPZEROCRITERIONSTART") = XPRS_SLPZEROCRITERIONSTART; + XPRS.attr("SLPZEROCRITERIONCOUNT") = XPRS_SLPZEROCRITERIONCOUNT; + XPRS.attr("SLPLSPATTERNLIMIT") = XPRS_SLPLSPATTERNLIMIT; + XPRS.attr("SLPLSITERLIMIT") = XPRS_SLPLSITERLIMIT; + XPRS.attr("SLPLSSTART") = XPRS_SLPLSSTART; + XPRS.attr("SLPPENALTYINFOSTART") = XPRS_SLPPENALTYINFOSTART; + XPRS.attr("SLPFILTER") = XPRS_SLPFILTER; + XPRS.attr("SLPTRACEMASKOPS") = XPRS_SLPTRACEMASKOPS; + XPRS.attr("SLPLSZEROLIMIT") = XPRS_SLPLSZEROLIMIT; + XPRS.attr("SLPHEURSTRATEGY") = XPRS_SLPHEURSTRATEGY; + XPRS.attr("SLPBARCROSSOVERSTART") = XPRS_SLPBARCROSSOVERSTART; + XPRS.attr("SLPBARSTALLINGLIMIT") = XPRS_SLPBARSTALLINGLIMIT; + XPRS.attr("SLPBARSTALLINGOBJLIMIT") = XPRS_SLPBARSTALLINGOBJLIMIT; + XPRS.attr("SLPBARSTARTOPS") = XPRS_SLPBARSTARTOPS; + XPRS.attr("SLPGRIDHEURSELECT") = XPRS_SLPGRIDHEURSELECT; + // Nonlinear related double controls + XPRS.attr("NLPINFINITY") = XPRS_NLPINFINITY; + XPRS.attr("NLPZERO") = XPRS_NLPZERO; + XPRS.attr("NLPDEFAULTIV") = XPRS_NLPDEFAULTIV; + XPRS.attr("NLPOPTTIME") = XPRS_NLPOPTTIME; + XPRS.attr("NLPVALIDATIONTOL_A") = XPRS_NLPVALIDATIONTOL_A; + XPRS.attr("NLPVALIDATIONTOL_R") = XPRS_NLPVALIDATIONTOL_R; + XPRS.attr("NLPVALIDATIONINDEX_A") = XPRS_NLPVALIDATIONINDEX_A; + XPRS.attr("NLPVALIDATIONINDEX_R") = XPRS_NLPVALIDATIONINDEX_R; + XPRS.attr("NLPPRIMALINTEGRALREF") = XPRS_NLPPRIMALINTEGRALREF; + XPRS.attr("NLPPRIMALINTEGRALALPHA") = XPRS_NLPPRIMALINTEGRALALPHA; + XPRS.attr("NLPOBJVAL") = XPRS_NLPOBJVAL; + XPRS.attr("NLPPRESOLVEZERO") = XPRS_NLPPRESOLVEZERO; + XPRS.attr("NLPMERITLAMBDA") = XPRS_NLPMERITLAMBDA; + XPRS.attr("MSMAXBOUNDRANGE") = XPRS_MSMAXBOUNDRANGE; + XPRS.attr("NLPVALIDATIONTOL_K") = XPRS_NLPVALIDATIONTOL_K; + XPRS.attr("NLPPRESOLVE_ELIMTOL") = XPRS_NLPPRESOLVE_ELIMTOL; + XPRS.attr("NLPVALIDATIONTARGET_R") = XPRS_NLPVALIDATIONTARGET_R; + XPRS.attr("NLPVALIDATIONTARGET_K") = XPRS_NLPVALIDATIONTARGET_K; + XPRS.attr("NLPVALIDATIONFACTOR") = XPRS_NLPVALIDATIONFACTOR; + XPRS.attr("NLPRELTOLBOUNDTHRESHOLD") = XPRS_NLPRELTOLBOUNDTHRESHOLD; + // SLP related double controls + XPRS.attr("SLPDAMP") = XPRS_SLPDAMP; + XPRS.attr("SLPDAMPEXPAND") = XPRS_SLPDAMPEXPAND; + XPRS.attr("SLPDAMPSHRINK") = XPRS_SLPDAMPSHRINK; + XPRS.attr("SLPDELTA_A") = XPRS_SLPDELTA_A; + XPRS.attr("SLPDELTA_R") = XPRS_SLPDELTA_R; + XPRS.attr("SLPDELTA_Z") = XPRS_SLPDELTA_Z; + XPRS.attr("SLPDELTACOST") = XPRS_SLPDELTACOST; + XPRS.attr("SLPDELTAMAXCOST") = XPRS_SLPDELTAMAXCOST; + XPRS.attr("SLPDJTOL") = XPRS_SLPDJTOL; + XPRS.attr("SLPERRORCOST") = XPRS_SLPERRORCOST; + XPRS.attr("SLPERRORMAXCOST") = XPRS_SLPERRORMAXCOST; + XPRS.attr("SLPERRORTOL_A") = XPRS_SLPERRORTOL_A; + XPRS.attr("SLPEXPAND") = XPRS_SLPEXPAND; + XPRS.attr("SLPMAXWEIGHT") = XPRS_SLPMAXWEIGHT; + XPRS.attr("SLPMINWEIGHT") = XPRS_SLPMINWEIGHT; + XPRS.attr("SLPSHRINK") = XPRS_SLPSHRINK; + XPRS.attr("SLPCTOL") = XPRS_SLPCTOL; + XPRS.attr("SLPATOL_A") = XPRS_SLPATOL_A; + XPRS.attr("SLPATOL_R") = XPRS_SLPATOL_R; + XPRS.attr("SLPMTOL_A") = XPRS_SLPMTOL_A; + XPRS.attr("SLPMTOL_R") = XPRS_SLPMTOL_R; + XPRS.attr("SLPITOL_A") = XPRS_SLPITOL_A; + XPRS.attr("SLPITOL_R") = XPRS_SLPITOL_R; + XPRS.attr("SLPSTOL_A") = XPRS_SLPSTOL_A; + XPRS.attr("SLPSTOL_R") = XPRS_SLPSTOL_R; + XPRS.attr("SLPMVTOL") = XPRS_SLPMVTOL; + XPRS.attr("SLPXTOL_A") = XPRS_SLPXTOL_A; + XPRS.attr("SLPXTOL_R") = XPRS_SLPXTOL_R; + XPRS.attr("SLPDEFAULTSTEPBOUND") = XPRS_SLPDEFAULTSTEPBOUND; + XPRS.attr("SLPDAMPMAX") = XPRS_SLPDAMPMAX; + XPRS.attr("SLPDAMPMIN") = XPRS_SLPDAMPMIN; + XPRS.attr("SLPDELTACOSTFACTOR") = XPRS_SLPDELTACOSTFACTOR; + XPRS.attr("SLPERRORCOSTFACTOR") = XPRS_SLPERRORCOSTFACTOR; + XPRS.attr("SLPERRORTOL_P") = XPRS_SLPERRORTOL_P; + XPRS.attr("SLPCASCADETOL_PA") = XPRS_SLPCASCADETOL_PA; + XPRS.attr("SLPCASCADETOL_PR") = XPRS_SLPCASCADETOL_PR; + XPRS.attr("SLPCASCADETOL_Z") = XPRS_SLPCASCADETOL_Z; + XPRS.attr("SLPOTOL_A") = XPRS_SLPOTOL_A; + XPRS.attr("SLPOTOL_R") = XPRS_SLPOTOL_R; + XPRS.attr("SLPDELTA_X") = XPRS_SLPDELTA_X; + XPRS.attr("SLPERRORCOSTS") = XPRS_SLPERRORCOSTS; + XPRS.attr("SLPGRANULARITY") = XPRS_SLPGRANULARITY; + XPRS.attr("SLPMIPCUTOFF_A") = XPRS_SLPMIPCUTOFF_A; + XPRS.attr("SLPMIPCUTOFF_R") = XPRS_SLPMIPCUTOFF_R; + XPRS.attr("SLPMIPOTOL_A") = XPRS_SLPMIPOTOL_A; + XPRS.attr("SLPMIPOTOL_R") = XPRS_SLPMIPOTOL_R; + XPRS.attr("SLPESCALATION") = XPRS_SLPESCALATION; + XPRS.attr("SLPOBJTOPENALTYCOST") = XPRS_SLPOBJTOPENALTYCOST; + XPRS.attr("SLPSHRINKBIAS") = XPRS_SLPSHRINKBIAS; + XPRS.attr("SLPFEASTOLTARGET") = XPRS_SLPFEASTOLTARGET; + XPRS.attr("SLPOPTIMALITYTOLTARGET") = XPRS_SLPOPTIMALITYTOLTARGET; + XPRS.attr("SLPDELTA_INFINITY") = XPRS_SLPDELTA_INFINITY; + XPRS.attr("SLPVTOL_A") = XPRS_SLPVTOL_A; + XPRS.attr("SLPVTOL_R") = XPRS_SLPVTOL_R; + XPRS.attr("SLPETOL_A") = XPRS_SLPETOL_A; + XPRS.attr("SLPETOL_R") = XPRS_SLPETOL_R; + XPRS.attr("SLPEVTOL_A") = XPRS_SLPEVTOL_A; + XPRS.attr("SLPEVTOL_R") = XPRS_SLPEVTOL_R; + XPRS.attr("SLPDELTA_ZERO") = XPRS_SLPDELTA_ZERO; + XPRS.attr("SLPMINSBFACTOR") = XPRS_SLPMINSBFACTOR; + XPRS.attr("SLPCLAMPVALIDATIONTOL_A") = XPRS_SLPCLAMPVALIDATIONTOL_A; + XPRS.attr("SLPCLAMPVALIDATIONTOL_R") = XPRS_SLPCLAMPVALIDATIONTOL_R; + XPRS.attr("SLPCLAMPSHRINK") = XPRS_SLPCLAMPSHRINK; + XPRS.attr("SLPECFTOL_A") = XPRS_SLPECFTOL_A; + XPRS.attr("SLPECFTOL_R") = XPRS_SLPECFTOL_R; + XPRS.attr("SLPWTOL_A") = XPRS_SLPWTOL_A; + XPRS.attr("SLPWTOL_R") = XPRS_SLPWTOL_R; + XPRS.attr("SLPMATRIXTOL") = XPRS_SLPMATRIXTOL; + XPRS.attr("SLPDRFIXRANGE") = XPRS_SLPDRFIXRANGE; + XPRS.attr("SLPDRCOLTOL") = XPRS_SLPDRCOLTOL; + XPRS.attr("SLPMIPERRORTOL_A") = XPRS_SLPMIPERRORTOL_A; + XPRS.attr("SLPMIPERRORTOL_R") = XPRS_SLPMIPERRORTOL_R; + XPRS.attr("SLPCDTOL_A") = XPRS_SLPCDTOL_A; + XPRS.attr("SLPCDTOL_R") = XPRS_SLPCDTOL_R; + XPRS.attr("SLPENFORCEMAXCOST") = XPRS_SLPENFORCEMAXCOST; + XPRS.attr("SLPENFORCECOSTSHRINK") = XPRS_SLPENFORCECOSTSHRINK; + XPRS.attr("SLPDRCOLDJTOL") = XPRS_SLPDRCOLDJTOL; + XPRS.attr("SLPBARSTALLINGTOL") = XPRS_SLPBARSTALLINGTOL; + XPRS.attr("SLPOBJTHRESHOLD") = XPRS_SLPOBJTHRESHOLD; + XPRS.attr("SLPBOUNDTHRESHOLD") = XPRS_SLPBOUNDTHRESHOLD; + // Nonlinear related string controls + XPRS.attr("NLPIVNAME") = XPRS_NLPIVNAME; + // SLP related string controls + XPRS.attr("SLPDELTAFORMAT") = XPRS_SLPDELTAFORMAT; + XPRS.attr("SLPMINUSDELTAFORMAT") = XPRS_SLPMINUSDELTAFORMAT; + XPRS.attr("SLPMINUSERRORFORMAT") = XPRS_SLPMINUSERRORFORMAT; + XPRS.attr("SLPPLUSDELTAFORMAT") = XPRS_SLPPLUSDELTAFORMAT; + XPRS.attr("SLPPLUSERRORFORMAT") = XPRS_SLPPLUSERRORFORMAT; + XPRS.attr("SLPSBNAME") = XPRS_SLPSBNAME; + XPRS.attr("SLPTOLNAME") = XPRS_SLPTOLNAME; + XPRS.attr("SLPUPDATEFORMAT") = XPRS_SLPUPDATEFORMAT; + XPRS.attr("SLPPENALTYROWFORMAT") = XPRS_SLPPENALTYROWFORMAT; + XPRS.attr("SLPPENALTYCOLFORMAT") = XPRS_SLPPENALTYCOLFORMAT; + XPRS.attr("SLPSBLOROWFORMAT") = XPRS_SLPSBLOROWFORMAT; + XPRS.attr("SLPSBUPROWFORMAT") = XPRS_SLPSBUPROWFORMAT; + XPRS.attr("SLPTRACEMASK") = XPRS_SLPTRACEMASK; + XPRS.attr("SLPITERFALLBACKOPS") = XPRS_SLPITERFALLBACKOPS; + // Nonlinear related integer attributes + XPRS.attr("NLPVALIDATIONSTATUS") = XPRS_NLPVALIDATIONSTATUS; + XPRS.attr("NLPSOLSTATUS") = XPRS_NLPSOLSTATUS; + XPRS.attr("NLPORIGINALROWS") = XPRS_NLPORIGINALROWS; + XPRS.attr("NLPORIGINALCOLS") = XPRS_NLPORIGINALCOLS; + XPRS.attr("NLPUFS") = XPRS_NLPUFS; + XPRS.attr("NLPIFS") = XPRS_NLPIFS; + XPRS.attr("NLPEQUALSCOLUMN") = XPRS_NLPEQUALSCOLUMN; + XPRS.attr("NLPVARIABLES") = XPRS_NLPVARIABLES; + XPRS.attr("NLPIMPLICITVARIABLES") = XPRS_NLPIMPLICITVARIABLES; + XPRS.attr("NONLINEARCONSTRAINTS") = XPRS_NONLINEARCONSTRAINTS; + XPRS.attr("NLPUSERFUNCCALLS") = XPRS_NLPUSERFUNCCALLS; + XPRS.attr("NLPUSEDERIVATIVES") = XPRS_NLPUSEDERIVATIVES; + XPRS.attr("NLPKEEPBESTITER") = XPRS_NLPKEEPBESTITER; + XPRS.attr("NLPSTATUS") = XPRS_NLPSTATUS; + XPRS.attr("LOCALSOLVERSELECTED") = XPRS_LOCALSOLVERSELECTED; + XPRS.attr("NLPMODELROWS") = XPRS_NLPMODELROWS; + XPRS.attr("NLPMODELCOLS") = XPRS_NLPMODELCOLS; + XPRS.attr("NLPJOBID") = XPRS_NLPJOBID; + XPRS.attr("MSJOBS") = XPRS_MSJOBS; + XPRS.attr("NLPSTOPSTATUS") = XPRS_NLPSTOPSTATUS; + XPRS.attr("NLPPRESOLVEELIMINATIONS") = XPRS_NLPPRESOLVEELIMINATIONS; + XPRS.attr("NLPTOTALEVALUATIONERRORS") = XPRS_NLPTOTALEVALUATIONERRORS; + // SLP related integer attributes + XPRS.attr("SLPEXPLOREDELTAS") = XPRS_SLPEXPLOREDELTAS; + XPRS.attr("SLPSEMICONTDELTAS") = XPRS_SLPSEMICONTDELTAS; + XPRS.attr("SLPINTEGERDELTAS") = XPRS_SLPINTEGERDELTAS; + XPRS.attr("SLPITER") = XPRS_SLPITER; + XPRS.attr("SLPSTATUS") = XPRS_SLPSTATUS; + XPRS.attr("SLPUNCONVERGED") = XPRS_SLPUNCONVERGED; + XPRS.attr("SLPSBXCONVERGED") = XPRS_SLPSBXCONVERGED; + XPRS.attr("SLPPENALTYDELTAROW") = XPRS_SLPPENALTYDELTAROW; + XPRS.attr("SLPPENALTYDELTACOLUMN") = XPRS_SLPPENALTYDELTACOLUMN; + XPRS.attr("SLPPENALTYERRORROW") = XPRS_SLPPENALTYERRORROW; + XPRS.attr("SLPPENALTYERRORCOLUMN") = XPRS_SLPPENALTYERRORCOLUMN; + XPRS.attr("SLPCOEFFICIENTS") = XPRS_SLPCOEFFICIENTS; + XPRS.attr("SLPPENALTYDELTAS") = XPRS_SLPPENALTYDELTAS; + XPRS.attr("SLPPENALTYERRORS") = XPRS_SLPPENALTYERRORS; + XPRS.attr("SLPPLUSPENALTYERRORS") = XPRS_SLPPLUSPENALTYERRORS; + XPRS.attr("SLPMINUSPENALTYERRORS") = XPRS_SLPMINUSPENALTYERRORS; + XPRS.attr("SLPUCCONSTRAINEDCOUNT") = XPRS_SLPUCCONSTRAINEDCOUNT; + XPRS.attr("SLPMIPNODES") = XPRS_SLPMIPNODES; + XPRS.attr("SLPMIPITER") = XPRS_SLPMIPITER; + XPRS.attr("SLPTOLSETS") = XPRS_SLPTOLSETS; + XPRS.attr("SLPECFCOUNT") = XPRS_SLPECFCOUNT; + XPRS.attr("SLPDELTAS") = XPRS_SLPDELTAS; + XPRS.attr("SLPZEROESRESET") = XPRS_SLPZEROESRESET; + XPRS.attr("SLPZEROESTOTAL") = XPRS_SLPZEROESTOTAL; + XPRS.attr("SLPZEROESRETAINED") = XPRS_SLPZEROESRETAINED; + XPRS.attr("SLPNONCONSTANTCOEFFS") = XPRS_SLPNONCONSTANTCOEFFS; + XPRS.attr("SLPMIPSOLS") = XPRS_SLPMIPSOLS; + // Nonlinear related double attributes + XPRS.attr("NLPVALIDATIONINDEX_K") = XPRS_NLPVALIDATIONINDEX_K; + XPRS.attr("NLPVALIDATIONNETOBJ") = XPRS_NLPVALIDATIONNETOBJ; + XPRS.attr("NLPPRIMALINTEGRAL") = XPRS_NLPPRIMALINTEGRAL; + // SLP related double attributes + XPRS.attr("SLPCURRENTDELTACOST") = XPRS_SLPCURRENTDELTACOST; + XPRS.attr("SLPCURRENTERRORCOST") = XPRS_SLPCURRENTERRORCOST; + XPRS.attr("SLPPENALTYERRORTOTAL") = XPRS_SLPPENALTYERRORTOTAL; + XPRS.attr("SLPPENALTYERRORVALUE") = XPRS_SLPPENALTYERRORVALUE; + XPRS.attr("SLPPENALTYDELTATOTAL") = XPRS_SLPPENALTYDELTATOTAL; + XPRS.attr("SLPPENALTYDELTAVALUE") = XPRS_SLPPENALTYDELTAVALUE; + // Nonlinear related string attributes + // SLP related string attributes + // Knitro's parameters + XPRS.attr("KNITRO_PARAM_NEWPOINT") = XPRS_KNITRO_PARAM_NEWPOINT; + XPRS.attr("KNITRO_PARAM_HONORBNDS") = XPRS_KNITRO_PARAM_HONORBNDS; + XPRS.attr("KNITRO_PARAM_ALGORITHM") = XPRS_KNITRO_PARAM_ALGORITHM; + XPRS.attr("KNITRO_PARAM_BAR_MURULE") = XPRS_KNITRO_PARAM_BAR_MURULE; + XPRS.attr("KNITRO_PARAM_BAR_FEASIBLE") = XPRS_KNITRO_PARAM_BAR_FEASIBLE; + XPRS.attr("KNITRO_PARAM_GRADOPT") = XPRS_KNITRO_PARAM_GRADOPT; + XPRS.attr("KNITRO_PARAM_HESSOPT") = XPRS_KNITRO_PARAM_HESSOPT; + XPRS.attr("KNITRO_PARAM_BAR_INITPT") = XPRS_KNITRO_PARAM_BAR_INITPT; + XPRS.attr("KNITRO_PARAM_MAXCGIT") = XPRS_KNITRO_PARAM_MAXCGIT; + XPRS.attr("KNITRO_PARAM_MAXIT") = XPRS_KNITRO_PARAM_MAXIT; + XPRS.attr("KNITRO_PARAM_OUTLEV") = XPRS_KNITRO_PARAM_OUTLEV; + XPRS.attr("KNITRO_PARAM_SCALE") = XPRS_KNITRO_PARAM_SCALE; + XPRS.attr("KNITRO_PARAM_SOC") = XPRS_KNITRO_PARAM_SOC; + XPRS.attr("KNITRO_PARAM_DELTA") = XPRS_KNITRO_PARAM_DELTA; + XPRS.attr("KNITRO_PARAM_BAR_FEASMODETOL") = XPRS_KNITRO_PARAM_BAR_FEASMODETOL; + XPRS.attr("KNITRO_PARAM_FEASTOL") = XPRS_KNITRO_PARAM_FEASTOL; + XPRS.attr("KNITRO_PARAM_FEASTOLABS") = XPRS_KNITRO_PARAM_FEASTOLABS; + XPRS.attr("KNITRO_PARAM_BAR_INITMU") = XPRS_KNITRO_PARAM_BAR_INITMU; + XPRS.attr("KNITRO_PARAM_OBJRANGE") = XPRS_KNITRO_PARAM_OBJRANGE; + XPRS.attr("KNITRO_PARAM_OPTTOL") = XPRS_KNITRO_PARAM_OPTTOL; + XPRS.attr("KNITRO_PARAM_OPTTOLABS") = XPRS_KNITRO_PARAM_OPTTOLABS; + XPRS.attr("KNITRO_PARAM_PIVOT") = XPRS_KNITRO_PARAM_PIVOT; + XPRS.attr("KNITRO_PARAM_XTOL") = XPRS_KNITRO_PARAM_XTOL; + XPRS.attr("KNITRO_PARAM_DEBUG") = XPRS_KNITRO_PARAM_DEBUG; + XPRS.attr("KNITRO_PARAM_MULTISTART") = XPRS_KNITRO_PARAM_MULTISTART; + XPRS.attr("KNITRO_PARAM_MSMAXSOLVES") = XPRS_KNITRO_PARAM_MSMAXSOLVES; + XPRS.attr("KNITRO_PARAM_MSMAXBNDRANGE") = XPRS_KNITRO_PARAM_MSMAXBNDRANGE; + XPRS.attr("KNITRO_PARAM_LMSIZE") = XPRS_KNITRO_PARAM_LMSIZE; + XPRS.attr("KNITRO_PARAM_BAR_MAXCROSSIT") = XPRS_KNITRO_PARAM_BAR_MAXCROSSIT; + XPRS.attr("KNITRO_PARAM_BLASOPTION") = XPRS_KNITRO_PARAM_BLASOPTION; + XPRS.attr("KNITRO_PARAM_BAR_MAXREFACTOR") = XPRS_KNITRO_PARAM_BAR_MAXREFACTOR; + XPRS.attr("KNITRO_PARAM_BAR_MAXBACKTRACK") = XPRS_KNITRO_PARAM_BAR_MAXBACKTRACK; + XPRS.attr("KNITRO_PARAM_BAR_PENRULE") = XPRS_KNITRO_PARAM_BAR_PENRULE; + XPRS.attr("KNITRO_PARAM_BAR_PENCONS") = XPRS_KNITRO_PARAM_BAR_PENCONS; + XPRS.attr("KNITRO_PARAM_MSNUMTOSAVE") = XPRS_KNITRO_PARAM_MSNUMTOSAVE; + XPRS.attr("KNITRO_PARAM_MSSAVETOL") = XPRS_KNITRO_PARAM_MSSAVETOL; + XPRS.attr("KNITRO_PARAM_MSTERMINATE") = XPRS_KNITRO_PARAM_MSTERMINATE; + XPRS.attr("KNITRO_PARAM_MSSTARTPTRANGE") = XPRS_KNITRO_PARAM_MSSTARTPTRANGE; + XPRS.attr("KNITRO_PARAM_INFEASTOL") = XPRS_KNITRO_PARAM_INFEASTOL; + XPRS.attr("KNITRO_PARAM_LINSOLVER") = XPRS_KNITRO_PARAM_LINSOLVER; + XPRS.attr("KNITRO_PARAM_BAR_DIRECTINTERVAL") = XPRS_KNITRO_PARAM_BAR_DIRECTINTERVAL; + XPRS.attr("KNITRO_PARAM_PRESOLVE") = XPRS_KNITRO_PARAM_PRESOLVE; + XPRS.attr("KNITRO_PARAM_PRESOLVE_TOL") = XPRS_KNITRO_PARAM_PRESOLVE_TOL; + XPRS.attr("KNITRO_PARAM_BAR_SWITCHRULE") = XPRS_KNITRO_PARAM_BAR_SWITCHRULE; + XPRS.attr("KNITRO_PARAM_MA_TERMINATE") = XPRS_KNITRO_PARAM_MA_TERMINATE; + XPRS.attr("KNITRO_PARAM_MSSEED") = XPRS_KNITRO_PARAM_MSSEED; + XPRS.attr("KNITRO_PARAM_BAR_RELAXCONS") = XPRS_KNITRO_PARAM_BAR_RELAXCONS; + XPRS.attr("KNITRO_PARAM_SOLTYPE") = XPRS_KNITRO_PARAM_SOLTYPE; + XPRS.attr("KNITRO_PARAM_MIP_METHOD") = XPRS_KNITRO_PARAM_MIP_METHOD; + XPRS.attr("KNITRO_PARAM_MIP_BRANCHRULE") = XPRS_KNITRO_PARAM_MIP_BRANCHRULE; + XPRS.attr("KNITRO_PARAM_MIP_SELECTRULE") = XPRS_KNITRO_PARAM_MIP_SELECTRULE; + XPRS.attr("KNITRO_PARAM_MIP_INTGAPABS") = XPRS_KNITRO_PARAM_MIP_INTGAPABS; + XPRS.attr("KNITRO_PARAM_MIP_INTGAPREL") = XPRS_KNITRO_PARAM_MIP_INTGAPREL; + XPRS.attr("KNITRO_PARAM_MIP_OUTLEVEL") = XPRS_KNITRO_PARAM_MIP_OUTLEVEL; + XPRS.attr("KNITRO_PARAM_MIP_OUTINTERVAL") = XPRS_KNITRO_PARAM_MIP_OUTINTERVAL; + XPRS.attr("KNITRO_PARAM_MIP_DEBUG") = XPRS_KNITRO_PARAM_MIP_DEBUG; + XPRS.attr("KNITRO_PARAM_MIP_IMPLICATNS") = XPRS_KNITRO_PARAM_MIP_IMPLICATNS; + XPRS.attr("KNITRO_PARAM_MIP_GUB_BRANCH") = XPRS_KNITRO_PARAM_MIP_GUB_BRANCH; + XPRS.attr("KNITRO_PARAM_MIP_KNAPSACK") = XPRS_KNITRO_PARAM_MIP_KNAPSACK; + XPRS.attr("KNITRO_PARAM_MIP_ROUNDING") = XPRS_KNITRO_PARAM_MIP_ROUNDING; + XPRS.attr("KNITRO_PARAM_MIP_ROOTALG") = XPRS_KNITRO_PARAM_MIP_ROOTALG; + XPRS.attr("KNITRO_PARAM_MIP_LPALG") = XPRS_KNITRO_PARAM_MIP_LPALG; + XPRS.attr("KNITRO_PARAM_MIP_MAXNODES") = XPRS_KNITRO_PARAM_MIP_MAXNODES; + XPRS.attr("KNITRO_PARAM_MIP_HEURISTIC") = XPRS_KNITRO_PARAM_MIP_HEURISTIC; + XPRS.attr("KNITRO_PARAM_MIP_HEUR_MAXIT") = XPRS_KNITRO_PARAM_MIP_HEUR_MAXIT; + XPRS.attr("KNITRO_PARAM_MIP_PSEUDOINIT") = XPRS_KNITRO_PARAM_MIP_PSEUDOINIT; + XPRS.attr("KNITRO_PARAM_MIP_STRONG_MAXIT") = XPRS_KNITRO_PARAM_MIP_STRONG_MAXIT; + XPRS.attr("KNITRO_PARAM_MIP_STRONG_CANDLIM") = XPRS_KNITRO_PARAM_MIP_STRONG_CANDLIM; + XPRS.attr("KNITRO_PARAM_MIP_STRONG_LEVEL") = XPRS_KNITRO_PARAM_MIP_STRONG_LEVEL; + XPRS.attr("KNITRO_PARAM_PAR_NUMTHREADS") = XPRS_KNITRO_PARAM_PAR_NUMTHREADS; + + nb::enum_(XPRS, "SOLSTATUS") + .value("NOTFOUND", SOLSTATUS::NOTFOUND) + .value("OPTIMAL", SOLSTATUS::OPTIMAL) + .value("FEASIBLE", SOLSTATUS::FEASIBLE) + .value("INFEASIBLE", SOLSTATUS::INFEASIBLE) + .value("UNBOUNDED", SOLSTATUS::UNBOUNDED); + + nb::enum_(XPRS, "SOLVESTATUS") + .value("UNSTARTED", SOLVESTATUS::UNSTARTED) + .value("STOPPED", SOLVESTATUS::STOPPED) + .value("FAILED", SOLVESTATUS::FAILED) + .value("COMPLETED", SOLVESTATUS::COMPLETED); + + nb::enum_(XPRS, "LPSTATUS") + .value("UNSTARTED", LPSTATUS::UNSTARTED) + .value("OPTIMAL", LPSTATUS::OPTIMAL) + .value("INFEAS", LPSTATUS::INFEAS) + .value("CUTOFF", LPSTATUS::CUTOFF) + .value("UNFINISHED", LPSTATUS::UNFINISHED) + .value("UNBOUNDED", LPSTATUS::UNBOUNDED) + .value("CUTOFF_IN_DUAL", LPSTATUS::CUTOFF_IN_DUAL) + .value("UNSOLVED", LPSTATUS::UNSOLVED) + .value("NONCONVEX", LPSTATUS::NONCONVEX); + + nb::enum_(XPRS, "MIPSTATUS") + .value("NOT_LOADED", MIPSTATUS::NOT_LOADED) + .value("LP_NOT_OPTIMAL", MIPSTATUS::LP_NOT_OPTIMAL) + .value("LP_OPTIMAL", MIPSTATUS::LP_OPTIMAL) + .value("NO_SOL_FOUND", MIPSTATUS::NO_SOL_FOUND) + .value("SOLUTION", MIPSTATUS::SOLUTION) + .value("INFEAS", MIPSTATUS::INFEAS) + .value("OPTIMAL", MIPSTATUS::OPTIMAL) + .value("UNBOUNDED", MIPSTATUS::UNBOUNDED); + + nb::enum_(XPRS, "NLPSTATUS") + .value("UNSTARTED", NLPSTATUS::UNSTARTED) + .value("SOLUTION", NLPSTATUS::SOLUTION) + .value("LOCALLY_OPTIMAL", NLPSTATUS::LOCALLY_OPTIMAL) + .value("OPTIMAL", NLPSTATUS::OPTIMAL) + .value("NOSOLUTION", NLPSTATUS::NOSOLUTION) + .value("LOCALLY_INFEASIBLE", NLPSTATUS::LOCALLY_INFEASIBLE) + .value("INFEASIBLE", NLPSTATUS::INFEASIBLE) + .value("UNBOUNDED", NLPSTATUS::UNBOUNDED) + .value("UNFINISHED", NLPSTATUS::UNFINISHED) + .value("UNSOLVED", NLPSTATUS::UNSOLVED); + + nb::enum_(XPRS, "IISSOLSTATUS") + .value("UNSTARTED", IISSOLSTATUS::UNSTARTED) + .value("FEASIBLE", IISSOLSTATUS::FEASIBLE) + .value("COMPLETED", IISSOLSTATUS::COMPLETED) + .value("UNFINISHED", IISSOLSTATUS::UNFINISHED); + + nb::enum_(XPRS, "SOLAVAILABLE") + .value("NOTFOUND", SOLAVAILABLE::NOTFOUND) + .value("OPTIMAL", SOLAVAILABLE::OPTIMAL) + .value("FEASIBLE", SOLAVAILABLE::FEASIBLE); + + nb::enum_(XPRS, "OPTIMIZETYPE") + .value("NONE", OPTIMIZETYPE::NONE) + .value("LP", OPTIMIZETYPE::LP) + .value("MIP", OPTIMIZETYPE::MIP) + .value("LOCAL", OPTIMIZETYPE::LOCAL) + .value("GLOBAL", OPTIMIZETYPE::GLOBAL); + + // Define Callbacks context enum + auto to_upper = [](char const *name) { + std::string res(name); + for (char &c : res) + c = std::toupper(c); + return res; + }; + nb::enum_(XPRS, "CB_CONTEXT", nb::is_arithmetic()) + // Use the callback list to define a value for each callback +#define XPRSCB_NB_ENUM(ID, NAME, ...) .value(to_upper(#NAME).c_str(), CB_CONTEXT::NAME) + XPRSCB_LIST(XPRSCB_NB_ENUM, XPRSCB_ARG_IGNORE); +#undef XPRSCB_NB_ENUM +} diff --git a/optimizer_version.toml b/optimizer_version.toml index b2b06aad..9bfbccbb 100644 --- a/optimizer_version.toml +++ b/optimizer_version.toml @@ -3,3 +3,4 @@ COPT = "7.2.8" MOSEK = "10.2.0" HiGHS = "1.10.0" IPOPT = "3.13.2" +Xpress = "9.8" diff --git a/src/pyoptinterface/_src/xpress.py b/src/pyoptinterface/_src/xpress.py new file mode 100644 index 00000000..62518935 --- /dev/null +++ b/src/pyoptinterface/_src/xpress.py @@ -0,0 +1,655 @@ +import os +import platform +from pathlib import Path +import logging +from typing import Dict, Tuple, Union, overload + +from .xpress_model_ext import RawModel, Env, load_library, XPRS +from .attributes import ( + VariableAttribute, + ConstraintAttribute, + ModelAttribute, + ResultStatusCode, + TerminationStatusCode, +) +from .core_ext import ( + VariableIndex, + ScalarAffineFunction, + ScalarQuadraticFunction, + ExprBuilder, + VariableDomain, + ConstraintType, + ConstraintSense, + ObjectiveSense, +) +from .nlexpr_ext import ExpressionHandle +from .nlfunc import ExpressionGraphContext, convert_to_expressionhandle +from .comparison_constraint import ComparisonConstraint +from .solver_common import ( + _get_model_attribute, + _set_model_attribute, + _get_entity_attribute, + _direct_get_entity_attribute, + _set_entity_attribute, + _direct_set_entity_attribute, +) + +from .aml import make_variable_tupledict, make_variable_ndarray +from .matrix import add_matrix_constraints + + +def detected_libraries(): + libs = [] + + subdir = { + "Linux": "lib", + "Darwin": "lib", + "Windows": "bin", + }[platform.system()] + libname = { + "Linux": "libxprs.so", + "Darwin": "libxprs.dylib", + "Windows": "xprs.dll", + }[platform.system()] + + # Environment + home = os.environ.get("XPRESSDIR", None) + if home and os.path.exists(home): + lib = Path(home) / subdir / libname + if lib.exists(): + libs.append(str(lib)) + + # default names + default_libname = libname + libs.append(default_libname) + + return libs + + +def autoload_library(): + libs = detected_libraries() + for lib in libs: + ret = load_library(lib) + if ret: + logging.info(f"Loaded Xpress library: {lib}") + return True + return False + + +autoload_library() + + +# LP status codes (TerminationStatus, RawStatusString) +_RAW_LPSTATUS_STRINGS = { + XPRS.LPSTATUS.UNSTARTED: ( + TerminationStatusCode.OPTIMIZE_NOT_CALLED, + "LP problem optimization not started", + ), + XPRS.LPSTATUS.OPTIMAL: ( + TerminationStatusCode.OPTIMAL, + "Optimal LP solution found", + ), + XPRS.LPSTATUS.INFEAS: ( + TerminationStatusCode.INFEASIBLE, + "Infeasible LP problem", + ), + XPRS.LPSTATUS.CUTOFF: ( + TerminationStatusCode.OBJECTIVE_LIMIT, + "LP problem objective worse than cutoff value", + ), + XPRS.LPSTATUS.UNFINISHED: ( + TerminationStatusCode.ITERATION_LIMIT, + "LP problem optimization unfinished", + ), + XPRS.LPSTATUS.UNBOUNDED: ( + TerminationStatusCode.DUAL_INFEASIBLE, + "LP problem is unbounded", + ), + XPRS.LPSTATUS.CUTOFF_IN_DUAL: ( + TerminationStatusCode.OBJECTIVE_LIMIT, + "LP dual bound is worse than dual cutoff value", + ), + XPRS.LPSTATUS.UNSOLVED: ( + TerminationStatusCode.NUMERICAL_ERROR, + "LP problem could not be solved due to numerical issues", + ), + XPRS.LPSTATUS.NONCONVEX: ( + TerminationStatusCode.INVALID_MODEL, + "LP problem contains quadratic data which is not convex, consider using FICO Xpress Global", + ), +} + +# MIP status codes (TerminationStatus, RawStatusString) +_RAW_MIPSTATUS_STRINGS = { + XPRS.MIPSTATUS.NOT_LOADED: ( + TerminationStatusCode.OPTIMIZE_NOT_CALLED, + "MIP problem has not been loaded", + ), + XPRS.MIPSTATUS.LP_NOT_OPTIMAL: ( + TerminationStatusCode.ITERATION_LIMIT, + "MIP search incomplete, the initial continuous relaxation has not been solved and no integer solution has been found", + ), + XPRS.MIPSTATUS.LP_OPTIMAL: ( + TerminationStatusCode.ITERATION_LIMIT, + "MIP search incomplete, the initial continuous relaxation has been solved and no integer solution has been found", + ), + XPRS.MIPSTATUS.NO_SOL_FOUND: ( + TerminationStatusCode.ITERATION_LIMIT, + "MIP search incomplete, no integer solution found", + ), + XPRS.MIPSTATUS.SOLUTION: ( + TerminationStatusCode.ITERATION_LIMIT, + "MIP search incomplete, an integer solution has been found", + ), + XPRS.MIPSTATUS.INFEAS: ( + TerminationStatusCode.INFEASIBLE, + "MIP search complete, MIP is infeasible, no integer solution found", + ), + XPRS.MIPSTATUS.OPTIMAL: ( + TerminationStatusCode.OPTIMAL, + "MIP search complete, optimal integer solution found", + ), + XPRS.MIPSTATUS.UNBOUNDED: ( + TerminationStatusCode.DUAL_INFEASIBLE, + "MIP search incomplete, the initial continuous relaxation was found to be unbounded. A solution may have been found", + ), +} + +# NLP status codes (TerminationStatus, RawStatusString) +_RAW_NLPSTATUS_STRINGS = { + XPRS.NLPSTATUS.UNSTARTED: ( + TerminationStatusCode.OPTIMIZE_NOT_CALLED, + "Optimization unstarted", + ), + XPRS.NLPSTATUS.SOLUTION: ( + TerminationStatusCode.LOCALLY_SOLVED, + "Solution found", + ), + XPRS.NLPSTATUS.OPTIMAL: ( + TerminationStatusCode.OPTIMAL, + "Globally optimal", + ), + XPRS.NLPSTATUS.NOSOLUTION: ( + TerminationStatusCode.ITERATION_LIMIT, + "No solution found", + ), + XPRS.NLPSTATUS.INFEASIBLE: ( + TerminationStatusCode.INFEASIBLE, + "Proven infeasible", + ), + XPRS.NLPSTATUS.UNBOUNDED: ( + TerminationStatusCode.DUAL_INFEASIBLE, + "Locally unbounded", + ), + XPRS.NLPSTATUS.UNFINISHED: ( + TerminationStatusCode.ITERATION_LIMIT, + "Not yet solved to completion", + ), + XPRS.NLPSTATUS.UNSOLVED: ( + TerminationStatusCode.NUMERICAL_ERROR, + "Could not be solved due to numerical issues", + ), +} + + +def get_terminationstatus(model): + opt_type = model.get_optimize_type() + + if opt_type == XPRS.OPTIMIZETYPE.LP: + raw_status = model.get_lp_status() + status_string_pair = _RAW_LPSTATUS_STRINGS.get(raw_status, None) + elif opt_type == XPRS.OPTIMIZETYPE.MIP: + raw_status = model.get_mip_status() + status_string_pair = _RAW_MIPSTATUS_STRINGS.get(raw_status, None) + else: # NLP or LOCAL + raw_status = model.get_nlp_status() + status_string_pair = _RAW_NLPSTATUS_STRINGS.get(raw_status, None) + + if not status_string_pair: + raise ValueError(f"Unknown termination status: {raw_status}") + return status_string_pair[0] + + +def get_primalstatus(model): + opt_type = model.get_optimize_type() + + if opt_type == XPRS.OPTIMIZETYPE.LP: + status = model.get_lp_status() + if status == XPRS.LPSTATUS.OPTIMAL: + return ResultStatusCode.FEASIBLE_POINT + return ResultStatusCode.NO_SOLUTION + + elif opt_type == XPRS.OPTIMIZETYPE.MIP: + status = model.get_mip_status() + if model.get_raw_attribute_int_by_id(XPRS.MIPSOLS) > 0: + return ResultStatusCode.FEASIBLE_POINT + return ResultStatusCode.NO_SOLUTION + + else: # NLP or LOCAL + status = model.get_nlp_status() + if status in ( + XPRS.NLPSTATUS.OPTIMAL, + XPRS.NLPSTATUS.SOLUTION, + XPRS.NLPSTATUS.UNBOUNDED, + ): + return ResultStatusCode.FEASIBLE_POINT + return ResultStatusCode.NO_SOLUTION + + +def get_dualstatus(model): + opt_type = model.get_optimize_type() + if opt_type != XPRS.OPTIMIZETYPE.LP: + return ResultStatusCode.NO_SOLUTION + + status = model.get_lp_status() + if status == XPRS.LPSTATUS.OPTIMAL: + return ResultStatusCode.FEASIBLE_POINT + return ResultStatusCode.NO_SOLUTION + + +def get_rawstatusstring(model): + opt_type = model.get_optimize_type() + + if opt_type == XPRS.OPTIMIZETYPE.LP: + raw_status = model.get_lp_status() + status_string_pair = _RAW_LPSTATUS_STRINGS.get(raw_status, None) + elif opt_type == XPRS.OPTIMIZETYPE.MIP: + raw_status = model.get_mip_status() + status_string_pair = _RAW_MIPSTATUS_STRINGS.get(raw_status, None) + else: # NLP or LOCAL + raw_status = model.get_nlp_status() + status_string_pair = _RAW_NLPSTATUS_STRINGS.get(raw_status, None) + + if not status_string_pair: + raise ValueError(f"Unknown termination status: {raw_status}") + return status_string_pair[1] + + +# Variable maps +variable_attribute_get_func_map = { # UB, LB, Name, etc + VariableAttribute.Value: lambda model, v: model.get_variable_value(v), + VariableAttribute.LowerBound: lambda model, v: model.get_variable_lowerbound(v), + VariableAttribute.UpperBound: lambda model, v: model.get_variable_upperbound(v), + VariableAttribute.PrimalStart: lambda model, v: model.get_variable_mip_start(v), + VariableAttribute.Domain: lambda model, v: model.get_variable_type(v), + VariableAttribute.Name: lambda model, v: model.get_variable_name(v), + VariableAttribute.IISLowerBound: lambda model, v: model.get_variable_lowerbound_IIS( + v + ), + VariableAttribute.IISUpperBound: lambda model, v: model.get_variable_upperbound_IIS( + v + ), + # VariableAttribute.??: lambda model, v: model.get_variable_rc(v), +} + +variable_attribute_set_func_map = ( + { # Subset of the previous one about stuff that can be set + VariableAttribute.LowerBound: lambda model, v, x: model.set_variable_lowerbound( + v, x + ), + VariableAttribute.UpperBound: lambda model, v, x: model.set_variable_upperbound( + v, x + ), + VariableAttribute.PrimalStart: lambda model, v, x: model.set_variable_mip_start( + v, x + ), + VariableAttribute.Domain: lambda model, v, x: model.set_variable_type(v, x), + VariableAttribute.Name: lambda model, v, x: model.set_variable_name(v, x), + } +) + +constraint_attribute_get_func_map = { + ConstraintAttribute.Name: lambda model, c: model.get_constraint_name(c), + ConstraintAttribute.Primal: lambda model, c: model.get_normalized_rhs(c) + - model.get_constraint_slack(c), + ConstraintAttribute.Dual: lambda model, c: model.get_constraint_dual(c), + ConstraintAttribute.IIS: lambda model, c: model.is_constraint_in_IIS(c), +} + +constraint_attribute_set_func_map = { + ConstraintAttribute.Name: lambda model, constraint, value: model.set_constraint_name( + constraint, value + ), +} + +model_attribute_get_func_map = { + ModelAttribute.Name: lambda model: model.get_problem_name(), + ModelAttribute.ObjectiveSense: lambda model: model.get_raw_attribute_dbl_by_id( + XPRS.OBJSENSE + ), + ModelAttribute.BarrierIterations: lambda model: model.get_raw_attribute_int_by_id( + XPRS.BARITER + ), + ModelAttribute.DualObjectiveValue: lambda model: model.get_raw_attribute_dbl_by_id( + XPRS.LPOBJVAL + ), + ModelAttribute.NodeCount: lambda model: model.get_raw_attribute_int_by_id( + XPRS.NODES + ), + ModelAttribute.ObjectiveBound: lambda model: model.get_raw_attribute_dbl_by_id( + XPRS.LPOBJVAL + ), + ModelAttribute.ObjectiveValue: lambda model: model.get_raw_attribute_dbl_by_id( + XPRS.OBJVAL + ), + ModelAttribute.SimplexIterations: lambda model: model.get_raw_attribute_int_by_id( + XPRS.SIMPLEXITER + ), + ModelAttribute.SolveTimeSec: lambda model: model.get_raw_attribute_dbl_by_id( + XPRS.TIME + ), + ModelAttribute.NumberOfThreads: lambda model: model.get_raw_control_int( + XPRS.THREADS + ), + ModelAttribute.RelativeGap: lambda model: model.get_raw_control_dbl_by_id( + XPRS.MIPRELSTOP + ), + ModelAttribute.TimeLimitSec: lambda model: model.get_raw_contorl_dbl_by_id( + XPRS.TIMELIMIT + ), + ModelAttribute.DualStatus: get_dualstatus, + ModelAttribute.PrimalStatus: get_primalstatus, + ModelAttribute.RawStatusString: get_rawstatusstring, + ModelAttribute.TerminationStatus: get_terminationstatus, + ModelAttribute.Silent: lambda model: model.get_raw_control_int_by_id(XPRS.OUTPUTLOG) + == 0, + ModelAttribute.SolverName: lambda _: "FICO Xpress", + ModelAttribute.SolverVersion: lambda model: model.version_string(), +} + +model_control_set_func_map = { + ModelAttribute.Name: lambda model, value: model.set_problem_name(value), + ModelAttribute.ObjectiveSense: lambda model, value: model.set_raw_control_dbl_by_id( + XPRS.OBJSENSE, value + ), + ModelAttribute.NumberOfThreads: lambda model, value: model.set_raw_control_int_by_id( + XPRS.THREADS, value + ), + ModelAttribute.TimeLimitSec: lambda model, value: model.set_raw_control_dbl_by_id( + XPRS.TIMELIMIT, value + ), + ModelAttribute.Silent: lambda model, value: model.set_raw_control_int_by_id( + XPRS.OUTPUTLOG, 0 if value else 1 + ), +} + +model_attribute_get_translate_func_map = { + ModelAttribute.ObjectiveSense: lambda v: { + XPRS.OBJ_MINIMIZE: ObjectiveSense.Minimize, + XPRS.OBJ_MAXIMIZE: ObjectiveSense.Maximize, + }[v], +} + +model_attribute_set_translate_func_map = { + ModelAttribute.ObjectiveSense: lambda v: { + ObjectiveSense.Minimize: XPRS.OBJ_MINIMIZE, + ObjectiveSense.Maximize: XPRS.OBJ_MAXIMIZE, + }[v], +} + +DEFAULT_ENV = None + + +def init_default_env(): + global DEFAULT_ENV + if DEFAULT_ENV is None: + DEFAULT_ENV = Env() + + +class Model(RawModel): + def __init__(self, env=None): + # Initializing with raw model object + if isinstance(env, RawModel): + super().__init__(env) + return + + if env is None: + init_default_env() + env = DEFAULT_ENV + super().__init__(env) + self.mip_start_values: Dict[VariableIndex, float] = dict() + + def optimize(self): + if self._is_mip(): + mip_start = self.mip_start_values + if len(mip_start) != 0: + variables = list(mip_start.keys()) + values = list(mip_start.values()) + self.add_mip_start(variables, values) + mip_start.clear() + super().optimize() + + @staticmethod + def supports_variable_attribute(attribute: VariableAttribute, settable=False): + if settable: + return attribute in variable_attribute_set_func_map + else: + return attribute in variable_attribute_get_func_map + + @staticmethod + def supports_model_attribute(attribute: ModelAttribute, settable=False): + if settable: + return attribute in model_control_set_func_map + else: + return attribute in model_attribute_get_func_map + + @staticmethod + def supports_constraint_attribute(attribute: ConstraintAttribute, settable=False): + if settable: + return attribute in constraint_attribute_set_func_map + else: + return attribute in constraint_attribute_get_func_map + + def get_variable_attribute(self, variable, attribute: VariableAttribute): + def e(attribute): + raise ValueError(f"Unknown variable attribute to get: {attribute}") + + value = _direct_get_entity_attribute( + self, + variable, + attribute, + variable_attribute_get_func_map, + e, + ) + return value + + def set_variable_attribute(self, variable, attribute: VariableAttribute, value): + def e(attribute): + raise ValueError(f"Unknown variable attribute to set: {attribute}") + + _direct_set_entity_attribute( + self, + variable, + attribute, + value, + variable_attribute_set_func_map, + e, + ) + + def number_of_constraints(self, type: ConstraintType): + if type in {ConstraintType.Linear, ConstraintType.Quadratic}: + return self.get_raw_attribute_int_by_id(XPRS.ROWS) + if type == ConstraintType.SOS: + return self.get_raw_attribute_int_by_id(XPRS.SETS) + raise ValueError(f"Unknown constraint type: {type}") + + def number_of_variables(self): + return self.get_raw_attribute_int_by_id(XPRS.INPUTCOLS) + + def get_model_attribute(self, attribute: ModelAttribute): + def e(attribute): + raise ValueError(f"Unknown model attribute to get: {attribute}") + + value = _get_model_attribute( + self, + attribute, + model_attribute_get_func_map, + model_attribute_get_translate_func_map, + e, + ) + return value + + def set_model_attribute(self, attribute: ModelAttribute, value): + def e(attribute): + raise ValueError(f"Unknown model attribute to set: {attribute}") + + _set_model_attribute( + self, + attribute, + value, + model_control_set_func_map, + model_attribute_set_translate_func_map, + e, + ) + + def get_constraint_attribute(self, constraint, attribute: ConstraintAttribute): + def e(attribute): + raise ValueError(f"Unknown constraint attribute to get: {attribute}") + + value = _direct_get_entity_attribute( + self, + constraint, + attribute, + constraint_attribute_get_func_map, + e, + ) + return value + + def set_constraint_attribute( + self, constraint, attribute: ConstraintAttribute, value + ): + def e(attribute): + raise ValueError(f"Unknown constraint attribute to set: {attribute}") + + _direct_set_entity_attribute( + self, + constraint, + attribute, + value, + constraint_attribute_set_func_map, + e, + ) + + @overload + def add_linear_constraint( + self, + expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder], + sense: ConstraintSense, + rhs: float, + name: str = "", + ): ... + + @overload + def add_linear_constraint( + self, + expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder], + interval: Tuple[float, float], + name: str = "", + ): ... + + @overload + def add_linear_constraint( + self, + con: ComparisonConstraint, + name: str = "", + ): ... + + def add_linear_constraint(self, arg, *args, **kwargs): + if isinstance(arg, ComparisonConstraint): + return self._add_linear_constraint( + arg.lhs, arg.sense, arg.rhs, *args, **kwargs + ) + else: + return self._add_linear_constraint(arg, *args, **kwargs) + + @overload + def add_quadratic_constraint( + self, + expr: Union[ScalarQuadraticFunction, ExprBuilder], + sense: ConstraintSense, + rhs: float, + name: str = "", + ): ... + + @overload + def add_quadratic_constraint( + self, + con: ComparisonConstraint, + name: str = "", + ): ... + + def add_quadratic_constraint(self, arg, *args, **kwargs): + if isinstance(arg, ComparisonConstraint): + return self._add_quadratic_constraint( + arg.lhs, arg.sense, arg.rhs, *args, **kwargs + ) + else: + return self._add_quadratic_constraint(arg, *args, **kwargs) + + @overload + def add_nl_constraint( + self, + expr, + sense: ConstraintSense, + rhs: float, + /, + name: str = "", + ): ... + + @overload + def add_nl_constraint( + self, + expr, + interval: Tuple[float, float], + /, + name: str = "", + ): ... + + @overload + def add_nl_constraint( + self, + con, + /, + name: str = "", + ): ... + + def add_nl_constraint(self, expr, *args, **kwargs): + graph = ExpressionGraphContext.current_graph() + expr = convert_to_expressionhandle(graph, expr) + if not isinstance(expr, ExpressionHandle): + raise ValueError( + "Expression should be convertible to ExpressionHandle" + ) + + con = self._add_single_nl_constraint(graph, expr, *args, **kwargs) + return con + + def add_nl_objective(self, expr): + graph = ExpressionGraphContext.current_graph() + expr = convert_to_expressionhandle(graph, expr) + if not isinstance(expr, ExpressionHandle): + raise ValueError( + "Expression should be convertible to ExpressionHandle" + ) + self._add_single_nl_objective(graph, expr) + + def set_callback(self, cb, where): + def cb_wrapper(raw_model, ctx): + # Warning: This is super hacky. We need to provide a complete Model + # object to the callback (a RawModel is not enough). Xpress invokes + # callbacks with thread-local problem pointers, so we reuse the + # original object by swapping the pointers temporarily. This is + # okay because we've serialized access to the model anyway (GIL + # limitation). But all of this happens at the C++ level, here we + # only need to provide the user callback with the original complete + # Model object. So it looks like we're giving the original model to + # the callbacks, but in reality we pull a switcheroo behind the + # curtains. + cb(self, ctx) + + super().set_callback(cb_wrapper, where) + + +Model.add_variables = make_variable_tupledict +Model.add_m_variables = make_variable_ndarray +Model.add_m_linear_constraints = add_matrix_constraints diff --git a/src/pyoptinterface/xpress.py b/src/pyoptinterface/xpress.py new file mode 100644 index 00000000..0e3da454 --- /dev/null +++ b/src/pyoptinterface/xpress.py @@ -0,0 +1,22 @@ +from pyoptinterface._src.xpress import Model, autoload_library +from pyoptinterface._src.xpress_model_ext import ( + Env, + XPRS, + load_library, + is_library_loaded, + license, + beginlicensing, + endlicensing, +) + +__all__ = [ + "Model", + "Env", + "XPRS", + "autoload_library", + "load_library", + "is_library_loaded", + "license", + "beginlicensing", + "endlicensing", +] diff --git a/tests/conftest.py b/tests/conftest.py index a6262ac5..c0720ca4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ import pytest import platform -from pyoptinterface import gurobi, copt, mosek, highs, ipopt +from pyoptinterface import gurobi, xpress, copt, mosek, highs, ipopt nlp_model_dict = {} @@ -16,7 +16,7 @@ def c(): nlp_model_dict["ipopt_llvm"] = llvm system = platform.system() if system != "Darwin": - # On macOS, loading dynamic library of Gurobi/COPT/Mosek before loading libtcc will cause memory error + # On macOS, loading dynamic library of Gurobi/Xpress/COPT/Mosek before loading libtcc will cause memory error # The reason is still unclear nlp_model_dict["ipopt_c"] = c @@ -35,6 +35,8 @@ def nlp_model_ctor(request): if gurobi.is_library_loaded(): model_interface_dict["gurobi"] = gurobi.Model +if xpress.is_library_loaded(): + model_interface_dict["xpress"] = xpress.Model if copt.is_library_loaded(): model_interface_dict["copt"] = copt.Model if mosek.is_library_loaded(): @@ -42,7 +44,6 @@ def nlp_model_ctor(request): if highs.is_library_loaded(): model_interface_dict["highs"] = highs.Model - @pytest.fixture(params=model_interface_dict.keys()) def model_interface(request): name = request.param diff --git a/tests/simple_cb.py b/tests/simple_cb.py index c35d34d4..7c4363b6 100644 --- a/tests/simple_cb.py +++ b/tests/simple_cb.py @@ -1,11 +1,10 @@ -import pyoptinterface as poi -from pyoptinterface import gurobi +import pyoptinterface as poi from pyoptinterface import gurobi, xpress GRB = gurobi.GRB +XPRS = xpress.XPRS - -def simple_cb(): - model = gurobi.Model() +def simple_cb(f): + model = f() x = model.add_variable(lb=0.0, ub=20.0) y = model.add_variable(lb=8.0, ub=20.0) @@ -17,20 +16,37 @@ def simple_cb(): model.set_objective(obj, poi.ObjectiveSense.Minimize) conexpr = x + y - con1 = model.add_linear_constraint( - conexpr, poi.ConstraintSense.GreaterEqual, 10.0, name="con1" - ) + model.add_linear_constraint(conexpr, poi.ConstraintSense.GreaterEqual, 10.0, name="con1") def cb(model, where): - if where == GRB.Callback.PRESOLVE: + runtime = 0.0 + coldel = 0 + rowdel = 0 + if isinstance(model, gurobi.Model) and where == GRB.Callback.PRESOLVE: runtime = model.cb_get_info(GRB.Callback.RUNTIME) coldel = model.cb_get_info(GRB.Callback.PRE_COLDEL) rowdel = model.cb_get_info(GRB.Callback.PRE_ROWDEL) print(f"Runtime: {runtime}, Coldel: {coldel}, Rowdel: {rowdel}") - - model.set_callback(cb) - + if isinstance(model, xpress.Model) and where == XPRS.CB_CONTEXT.PRESOLVE: + runtime = model.get_raw_attribute_dbl_by_id(XPRS.TIME) + coldel = model.get_raw_attribute_int_by_id(XPRS.ORIGINALCOLS) - model.get_raw_attribute_int_by_id(XPRS.COLS) + rowdel = model.get_raw_attribute_int_by_id(XPRS.ORIGINALROWS) - model.get_raw_attribute_int_by_id(XPRS.ROWS) + print(f"CB[AFTER-PRESOLVE] >> Runtime: {runtime}, Coldel: {coldel}, Rowdel: {rowdel}") + if isinstance(model, xpress.Model) and where == XPRS.CB_CONTEXT.MESSAGE: + args = model.cb_get_arguments() + print(f"CB[MESSAGE-{args.msgtype}] >> {args.msg}") + + + if isinstance(model, gurobi.Model): + model.set_callback(cb) + elif isinstance(model, xpress.Model): + model.set_callback(cb, XPRS.CB_CONTEXT.PRESOLVE | XPRS.CB_CONTEXT.MESSAGE) + + model.set_model_attribute(poi.ModelAttribute.Silent, False) model.optimize() -simple_cb() +if xpress.is_library_loaded(): + simple_cb(xpress.Model) +if gurobi.is_library_loaded(): + simple_cb(gurobi.Model) diff --git a/tests/test_close.py b/tests/test_close.py index c554b55b..11c02063 100644 --- a/tests/test_close.py +++ b/tests/test_close.py @@ -1,10 +1,13 @@ -from pyoptinterface import gurobi, copt, mosek +from pyoptinterface import gurobi, xpress, copt, mosek envs = [] models = [] if gurobi.is_library_loaded(): envs.append(gurobi.Env) models.append(gurobi.Model) +if xpress.is_library_loaded(): + envs.append(xpress.Env) + models.append(xpress.Model) if copt.is_library_loaded(): envs.append(copt.Env) models.append(copt.Model) @@ -12,7 +15,6 @@ envs.append(mosek.Env) models.append(mosek.Model) - def test_close(): for env, model in zip(envs, models): env_instance = env() diff --git a/tests/test_nlp_expression.py b/tests/test_nlp_expression.py index 5f8d2ead..4ce1f97a 100644 --- a/tests/test_nlp_expression.py +++ b/tests/test_nlp_expression.py @@ -26,9 +26,13 @@ def test_nlp_expressiontree(model_interface): x_value = model.get_value(x) y_value = model.get_value(y) - - assert x_value == approx(1.0, rel=1e-6) - assert y_value == approx(0.5, rel=1e-6) + + # Note: with a feasibility tolerance defaulted to 1e-6 + the + # effect of the internal solver scaling, x and y can assume + # values relatively far away from the expected ones. + # E.g.: x = 1.0005, y = 0.49975 + assert x_value == approx(1.0, rel=1e-2) + assert y_value == approx(0.5, rel=1e-2) def test_nlp_expressiontree_obj(model_interface): diff --git a/tests/test_qp.py b/tests/test_qp.py index db29e95a..fec26653 100644 --- a/tests/test_qp.py +++ b/tests/test_qp.py @@ -20,4 +20,4 @@ def test_simple_qp(model_interface): assert status == poi.TerminationStatusCode.OPTIMAL obj_val = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue) - assert obj_val == approx(N**2) + assert obj_val == approx(N**2, rel=1e-5) diff --git a/tests/test_soc.py b/tests/test_soc.py index d18b419f..1df13287 100644 --- a/tests/test_soc.py +++ b/tests/test_soc.py @@ -23,11 +23,11 @@ def test_soc(model_interface): x_val = model.get_value(x) y_val = model.get_value(y) z_val = model.get_value(z) - assert x_val == approx(5.0) - assert y_val == approx(3.0) - assert z_val == approx(4.0) + assert x_val == approx(5.0, rel=1e-5) + assert y_val == approx(3.0, rel=1e-5) + assert z_val == approx(4.0, rel=1e-5) obj_val = model.get_value(obj) - assert obj_val == approx(12.0) + assert obj_val == approx(12.0, rel=1e-5) model.delete_constraint(con1) xx = model.add_variable(lb=0.0, name="xx") @@ -40,11 +40,11 @@ def test_soc(model_interface): x_val = model.get_value(x) y_val = model.get_value(y) z_val = model.get_value(z) - assert x_val == approx(2.5) - assert y_val == approx(3.0) - assert z_val == approx(4.0) + assert x_val == approx(2.5, rel=1e-5) + assert y_val == approx(3.0, rel=1e-5) + assert z_val == approx(4.0, rel=1e-5) obj_val = model.get_value(obj) - assert obj_val == approx(9.5) + assert obj_val == approx(9.5, rel=1e-5) def test_rotated_soc(model_interface): diff --git a/tests/tsp_cb.py b/tests/tsp_cb.py index 4fe3d2f8..b4b134e1 100644 --- a/tests/tsp_cb.py +++ b/tests/tsp_cb.py @@ -1,5 +1,5 @@ # This file is adapted from the examples/python/tsp.py in Gurobi installation. -# We use this file to ensure our callback implementation is correct and the result is compared with gurobipy/coptpy +# We use this file to ensure our callback implementation is correct and the result is compared with gurobipy/coptpy/xpress # this test is currently run manually # Copyright 2024, Gurobi Optimization, LLC @@ -11,14 +11,38 @@ from collections import defaultdict from itertools import combinations -import pyoptinterface as poi -from pyoptinterface import gurobi, copt +# Test what is available in the current system +GUROBIPY_AVAILABLE = False +COPTPY_AVAILABLE = False +XPRESS_AVAILABLE = False + +try: + import gurobipy as gp + + GUROBIPY_AVAILABLE = True +except ImportError: + print("Gurobipy not found.") -import gurobipy as gp -from gurobipy import GRB +try: + import coptpy as cp -import coptpy as cp -from coptpy import COPT + COPTPY_AVAILABLE = True +except ImportError: + print("Coptpy not found.") + +try: + import xpress as xp + + XPRESS_AVAILABLE = True +except ImportError: + print("Xpress Python Interface not found.") + +import pyoptinterface as poi +from pyoptinterface import gurobi, copt, xpress + +GRB = gurobi.GRB +COPT = copt.COPT +XPRS = xpress.XPRS def shortest_subtour(edges: List[Tuple[int, int]]) -> List[int]: @@ -46,57 +70,176 @@ def shortest_subtour(edges: List[Tuple[int, int]]) -> List[int]: return shortest -class GurobiTSPCallback: - def __init__(self, nodes, x): - self.nodes = nodes - self.x = x +if GUROBIPY_AVAILABLE: - def __call__(self, model, where): - if where == GRB.Callback.MIPSOL: - self.eliminate_subtours_gurobipy(model) + class GurobiTSPCallback: + def __init__(self, nodes, x): + self.nodes = nodes + self.x = x + + def __call__(self, model, where): + if where == GRB.Callback.MIPSOL: + self.eliminate_subtours_gurobipy(model) + + def eliminate_subtours_gurobipy(self, model): + values = model.cbGetSolution(self.x) + edges = [(i, j) for (i, j), v in values.items() if v > 0.5] + tour = shortest_subtour(edges) + if len(tour) < len(self.nodes): + # add subtour elimination constraint for every pair of cities in tour + model.cbLazy( + gp.quicksum(self.x[i, j] for i, j in combinations(tour, 2)) + <= len(tour) - 1 + ) + + def solve_tsp_gurobipy(nodes, distances): + """ + Solve a dense symmetric TSP using the following base formulation: + + min sum_ij d_ij x_ij + s.t. sum_j x_ij == 2 forall i in V + x_ij binary forall (i,j) in E + + and subtours eliminated using lazy constraints. + """ + + m = gp.Model() + + x = m.addVars(distances.keys(), obj=distances, vtype=GRB.BINARY, name="e") + x.update({(j, i): v for (i, j), v in x.items()}) + + # Create degree 2 constraints + for i in nodes: + m.addConstr(gp.quicksum(x[i, j] for j in nodes if i != j) == 2) + + m.Params.OutputFlag = 0 + m.Params.LazyConstraints = 1 + cb = GurobiTSPCallback(nodes, x) + m.optimize(cb) - def eliminate_subtours_gurobipy(self, model): - values = model.cbGetSolution(self.x) - edges = [(i, j) for (i, j), v in values.items() if v > 0.5] + edges = [(i, j) for (i, j), v in x.items() if v.X > 0.5] tour = shortest_subtour(edges) - if len(tour) < len(self.nodes): - # add subtour elimination constraint for every pair of cities in tour - model.cbLazy( - gp.quicksum(self.x[i, j] for i, j in combinations(tour, 2)) - <= len(tour) - 1 - ) + assert set(tour) == set(nodes) + + return tour, m.ObjVal + + +if COPTPY_AVAILABLE: + + class COPTTSPCallback(cp.CallbackBase): + def __init__(self, nodes, x): + super().__init__() + self.nodes = nodes + self.x = x + + def callback(self): + if self.where() == COPT.CBCONTEXT_MIPSOL: + self.eliminate_subtours_coptpy() + + def eliminate_subtours_coptpy(self): + values = self.getSolution(self.x) + edges = [(i, j) for (i, j), v in values.items() if v > 0.5] + tour = shortest_subtour(edges) + if len(tour) < len(self.nodes): + # add subtour elimination constraint for every pair of cities in tour + self.addLazyConstr( + cp.quicksum(self.x[i, j] for i, j in combinations(tour, 2)) + <= len(tour) - 1 + ) + + def solve_tsp_coptpy(nodes, distances): + env = cp.Envr() + m = env.createModel("TSP Callback Example") + + x = m.addVars(distances.keys(), vtype=COPT.BINARY, nameprefix="e") + for (i, j), v in x.items(): + v.setInfo(COPT.Info.Obj, distances[i, j]) + for i, j in distances.keys(): + x[j, i] = x[i, j] + + # Create degree 2 constraints + for i in nodes: + m.addConstr(cp.quicksum(x[i, j] for j in nodes if i != j) == 2) + + m.Param.Logging = 0 + cb = COPTTSPCallback(nodes, x) + m.setCallback(cb, COPT.CBCONTEXT_MIPSOL) + m.solve() + + edges = [(i, j) for (i, j), v in x.items() if v.x > 0.5] + tour = shortest_subtour(edges) + assert set(tour) == set(nodes) + return tour, m.objval -def solve_tsp_gurobipy(nodes, distances): - """ - Solve a dense symmetric TSP using the following base formulation: - min sum_ij d_ij x_ij - s.t. sum_j x_ij == 2 forall i in V - x_ij binary forall (i,j) in E +if XPRESS_AVAILABLE: - and subtours eliminated using lazy constraints. - """ + class XpressTSPCallback: + def __init__(self, nodes, x): + self.nodes = nodes + self.x = x - m = gp.Model() + def __call__(self, prob, data, soltype, cutoff): + """ + Pre-integer solution callback: checks candidate solution and adds + subtour elimination cuts. - x = m.addVars(distances.keys(), obj=distances, vtype=GRB.BINARY, name="e") - x.update({(j, i): v for (i, j), v in x.items()}) + Args: + soltype: Solution origin (0=B&B node, 1=heuristic, 2=user) + cutoff: Current cutoff value - # Create degree 2 constraints - for i in nodes: - m.addConstr(gp.quicksum(x[i, j] for j in nodes if i != j) == 2) + Returns: + (reject, new_cutoff): reject=1 to discard solution, new_cutoff + to update solution cutoff value + """ - m.Params.OutputFlag = 0 - m.Params.LazyConstraints = 1 - cb = GurobiTSPCallback(nodes, x) - m.optimize(cb) + # Extract solution and identify active edges + sol = prob.getCallbackSolution() + edges = [(i, j) for i, j in self.x if sol[self.x[i, j].index] > 0.5] - edges = [(i, j) for (i, j), v in x.items() if v.X > 0.5] - tour = shortest_subtour(edges) - assert set(tour) == set(nodes) + tour = shortest_subtour(edges) + if len(tour) == len(self.nodes): # Complete tour + return (0, None) + + if soltype != 0: # Can only add cuts at B&B nodes + return (1, None) + + # Build and presolve SEC + idxs = [self.x[i, j].index for i, j in combinations(tour, 2)] + coeffs = [1.0] * len(idxs) + rhs = len(tour) - 1 + + idxs, coeffs, rhs, status = prob.presolveRow("L", idxs, coeffs, rhs) + if status < 0: # Presolve failed (dual reductions on?) + return (1, None) - return tour, m.ObjVal + # Add cut + prob.addCuts([0], ["L"], [rhs], [0, len(idxs)], idxs, coeffs) + return (0, None) # reject=1 would drop the node as well! + + def solve_tsp_xpress(nodes, distances): + prob = xp.problem() + + x = prob.addVariables(distances.keys(), vartype=xp.binary, name="e") + prob.setObjective(xp.Sum(dist * x[i, j] for (i, j), dist in distances.items())) + x.update({(j, i): v for (i, j), v in x.items()}) + + # Create degree 2 constraints + for i in nodes: + prob.addConstraint(xp.Sum(x[i, j] for j in nodes if i != j) == 2) + + prob.controls.outputlog = 0 + prob.controls.mipdualreductions = 0 + cb = XpressTSPCallback(nodes, x) + prob.addPreIntsolCallback(cb, None, 0) + + prob.optimize() + + edges = [(i, j) for (i, j), v in x.items() if prob.getSolution(v) > 0.5] + tour = shortest_subtour(edges) + assert set(tour) == set(nodes) + return tour, prob.attributes.objval class POITSPCallback: @@ -112,6 +255,10 @@ def run_copt(self, model, where): if where == COPT.CBCONTEXT_MIPSOL: self.eliminate_subtours_poi(model) + def run_xpress(self, model, where): + if where == XPRS.CB_CONTEXT.PREINTSOL: + self.eliminate_subtours_poi(model) + def eliminate_subtours_poi(self, model): edges = [] for (i, j), xij in self.x.items(): @@ -147,6 +294,9 @@ def solve_tsp_poi(f, nodes, distances): m.set_callback(cb.run_gurobi) elif isinstance(m, copt.Model): m.set_callback(cb.run_copt, COPT.CBCONTEXT_MIPSOL) + elif isinstance(m, xpress.Model): + m.set_raw_control("XPRS_MIPDUALREDUCTIONS", 0) + m.set_callback(cb.run_xpress, XPRS.CB_CONTEXT.PREINTSOL) m.optimize() # Extract the solution as a tour @@ -159,54 +309,6 @@ def solve_tsp_poi(f, nodes, distances): return tour, objval -class COPTTSPCallback(cp.CallbackBase): - def __init__(self, nodes, x): - super().__init__() - self.nodes = nodes - self.x = x - - def callback(self): - if self.where() == COPT.CBCONTEXT_MIPSOL: - self.eliminate_subtours_coptpy() - - def eliminate_subtours_coptpy(self): - values = self.getSolution(self.x) - edges = [(i, j) for (i, j), v in values.items() if v > 0.5] - tour = shortest_subtour(edges) - if len(tour) < len(self.nodes): - # add subtour elimination constraint for every pair of cities in tour - self.addLazyConstr( - cp.quicksum(self.x[i, j] for i, j in combinations(tour, 2)) - <= len(tour) - 1 - ) - - -def solve_tsp_coptpy(nodes, distances): - env = cp.Envr() - m = env.createModel("TSP Callback Example") - - x = m.addVars(distances.keys(), vtype=COPT.BINARY, nameprefix="e") - for (i, j), v in x.items(): - v.setInfo(COPT.Info.Obj, distances[i, j]) - for i, j in distances.keys(): - x[j, i] = x[i, j] - - # Create degree 2 constraints - for i in nodes: - m.addConstr(cp.quicksum(x[i, j] for j in nodes if i != j) == 2) - - m.Param.Logging = 0 - cb = COPTTSPCallback(nodes, x) - m.setCallback(cb, COPT.CBCONTEXT_MIPSOL) - m.solve() - - edges = [(i, j) for (i, j), v in x.items() if v.x > 0.5] - tour = shortest_subtour(edges) - assert set(tour) == set(nodes) - - return tour, m.objval - - def create_map(npoints, seed): # Create n random points in 2D random.seed(seed) @@ -264,10 +366,43 @@ def test_copt(npoints_series, seed): assert abs(cost1 - cost2) < 1e-6 +def test_xpress(npoints_series, seed): + for npoints in npoints_series: + nodes, distances = create_map(npoints, seed) + + print(f"npoints = {npoints}") + + t0 = time.time() + tour1, cost1 = solve_tsp_xpress(nodes, distances) + t1 = time.time() + print(f"\t Xpress-Python cost: {cost1}, time: {t1 - t0:g} seconds") + + t0 = time.time() + f = xpress.Model + tour2, cost2 = solve_tsp_poi(f, nodes, distances) + t1 = time.time() + print(f"\t PyOptInterface cost: {cost2}, time: {t1 - t0:g} seconds") + + assert tour1 == tour2 + assert abs(cost1 - cost2) < 1e-6 + + if __name__ == "__main__": seed = 987651234 - X = range(10, 90, 20) + X = range(10, 90, 10) + + if copt.is_library_loaded(): + test_copt(X, seed) + else: + print("PyOptInterface did not find COPT.") + + if gurobi.is_library_loaded(): + test_gurobi(X, seed) + else: + print("PyOptInterface did not find Gurobi.") - test_copt(X, seed) - test_gurobi(X, seed) + if xpress.is_library_loaded(): + test_xpress(X, seed) + else: + print("PyOptInterface did not find Xpress.") diff --git a/tests/tsp_xpress.py b/tests/tsp_xpress.py new file mode 100644 index 00000000..15935d71 --- /dev/null +++ b/tests/tsp_xpress.py @@ -0,0 +1,437 @@ +# TSP example using numpy functions (for efficiency) +# +# (C) Fair Isaac Corp., 1983-2025 + +from typing import List, Tuple +import math +import random +import time +from collections import defaultdict +from itertools import combinations + +import pyoptinterface as poi +from pyoptinterface import xpress + +import xpress as xp +import numpy as np + +XPRS = xpress.XPRS + + +def cb_preintsol(prob, data, soltype, cutoff): + """Callback for checking if solution is acceptable""" + + n = data + xsol = prob.getCallbackSolution() + xsolf = np.array(xsol) + xsol = xsolf.reshape(n, n) + nextc = np.argmax(xsol, axis=1) + + i = 0 + ncities = 1 + + while nextc[i] != 0 and ncities < n: + ncities += 1 + i = nextc[i] + + reject = False + if ncities < n: + if soltype != 0: + reject = True + else: + unchecked = np.zeros(n) + ngroup = 0 + + cut_mstart = [0] + cut_ind = [] + cut_coe = [] + cut_rhs = [] + + nnz = 0 + ncuts = 0 + + while np.min(unchecked) == 0 and ngroup <= n: + """Seek a tour""" + + ngroup += 1 + firstcity = np.argmin(unchecked) + i = firstcity + ncities = 0 + while True: + unchecked[i] = ngroup + ncities += 1 + i = nextc[i] + + if i == firstcity or ncities > n + 1: + break + + S = np.where(unchecked == ngroup)[0].tolist() + compS = np.where(unchecked != ngroup)[0].tolist() + + indices = [i * n + j for i in S for j in compS] + + if sum(xsolf[i] for i in indices) < 1 - 1e-3: + mcolsp, dvalp = [], [] + + drhsp, status = prob.presolverow( + rowtype="G", + origcolind=indices, + origrowcoef=np.ones(len(indices)), + origrhs=1, + maxcoefs=prob.attributes.cols, + colind=mcolsp, + rowcoef=dvalp, + ) + assert status == 0 + + nnz += len(mcolsp) + ncuts += 1 + + cut_ind.extend(mcolsp) + cut_coe.extend(dvalp) + cut_rhs.append(drhsp) + cut_mstart.append(nnz) + + if ncuts > 0: + prob.addcuts( + cuttype=[0] * ncuts, + rowtype=["G"] * ncuts, + rhs=cut_rhs, + start=cut_mstart, + colind=cut_ind, + cutcoef=cut_coe, + ) + + return (reject, None) + + +def print_sol(p, n): + """Print the solution: order of nodes and cost""" + + xsol = np.array(p.getSolution()).reshape(n, n) + nextc = np.argmax(xsol, axis=1) + + i = 0 + + tour = [] + while i != 0 or len(tour) == 0: + tour.append(str(i)) + i = nextc[i] + print("->".join(tour), "->0; cost: ", p.attributes.objval, sep="") + + +def create_initial_tour(n): + """Returns a permuted trivial solution 0->1->2->...->(n-1)->0""" + sol = np.zeros((n, n)) + p = np.random.permutation(n) + for i in range(n): + sol[p[i], p[(i + 1) % n]] = 1 + return sol.flatten() + + +def solve_xpress(nodes, distances): + n = len(nodes) + nodes = range(n) + p = xp.problem() + p.controls.outputlog = 0 + + fly = np.array( + [ + p.addVariable(vartype=xp.binary, name=f"x_{i}_{j}") + for i in nodes + for j in nodes + ], + dtype=xp.npvar, + ).reshape(n, n) + + # Outgoing constraints: sum of outgoing arcs from i equals 1 + for i in nodes: + p.addConstraint(xp.Sum(fly[i, :]) - fly[i, i] == 1) + + # Incoming constraints: sum of incoming arcs to i equals 1 + for i in nodes: + p.addConstraint(xp.Sum(fly[:, i]) - fly[i, i] == 1) + + # No self-loops + for i in nodes: + p.addConstraint(fly[i, i] == 0) + + p.setObjective(xp.Sum(fly[i, j] * distances[i, j] for i in nodes for j in nodes)) + p.addcbpreintsol(cb_preintsol, n) + p.controls.mipdualreductions = 0 + + for k in range(10): + InitTour = create_initial_tour(n) + p.addmipsol(solval=InitTour, name=f"InitTour_{k}") + + p.optimize() + + if p.attributes.solstatus not in [xp.SolStatus.OPTIMAL, xp.SolStatus.FEASIBLE]: + print("Solve status:", p.attributes.solvestatus.name) + print("Solution status:", p.attributes.solstatus.name) + else: + print_sol(p, n) + + xvals = np.array(p.getSolution()).reshape(n, n) + edges = [(i, j) for i in nodes for j in nodes if xvals[i, j] > 0.5] + print(edges) + + tour = shortest_subtour(edges) + objval = p.attributes.objval + + return tour, objval + + +def shortest_subtour(edges: List[Tuple[int, int]]) -> List[int]: + node_neighbors = defaultdict(list) + for i, j in edges: + node_neighbors[i].append(j) + + # Follow edges to find cycles. Each time a new cycle is found, keep track + # of the shortest cycle found so far and restart from an unvisited node. + unvisited = set(node_neighbors) + shortest = None + while unvisited: + cycle = [] + neighbors = list(unvisited) + while neighbors: + current = neighbors.pop() + cycle.append(current) + unvisited.remove(current) + neighbors = [j for j in node_neighbors[current] if j in unvisited] + if shortest is None or len(cycle) < len(shortest): + shortest = cycle + + assert shortest is not None + return shortest + + +def solve_poi(f, nodes, distances): + n = len(nodes) + m = f() + + fly = np.array( + [ + m.add_variable(name=f"x_{i}_{j}", domain=poi.VariableDomain.Binary) + for i in nodes + for j in nodes + ], + dtype=object, # Changed from xp.npvar + ).reshape(n, n) + + # Outgoing constraints: sum of outgoing arcs from i equals 1 + for i in nodes: + m.add_linear_constraint(poi.quicksum(fly[i, :]) - fly[i, i], poi.Eq, 1) + + # Incoming constraints: sum of incoming arcs to i equals 1 + for i in nodes: + m.add_linear_constraint(poi.quicksum(fly[:, i]) - fly[i, i], poi.Eq, 1) + + # No self-loops + for i in nodes: + m.add_linear_constraint(fly[i, i], poi.Eq, 0) + + m.set_objective( + poi.quicksum(fly[i, j] * distances[i, j] for i in nodes for j in nodes) + ) + + def eliminate_subtours_poi(model): + edges = [ + (i, j) + for (i, j), v in np.ndenumerate(fly) + if model.cb_get_solution(v) > 0.5 + ] + tour = shortest_subtour(edges) + if len(tour) < len(nodes): + print(" Shortest subtour:", tour) + print( + f" Adding new cut with {len(tour)**2 - len(tour)} nonzeros." + ) + model.cb_add_lazy_constraint( + poi.quicksum(fly[i, j] + fly[j, i] for i, j in combinations(tour, 2)), + poi.Leq, + len(tour) - 1, + ) + + def cb(model, ctx): + args = model.cb_get_arguments() + if ctx == XPRS.CB_CONTEXT.MESSAGE and args.msgtype > 0: + print(f"{ctx.name:>16}: {args.msg}") + if ctx == XPRS.CB_CONTEXT.BARITERATION: + print( + f"{ctx.name:>16}: Barrier iter {model.get_raw_attribute("XPRS_BARITER")}, primal {model.get_raw_attribute("XPRS_BARPRIMALOBJ")}, dual {model.get_raw_attribute("XPRS_BARDUALOBJ")}, primal inf {model.get_raw_attribute("XPRS_BARPRIMALINF")}, dual inf{model.get_raw_attribute("XPRS_BARDUALINF")}, gap {model.get_raw_attribute("XPRS_BARCGAP")}" + ) + if ctx == XPRS.CB_CONTEXT.BARLOG: + print( + f"{ctx.name:>16}: Barrier iter {model.get_raw_attribute("XPRS_BARITER")}, primal {model.get_raw_attribute("XPRS_BARPRIMALOBJ")}, dual {model.get_raw_attribute("XPRS_BARDUALOBJ")}, primal inf {model.get_raw_attribute("XPRS_BARPRIMALINF")}, dual inf{model.get_raw_attribute("XPRS_BARDUALINF")}, gap {model.get_raw_attribute("XPRS_BARCGAP")}" + ) + if ctx == XPRS.CB_CONTEXT.AFTEROBJECTIVE: + print( + f"{ctx.name:>16}: Completed obj solve {model.get_raw_attribute("XPRS_SOLVEDOBJS")}" + ) + if ctx == XPRS.CB_CONTEXT.BEFOREOBJECTIVE: + print( + f"{ctx.name:>16}: Starting obj solve {model.get_raw_attribute("XPRS_SOLVEDOBJS")}" + ) + if ctx == XPRS.CB_CONTEXT.PRESOLVE: + runtime = model.get_raw_attribute_dbl_by_id(XPRS.TIME) + coldel = model.get_raw_attribute_int_by_id( + XPRS.ORIGINALCOLS + ) - model.get_raw_attribute_int_by_id(XPRS.COLS) + rowdel = model.get_raw_attribute_int_by_id( + XPRS.ORIGINALROWS + ) - model.get_raw_attribute_int_by_id(XPRS.ROWS) + print( + f"{ctx.name:>16}: Runtime: {runtime}, Coldel: {coldel}, Rowdel: {rowdel}" + ) + if ctx == XPRS.CB_CONTEXT.CHECKTIME: + print( + f"{ctx.name:>16}: {model.get_raw_attribute("XPRS_TIME")} seconds have passed." + ) + if ctx == XPRS.CB_CONTEXT.CHGBRANCHOBJECT: + print(f"{ctx.name:>16}: Not a lot to print here at the moment") + if ctx == XPRS.CB_CONTEXT.CUTLOG: + print( + f"{ctx.name:>16}: You should see the cutlog somewhere near this message." + ) + if ctx == XPRS.CB_CONTEXT.CUTROUND: + print( + f"{ctx.name:>16}: The optimizer would have done another cut round? {args.ifxpresscuts} - Forcing it." + ) + args.p_action = 1 + if ctx == XPRS.CB_CONTEXT.DESTROYMT: + print(f"{ctx.name:>16}: Somewhere someone is killing a MIP Thread. RIP :(") + if ctx == XPRS.CB_CONTEXT.GAPNOTIFY: + obj = model.get_raw_attribute_dbl_by_id(XPRS.MIPOBJVAL) + bound = model.get_raw_attribute_dbl_by_id(XPRS.BESTBOUND) + gap = 0 + if obj != 0 or bound != 0: + gap = abs(obj - bound) / max(abs(obj), abs(bound)) + print(f"{ctx.name:>16}: Current gap {gap}, next target set to {gap/2}") + if ctx == XPRS.CB_CONTEXT.MIPLOG: + print( + f"{ctx.name:>16}: Node {model.get_raw_attribute("XPRS_CURRENTNODE")} with depth {model.get_raw_attribute("XPRS_NODEDEPTH")} has just been processed" + ) + if ctx == XPRS.CB_CONTEXT.INFNODE: + print( + f"{ctx.name:>16}: Infeasible node id {model.get_raw_attribute("XPRS_CURRENTNODE")}" + ) + if ctx == XPRS.CB_CONTEXT.INTSOL: + print( + f"{ctx.name:>16}: Integer solution value: {model.get_raw_attribute("XPRS_MIPOBJVAL")}" + ) + if ctx == XPRS.CB_CONTEXT.LPLOG: + print( + f"{ctx.name:>16}: At iteration {model.get_raw_attribute("XPRS_SIMPLEXITER")} objval is {model.get_raw_attribute("XPRS_LPOBJVAL")}" + ) + if ctx == XPRS.CB_CONTEXT.NEWNODE: + print( + f"{ctx.name:>16}: New node id {args.node}, parent node {args.parentnode}, branch {args.branch}" + ) + # if ctx == XPRS.CB_CONTEXT.MIPTHREAD: + # print(f"{ctx.name:>16}: Not a lot to print here at the moment") + if ctx == XPRS.CB_CONTEXT.NODECUTOFF: + print(f"{ctx.name:>16}: Node {args.node} cut off.") + if ctx == XPRS.CB_CONTEXT.NODELPSOLVED: + obj = model.get_raw_attribute_dbl_by_id(XPRS.LPOBJVAL) + print( + f"{ctx.name:>16}: Solved relaxation at node {model.get_raw_attribute("XPRS_CURRENTNODE")}, lp obj {obj}" + ) + if ctx == XPRS.CB_CONTEXT.OPTNODE: + obj = model.get_raw_attribute_dbl_by_id(XPRS.LPOBJVAL) + print( + f"{ctx.name:>16}: Finished processing node {model.get_raw_attribute("XPRS_CURRENTNODE")}, lp obj {obj}" + ) + if ctx == XPRS.CB_CONTEXT.PREINTSOL: + print( + f"{ctx.name:>16}: Candidate integer solution objective {model.get_raw_attribute("LPOBJVAL")}, soltype: {args.soltype}, p_reject: {args.p_reject}, p_cutoff: {args.p_cutoff}" + ) + eliminate_subtours_poi(model) + if ctx == XPRS.CB_CONTEXT.PRENODE: + print(f"{ctx.name:>16}: Node optimization is about to start...") + if ctx == XPRS.CB_CONTEXT.USERSOLNOTIFY: + print( + f"{ctx.name:>16}: Solution {args.solname} was processed resulting in status {args.status}." + ) + + m.set_callback( + cb, + XPRS.CB_CONTEXT.MESSAGE + | XPRS.CB_CONTEXT.BARITERATION + | XPRS.CB_CONTEXT.BARLOG + | XPRS.CB_CONTEXT.AFTEROBJECTIVE + | XPRS.CB_CONTEXT.BEFOREOBJECTIVE + | XPRS.CB_CONTEXT.PRESOLVE + | XPRS.CB_CONTEXT.CHECKTIME + | XPRS.CB_CONTEXT.CHGBRANCHOBJECT + | XPRS.CB_CONTEXT.CUTLOG + | XPRS.CB_CONTEXT.CUTROUND + | XPRS.CB_CONTEXT.DESTROYMT + | XPRS.CB_CONTEXT.GAPNOTIFY + | XPRS.CB_CONTEXT.MIPLOG + | XPRS.CB_CONTEXT.INFNODE + | XPRS.CB_CONTEXT.INTSOL + | XPRS.CB_CONTEXT.LPLOG + # |XPRS.CB_CONTEXT.MIPTHREAD + | XPRS.CB_CONTEXT.NEWNODE + | XPRS.CB_CONTEXT.NODECUTOFF + | XPRS.CB_CONTEXT.NODELPSOLVED + | XPRS.CB_CONTEXT.OPTNODE + | XPRS.CB_CONTEXT.PREINTSOL + | XPRS.CB_CONTEXT.PRENODE + | XPRS.CB_CONTEXT.USERSOLNOTIFY, + ) + m.set_raw_control_int_by_id(XPRS.CALLBACKCHECKTIMEDELAY, 10) + m.set_raw_control_dbl_by_id(XPRS.MIPRELGAPNOTIFY, 1.0) + m.set_raw_control("XPRS_MIPDUALREDUCTIONS", 0) + m.optimize() + + # Extract the solution as a tour + edges = [(i, j) for (i, j), v in np.ndenumerate(fly) if m.get_value(v) > 0.5] + tour = shortest_subtour(edges) + + objval = m.get_model_attribute(poi.ModelAttribute.ObjectiveValue) + + return tour, objval + + +def create_map(npoints, seed): + # Create n random points in 2D + random.seed(seed) + nodes = list(range(npoints)) + points = [(random.randint(0, 100), random.randint(0, 100)) for _ in nodes] + + # Dictionary of Euclidean distance between each pair of points + distances = { + (i, j): math.sqrt(sum((points[i][k] - points[j][k]) ** 2 for k in range(2))) + for i in nodes + for j in nodes + } + return nodes, distances + + +def test_xpress(npoints_series, seed): + for npoints in npoints_series: + nodes, distances = create_map(npoints, seed) + + print(f"npoints = {npoints}") + + t0 = time.time() + f = xpress.Model + _, cost2 = solve_poi(f, nodes, distances) + t1 = time.time() + print(f"\t poi time: {t1 - t0:g} seconds") + print(f"POI solution value: {cost2}") + + t0 = time.time() + _, cost1 = solve_xpress(nodes, distances) + t1 = time.time() + print(f"\t xpress time: {t1 - t0:g} seconds") + print(f"Xpress solution value: {cost1}") + + +if __name__ == "__main__": + seed = 987651234 + + X = range(20, 10000, 10000) + test_xpress(X, seed) From e089ad4fdad7b474add8fc531cf34415ea1a0dd3 Mon Sep 17 00:00:00 2001 From: metab0t Date: Thu, 11 Dec 2025 17:17:27 +0800 Subject: [PATCH 2/8] Capture solver output in Python --- include/pyoptinterface/copt_model.hpp | 15 +++++++++++++- include/pyoptinterface/gurobi_model.hpp | 16 ++++++++++++--- include/pyoptinterface/mosek_model.hpp | 13 +++++++++++- lib/copt_model.cpp | 18 ++++++++++++++++- lib/copt_model_ext.cpp | 2 ++ lib/gurobi_model.cpp | 19 ++++++++++++++++- lib/gurobi_model_ext.cpp | 2 ++ lib/mosek_model.cpp | 27 +++++++++++++++---------- lib/mosek_model_ext.cpp | 3 ++- src/pyoptinterface/_src/copt.py | 4 ++++ src/pyoptinterface/_src/gurobi.py | 7 +++++-- src/pyoptinterface/_src/mosek.py | 5 +++-- 12 files changed, 108 insertions(+), 23 deletions(-) diff --git a/include/pyoptinterface/copt_model.hpp b/include/pyoptinterface/copt_model.hpp index 646c8fd8..4b85cef3 100644 --- a/include/pyoptinterface/copt_model.hpp +++ b/include/pyoptinterface/copt_model.hpp @@ -98,7 +98,8 @@ extern "C" B(COPT_GetColUpperIIS); \ B(COPT_GetRowLowerIIS); \ B(COPT_GetRowUpperIIS); \ - B(COPT_GetSOSIIS); + B(COPT_GetSOSIIS); \ + B(COPT_SetLogCallback); namespace copt { @@ -170,6 +171,13 @@ struct COPTCallbackUserdata bool cb_requires_submit_solution = false; }; +using COPTLoggingCallback = std::function; + +struct COPTLoggingCallbackUserdata +{ + COPTLoggingCallback callback; +}; + class COPTModel : public OnesideLinearConstraintMixin, public TwosideLinearConstraintMixin, public OnesideQuadraticConstraintMixin, @@ -304,6 +312,11 @@ class COPTModel : public OnesideLinearConstraintMixin, int _constraint_index(const ConstraintIndex &constraint); int _checked_constraint_index(const ConstraintIndex &constraint); + // Control logging + void set_logging(const COPTLoggingCallback &callback); + + COPTLoggingCallbackUserdata m_logging_callback_userdata; + // Callback void set_callback(const COPTCallback &callback, int cbctx); diff --git a/include/pyoptinterface/gurobi_model.hpp b/include/pyoptinterface/gurobi_model.hpp index ba6bbf29..d68521c2 100644 --- a/include/pyoptinterface/gurobi_model.hpp +++ b/include/pyoptinterface/gurobi_model.hpp @@ -73,6 +73,7 @@ B(GRBloadenv); \ B(GRBfreeenv); \ B(GRBstartenv); \ + B(GRBsetlogcallbackfunc); \ B(GRBconverttofixed); \ B(GRBcomputeIIS); @@ -104,10 +105,7 @@ class GurobiEnv void check_error(int error); - private: GRBenv *m_env = nullptr; - - friend class GurobiModel; }; struct GRBfreemodelT @@ -138,6 +136,13 @@ struct GurobiCallbackUserdata bool cb_requires_submit_solution = false; }; +using GurobiLoggingCallback = std::function; + +struct GurobiLoggingCallbackUserdata +{ + GurobiLoggingCallback callback; +}; + class GurobiModel : public OnesideLinearConstraintMixin, public OnesideQuadraticConstraintMixin, public TwosideNLConstraintMixin, @@ -293,6 +298,11 @@ class GurobiModel : public OnesideLinearConstraintMixin, // Non-exported functions void check_error(int error); + // Control logging + void set_logging(const GurobiLoggingCallback &callback); + + GurobiLoggingCallbackUserdata m_logging_callback_userdata; + // Callback void set_callback(const GurobiCallback &callback); diff --git a/include/pyoptinterface/mosek_model.hpp b/include/pyoptinterface/mosek_model.hpp index c2ad6cbb..9782bfca 100644 --- a/include/pyoptinterface/mosek_model.hpp +++ b/include/pyoptinterface/mosek_model.hpp @@ -121,6 +121,13 @@ struct MOSEKfreemodelT }; }; +using MOSEKLoggingCallback = std::function; + +struct MOSEKLoggingCallbackUserdata +{ + MOSEKLoggingCallback callback; +}; + class MOSEKModel : public OnesideLinearConstraintMixin, public TwosideLinearConstraintMixin, public OnesideQuadraticConstraintMixin, @@ -206,7 +213,6 @@ class MOSEKModel : public OnesideLinearConstraintMixin, double getprimalobj(); double getdualobj(); - void enable_log(); void disable_log(); // Accessing information of problem @@ -246,6 +252,11 @@ class MOSEKModel : public OnesideLinearConstraintMixin, MSKint32t _constraint_index(const ConstraintIndex &constraint); MSKint32t _checked_constraint_index(const ConstraintIndex &constraint); + // Control logging + void set_logging(const MOSEKLoggingCallback &callback); + + MOSEKLoggingCallbackUserdata m_logging_callback_userdata; + private: MonotoneIndexer m_variable_index; diff --git a/lib/copt_model.cpp b/lib/copt_model.cpp index 4fc79e27..ef24f0d7 100644 --- a/lib/copt_model.cpp +++ b/lib/copt_model.cpp @@ -1390,8 +1390,24 @@ void COPTEnvConfig::set(const char *param_name, const char *value) check_error(error); } +// Logging callback +static void RealLoggingCallbackFunction(char *msg, void *logdata) +{ + auto real_logdata = static_cast(logdata); + auto &callback = real_logdata->callback; + callback(msg); +} + +void COPTModel::set_logging(const COPTLoggingCallback &callback) +{ + m_logging_callback_userdata.callback = callback; + int error = copt::COPT_SetLogCallback(m_model.get(), &RealLoggingCallbackFunction, + &m_logging_callback_userdata); + check_error(error); +} + // Callback -int RealCOPTCallbackFunction(copt_prob *prob, void *cbdata, int cbctx, void *userdata) +static int RealCOPTCallbackFunction(copt_prob *prob, void *cbdata, int cbctx, void *userdata) { auto real_userdata = static_cast(userdata); auto model = static_cast(real_userdata->model); diff --git a/lib/copt_model_ext.cpp b/lib/copt_model_ext.cpp index 95e87792..7adfde4f 100644 --- a/lib/copt_model_ext.cpp +++ b/lib/copt_model_ext.cpp @@ -149,6 +149,8 @@ NB_MODULE(copt_model_ext, m) BIND_F(version_string) BIND_F(get_raw_model) + BIND_F(set_logging) + BIND_F(set_callback) BIND_F(cb_get_info_int) BIND_F(cb_get_info_double) diff --git a/lib/gurobi_model.cpp b/lib/gurobi_model.cpp index 3b3d7f36..bbf7dca1 100644 --- a/lib/gurobi_model.cpp +++ b/lib/gurobi_model.cpp @@ -1404,8 +1404,25 @@ void GurobiEnv::check_error(int error) } } +// Logging callback +static int RealLoggingCallbackFunction(char *msg, void *logdata) +{ + auto real_logdata = static_cast(logdata); + auto &callback = real_logdata->callback; + callback(msg); + return 0; +} + +void GurobiModel::set_logging(const GurobiLoggingCallback &callback) +{ + m_logging_callback_userdata.callback = callback; + int error = gurobi::GRBsetlogcallbackfunc(m_model.get(), &RealLoggingCallbackFunction, + &m_logging_callback_userdata); + check_error(error); +} + // Callback -int RealGurobiCallbackFunction(GRBmodel *, void *cbdata, int where, void *usrdata) +static int RealGurobiCallbackFunction(GRBmodel *, void *cbdata, int where, void *usrdata) { auto real_userdata = static_cast(usrdata); auto model = static_cast(real_userdata->model); diff --git a/lib/gurobi_model_ext.cpp b/lib/gurobi_model_ext.cpp index 0fdac684..b69c1891 100644 --- a/lib/gurobi_model_ext.cpp +++ b/lib/gurobi_model_ext.cpp @@ -153,6 +153,8 @@ NB_MODULE(gurobi_model_ext, m) BIND_F(version_string) BIND_F(get_raw_model) + BIND_F(set_logging) + BIND_F(set_callback) BIND_F(cb_get_info_int) BIND_F(cb_get_info_double) diff --git a/lib/mosek_model.cpp b/lib/mosek_model.cpp index a5d98237..07ceeec8 100644 --- a/lib/mosek_model.cpp +++ b/lib/mosek_model.cpp @@ -940,17 +940,6 @@ double MOSEKModel::getdualobj() return retval; } -static void printstr(void *handle, const char *str) -{ - printf("%s", str); - fflush(stdout); -} -void MOSEKModel::enable_log() -{ - auto error = mosek::MSK_linkfunctotaskstream(m_model.get(), MSK_STREAM_LOG, NULL, printstr); - check_error(error); -} - void MOSEKModel::disable_log() { auto error = mosek::MSK_linkfunctotaskstream(m_model.get(), MSK_STREAM_LOG, NULL, NULL); @@ -1402,6 +1391,22 @@ MSKint32t MOSEKModel::_checked_constraint_index(const ConstraintIndex &constrain return row; } +// Logging callback +static void RealLoggingCallbackFunction(void *handle, const char *msg) +{ + auto real_logdata = static_cast(handle); + auto &callback = real_logdata->callback; + callback(msg); +} + +void MOSEKModel::set_logging(const MOSEKLoggingCallback &callback) +{ + m_logging_callback_userdata.callback = callback; + auto error = mosek::MSK_linkfunctotaskstream( + m_model.get(), MSK_STREAM_LOG, &m_logging_callback_userdata, &RealLoggingCallbackFunction); + check_error(error); +} + void *MOSEKModel::get_raw_model() { return m_model.get(); diff --git a/lib/mosek_model_ext.cpp b/lib/mosek_model_ext.cpp index 7f78dd2f..81fe6438 100644 --- a/lib/mosek_model_ext.cpp +++ b/lib/mosek_model_ext.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "pyoptinterface/mosek_model.hpp" @@ -135,7 +136,7 @@ NB_MODULE(mosek_model_ext, m) BIND_F(getprimalobj) BIND_F(getdualobj) - BIND_F(enable_log) + BIND_F(set_logging) BIND_F(disable_log) BIND_F(set_variable_name) diff --git a/src/pyoptinterface/_src/copt.py b/src/pyoptinterface/_src/copt.py index 11b198ed..5d734cae 100644 --- a/src/pyoptinterface/_src/copt.py +++ b/src/pyoptinterface/_src/copt.py @@ -384,6 +384,10 @@ def __init__(self, env=None): self.variable_start_values: Dict[VariableIndex, float] = dict() self.nl_start_values: Dict[VariableIndex, float] = dict() + # override logging + self.set_raw_parameter("LogToConsole", 0) + self.set_logging(print) + def add_variables(self, *args, **kwargs): return make_variable_tupledict(self, *args, **kwargs) diff --git a/src/pyoptinterface/_src/gurobi.py b/src/pyoptinterface/_src/gurobi.py index c2063ba6..63c84f50 100644 --- a/src/pyoptinterface/_src/gurobi.py +++ b/src/pyoptinterface/_src/gurobi.py @@ -1,5 +1,3 @@ -# try to load DLL of gurobi in${GUROBI_HOME}/bin -# only on windows import os import platform from pathlib import Path @@ -550,6 +548,11 @@ def __init__(self, env=None): # We must keep a reference to the environment to prevent it from being garbage collected self._env = env + # Replace default logging behavior to use Python print + # otherwise it prints directly to stdout/stderr bypassing Python and causing issues in Jupyter notebooks + self.set_raw_parameter("LogToConsole", 0) + self.set_logging(lambda msg: print(msg, end="")) + @staticmethod def supports_variable_attribute(attribute: VariableAttribute, settable=False): if settable: diff --git a/src/pyoptinterface/_src/mosek.py b/src/pyoptinterface/_src/mosek.py index bdfe88a0..d28e8fe8 100644 --- a/src/pyoptinterface/_src/mosek.py +++ b/src/pyoptinterface/_src/mosek.py @@ -308,7 +308,7 @@ def set_silent(model, value: bool): if value: model.disable_log() else: - model.enable_log() + model.set_logging(lambda msg: print(msg, end="")) model_attribute_set_func_map = { @@ -364,7 +364,8 @@ def __init__(self, env=None): # We must keep a reference to the environment to prevent it from being garbage collected self._env = env self.last_solve_return_code: Optional[int] = None - self.silent = True + self.silent = False + self.set_logging(lambda msg: print(msg, end="")) @staticmethod def supports_variable_attribute(attribute: VariableAttribute, settable=False): From 01c819aec59da8fa1a3609367b84a8b4215b6cdc Mon Sep 17 00:00:00 2001 From: metab0t Date: Thu, 11 Dec 2025 20:33:00 +0800 Subject: [PATCH 3/8] Update GHA to use Gurobi 13 --- .github/actions/setup_optimizers_linux/action.yml | 12 ++++++------ .github/actions/setup_optimizers_macos/action.yml | 4 ++-- .github/actions/setup_optimizers_windows/action.yml | 10 +++++----- optimizer_version.toml | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/actions/setup_optimizers_linux/action.yml b/.github/actions/setup_optimizers_linux/action.yml index 89cdfc35..13e9f045 100644 --- a/.github/actions/setup_optimizers_linux/action.yml +++ b/.github/actions/setup_optimizers_linux/action.yml @@ -48,7 +48,7 @@ runs: shell: bash name: Download X64 Installers run: | - curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/12.0/gurobi12.0.2_linux64.tar.gz + curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_linux64.tar.gz curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/linux64/CardinalOptimizer-7.2.8-lnx64.tar.gz curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinux64x86.tar.bz2 curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-x86_64.tar.gz @@ -57,7 +57,7 @@ runs: shell: bash name: Download ARM64 Installers run: | - curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/12.0/gurobi12.0.2_armlinux64.tar.gz + curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_armlinux64.tar.gz curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/aarch64/CardinalOptimizer-7.2.8-aarch64_lnx.tar.gz curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinuxaarch64.tar.bz2 curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-aarch64.tar.gz @@ -67,18 +67,18 @@ runs: shell: bash run: | tar xfz ~/installers/gurobi.tar.gz -C ~/ - ls ~/gurobi1202/linux64 + ls ~/gurobi1300/linux64 # set environment variables - export GUROBI_HOME="${HOME}/gurobi1202/linux64" + export GUROBI_HOME="${HOME}/gurobi1300/linux64" echo "GUROBI_HOME=${GUROBI_HOME}" >> $GITHUB_ENV - name: Setup Gurobi Installation Home if: ${{ inputs.ARCH == 'ARM64' }} shell: bash run: | tar xfz ~/installers/gurobi.tar.gz -C ~/ - ls ~/gurobi1202/armlinux64 + ls ~/gurobi1300/armlinux64 # set environment variables - export GUROBI_HOME="${HOME}/gurobi1202/armlinux64" + export GUROBI_HOME="${HOME}/gurobi1300/armlinux64" echo "GUROBI_HOME=${GUROBI_HOME}" >> $GITHUB_ENV - name: Setup Gurobi Installation shell: bash diff --git a/.github/actions/setup_optimizers_macos/action.yml b/.github/actions/setup_optimizers_macos/action.yml index 94134273..875320ee 100644 --- a/.github/actions/setup_optimizers_macos/action.yml +++ b/.github/actions/setup_optimizers_macos/action.yml @@ -48,7 +48,7 @@ runs: shell: bash name: Download Universal Installers run: | - curl -L -o ~/installers/gurobi.pkg https://packages.gurobi.com/12.0/gurobi12.0.2_macos_universal2.pkg + curl -L -o ~/installers/gurobi.pkg https://packages.gurobi.com/13.0/gurobi13.0.0_macos_universal2.pkg curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/osx64/CardinalOptimizer-7.2.8-universal_mac.tar.gz - if: ${{ (steps.cache-installers-macos.outputs.cache-hit != 'true') && (inputs.ARCH == 'X64') }} @@ -73,7 +73,7 @@ runs: pkgutil --expand-full ~/installers/gurobi.pkg ~/gurobi ls ~/gurobi # set environment variables - export GUROBI_HOME="${HOME}/gurobi/gurobi12.0.2_macos_universal2.component.pkg/Payload/Library/gurobi1202/macos_universal2" + export GUROBI_HOME="${HOME}/gurobi/gurobi13.0.0_macos_universal2.component.pkg/Payload/Library/gurobi1300/macos_universal2" echo "GUROBI_HOME=${GUROBI_HOME}" >> $GITHUB_ENV echo "PATH=${PATH}:${GUROBI_HOME}/bin" >> $GITHUB_ENV echo "DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${GUROBI_HOME}/lib" >> $GITHUB_ENV diff --git a/.github/actions/setup_optimizers_windows/action.yml b/.github/actions/setup_optimizers_windows/action.yml index 27ce9410..c96dc2b2 100644 --- a/.github/actions/setup_optimizers_windows/action.yml +++ b/.github/actions/setup_optimizers_windows/action.yml @@ -51,7 +51,7 @@ runs: shell: pwsh name: Download Installers run: | - curl -L -o D:\installers\gurobi.msi https://packages.gurobi.com/12.0/Gurobi-12.0.2-win64.msi + curl -L -o D:\installers\gurobi.msi https://packages.gurobi.com/13.0/Gurobi-13.0.0-win64.msi curl -L -o D:\installers\copt.zip https://pub.shanshu.ai/download/copt/7.2.8/win64/CardinalOptimizer-7.2.8-win64.zip curl -L -o D:\installers\mosek.msi https://download.mosek.com/stable/10.2.0/moseksetupwin64x86.msi curl -L -o D:\installers\idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-windows-x86_64.tar.gz @@ -67,12 +67,12 @@ runs: GUROBI_WLS: ${{ inputs.GUROBI_WLS }} run: | lessmsi x D:\installers\gurobi.msi "D:\" gurobi_cl.exe - lessmsi x D:\installers\gurobi.msi "D:\" gurobi120.dll gurobi120.lib + lessmsi x D:\installers\gurobi.msi "D:\" gurobi130.dll gurobi130.lib lessmsi x D:\installers\gurobi.msi "D:\" gurobi_c.h - ls D:\SourceDir\gurobi1202\win64 + ls D:\SourceDir\gurobi1300\win64 # set environment variables - echo "GUROBI_HOME=D:\SourceDir\gurobi1202\win64" >> $env:GITHUB_ENV - echo "PATH=$env:PATH;D:\SourceDir\gurobi1202\win64\bin" >> $env:GITHUB_ENV + echo "GUROBI_HOME=D:\SourceDir\gurobi1300\win64" >> $env:GITHUB_ENV + echo "PATH=$env:PATH;D:\SourceDir\gurobi1300\win64\bin" >> $env:GITHUB_ENV echo $env:GUROBI_HOME # setup license using secrets diff --git a/optimizer_version.toml b/optimizer_version.toml index b2b06aad..ceb55c5b 100644 --- a/optimizer_version.toml +++ b/optimizer_version.toml @@ -1,5 +1,5 @@ -Gurobi = "12.0.2" +Gurobi = "13.0.0" COPT = "7.2.8" MOSEK = "10.2.0" -HiGHS = "1.10.0" +HiGHS = "1.12.0" IPOPT = "3.13.2" From 9c6e58bc6778b28f6a747969b39128636b73b98a Mon Sep 17 00:00:00 2001 From: metab0t Date: Thu, 11 Dec 2025 20:43:45 +0800 Subject: [PATCH 4/8] Update GHA to COPT 8.0.2 --- .../actions/setup_optimizers_linux/action.yml | 8 +++---- .../actions/setup_optimizers_macos/action.yml | 6 ++--- .../setup_optimizers_windows/action.yml | 8 +++---- docs/source/getting_started.md | 24 +++++++++---------- optimizer_version.toml | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/actions/setup_optimizers_linux/action.yml b/.github/actions/setup_optimizers_linux/action.yml index 13e9f045..93660eed 100644 --- a/.github/actions/setup_optimizers_linux/action.yml +++ b/.github/actions/setup_optimizers_linux/action.yml @@ -49,7 +49,7 @@ runs: name: Download X64 Installers run: | curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_linux64.tar.gz - curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/linux64/CardinalOptimizer-7.2.8-lnx64.tar.gz + curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/linux64/CardinalOptimizer-8.0.2-lnx64.tar.gz curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinux64x86.tar.bz2 curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-x86_64.tar.gz @@ -58,7 +58,7 @@ runs: name: Download ARM64 Installers run: | curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_armlinux64.tar.gz - curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/aarch64/CardinalOptimizer-7.2.8-aarch64_lnx.tar.gz + curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/aarch64/CardinalOptimizer-8.0.2-aarch64_lnx.tar.gz curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinuxaarch64.tar.bz2 curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-aarch64.tar.gz @@ -104,9 +104,9 @@ runs: COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }} run: | tar xfz ~/installers/copt.tar.gz -C ~/ - ls ~/copt72 + ls ~/copt80 # set environment variables - export COPT_HOME="${HOME}/copt72" + export COPT_HOME="${HOME}/copt80" echo "COPT_HOME=${COPT_HOME}" >> $GITHUB_ENV echo "PATH=${PATH}:${COPT_HOME}/bin" >> $GITHUB_ENV echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${COPT_HOME}/lib" >> $GITHUB_ENV diff --git a/.github/actions/setup_optimizers_macos/action.yml b/.github/actions/setup_optimizers_macos/action.yml index 875320ee..9a8b9111 100644 --- a/.github/actions/setup_optimizers_macos/action.yml +++ b/.github/actions/setup_optimizers_macos/action.yml @@ -49,7 +49,7 @@ runs: name: Download Universal Installers run: | curl -L -o ~/installers/gurobi.pkg https://packages.gurobi.com/13.0/gurobi13.0.0_macos_universal2.pkg - curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/osx64/CardinalOptimizer-7.2.8-universal_mac.tar.gz + curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/osx64/CardinalOptimizer-8.0.2-universal_mac.tar.gz - if: ${{ (steps.cache-installers-macos.outputs.cache-hit != 'true') && (inputs.ARCH == 'X64') }} shell: bash @@ -95,9 +95,9 @@ runs: COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }} run: | tar xfz ~/installers/copt.tar.gz -C ~/ - ls ~/copt72 + ls ~/copt80 # set environment variables - export COPT_HOME="${HOME}/copt72" + export COPT_HOME="${HOME}/copt80" echo "COPT_HOME=${COPT_HOME}" >> $GITHUB_ENV echo "PATH=${PATH}:${COPT_HOME}/bin" >> $GITHUB_ENV echo "DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${COPT_HOME}/lib" >> $GITHUB_ENV diff --git a/.github/actions/setup_optimizers_windows/action.yml b/.github/actions/setup_optimizers_windows/action.yml index c96dc2b2..105430ab 100644 --- a/.github/actions/setup_optimizers_windows/action.yml +++ b/.github/actions/setup_optimizers_windows/action.yml @@ -52,7 +52,7 @@ runs: name: Download Installers run: | curl -L -o D:\installers\gurobi.msi https://packages.gurobi.com/13.0/Gurobi-13.0.0-win64.msi - curl -L -o D:\installers\copt.zip https://pub.shanshu.ai/download/copt/7.2.8/win64/CardinalOptimizer-7.2.8-win64.zip + curl -L -o D:\installers\copt.zip https://pub.shanshu.ai/download/copt/8.0.2/win64/CardinalOptimizer-8.0.2-win64.zip curl -L -o D:\installers\mosek.msi https://download.mosek.com/stable/10.2.0/moseksetupwin64x86.msi curl -L -o D:\installers\idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-windows-x86_64.tar.gz @@ -91,10 +91,10 @@ runs: run: | # unzip with 7zip 7z x D:\installers\copt.zip -oD:\ - ls D:\copt72 + ls D:\copt80 # set environment variables - echo "COPT_HOME=D:\copt72" >> $env:GITHUB_ENV - echo "PATH=$env:PATH;D:\copt72\bin" >> $env:GITHUB_ENV + echo "COPT_HOME=D:\copt80" >> $env:GITHUB_ENV + echo "PATH=$env:PATH;D:\copt80\bin" >> $env:GITHUB_ENV echo $env:COPT_HOME # Just use the size-limited license diff --git a/docs/source/getting_started.md b/docs/source/getting_started.md index 37aa91a4..5814a9b7 100644 --- a/docs/source/getting_started.md +++ b/docs/source/getting_started.md @@ -77,15 +77,15 @@ The typical paths where the dynamic library of optimizers are located are as fol - macOS(ARM) - macOS(Intel) * - Gurobi - - `C:\gurobi1101\win64\bin` - - `/opt/gurobi1100/linux64/lib` - - `/opt/gurobi1100/macos_universal2/lib` - - `/opt/gurobi1100/macos_universal2/lib` + - `C:\gurobi1300\win64\bin` + - `/opt/gurobi1300/linux64/lib` + - `/opt/gurobi1300/macos_universal2/lib` + - `/opt/gurobi1300/macos_universal2/lib` * - COPT - - `C:\Program Files\copt71\bin` - - `/opt/copt72/lib` - - `/opt/copt72/lib` - - `/opt/copt72/lib` + - `C:\Program Files\copt80\bin` + - `/opt/copt80/lib` + - `/opt/copt80/lib` + - `/opt/copt80/lib` * - Mosek - `C:\Program Files\Mosek\10.2\tools\platform\win64x86\bin` - `/opt/mosek/10.2/tools/platform/linux64x86/bin` @@ -101,16 +101,16 @@ The typical paths where the dynamic library of optimizers are located are as fol ### Gurobi -The currently supported version is **11.0.x** and **12.0.0**. Other versions may work but are not tested. +The currently supported version is **13.0.0**. Other versions may work but are not tested. For Gurobi, the automatic detection looks for the following things in order: 1. The environment variable `GUROBI_HOME` set by the installer of Gurobi 2. The installation of `gurobipy` -3. `gurobi110.dll`/`libgurobi110.so`/`libgurobi110.dylib` in the system loadable path +3. `gurobi130.dll`/`libgurobi130.so`/`libgurobi130.dylib` in the system loadable path ### COPT -The currently supported version is **7.2.x**. Other versions may work but are not tested. +The currently supported version is **8.0.x**. Other versions may work but are not tested. For COPT, the automatic detection looks for the following things in order: 1. The environment variable `COPT_HOME` set by the installer of COPT @@ -127,7 +127,7 @@ For Mosek, the automatic detection looks for the following things in order: ### HiGHS -The currently supported version is **1.8.x**. Other versions may work but are not tested. +The currently supported version is **1.12.x**. Other versions may work but are not tested. For HiGHS, the automatic detection looks for the following things in order: 1. The environment variable `HiGHS_HOME` set by the user diff --git a/optimizer_version.toml b/optimizer_version.toml index ceb55c5b..7c6c7560 100644 --- a/optimizer_version.toml +++ b/optimizer_version.toml @@ -1,5 +1,5 @@ Gurobi = "13.0.0" -COPT = "7.2.8" +COPT = "8.0.2" MOSEK = "10.2.0" HiGHS = "1.12.0" IPOPT = "3.13.2" From 2cedf6b0a120788d469df34dccfecc705e18c136 Mon Sep 17 00:00:00 2001 From: metab0t Date: Thu, 11 Dec 2025 20:50:01 +0800 Subject: [PATCH 5/8] Smaller test to avoid license error --- tests/test_nlp_clnlbeam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_nlp_clnlbeam.py b/tests/test_nlp_clnlbeam.py index e91ed3c0..87b77fb3 100644 --- a/tests/test_nlp_clnlbeam.py +++ b/tests/test_nlp_clnlbeam.py @@ -7,7 +7,7 @@ def test_clnlbeam(nlp_model_ctor): model = nlp_model_ctor() - N = 1000 + N = 100 h = 1 / N alpha = 350 From 3fcafdf6ada81c71403e8a5297483baad2bd0897 Mon Sep 17 00:00:00 2001 From: metab0t Date: Thu, 11 Dec 2025 20:59:37 +0800 Subject: [PATCH 6/8] ci: upgrade Python version to 3.13 in all CI workflows --- .github/workflows/doc-build.yml | 2 +- .github/workflows/linux-build.yml | 2 +- .github/workflows/macos-build.yml | 2 +- .github/workflows/windows-build.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 4f74c07d..03a4fb64 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.12"] + python-version: ["3.13"] env: PYTHON_VERSION: ${{ matrix.python-version }} diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 440ad6d2..9fd2af8d 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -20,7 +20,7 @@ jobs: matrix: os: [ubuntu-latest, ubuntu-24.04-arm] # python-version: ["3.9", "3.10", "3.11", "3.12"] - python-version: ["3.12"] + python-version: ["3.13"] env: PYTHON_VERSION: ${{ matrix.python-version }} diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml index 31d5fb29..8a21b01f 100644 --- a/.github/workflows/macos-build.yml +++ b/.github/workflows/macos-build.yml @@ -16,7 +16,7 @@ jobs: matrix: os: [macos-14] # python-version: ["3.9", "3.10", "3.11", "3.12"] - python-version: ["3.11", "3.12"] + python-version: ["3.11", "3.13"] env: PYTHON_VERSION: ${{ matrix.python-version }} diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index c16de04a..fbb0ae96 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.12"] + python-version: ["3.9", "3.13"] env: PYTHON_VERSION: ${{ matrix.python-version }} From 59f3393ad5f0901806e3909721bcefb4297c4565 Mon Sep 17 00:00:00 2001 From: metab0t Date: Fri, 12 Dec 2025 00:22:55 +0800 Subject: [PATCH 7/8] Use prek to setup pre-commit check and reformat all the files --- .pre-commit-config.yaml | 16 ++++++++++ include/pyoptinterface/cache_model.hpp | 1 - include/pyoptinterface/core.hpp | 36 +++++++++++----------- include/pyoptinterface/cppad_interface.hpp | 1 - lib/core_ext.cpp | 3 +- lib/highs_model_ext.cpp | 31 ++++++++----------- 6 files changed, 48 insertions(+), 40 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..1b203495 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,16 @@ +repos: + # C++ 格式化 - clang-format + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v21.1.7 + hooks: + - id: clang-format + types_or: [c++, c] + files: \.(cpp|hpp|c|h|cc|cxx|hxx)$ + exclude: ^thirdparty/ + + # Python 格式化 - black + - repo: https://github.com/psf/black + rev: 25.12.0 + hooks: + - id: black + language_version: python3 diff --git a/include/pyoptinterface/cache_model.hpp b/include/pyoptinterface/cache_model.hpp index 7a0749cb..6104592e 100644 --- a/include/pyoptinterface/cache_model.hpp +++ b/include/pyoptinterface/cache_model.hpp @@ -54,4 +54,3 @@ struct QuadraticExpressionCache lin_column_ptr.push_back(lin_variables.size()); } }; - diff --git a/include/pyoptinterface/core.hpp b/include/pyoptinterface/core.hpp index 206d453f..a2b06833 100644 --- a/include/pyoptinterface/core.hpp +++ b/include/pyoptinterface/core.hpp @@ -173,18 +173,18 @@ auto operator+(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction; auto operator+(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction; auto operator+(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction; auto operator+(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction; -auto operator+(const ScalarAffineFunction &a, - const ScalarAffineFunction &b) -> ScalarAffineFunction; +auto operator+(const ScalarAffineFunction &a, const ScalarAffineFunction &b) + -> ScalarAffineFunction; auto operator+(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction; auto operator+(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; auto operator+(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction; auto operator+(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; -auto operator+(const ScalarQuadraticFunction &a, - const ScalarAffineFunction &b) -> ScalarQuadraticFunction; -auto operator+(const ScalarAffineFunction &a, - const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; -auto operator+(const ScalarQuadraticFunction &a, - const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; +auto operator+(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b) + -> ScalarQuadraticFunction; +auto operator+(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b) + -> ScalarQuadraticFunction; +auto operator+(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b) + -> ScalarQuadraticFunction; auto operator-(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction; auto operator-(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction; @@ -193,18 +193,18 @@ auto operator-(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction; auto operator-(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction; auto operator-(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction; auto operator-(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction; -auto operator-(const ScalarAffineFunction &a, - const ScalarAffineFunction &b) -> ScalarAffineFunction; +auto operator-(const ScalarAffineFunction &a, const ScalarAffineFunction &b) + -> ScalarAffineFunction; auto operator-(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction; auto operator-(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; auto operator-(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction; auto operator-(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; -auto operator-(const ScalarQuadraticFunction &a, - const ScalarAffineFunction &b) -> ScalarQuadraticFunction; -auto operator-(const ScalarAffineFunction &a, - const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; -auto operator-(const ScalarQuadraticFunction &a, - const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; +auto operator-(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b) + -> ScalarQuadraticFunction; +auto operator-(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b) + -> ScalarQuadraticFunction; +auto operator-(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b) + -> ScalarQuadraticFunction; auto operator*(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction; auto operator*(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction; @@ -213,8 +213,8 @@ auto operator*(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction; auto operator*(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction; auto operator*(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction; auto operator*(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarQuadraticFunction; -auto operator*(const ScalarAffineFunction &a, - const ScalarAffineFunction &b) -> ScalarQuadraticFunction; +auto operator*(const ScalarAffineFunction &a, const ScalarAffineFunction &b) + -> ScalarQuadraticFunction; auto operator*(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction; auto operator*(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction; diff --git a/include/pyoptinterface/cppad_interface.hpp b/include/pyoptinterface/cppad_interface.hpp index 09cd6b39..86adb7c5 100644 --- a/include/pyoptinterface/cppad_interface.hpp +++ b/include/pyoptinterface/cppad_interface.hpp @@ -35,7 +35,6 @@ ADFunDouble sparse_hessian(const ADFunDouble &f, const sparsity_pattern_t &patte ADFunDouble cppad_trace_graph_constraints(const ExpressionGraph &graph); ADFunDouble cppad_trace_graph_objective(const ExpressionGraph &graph); - struct CppADAutodiffGraph { CppAD::cpp_graph f_graph, jacobian_graph, hessian_graph; diff --git a/lib/core_ext.cpp b/lib/core_ext.cpp index 7222177f..d7919e1c 100644 --- a/lib/core_ext.cpp +++ b/lib/core_ext.cpp @@ -103,8 +103,7 @@ NB_MODULE(core_ext, m) return expr; }, - nb::arg("coefficients"), nb::arg("variables"), - nb::rv_policy::take_ownership) + nb::arg("coefficients"), nb::arg("variables"), nb::rv_policy::take_ownership) .def_static( "from_numpy", [](CoeffNdarrayT coefficients, IndexNdarrayT variables, CoeffT constant) { diff --git a/lib/highs_model_ext.cpp b/lib/highs_model_ext.cpp index b56e4537..48a33520 100644 --- a/lib/highs_model_ext.cpp +++ b/lib/highs_model_ext.cpp @@ -57,26 +57,22 @@ NB_MODULE(highs_model_ext, m) .def("set_variable_bounds", &HighsModel::set_variable_bounds, nb::arg("variable"), nb::arg("lb"), nb::arg("ub")) + .def("get_value", nb::overload_cast(&HighsModel::get_variable_value)) .def("get_value", - nb::overload_cast(&HighsModel::get_variable_value)) - .def("get_value", nb::overload_cast( - &HighsModel::get_expression_value)) - .def("get_value", nb::overload_cast( - &HighsModel::get_expression_value)) + nb::overload_cast(&HighsModel::get_expression_value)) .def("get_value", - nb::overload_cast(&HighsModel::get_expression_value)) + nb::overload_cast(&HighsModel::get_expression_value)) + .def("get_value", nb::overload_cast(&HighsModel::get_expression_value)) .def("pprint", &HighsModel::pprint_variable) .def("pprint", - nb::overload_cast( - &HighsModel::pprint_expression), + nb::overload_cast(&HighsModel::pprint_expression), nb::arg("expr"), nb::arg("precision") = 4) - .def("pprint", - nb::overload_cast( - &HighsModel::pprint_expression), - nb::arg("expr"), nb::arg("precision") = 4) - .def("pprint", - nb::overload_cast(&HighsModel::pprint_expression), + .def( + "pprint", + nb::overload_cast(&HighsModel::pprint_expression), + nb::arg("expr"), nb::arg("precision") = 4) + .def("pprint", nb::overload_cast(&HighsModel::pprint_expression), nb::arg("expr"), nb::arg("precision") = 4) .def("_add_linear_constraint", @@ -107,10 +103,9 @@ NB_MODULE(highs_model_ext, m) nb::overload_cast( &HighsModel::set_objective), nb::arg("expr"), nb::arg("sense") = ObjectiveSense::Minimize) - .def( - "set_objective", - nb::overload_cast(&HighsModel::set_objective), - nb::arg("expr"), nb::arg("sense") = ObjectiveSense::Minimize) + .def("set_objective", + nb::overload_cast(&HighsModel::set_objective), + nb::arg("expr"), nb::arg("sense") = ObjectiveSense::Minimize) .def("set_objective", nb::overload_cast( &HighsModel::set_objective_as_variable), From 27122e389c7518871301540a2173a433f9953124 Mon Sep 17 00:00:00 2001 From: Francesco Cavaliere Date: Fri, 19 Dec 2025 10:19:25 +0100 Subject: [PATCH 8/8] Proxy header + renamed constant to avoid any copyright issues (#3) * Proxy header * Renamed constant to avoid any copyright issues * Removed XPRS_CC * Improved _get_entity_name impl * Added back _get_entity_name checks * I've also fixed a typo and added some urls in one of the readme that was missing them. --- include/pyoptinterface/xpress_model.hpp | 117 +- lib/xpress_model.cpp | 243 ++- lib/xpress_model_ext.cpp | 2 +- lib/xpress_model_ext_constants.cpp | 1641 +++++++++-------- thirdparty/solvers/xpress/function_list.txt | 131 ++ .../solvers/xpress/xpress_forward_decls.h | 1528 +++++++++++++++ 6 files changed, 2656 insertions(+), 1006 deletions(-) create mode 100644 thirdparty/solvers/xpress/function_list.txt create mode 100644 thirdparty/solvers/xpress/xpress_forward_decls.h diff --git a/include/pyoptinterface/xpress_model.hpp b/include/pyoptinterface/xpress_model.hpp index 94f463b3..d17d43eb 100644 --- a/include/pyoptinterface/xpress_model.hpp +++ b/include/pyoptinterface/xpress_model.hpp @@ -4,7 +4,8 @@ #include #include -#include +// #include +#include "../thirdparty/solvers/xpress/xpress_forward_decls.h" #include "pyoptinterface/core.hpp" #include "pyoptinterface/container.hpp" @@ -17,7 +18,7 @@ #define XPRS_VER_MINOR 1 #define XPRS_VER_BUILD 1 -#if XPVERSION_MAJOR < XPRS_VER_MAJOR +#if POI_XPVERSION_MAJOR < XPRS_VER_MAJOR #warning "System Xpress library major version is older than the officially supported version. " \ "Some features may not work correctly." #endif @@ -243,91 +244,91 @@ struct Env // Types associated with Xpress attribute and controls enum class CATypes : int { - NOTDEFINED = XPRS_TYPE_NOTDEFINED, - INT = XPRS_TYPE_INT, - INT64 = XPRS_TYPE_INT64, - DOUBLE = XPRS_TYPE_DOUBLE, - STRING = XPRS_TYPE_STRING, + NOTDEFINED = POI_XPRS_TYPE_NOTDEFINED, + INT = POI_XPRS_TYPE_INT, + INT64 = POI_XPRS_TYPE_INT64, + DOUBLE = POI_XPRS_TYPE_DOUBLE, + STRING = POI_XPRS_TYPE_STRING, }; enum class SOLSTATUS : int { - NOTFOUND = XPRS_SOLSTATUS_NOTFOUND, - OPTIMAL = XPRS_SOLSTATUS_OPTIMAL, - FEASIBLE = XPRS_SOLSTATUS_FEASIBLE, - INFEASIBLE = XPRS_SOLSTATUS_INFEASIBLE, - UNBOUNDED = XPRS_SOLSTATUS_UNBOUNDED + NOTFOUND = POI_XPRS_SOLSTATUS_NOTFOUND, + OPTIMAL = POI_XPRS_SOLSTATUS_OPTIMAL, + FEASIBLE = POI_XPRS_SOLSTATUS_FEASIBLE, + INFEASIBLE = POI_XPRS_SOLSTATUS_INFEASIBLE, + UNBOUNDED = POI_XPRS_SOLSTATUS_UNBOUNDED }; enum class SOLVESTATUS : int { - UNSTARTED = XPRS_SOLVESTATUS_UNSTARTED, - STOPPED = XPRS_SOLVESTATUS_STOPPED, - FAILED = XPRS_SOLVESTATUS_FAILED, - COMPLETED = XPRS_SOLVESTATUS_COMPLETED + UNSTARTED = POI_XPRS_SOLVESTATUS_UNSTARTED, + STOPPED = POI_XPRS_SOLVESTATUS_STOPPED, + FAILED = POI_XPRS_SOLVESTATUS_FAILED, + COMPLETED = POI_XPRS_SOLVESTATUS_COMPLETED }; enum class LPSTATUS : int { - UNSTARTED = XPRS_LP_UNSTARTED, - OPTIMAL = XPRS_LP_OPTIMAL, - INFEAS = XPRS_LP_INFEAS, - CUTOFF = XPRS_LP_CUTOFF, - UNFINISHED = XPRS_LP_UNFINISHED, - UNBOUNDED = XPRS_LP_UNBOUNDED, - CUTOFF_IN_DUAL = XPRS_LP_CUTOFF_IN_DUAL, - UNSOLVED = XPRS_LP_UNSOLVED, - NONCONVEX = XPRS_LP_NONCONVEX + UNSTARTED = POI_XPRS_LP_UNSTARTED, + OPTIMAL = POI_XPRS_LP_OPTIMAL, + INFEAS = POI_XPRS_LP_INFEAS, + CUTOFF = POI_XPRS_LP_CUTOFF, + UNFINISHED = POI_XPRS_LP_UNFINISHED, + UNBOUNDED = POI_XPRS_LP_UNBOUNDED, + CUTOFF_IN_DUAL = POI_XPRS_LP_CUTOFF_IN_DUAL, + UNSOLVED = POI_XPRS_LP_UNSOLVED, + NONCONVEX = POI_XPRS_LP_NONCONVEX }; enum class MIPSTATUS : int { - NOT_LOADED = XPRS_MIP_NOT_LOADED, - LP_NOT_OPTIMAL = XPRS_MIP_LP_NOT_OPTIMAL, - LP_OPTIMAL = XPRS_MIP_LP_OPTIMAL, - NO_SOL_FOUND = XPRS_MIP_NO_SOL_FOUND, - SOLUTION = XPRS_MIP_SOLUTION, - INFEAS = XPRS_MIP_INFEAS, - OPTIMAL = XPRS_MIP_OPTIMAL, - UNBOUNDED = XPRS_MIP_UNBOUNDED + NOT_LOADED = POI_XPRS_MIP_NOT_LOADED, + LP_NOT_OPTIMAL = POI_XPRS_MIP_LP_NOT_OPTIMAL, + LP_OPTIMAL = POI_XPRS_MIP_LP_OPTIMAL, + NO_SOL_FOUND = POI_XPRS_MIP_NO_SOL_FOUND, + SOLUTION = POI_XPRS_MIP_SOLUTION, + INFEAS = POI_XPRS_MIP_INFEAS, + OPTIMAL = POI_XPRS_MIP_OPTIMAL, + UNBOUNDED = POI_XPRS_MIP_UNBOUNDED }; enum class NLPSTATUS : int { - UNSTARTED = XPRS_NLPSTATUS_UNSTARTED, - SOLUTION = XPRS_NLPSTATUS_SOLUTION, - LOCALLY_OPTIMAL = XPRS_NLPSTATUS_LOCALLY_OPTIMAL, - OPTIMAL = XPRS_NLPSTATUS_OPTIMAL, - NOSOLUTION = XPRS_NLPSTATUS_NOSOLUTION, - LOCALLY_INFEASIBLE = XPRS_NLPSTATUS_LOCALLY_INFEASIBLE, - INFEASIBLE = XPRS_NLPSTATUS_INFEASIBLE, - UNBOUNDED = XPRS_NLPSTATUS_UNBOUNDED, - UNFINISHED = XPRS_NLPSTATUS_UNFINISHED, - UNSOLVED = XPRS_NLPSTATUS_UNSOLVED, + UNSTARTED = POI_XPRS_NLPSTATUS_UNSTARTED, + SOLUTION = POI_XPRS_NLPSTATUS_SOLUTION, + LOCALLY_OPTIMAL = POI_XPRS_NLPSTATUS_LOCALLY_OPTIMAL, + OPTIMAL = POI_XPRS_NLPSTATUS_OPTIMAL, + NOSOLUTION = POI_XPRS_NLPSTATUS_NOSOLUTION, + LOCALLY_INFEASIBLE = POI_XPRS_NLPSTATUS_LOCALLY_INFEASIBLE, + INFEASIBLE = POI_XPRS_NLPSTATUS_INFEASIBLE, + UNBOUNDED = POI_XPRS_NLPSTATUS_UNBOUNDED, + UNFINISHED = POI_XPRS_NLPSTATUS_UNFINISHED, + UNSOLVED = POI_XPRS_NLPSTATUS_UNSOLVED, }; enum class IISSOLSTATUS : int { - UNSTARTED = XPRS_IIS_UNSTARTED, - FEASIBLE = XPRS_IIS_FEASIBLE, - COMPLETED = XPRS_IIS_COMPLETED, - UNFINISHED = XPRS_IIS_UNFINISHED + UNSTARTED = POI_XPRS_IIS_UNSTARTED, + FEASIBLE = POI_XPRS_IIS_FEASIBLE, + COMPLETED = POI_XPRS_IIS_COMPLETED, + UNFINISHED = POI_XPRS_IIS_UNFINISHED }; enum class SOLAVAILABLE : int { - NOTFOUND = XPRS_SOLAVAILABLE_NOTFOUND, - OPTIMAL = XPRS_SOLAVAILABLE_OPTIMAL, - FEASIBLE = XPRS_SOLAVAILABLE_FEASIBLE + NOTFOUND = POI_XPRS_SOLAVAILABLE_NOTFOUND, + OPTIMAL = POI_XPRS_SOLAVAILABLE_OPTIMAL, + FEASIBLE = POI_XPRS_SOLAVAILABLE_FEASIBLE }; enum class OPTIMIZETYPE : int { - NONE = XPRS_OPTIMIZETYPE_NONE, - LP = XPRS_OPTIMIZETYPE_LP, - MIP = XPRS_OPTIMIZETYPE_MIP, - LOCAL = XPRS_OPTIMIZETYPE_LOCAL, - GLOBAL = XPRS_OPTIMIZETYPE_GLOBAL + NONE = POI_XPRS_OPTIMIZETYPE_NONE, + LP = POI_XPRS_OPTIMIZETYPE_LP, + MIP = POI_XPRS_OPTIMIZETYPE_MIP, + LOCAL = POI_XPRS_OPTIMIZETYPE_LOCAL, + GLOBAL = POI_XPRS_OPTIMIZETYPE_GLOBAL }; //////////////////////////////////////////////////////////////////////////////// @@ -512,8 +513,8 @@ class Model : public OnesideLinearConstraintMixin, // Variables VariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous, - double lb = XPRS_MINUSINFINITY, double ub = XPRS_PLUSINFINITY, - const char *name = nullptr); + double lb = POI_XPRS_MINUSINFINITY, + double ub = POI_XPRS_PLUSINFINITY, const char *name = nullptr); void delete_variable(VariableIndex variable); void delete_variables(const Vector &variables); void set_objective_coefficient(VariableIndex variable, double value); @@ -638,7 +639,7 @@ class Model : public OnesideLinearConstraintMixin, void cb_exit(); - // NOTE: Xpress only provive ways to add local cuts, so, all these functions map to the same + // NOTE: Xpress only provide ways to add local cuts, so, all these functions map to the same // XPRSaddcuts operation void cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs); diff --git a/lib/xpress_model.cpp b/lib/xpress_model.cpp index 34f56620..775c5378 100644 --- a/lib/xpress_model.cpp +++ b/lib/xpress_model.cpp @@ -63,8 +63,7 @@ bool load_library(const std::string &path) int build = {}; XPRSgetversionnumbers(&major, &minor, &build); // Use tuple comparison operator - if (std::make_tuple(major, minor, build) < - std::make_tuple(XPRS_VER_MAJOR, XPRS_VER_MINOR, XPRS_VER_BUILD)) + if (major < XPRS_VER_MAJOR) { fmt::print( stderr, @@ -81,7 +80,7 @@ static void check_license(int error) return; } - char buffer[XPRS_MAXMESSAGELENGTH]; + char buffer[POI_XPRS_MAXMESSAGELENGTH]; if (XPRSgetlicerrmsg(buffer, sizeof buffer) != 0) { throw std::runtime_error("Error while getting the Xpress license error message"); @@ -196,9 +195,9 @@ static int poi_to_xprs_obj_sense(ObjectiveSense sense) switch (sense) { case ObjectiveSense::Minimize: - return XPRS_OBJ_MINIMIZE; + return POI_XPRS_OBJ_MINIMIZE; case ObjectiveSense::Maximize: - return XPRS_OBJ_MAXIMIZE; + return POI_XPRS_OBJ_MAXIMIZE; default: throw std::runtime_error("Unknown objective function sense"); } @@ -292,7 +291,7 @@ void Model::_check(int error) return; } - char error_buffer[XPRS_MAXMESSAGELENGTH]; + char error_buffer[POI_XPRS_MAXMESSAGELENGTH]; if (XPRSgetlasterror(m_model.get(), error_buffer) != 0) { throw std::runtime_error("Error while getting Xpress message error"); @@ -324,17 +323,17 @@ Model::Model(const Env &env) // adjust some controls: // Verbose by default, the user can silence if needed - set_raw_control_int_by_id(XPRS_OUTPUTLOG, 1); + set_raw_control_int_by_id(POI_XPRS_OUTPUTLOG, 1); // Register a message callback (can be overridden) _check(XPRSaddcbmessage(m_model.get(), &default_print, nullptr, 0)); is_default_message_cb_set = true; // We do not support concurrent CBs invocation since each callback have to acquire Python GIL - _check(XPRSsetintcontrol64(m_model.get(), XPRS_MUTEXCALLBACKS, 1)); + _check(XPRSsetintcontrol64(m_model.get(), POI_XPRS_MUTEXCALLBACKS, 1)); // Use global solver if the model contains non linear formulas - set_raw_control_int_by_id(XPRS_NLPSOLVER, XPRS_NLPSOLVER_GLOBAL); + set_raw_control_int_by_id(POI_XPRS_NLPSOLVER, POI_XPRS_NLPSOLVER_GLOBAL); } void Model::init(const Env &env) @@ -403,7 +402,7 @@ void Model::_clear_caches() double Model::get_infinity() { - return XPRS_PLUSINFINITY; + return POI_XPRS_PLUSINFINITY; } void Model::write(const std::string &filename) @@ -462,7 +461,7 @@ void Model::write(const std::string &filename) std::string Model::get_problem_name() { - int size = get_raw_attribute_int_by_id(XPRS_MAXPROBNAMELENGTH) + 1; + int size = get_raw_attribute_int_by_id(POI_XPRS_MAXPROBNAMELENGTH) + 1; std::string probname; probname.resize(size); _check(XPRSgetprobname(m_model.get(), probname.data())); @@ -486,9 +485,9 @@ VariableIndex Model::add_variable(VariableDomain domain, double lb, double ub, c VariableIndex variable(index); double zero[] = {0.0}; - int colidx = get_raw_attribute_int_by_id(XPRS_COLS); + int colidx = get_raw_attribute_int_by_id(POI_XPRS_COLS); _check(XPRSaddcols64(m_model.get(), 1, 0, zero, nullptr, nullptr, nullptr, &lb, &ub)); - _set_entity_name(XPRS_NAMES_COLUMN, colidx, name); + _set_entity_name(POI_XPRS_NAMES_COLUMN, colidx, name); char vtype = poi_to_xprs_var_type(domain); if (domain != VariableDomain::Continuous) { @@ -558,43 +557,31 @@ std::string Model::pprint_variable(VariableIndex variable) std::string Model::_get_entity_name(int etype, int eidx) { - _check_expected_mode(XPRESS_MODEL_MODE::MAIN); + _check_expected_mode(XPRESS_MODEL_MODE::MAIN); _ensure_postsolved(); int req_size = {}; _check(XPRSgetnamelist(m_model.get(), etype, nullptr, 0, &req_size, eidx, eidx)); - - // Small string opt for temporary string - char buffer[64]; - char *value = buffer; - if (req_size > sizeof buffer) + std::string value = {}; + value.resize(req_size); + _check(XPRSgetnamelist(m_model.get(), etype, value.data(), req_size, &req_size, eidx, eidx)); + while (value.back() == '\0') { - value = (char *)malloc(req_size); + value.pop_back(); } - Defer value_cleanup = [&] { - if (req_size > sizeof buffer) - { - free(value); - } - }; - - _check(XPRSgetnamelist(m_model.get(), etype, value, req_size, &req_size, eidx, eidx)); - - assert(value[req_size - 1] == '\0'); - std::string res(value); - return res; + return value; } std::string Model::get_variable_name(VariableIndex variable) { int colidx = _checked_variable_index(variable); - return _get_entity_name(XPRS_NAMES_COLUMN, colidx); + return _get_entity_name(POI_XPRS_NAMES_COLUMN, colidx); } std::string Model::get_constraint_name(ConstraintIndex constraint) { int rowidx = _checked_constraint_index(constraint); - return _get_entity_name(XPRS_NAMES_ROW, rowidx); + return _get_entity_name(POI_XPRS_NAMES_ROW, rowidx); } void Model::set_variable_bounds(VariableIndex variable, double lb, double ub) @@ -678,7 +665,7 @@ void Model::set_variable_name(VariableIndex variable, const char *name) _ensure_postsolved(); int column = _checked_variable_index(variable); - _set_entity_name(XPRS_NAMES_COLUMN, column, name); + _set_entity_name(POI_XPRS_NAMES_COLUMN, column, name); } void Model::set_constraint_name(ConstraintIndex constraint, const char *name) @@ -687,7 +674,7 @@ void Model::set_constraint_name(ConstraintIndex constraint, const char *name) _ensure_postsolved(); int row = _checked_constraint_index(constraint); - _set_entity_name(XPRS_NAMES_ROW, row, name); + _set_entity_name(POI_XPRS_NAMES_ROW, row, name); } ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &function, @@ -700,16 +687,16 @@ ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &functio auto [lb, ub] = interval; double constant = static_cast(function.constant.value_or(CoeffT{})); - lb = std::clamp(lb - constant, XPRS_MINUSINFINITY, XPRS_PLUSINFINITY); - ub = std::clamp(ub - constant, XPRS_MINUSINFINITY, XPRS_PLUSINFINITY); + lb = std::clamp(lb - constant, POI_XPRS_MINUSINFINITY, POI_XPRS_PLUSINFINITY); + ub = std::clamp(ub - constant, POI_XPRS_MINUSINFINITY, POI_XPRS_PLUSINFINITY); if (lb > ub - 1e-10) { throw std::runtime_error("LB > UB in the provieded interval."); } // Handle infinity bounds - bool lb_inf = lb <= XPRS_MINUSINFINITY; - bool ub_inf = ub >= XPRS_PLUSINFINITY; + bool lb_inf = lb <= POI_XPRS_MINUSINFINITY; + bool ub_inf = ub >= POI_XPRS_PLUSINFINITY; // Determine constraint type and parameters char g_sense = {}; @@ -747,7 +734,7 @@ ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &functio IndexT index = m_constraint_index.add_index(); ConstraintIndex constraint_index(ConstraintType::Linear, index); - int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + int rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS); AffineFunctionPtrForm ptr_form; ptr_form.make(this, function); @@ -757,7 +744,7 @@ ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &functio const double *cval = ptr_form.value; _check(XPRSaddrows64(m_model.get(), 1, numnz, &g_sense, &g_rhs, g_range, beg, cind, cval)); - _set_entity_name(XPRS_NAMES_ROW, rowidx, name); + _set_entity_name(POI_XPRS_NAMES_ROW, rowidx, name); return constraint_index; } @@ -771,19 +758,19 @@ ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &functio IndexT index = m_constraint_index.add_index(); ConstraintIndex constraint_index(ConstraintType::Linear, index); - int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + int rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS); AffineFunctionPtrForm ptr_form; ptr_form.make(this, function); int numnz = ptr_form.numnz; double g_rhs = static_cast(rhs - function.constant.value_or(CoeffT{})); - g_rhs = std::clamp(g_rhs, XPRS_MINUSINFINITY, XPRS_PLUSINFINITY); + g_rhs = std::clamp(g_rhs, POI_XPRS_MINUSINFINITY, POI_XPRS_PLUSINFINITY); // Map expr >= -inf and expr <= +inf to free rows char g_sense = poi_to_xprs_cons_sense(sense); - if ((g_sense == 'G' && g_rhs <= XPRS_MINUSINFINITY) || - (g_sense == 'L' && g_rhs >= XPRS_PLUSINFINITY)) + if ((g_sense == 'G' && g_rhs <= POI_XPRS_MINUSINFINITY) || + (g_sense == 'L' && g_rhs >= POI_XPRS_PLUSINFINITY)) { g_sense = 'N'; // Free row g_rhs = 0.0; @@ -793,7 +780,7 @@ ConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &functio const int *cind = ptr_form.index; const double *cval = ptr_form.value; _check(XPRSaddrows64(m_model.get(), 1, numnz, &g_sense, &g_rhs, nullptr, beg, cind, cval)); - _set_entity_name(XPRS_NAMES_ROW, rowidx, name); + _set_entity_name(POI_XPRS_NAMES_ROW, rowidx, name); return constraint_index; } @@ -857,7 +844,7 @@ ConstraintIndex Model::add_quadratic_constraint(const ScalarQuadraticFunction &f _ensure_postsolved(); _clear_caches(); - int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + int rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS); const auto &affine_part = function.affine_part.value_or(ScalarAffineFunction{}); ConstraintIndex constraint_index = add_linear_constraint(affine_part, sense, rhs, name); @@ -945,17 +932,17 @@ ConstraintIndex Model::add_exp_cone_constraint(const Vector &vari if (dual) { // linear_term + x_2 * exp(x_1 / x_2 - 1) >= 0 - auto [types, values] = make_type_value_arrays( // - Tvp{XPRS_TOK_COL, var2_idx}, // x_2 - Tvp{XPRS_TOK_RB, {}}, // ) - Tvp{XPRS_TOK_COL, var1_idx}, // x_1 - Tvp{XPRS_TOK_COL, var2_idx}, // x_2 - Tvp{XPRS_TOK_OP, XPRS_OP_DIVIDE}, // / - Tvp{XPRS_TOK_CON, 1.0}, // 1.0 - Tvp{XPRS_TOK_OP, XPRS_OP_MINUS}, // - - Tvp{XPRS_TOK_IFUN, XPRS_IFUN_EXP}, // exp( - Tvp{XPRS_TOK_OP, XPRS_OP_MULTIPLY}, // * - Tvp{XPRS_TOK_EOF, {}}); // EOF + auto [types, values] = make_type_value_arrays( // + Tvp{POI_XPRS_TOK_COL, var2_idx}, // x_2 + Tvp{POI_XPRS_TOK_RB, {}}, // ) + Tvp{POI_XPRS_TOK_COL, var1_idx}, // x_1 + Tvp{POI_XPRS_TOK_COL, var2_idx}, // x_2 + Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_DIVIDE}, // / + Tvp{POI_XPRS_TOK_CON, 1.0}, // 1.0 + Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_MINUS}, // - + Tvp{POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_EXP}, // exp( + Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY}, // * + Tvp{POI_XPRS_TOK_EOF, {}}); // EOF int begs[] = {0, std::ssize(types)}; _check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types, values)); @@ -963,16 +950,16 @@ ConstraintIndex Model::add_exp_cone_constraint(const Vector &vari else { // linear_term - x_1 * exp(x_2 / x_1) >= 0 - auto [types, values] = make_type_value_arrays( // - Tvp{XPRS_TOK_COL, var1_idx}, // x_1 - Tvp{XPRS_TOK_RB, {}}, // ) - Tvp{XPRS_TOK_COL, var2_idx}, // x_2 - Tvp{XPRS_TOK_COL, var1_idx}, // x_1 - Tvp{XPRS_TOK_OP, XPRS_OP_DIVIDE}, // / - Tvp{XPRS_TOK_IFUN, XPRS_IFUN_EXP}, // exp( - Tvp{XPRS_TOK_OP, XPRS_OP_MULTIPLY}, // * - Tvp{XPRS_TOK_OP, XPRS_OP_UMINUS}, // - - Tvp{XPRS_TOK_EOF, {}}); // EOF + auto [types, values] = make_type_value_arrays( // + Tvp{POI_XPRS_TOK_COL, var1_idx}, // x_1 + Tvp{POI_XPRS_TOK_RB, {}}, // ) + Tvp{POI_XPRS_TOK_COL, var2_idx}, // x_2 + Tvp{POI_XPRS_TOK_COL, var1_idx}, // x_1 + Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_DIVIDE}, // / + Tvp{POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_EXP}, // exp( + Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY}, // * + Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_UMINUS}, // - + Tvp{POI_XPRS_TOK_EOF, {}}); // EOF int begs[] = {0, std::ssize(types)}; _check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types, values)); @@ -1040,29 +1027,29 @@ Tvp to_xprs_opcode(UnaryOperator opcode_enum) switch (opcode_enum) { case UnaryOperator::Neg: - return {XPRS_TOK_OP, XPRS_OP_UMINUS}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_UMINUS}; case UnaryOperator::Sin: - return {XPRS_TOK_IFUN, XPRS_IFUN_SIN}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_SIN}; case UnaryOperator::Cos: - return {XPRS_TOK_IFUN, XPRS_IFUN_COS}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_COS}; case UnaryOperator::Tan: - return {XPRS_TOK_IFUN, XPRS_IFUN_TAN}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_TAN}; case UnaryOperator::Asin: - return {XPRS_TOK_IFUN, XPRS_IFUN_ARCSIN}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ARCSIN}; case UnaryOperator::Acos: - return {XPRS_TOK_IFUN, XPRS_IFUN_ARCCOS}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ARCCOS}; case UnaryOperator::Atan: - return {XPRS_TOK_IFUN, XPRS_IFUN_ARCTAN}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ARCTAN}; case UnaryOperator::Abs: - return {XPRS_TOK_IFUN, XPRS_IFUN_ABS}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ABS}; case UnaryOperator::Sqrt: - return {XPRS_TOK_IFUN, XPRS_IFUN_SQRT}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_SQRT}; case UnaryOperator::Exp: - return {XPRS_TOK_IFUN, XPRS_IFUN_EXP}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_EXP}; case UnaryOperator::Log: - return {XPRS_TOK_IFUN, XPRS_IFUN_LOG}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_LN}; case UnaryOperator::Log10: - return {XPRS_TOK_IFUN, XPRS_IFUN_LOG10}; + return {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_LOG10}; default: { auto opname = unary_operator_to_string(opcode_enum); auto msg = fmt::format("Unknown unary operator for Xpress: {}", opname); @@ -1076,15 +1063,15 @@ Tvp to_xprs_opcode(BinaryOperator opcode_enum) switch (opcode_enum) { case BinaryOperator::Sub: - return {XPRS_TOK_OP, XPRS_OP_MINUS}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_MINUS}; case BinaryOperator::Div: - return {XPRS_TOK_OP, XPRS_OP_DIVIDE}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_DIVIDE}; case BinaryOperator::Pow: - return {XPRS_TOK_OP, XPRS_OP_EXPONENT}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_EXPONENT}; case BinaryOperator::Add2: - return {XPRS_TOK_OP, XPRS_OP_PLUS}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_PLUS}; case BinaryOperator::Mul2: - return {XPRS_TOK_OP, XPRS_OP_MULTIPLY}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY}; default: auto opname = binary_operator_to_string(opcode_enum); auto msg = fmt::format("Unknown unary operator for Xpress: {}", opname); @@ -1104,9 +1091,9 @@ Tvp to_xprs_opcode(NaryOperator opcode_enum) switch (opcode_enum) { case NaryOperator::Add: - return {XPRS_TOK_OP, XPRS_OP_PLUS}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_PLUS}; case NaryOperator::Mul: - return {XPRS_TOK_OP, XPRS_OP_MULTIPLY}; + return {POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY}; default: auto opname = nary_operator_to_string(opcode_enum); auto msg = fmt::format("Unknown nary operator for Xpress: {}", opname); @@ -1138,9 +1125,9 @@ Tvp Model::_decode_expr(const ExpressionGraph &graph, const ExpressionHandle &ex switch (array_type) { case ArrayType::Constant: - return {XPRS_TOK_CON, static_cast(graph.m_constants[index])}; + return {POI_XPRS_TOK_CON, static_cast(graph.m_constants[index])}; case ArrayType::Variable: - return {XPRS_TOK_COL, + return {POI_XPRS_TOK_COL, static_cast(_checked_variable_index(graph.m_variables[index]))}; case ArrayType::Parameter: break; @@ -1204,9 +1191,9 @@ std::pair, std::vector> Model::_decode_graph_postfix_or } // Xpress requires a parenthesis to start an internal or user function - if (type == XPRS_TOK_IFUN || type == XPRS_TOK_FUN) + if (type == POI_XPRS_TOK_IFUN || type == POI_XPRS_TOK_FUN) { - types.push_back(XPRS_TOK_RB); + types.push_back(POI_XPRS_TOK_RB); values.push_back({}); } @@ -1236,7 +1223,7 @@ std::pair, std::vector> Model::_decode_graph_postfix_or visit_children = false; } - types.push_back(XPRS_TOK_EOF); + types.push_back(POI_XPRS_TOK_EOF); values.push_back({}); return {std::move(types), std::move(values)}; } @@ -1250,7 +1237,7 @@ ConstraintIndex Model::add_single_nl_constraint(ExpressionGraph &graph, _ensure_postsolved(); _clear_caches(); - int rowidx = get_raw_attribute_int_by_id(XPRS_ROWS); + int rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS); ConstraintIndex constraint = add_linear_constraint(ScalarAffineFunction{}, interval, name); constraint.type = ConstraintType::Xpress_Nlp; @@ -1522,8 +1509,8 @@ int Model::_checked_variable_index(VariableIndex variable) bool Model::_is_mip() { - return get_raw_attribute_int_by_id(XPRS_MIPENTS) > 0 || - get_raw_attribute_int_by_id(XPRS_SETS) > 0; + return get_raw_attribute_int_by_id(POI_XPRS_MIPENTS) > 0 || + get_raw_attribute_int_by_id(POI_XPRS_SETS) > 0; } void Model::optimize() @@ -1533,17 +1520,17 @@ void Model::optimize() int stop_status = 0; _check(XPRSoptimize(m_model.get(), "", &stop_status, nullptr)); - m_need_postsolve = (stop_status == XPRS_SOLVESTATUS_STOPPED); + m_need_postsolve = (stop_status == POI_XPRS_SOLVESTATUS_STOPPED); } double Model::get_variable_value(VariableIndex variable) { _check_expected_mode(XPRESS_MODEL_MODE::MAIN); int colidx = _checked_variable_index(variable); - int status = XPRS_SOLAVAILABLE_NOTFOUND; + int status = POI_XPRS_SOLAVAILABLE_NOTFOUND; double value = {}; _check(XPRSgetsolution(m_model.get(), &status, &value, colidx, colidx)); - if (status == XPRS_SOLAVAILABLE_NOTFOUND) + if (status == POI_XPRS_SOLAVAILABLE_NOTFOUND) { throw std::runtime_error("No solution found"); } @@ -1554,10 +1541,10 @@ double Model::get_variable_rc(VariableIndex variable) { _check_expected_mode(XPRESS_MODEL_MODE::MAIN); int colidx = _checked_variable_index(variable); - int status = XPRS_SOLAVAILABLE_NOTFOUND; + int status = POI_XPRS_SOLAVAILABLE_NOTFOUND; double value = {}; _check(XPRSgetredcosts(m_model.get(), &status, &value, colidx, colidx)); - if (status == XPRS_SOLAVAILABLE_NOTFOUND) + if (status == POI_XPRS_SOLAVAILABLE_NOTFOUND) { throw std::runtime_error("No solution found"); } @@ -1577,7 +1564,7 @@ double Model::get_variable_primal_ray(VariableIndex variable) { throw std::runtime_error("Primal ray not available"); } - m_primal_ray.resize(get_raw_attribute_int_by_id(XPRS_COLS)); + m_primal_ray.resize(get_raw_attribute_int_by_id(POI_XPRS_COLS)); _check(XPRSgetprimalray(m_model.get(), m_primal_ray.data(), &has_ray)); assert(has_ray != 0); } @@ -1605,23 +1592,24 @@ int Model::_get_basis_stat(int entity_idx, bool is_row) bool Model::is_variable_basic(VariableIndex variable) { - return _get_basis_stat(_checked_variable_index(variable), false) == XPRS_BASISSTATUS_BASIC; + return _get_basis_stat(_checked_variable_index(variable), false) == POI_XPRS_BASISSTATUS_BASIC; } bool Model::is_variable_nonbasic_lb(VariableIndex variable) { return _get_basis_stat(_checked_variable_index(variable), false) == - XPRS_BASISSTATUS_NONBASIC_LOWER; + POI_XPRS_BASISSTATUS_NONBASIC_LOWER; } bool Model::is_variable_nonbasic_ub(VariableIndex variable) { return _get_basis_stat(_checked_variable_index(variable), false) == - XPRS_BASISSTATUS_NONBASIC_UPPER; + POI_XPRS_BASISSTATUS_NONBASIC_UPPER; } bool Model::is_variable_superbasic(VariableIndex variable) { - return _get_basis_stat(_checked_variable_index(variable), false) == XPRS_BASISSTATUS_SUPERBASIC; + return _get_basis_stat(_checked_variable_index(variable), false) == + POI_XPRS_BASISSTATUS_SUPERBASIC; } double Model::get_variable_lowerbound(VariableIndex variable) @@ -1733,10 +1721,10 @@ double Model::get_constraint_slack(ConstraintIndex constraint) _ensure_postsolved(); int rowidx = _checked_constraint_index(constraint); - int status = XPRS_SOLAVAILABLE_NOTFOUND; + int status = POI_XPRS_SOLAVAILABLE_NOTFOUND; double value = {}; _check(XPRSgetslacks(m_model.get(), &status, &value, rowidx, rowidx)); - if (status == XPRS_SOLAVAILABLE_NOTFOUND) + if (status == POI_XPRS_SOLAVAILABLE_NOTFOUND) { throw std::runtime_error("No solution found"); } @@ -1749,10 +1737,10 @@ double Model::get_constraint_dual(ConstraintIndex constraint) _ensure_postsolved(); int rowidx = _checked_constraint_index(constraint); - int status = XPRS_SOLAVAILABLE_NOTFOUND; + int status = POI_XPRS_SOLAVAILABLE_NOTFOUND; double value = {}; _check(XPRSgetduals(m_model.get(), &status, &value, rowidx, rowidx)); - if (status == XPRS_SOLAVAILABLE_NOTFOUND) + if (status == POI_XPRS_SOLAVAILABLE_NOTFOUND) { throw std::runtime_error("No solution found"); } @@ -1773,7 +1761,7 @@ double Model::get_constraint_dual_ray(ConstraintIndex constraint) { throw std::runtime_error("Dual ray not available"); } - m_dual_ray.resize(get_raw_attribute_int_by_id(XPRS_ROWS)); + m_dual_ray.resize(get_raw_attribute_int_by_id(POI_XPRS_ROWS)); _check(XPRSgetdualray(m_model.get(), m_dual_ray.data(), &has_ray)); assert(has_ray != 0); } @@ -1784,25 +1772,26 @@ double Model::get_constraint_dual_ray(ConstraintIndex constraint) bool Model::is_constraint_basic(ConstraintIndex constraint) { - return _get_basis_stat(_checked_constraint_index(constraint), true) == XPRS_BASISSTATUS_BASIC; + return _get_basis_stat(_checked_constraint_index(constraint), true) == + POI_XPRS_BASISSTATUS_BASIC; } bool Model::is_constraint_nonbasic_lb(ConstraintIndex constraint) { return _get_basis_stat(_checked_constraint_index(constraint), true) == - XPRS_BASISSTATUS_NONBASIC_LOWER; + POI_XPRS_BASISSTATUS_NONBASIC_LOWER; } bool Model::is_constraint_nonbasic_ub(ConstraintIndex constraint) { return _get_basis_stat(_checked_constraint_index(constraint), true) == - XPRS_BASISSTATUS_NONBASIC_UPPER; + POI_XPRS_BASISSTATUS_NONBASIC_UPPER; } bool Model::is_constraint_superbasic(ConstraintIndex constraint) { return _get_basis_stat(_checked_constraint_index(constraint), true) == - XPRS_BASISSTATUS_SUPERBASIC; + POI_XPRS_BASISSTATUS_SUPERBASIC; } bool Model::is_constraint_in_IIS(ConstraintIndex constraint) @@ -2049,7 +2038,7 @@ void Model::set_raw_control_int_by_id(int control, XPRSint64 value) { // Disabling Xpress internal callback mutex is forbidden since this could easily create race // condition and deadlocks since it's used in conjunction with Python GIL. - if (control == XPRS_MUTEXCALLBACKS) + if (control == POI_XPRS_MUTEXCALLBACKS) { throw std::runtime_error( "Changing Xpress callback mutex setting is currently not supported."); @@ -2127,37 +2116,37 @@ std::string Model::get_raw_attribute_str_by_id(int attrib) LPSTATUS Model::get_lp_status() { - return static_cast(get_raw_attribute_int_by_id(XPRS_LPSTATUS)); + return static_cast(get_raw_attribute_int_by_id(POI_XPRS_LPSTATUS)); } MIPSTATUS Model::get_mip_status() { - return static_cast(get_raw_attribute_int_by_id(XPRS_MIPSTATUS)); + return static_cast(get_raw_attribute_int_by_id(POI_XPRS_MIPSTATUS)); } NLPSTATUS Model::get_nlp_status() { - return static_cast(get_raw_attribute_int_by_id(XPRS_NLPSTATUS)); + return static_cast(get_raw_attribute_int_by_id(POI_XPRS_NLPSTATUS)); } SOLVESTATUS Model::get_solve_status() { - return static_cast(get_raw_attribute_int_by_id(XPRS_SOLVESTATUS)); + return static_cast(get_raw_attribute_int_by_id(POI_XPRS_SOLVESTATUS)); } SOLSTATUS Model::get_sol_status() { - return static_cast(get_raw_attribute_int_by_id(XPRS_SOLSTATUS)); + return static_cast(get_raw_attribute_int_by_id(POI_XPRS_SOLSTATUS)); } IISSOLSTATUS Model::get_iis_sol_status() { - return static_cast(get_raw_attribute_int_by_id(XPRS_IISSOLSTATUS)); + return static_cast(get_raw_attribute_int_by_id(POI_XPRS_IISSOLSTATUS)); } OPTIMIZETYPE Model::get_optimize_type() { - return static_cast(get_raw_attribute_int_by_id(XPRS_OPTIMIZETYPEUSED)); + return static_cast(get_raw_attribute_int_by_id(POI_XPRS_OPTIMIZETYPEUSED)); } void Model::_ensure_postsolved() @@ -2288,7 +2277,7 @@ void Model::cb_submit_solution() void Model::cb_exit() { _check_expected_mode(XPRESS_MODEL_MODE::CALLBACK); - _check(XPRSinterrupt(m_model.get(), XPRS_STOP_USER)); + _check(XPRSinterrupt(m_model.get(), POI_XPRS_STOP_USER)); } void Model::_cb_add_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs) @@ -2304,7 +2293,7 @@ void Model::_cb_add_cut(const ScalarAffineFunction &function, ConstraintSense se // Before adding the cut, we must translate it to the presolved model. If this translation fails // then we cannot continue. The translation can only fail if we have presolve operations enabled // that should be disabled in case of dynamically separated constraints. - int ncols = get_raw_attribute_int_by_id(XPRS_COLS); + int ncols = get_raw_attribute_int_by_id(POI_XPRS_COLS); int ps_numnz = 0; std::vector ps_cind(ncols); std::vector ps_cval(ncols); @@ -2380,7 +2369,7 @@ void Model::cb_add_lazy_constraint(const ScalarAffineFunction &function, Constra { infeas = std::max(infeas, real_rhs - activity); } - const double feastol = get_raw_control_dbl_by_id(XPRS_FEASTOL); + const double feastol = get_raw_control_dbl_by_id(POI_XPRS_FEASTOL); if (infeas > feastol) { // The user added a cut, but we are not in a context where it can be added. So, the only @@ -2453,7 +2442,7 @@ struct Model::CbWrap { // We cannot let any exception slip through a callback, we have to catch it, // terminate Xpress gracefully and then we can throw it again. - if (XPRSinterrupt(cb_prob, XPRS_STOP_USER) != 0) + if (XPRSinterrupt(cb_prob, POI_XPRS_STOP_USER) != 0) { std::rethrow_exception(std::current_exception()); // We have to terminate somehow } diff --git a/lib/xpress_model_ext.cpp b/lib/xpress_model_ext.cpp index d46da5ed..f563c724 100644 --- a/lib/xpress_model_ext.cpp +++ b/lib/xpress_model_ext.cpp @@ -59,7 +59,7 @@ NB_MODULE(xpress_model_ext, m) // Variables .def("add_variable", &Model::add_variable, "domain"_a = VariableDomain::Continuous, - "lb"_a = XPRS_MINUSINFINITY, "ub"_a = XPRS_PLUSINFINITY, "name"_a = "") + "lb"_a = POI_XPRS_MINUSINFINITY, "ub"_a = POI_XPRS_PLUSINFINITY, "name"_a = "") .def("delete_variable", &Model::delete_variable, "variable"_a) .def("delete_variables", &Model::delete_variables, "variables"_a) .def("set_objective_coefficient", &Model::set_objective_coefficient, "variable"_a, diff --git a/lib/xpress_model_ext_constants.cpp b/lib/xpress_model_ext_constants.cpp index c2cae68b..bf657289 100644 --- a/lib/xpress_model_ext_constants.cpp +++ b/lib/xpress_model_ext_constants.cpp @@ -9,852 +9,853 @@ void bind_xpress_constants(nb::module_ &m) { nb::module_ XPRS = m.def_submodule("XPRS"); /* useful constants */ - XPRS.attr("PLUSINFINITY") = XPRS_PLUSINFINITY; - XPRS.attr("MINUSINFINITY") = XPRS_MINUSINFINITY; - XPRS.attr("MAXINT") = XPRS_MAXINT; - XPRS.attr("MAXBANNERLENGTH") = XPRS_MAXBANNERLENGTH; - XPRS.attr("VERSION") = XPVERSION; - XPRS.attr("VERSION_MAJOR") = XPVERSION_FULL; - XPRS.attr("VERSION_MINOR") = XPVERSION_BUILD; - XPRS.attr("VERSION_BUILD") = XPVERSION_MINOR; - XPRS.attr("VERSION_FULL") = XPVERSION_MAJOR; - XPRS.attr("MAXMESSAGELENGTH") = XPRS_MAXMESSAGELENGTH; + XPRS.attr("PLUSINFINITY") = POI_XPRS_PLUSINFINITY; + XPRS.attr("MINUSINFINITY") = POI_XPRS_MINUSINFINITY; + XPRS.attr("MAXINT") = POI_XPRS_MAXINT; + XPRS.attr("MAXBANNERLENGTH") = POI_XPRS_MAXBANNERLENGTH; + XPRS.attr("VERSION") = POI_XPVERSION; + XPRS.attr("VERSION_MAJOR") = POI_XPVERSION_FULL; + XPRS.attr("VERSION_MINOR") = POI_XPVERSION_BUILD; + XPRS.attr("VERSION_BUILD") = POI_XPVERSION_MINOR; + XPRS.attr("VERSION_FULL") = POI_XPVERSION_MAJOR; + XPRS.attr("MAXMESSAGELENGTH") = POI_XPRS_MAXMESSAGELENGTH; /* control parameters for XPRSprob */ /* String control parameters */ - XPRS.attr("MPSRHSNAME") = XPRS_MPSRHSNAME; - XPRS.attr("MPSOBJNAME") = XPRS_MPSOBJNAME; - XPRS.attr("MPSRANGENAME") = XPRS_MPSRANGENAME; - XPRS.attr("MPSBOUNDNAME") = XPRS_MPSBOUNDNAME; - XPRS.attr("OUTPUTMASK") = XPRS_OUTPUTMASK; - XPRS.attr("TUNERMETHODFILE") = XPRS_TUNERMETHODFILE; - XPRS.attr("TUNEROUTPUTPATH") = XPRS_TUNEROUTPUTPATH; - XPRS.attr("TUNERSESSIONNAME") = XPRS_TUNERSESSIONNAME; - XPRS.attr("COMPUTEEXECSERVICE") = XPRS_COMPUTEEXECSERVICE; + XPRS.attr("MPSRHSNAME") = POI_XPRS_MPSRHSNAME; + XPRS.attr("MPSOBJNAME") = POI_XPRS_MPSOBJNAME; + XPRS.attr("MPSRANGENAME") = POI_XPRS_MPSRANGENAME; + XPRS.attr("MPSBOUNDNAME") = POI_XPRS_MPSBOUNDNAME; + XPRS.attr("OUTPUTMASK") = POI_XPRS_OUTPUTMASK; + XPRS.attr("TUNERMETHODFILE") = POI_XPRS_TUNERMETHODFILE; + XPRS.attr("TUNEROUTPUTPATH") = POI_XPRS_TUNEROUTPUTPATH; + XPRS.attr("TUNERSESSIONNAME") = POI_XPRS_TUNERSESSIONNAME; + XPRS.attr("COMPUTEEXECSERVICE") = POI_XPRS_COMPUTEEXECSERVICE; /* Double control parameters */ - XPRS.attr("MAXCUTTIME") = XPRS_MAXCUTTIME; - XPRS.attr("MAXSTALLTIME") = XPRS_MAXSTALLTIME; - XPRS.attr("TUNERMAXTIME") = XPRS_TUNERMAXTIME; - XPRS.attr("MATRIXTOL") = XPRS_MATRIXTOL; - XPRS.attr("PIVOTTOL") = XPRS_PIVOTTOL; - XPRS.attr("FEASTOL") = XPRS_FEASTOL; - XPRS.attr("OUTPUTTOL") = XPRS_OUTPUTTOL; - XPRS.attr("SOSREFTOL") = XPRS_SOSREFTOL; - XPRS.attr("OPTIMALITYTOL") = XPRS_OPTIMALITYTOL; - XPRS.attr("ETATOL") = XPRS_ETATOL; - XPRS.attr("RELPIVOTTOL") = XPRS_RELPIVOTTOL; - XPRS.attr("MIPTOL") = XPRS_MIPTOL; - XPRS.attr("MIPTOLTARGET") = XPRS_MIPTOLTARGET; - XPRS.attr("BARPERTURB") = XPRS_BARPERTURB; - XPRS.attr("MIPADDCUTOFF") = XPRS_MIPADDCUTOFF; - XPRS.attr("MIPABSCUTOFF") = XPRS_MIPABSCUTOFF; - XPRS.attr("MIPRELCUTOFF") = XPRS_MIPRELCUTOFF; - XPRS.attr("PSEUDOCOST") = XPRS_PSEUDOCOST; - XPRS.attr("PENALTY") = XPRS_PENALTY; - XPRS.attr("BIGM") = XPRS_BIGM; - XPRS.attr("MIPABSSTOP") = XPRS_MIPABSSTOP; - XPRS.attr("MIPRELSTOP") = XPRS_MIPRELSTOP; - XPRS.attr("CROSSOVERACCURACYTOL") = XPRS_CROSSOVERACCURACYTOL; - XPRS.attr("PRIMALPERTURB") = XPRS_PRIMALPERTURB; - XPRS.attr("DUALPERTURB") = XPRS_DUALPERTURB; - XPRS.attr("BAROBJSCALE") = XPRS_BAROBJSCALE; - XPRS.attr("BARRHSSCALE") = XPRS_BARRHSSCALE; - XPRS.attr("CHOLESKYTOL") = XPRS_CHOLESKYTOL; - XPRS.attr("BARGAPSTOP") = XPRS_BARGAPSTOP; - XPRS.attr("BARDUALSTOP") = XPRS_BARDUALSTOP; - XPRS.attr("BARPRIMALSTOP") = XPRS_BARPRIMALSTOP; - XPRS.attr("BARSTEPSTOP") = XPRS_BARSTEPSTOP; - XPRS.attr("ELIMTOL") = XPRS_ELIMTOL; - XPRS.attr("MARKOWITZTOL") = XPRS_MARKOWITZTOL; - XPRS.attr("MIPABSGAPNOTIFY") = XPRS_MIPABSGAPNOTIFY; - XPRS.attr("MIPRELGAPNOTIFY") = XPRS_MIPRELGAPNOTIFY; - XPRS.attr("BARLARGEBOUND") = XPRS_BARLARGEBOUND; - XPRS.attr("PPFACTOR") = XPRS_PPFACTOR; - XPRS.attr("REPAIRINDEFINITEQMAX") = XPRS_REPAIRINDEFINITEQMAX; - XPRS.attr("BARGAPTARGET") = XPRS_BARGAPTARGET; - XPRS.attr("DUMMYCONTROL") = XPRS_DUMMYCONTROL; - XPRS.attr("BARSTARTWEIGHT") = XPRS_BARSTARTWEIGHT; - XPRS.attr("BARFREESCALE") = XPRS_BARFREESCALE; - XPRS.attr("SBEFFORT") = XPRS_SBEFFORT; - XPRS.attr("HEURDIVERANDOMIZE") = XPRS_HEURDIVERANDOMIZE; - XPRS.attr("HEURSEARCHEFFORT") = XPRS_HEURSEARCHEFFORT; - XPRS.attr("CUTFACTOR") = XPRS_CUTFACTOR; - XPRS.attr("EIGENVALUETOL") = XPRS_EIGENVALUETOL; - XPRS.attr("INDLINBIGM") = XPRS_INDLINBIGM; - XPRS.attr("TREEMEMORYSAVINGTARGET") = XPRS_TREEMEMORYSAVINGTARGET; - XPRS.attr("INDPRELINBIGM") = XPRS_INDPRELINBIGM; - XPRS.attr("RELAXTREEMEMORYLIMIT") = XPRS_RELAXTREEMEMORYLIMIT; - XPRS.attr("MIPABSGAPNOTIFYOBJ") = XPRS_MIPABSGAPNOTIFYOBJ; - XPRS.attr("MIPABSGAPNOTIFYBOUND") = XPRS_MIPABSGAPNOTIFYBOUND; - XPRS.attr("PRESOLVEMAXGROW") = XPRS_PRESOLVEMAXGROW; - XPRS.attr("HEURSEARCHTARGETSIZE") = XPRS_HEURSEARCHTARGETSIZE; - XPRS.attr("CROSSOVERRELPIVOTTOL") = XPRS_CROSSOVERRELPIVOTTOL; - XPRS.attr("CROSSOVERRELPIVOTTOLSAFE") = XPRS_CROSSOVERRELPIVOTTOLSAFE; - XPRS.attr("DETLOGFREQ") = XPRS_DETLOGFREQ; - XPRS.attr("MAXIMPLIEDBOUND") = XPRS_MAXIMPLIEDBOUND; - XPRS.attr("FEASTOLTARGET") = XPRS_FEASTOLTARGET; - XPRS.attr("OPTIMALITYTOLTARGET") = XPRS_OPTIMALITYTOLTARGET; - XPRS.attr("PRECOMPONENTSEFFORT") = XPRS_PRECOMPONENTSEFFORT; - XPRS.attr("LPLOGDELAY") = XPRS_LPLOGDELAY; - XPRS.attr("HEURDIVEITERLIMIT") = XPRS_HEURDIVEITERLIMIT; - XPRS.attr("BARKERNEL") = XPRS_BARKERNEL; - XPRS.attr("FEASTOLPERTURB") = XPRS_FEASTOLPERTURB; - XPRS.attr("CROSSOVERFEASWEIGHT") = XPRS_CROSSOVERFEASWEIGHT; - XPRS.attr("LUPIVOTTOL") = XPRS_LUPIVOTTOL; - XPRS.attr("MIPRESTARTGAPTHRESHOLD") = XPRS_MIPRESTARTGAPTHRESHOLD; - XPRS.attr("NODEPROBINGEFFORT") = XPRS_NODEPROBINGEFFORT; - XPRS.attr("INPUTTOL") = XPRS_INPUTTOL; - XPRS.attr("MIPRESTARTFACTOR") = XPRS_MIPRESTARTFACTOR; - XPRS.attr("BAROBJPERTURB") = XPRS_BAROBJPERTURB; - XPRS.attr("CPIALPHA") = XPRS_CPIALPHA; - XPRS.attr("GLOBALSPATIALBRANCHPROPAGATIONEFFORT") = XPRS_GLOBALSPATIALBRANCHPROPAGATIONEFFORT; - XPRS.attr("GLOBALSPATIALBRANCHCUTTINGEFFORT") = XPRS_GLOBALSPATIALBRANCHCUTTINGEFFORT; - XPRS.attr("GLOBALBOUNDINGBOX") = XPRS_GLOBALBOUNDINGBOX; - XPRS.attr("TIMELIMIT") = XPRS_TIMELIMIT; - XPRS.attr("SOLTIMELIMIT") = XPRS_SOLTIMELIMIT; - XPRS.attr("REPAIRINFEASTIMELIMIT") = XPRS_REPAIRINFEASTIMELIMIT; - XPRS.attr("BARHGEXTRAPOLATE") = XPRS_BARHGEXTRAPOLATE; - XPRS.attr("WORKLIMIT") = XPRS_WORKLIMIT; - XPRS.attr("CALLBACKCHECKTIMEWORKDELAY") = XPRS_CALLBACKCHECKTIMEWORKDELAY; - XPRS.attr("PREROOTWORKLIMIT") = XPRS_PREROOTWORKLIMIT; - XPRS.attr("PREROOTEFFORT") = XPRS_PREROOTEFFORT; + XPRS.attr("MAXCUTTIME") = POI_XPRS_MAXCUTTIME; + XPRS.attr("MAXSTALLTIME") = POI_XPRS_MAXSTALLTIME; + XPRS.attr("TUNERMAXTIME") = POI_XPRS_TUNERMAXTIME; + XPRS.attr("MATRIXTOL") = POI_XPRS_MATRIXTOL; + XPRS.attr("PIVOTTOL") = POI_XPRS_PIVOTTOL; + XPRS.attr("FEASTOL") = POI_XPRS_FEASTOL; + XPRS.attr("OUTPUTTOL") = POI_XPRS_OUTPUTTOL; + XPRS.attr("SOSREFTOL") = POI_XPRS_SOSREFTOL; + XPRS.attr("OPTIMALITYTOL") = POI_XPRS_OPTIMALITYTOL; + XPRS.attr("ETATOL") = POI_XPRS_ETATOL; + XPRS.attr("RELPIVOTTOL") = POI_XPRS_RELPIVOTTOL; + XPRS.attr("MIPTOL") = POI_XPRS_MIPTOL; + XPRS.attr("MIPTOLTARGET") = POI_XPRS_MIPTOLTARGET; + XPRS.attr("BARPERTURB") = POI_XPRS_BARPERTURB; + XPRS.attr("MIPADDCUTOFF") = POI_XPRS_MIPADDCUTOFF; + XPRS.attr("MIPABSCUTOFF") = POI_XPRS_MIPABSCUTOFF; + XPRS.attr("MIPRELCUTOFF") = POI_XPRS_MIPRELCUTOFF; + XPRS.attr("PSEUDOCOST") = POI_XPRS_PSEUDOCOST; + XPRS.attr("PENALTY") = POI_XPRS_PENALTY; + XPRS.attr("BIGM") = POI_XPRS_BIGM; + XPRS.attr("MIPABSSTOP") = POI_XPRS_MIPABSSTOP; + XPRS.attr("MIPRELSTOP") = POI_XPRS_MIPRELSTOP; + XPRS.attr("CROSSOVERACCURACYTOL") = POI_XPRS_CROSSOVERACCURACYTOL; + XPRS.attr("PRIMALPERTURB") = POI_XPRS_PRIMALPERTURB; + XPRS.attr("DUALPERTURB") = POI_XPRS_DUALPERTURB; + XPRS.attr("BAROBJSCALE") = POI_XPRS_BAROBJSCALE; + XPRS.attr("BARRHSSCALE") = POI_XPRS_BARRHSSCALE; + XPRS.attr("CHOLESKYTOL") = POI_XPRS_CHOLESKYTOL; + XPRS.attr("BARGAPSTOP") = POI_XPRS_BARGAPSTOP; + XPRS.attr("BARDUALSTOP") = POI_XPRS_BARDUALSTOP; + XPRS.attr("BARPRIMALSTOP") = POI_XPRS_BARPRIMALSTOP; + XPRS.attr("BARSTEPSTOP") = POI_XPRS_BARSTEPSTOP; + XPRS.attr("ELIMTOL") = POI_XPRS_ELIMTOL; + XPRS.attr("MARKOWITZTOL") = POI_XPRS_MARKOWITZTOL; + XPRS.attr("MIPABSGAPNOTIFY") = POI_XPRS_MIPABSGAPNOTIFY; + XPRS.attr("MIPRELGAPNOTIFY") = POI_XPRS_MIPRELGAPNOTIFY; + XPRS.attr("BARLARGEBOUND") = POI_XPRS_BARLARGEBOUND; + XPRS.attr("PPFACTOR") = POI_XPRS_PPFACTOR; + XPRS.attr("REPAIRINDEFINITEQMAX") = POI_XPRS_REPAIRINDEFINITEQMAX; + XPRS.attr("BARGAPTARGET") = POI_XPRS_BARGAPTARGET; + XPRS.attr("DUMMYCONTROL") = POI_XPRS_DUMMYCONTROL; + XPRS.attr("BARSTARTWEIGHT") = POI_XPRS_BARSTARTWEIGHT; + XPRS.attr("BARFREESCALE") = POI_XPRS_BARFREESCALE; + XPRS.attr("SBEFFORT") = POI_XPRS_SBEFFORT; + XPRS.attr("HEURDIVERANDOMIZE") = POI_XPRS_HEURDIVERANDOMIZE; + XPRS.attr("HEURSEARCHEFFORT") = POI_XPRS_HEURSEARCHEFFORT; + XPRS.attr("CUTFACTOR") = POI_XPRS_CUTFACTOR; + XPRS.attr("EIGENVALUETOL") = POI_XPRS_EIGENVALUETOL; + XPRS.attr("INDLINBIGM") = POI_XPRS_INDLINBIGM; + XPRS.attr("TREEMEMORYSAVINGTARGET") = POI_XPRS_TREEMEMORYSAVINGTARGET; + XPRS.attr("INDPRELINBIGM") = POI_XPRS_INDPRELINBIGM; + XPRS.attr("RELAXTREEMEMORYLIMIT") = POI_XPRS_RELAXTREEMEMORYLIMIT; + XPRS.attr("MIPABSGAPNOTIFYOBJ") = POI_XPRS_MIPABSGAPNOTIFYOBJ; + XPRS.attr("MIPABSGAPNOTIFYBOUND") = POI_XPRS_MIPABSGAPNOTIFYBOUND; + XPRS.attr("PRESOLVEMAXGROW") = POI_XPRS_PRESOLVEMAXGROW; + XPRS.attr("HEURSEARCHTARGETSIZE") = POI_XPRS_HEURSEARCHTARGETSIZE; + XPRS.attr("CROSSOVERRELPIVOTTOL") = POI_XPRS_CROSSOVERRELPIVOTTOL; + XPRS.attr("CROSSOVERRELPIVOTTOLSAFE") = POI_XPRS_CROSSOVERRELPIVOTTOLSAFE; + XPRS.attr("DETLOGFREQ") = POI_XPRS_DETLOGFREQ; + XPRS.attr("MAXIMPLIEDBOUND") = POI_XPRS_MAXIMPLIEDBOUND; + XPRS.attr("FEASTOLTARGET") = POI_XPRS_FEASTOLTARGET; + XPRS.attr("OPTIMALITYTOLTARGET") = POI_XPRS_OPTIMALITYTOLTARGET; + XPRS.attr("PRECOMPONENTSEFFORT") = POI_XPRS_PRECOMPONENTSEFFORT; + XPRS.attr("LPLOGDELAY") = POI_XPRS_LPLOGDELAY; + XPRS.attr("HEURDIVEITERLIMIT") = POI_XPRS_HEURDIVEITERLIMIT; + XPRS.attr("BARKERNEL") = POI_XPRS_BARKERNEL; + XPRS.attr("FEASTOLPERTURB") = POI_XPRS_FEASTOLPERTURB; + XPRS.attr("CROSSOVERFEASWEIGHT") = POI_XPRS_CROSSOVERFEASWEIGHT; + XPRS.attr("LUPIVOTTOL") = POI_XPRS_LUPIVOTTOL; + XPRS.attr("MIPRESTARTGAPTHRESHOLD") = POI_XPRS_MIPRESTARTGAPTHRESHOLD; + XPRS.attr("NODEPROBINGEFFORT") = POI_XPRS_NODEPROBINGEFFORT; + XPRS.attr("INPUTTOL") = POI_XPRS_INPUTTOL; + XPRS.attr("MIPRESTARTFACTOR") = POI_XPRS_MIPRESTARTFACTOR; + XPRS.attr("BAROBJPERTURB") = POI_XPRS_BAROBJPERTURB; + XPRS.attr("CPIALPHA") = POI_XPRS_CPIALPHA; + XPRS.attr("GLOBALSPATIALBRANCHPROPAGATIONEFFORT") = + POI_XPRS_GLOBALSPATIALBRANCHPROPAGATIONEFFORT; + XPRS.attr("GLOBALSPATIALBRANCHCUTTINGEFFORT") = POI_XPRS_GLOBALSPATIALBRANCHCUTTINGEFFORT; + XPRS.attr("GLOBALBOUNDINGBOX") = POI_XPRS_GLOBALBOUNDINGBOX; + XPRS.attr("TIMELIMIT") = POI_XPRS_TIMELIMIT; + XPRS.attr("SOLTIMELIMIT") = POI_XPRS_SOLTIMELIMIT; + XPRS.attr("REPAIRINFEASTIMELIMIT") = POI_XPRS_REPAIRINFEASTIMELIMIT; + XPRS.attr("BARHGEXTRAPOLATE") = POI_XPRS_BARHGEXTRAPOLATE; + XPRS.attr("WORKLIMIT") = POI_XPRS_WORKLIMIT; + XPRS.attr("CALLBACKCHECKTIMEWORKDELAY") = POI_XPRS_CALLBACKCHECKTIMEWORKDELAY; + XPRS.attr("PREROOTWORKLIMIT") = POI_XPRS_PREROOTWORKLIMIT; + XPRS.attr("PREROOTEFFORT") = POI_XPRS_PREROOTEFFORT; /* Integer control parameters */ - XPRS.attr("EXTRAROWS") = XPRS_EXTRAROWS; - XPRS.attr("EXTRACOLS") = XPRS_EXTRACOLS; - XPRS.attr("LPITERLIMIT") = XPRS_LPITERLIMIT; - XPRS.attr("LPLOG") = XPRS_LPLOG; - XPRS.attr("SCALING") = XPRS_SCALING; - XPRS.attr("PRESOLVE") = XPRS_PRESOLVE; - XPRS.attr("CRASH") = XPRS_CRASH; - XPRS.attr("PRICINGALG") = XPRS_PRICINGALG; - XPRS.attr("INVERTFREQ") = XPRS_INVERTFREQ; - XPRS.attr("INVERTMIN") = XPRS_INVERTMIN; - XPRS.attr("MAXNODE") = XPRS_MAXNODE; - XPRS.attr("MAXMIPSOL") = XPRS_MAXMIPSOL; - XPRS.attr("SIFTPASSES") = XPRS_SIFTPASSES; - XPRS.attr("DEFAULTALG") = XPRS_DEFAULTALG; - XPRS.attr("VARSELECTION") = XPRS_VARSELECTION; - XPRS.attr("NODESELECTION") = XPRS_NODESELECTION; - XPRS.attr("BACKTRACK") = XPRS_BACKTRACK; - XPRS.attr("MIPLOG") = XPRS_MIPLOG; - XPRS.attr("KEEPNROWS") = XPRS_KEEPNROWS; - XPRS.attr("MPSECHO") = XPRS_MPSECHO; - XPRS.attr("MAXPAGELINES") = XPRS_MAXPAGELINES; - XPRS.attr("OUTPUTLOG") = XPRS_OUTPUTLOG; - XPRS.attr("BARSOLUTION") = XPRS_BARSOLUTION; - XPRS.attr("CROSSOVER") = XPRS_CROSSOVER; - XPRS.attr("BARITERLIMIT") = XPRS_BARITERLIMIT; - XPRS.attr("CHOLESKYALG") = XPRS_CHOLESKYALG; - XPRS.attr("BAROUTPUT") = XPRS_BAROUTPUT; - XPRS.attr("EXTRAMIPENTS") = XPRS_EXTRAMIPENTS; - XPRS.attr("REFACTOR") = XPRS_REFACTOR; - XPRS.attr("BARTHREADS") = XPRS_BARTHREADS; - XPRS.attr("KEEPBASIS") = XPRS_KEEPBASIS; - XPRS.attr("CROSSOVEROPS") = XPRS_CROSSOVEROPS; - XPRS.attr("VERSION") = XPRS_VERSION; - XPRS.attr("CROSSOVERTHREADS") = XPRS_CROSSOVERTHREADS; - XPRS.attr("BIGMMETHOD") = XPRS_BIGMMETHOD; - XPRS.attr("MPSNAMELENGTH") = XPRS_MPSNAMELENGTH; - XPRS.attr("ELIMFILLIN") = XPRS_ELIMFILLIN; - XPRS.attr("PRESOLVEOPS") = XPRS_PRESOLVEOPS; - XPRS.attr("MIPPRESOLVE") = XPRS_MIPPRESOLVE; - XPRS.attr("MIPTHREADS") = XPRS_MIPTHREADS; - XPRS.attr("BARORDER") = XPRS_BARORDER; - XPRS.attr("BREADTHFIRST") = XPRS_BREADTHFIRST; - XPRS.attr("AUTOPERTURB") = XPRS_AUTOPERTURB; - XPRS.attr("DENSECOLLIMIT") = XPRS_DENSECOLLIMIT; - XPRS.attr("CALLBACKFROMMASTERTHREAD") = XPRS_CALLBACKFROMMASTERTHREAD; - XPRS.attr("MAXMCOEFFBUFFERELEMS") = XPRS_MAXMCOEFFBUFFERELEMS; - XPRS.attr("REFINEOPS") = XPRS_REFINEOPS; - XPRS.attr("LPREFINEITERLIMIT") = XPRS_LPREFINEITERLIMIT; - XPRS.attr("MIPREFINEITERLIMIT") = XPRS_MIPREFINEITERLIMIT; - XPRS.attr("DUALIZEOPS") = XPRS_DUALIZEOPS; - XPRS.attr("CROSSOVERITERLIMIT") = XPRS_CROSSOVERITERLIMIT; - XPRS.attr("PREBASISRED") = XPRS_PREBASISRED; - XPRS.attr("PRESORT") = XPRS_PRESORT; - XPRS.attr("PREPERMUTE") = XPRS_PREPERMUTE; - XPRS.attr("PREPERMUTESEED") = XPRS_PREPERMUTESEED; - XPRS.attr("MAXMEMORYSOFT") = XPRS_MAXMEMORYSOFT; - XPRS.attr("CUTFREQ") = XPRS_CUTFREQ; - XPRS.attr("SYMSELECT") = XPRS_SYMSELECT; - XPRS.attr("SYMMETRY") = XPRS_SYMMETRY; - XPRS.attr("MAXMEMORYHARD") = XPRS_MAXMEMORYHARD; - XPRS.attr("MIQCPALG") = XPRS_MIQCPALG; - XPRS.attr("QCCUTS") = XPRS_QCCUTS; - XPRS.attr("QCROOTALG") = XPRS_QCROOTALG; - XPRS.attr("PRECONVERTSEPARABLE") = XPRS_PRECONVERTSEPARABLE; - XPRS.attr("ALGAFTERNETWORK") = XPRS_ALGAFTERNETWORK; - XPRS.attr("TRACE") = XPRS_TRACE; - XPRS.attr("MAXIIS") = XPRS_MAXIIS; - XPRS.attr("CPUTIME") = XPRS_CPUTIME; - XPRS.attr("COVERCUTS") = XPRS_COVERCUTS; - XPRS.attr("GOMCUTS") = XPRS_GOMCUTS; - XPRS.attr("LPFOLDING") = XPRS_LPFOLDING; - XPRS.attr("MPSFORMAT") = XPRS_MPSFORMAT; - XPRS.attr("CUTSTRATEGY") = XPRS_CUTSTRATEGY; - XPRS.attr("CUTDEPTH") = XPRS_CUTDEPTH; - XPRS.attr("TREECOVERCUTS") = XPRS_TREECOVERCUTS; - XPRS.attr("TREEGOMCUTS") = XPRS_TREEGOMCUTS; - XPRS.attr("CUTSELECT") = XPRS_CUTSELECT; - XPRS.attr("TREECUTSELECT") = XPRS_TREECUTSELECT; - XPRS.attr("DUALIZE") = XPRS_DUALIZE; - XPRS.attr("DUALGRADIENT") = XPRS_DUALGRADIENT; - XPRS.attr("SBITERLIMIT") = XPRS_SBITERLIMIT; - XPRS.attr("SBBEST") = XPRS_SBBEST; - XPRS.attr("BARINDEFLIMIT") = XPRS_BARINDEFLIMIT; - XPRS.attr("HEURFREQ") = XPRS_HEURFREQ; - XPRS.attr("HEURDEPTH") = XPRS_HEURDEPTH; - XPRS.attr("HEURMAXSOL") = XPRS_HEURMAXSOL; - XPRS.attr("HEURNODES") = XPRS_HEURNODES; - XPRS.attr("LNPBEST") = XPRS_LNPBEST; - XPRS.attr("LNPITERLIMIT") = XPRS_LNPITERLIMIT; - XPRS.attr("BRANCHCHOICE") = XPRS_BRANCHCHOICE; - XPRS.attr("BARREGULARIZE") = XPRS_BARREGULARIZE; - XPRS.attr("SBSELECT") = XPRS_SBSELECT; - XPRS.attr("IISLOG") = XPRS_IISLOG; - XPRS.attr("LOCALCHOICE") = XPRS_LOCALCHOICE; - XPRS.attr("LOCALBACKTRACK") = XPRS_LOCALBACKTRACK; - XPRS.attr("DUALSTRATEGY") = XPRS_DUALSTRATEGY; - XPRS.attr("HEURDIVESTRATEGY") = XPRS_HEURDIVESTRATEGY; - XPRS.attr("HEURSELECT") = XPRS_HEURSELECT; - XPRS.attr("BARSTART") = XPRS_BARSTART; - XPRS.attr("PRESOLVEPASSES") = XPRS_PRESOLVEPASSES; - XPRS.attr("BARORDERTHREADS") = XPRS_BARORDERTHREADS; - XPRS.attr("EXTRASETS") = XPRS_EXTRASETS; - XPRS.attr("FEASIBILITYPUMP") = XPRS_FEASIBILITYPUMP; - XPRS.attr("PRECOEFELIM") = XPRS_PRECOEFELIM; - XPRS.attr("PREDOMCOL") = XPRS_PREDOMCOL; - XPRS.attr("HEURSEARCHFREQ") = XPRS_HEURSEARCHFREQ; - XPRS.attr("HEURDIVESPEEDUP") = XPRS_HEURDIVESPEEDUP; - XPRS.attr("SBESTIMATE") = XPRS_SBESTIMATE; - XPRS.attr("BARCORES") = XPRS_BARCORES; - XPRS.attr("MAXCHECKSONMAXTIME") = XPRS_MAXCHECKSONMAXTIME; - XPRS.attr("MAXCHECKSONMAXCUTTIME") = XPRS_MAXCHECKSONMAXCUTTIME; - XPRS.attr("HISTORYCOSTS") = XPRS_HISTORYCOSTS; - XPRS.attr("ALGAFTERCROSSOVER") = XPRS_ALGAFTERCROSSOVER; - XPRS.attr("MUTEXCALLBACKS") = XPRS_MUTEXCALLBACKS; - XPRS.attr("BARCRASH") = XPRS_BARCRASH; - XPRS.attr("HEURDIVESOFTROUNDING") = XPRS_HEURDIVESOFTROUNDING; - XPRS.attr("HEURSEARCHROOTSELECT") = XPRS_HEURSEARCHROOTSELECT; - XPRS.attr("HEURSEARCHTREESELECT") = XPRS_HEURSEARCHTREESELECT; - XPRS.attr("MPS18COMPATIBLE") = XPRS_MPS18COMPATIBLE; - XPRS.attr("ROOTPRESOLVE") = XPRS_ROOTPRESOLVE; - XPRS.attr("CROSSOVERDRP") = XPRS_CROSSOVERDRP; - XPRS.attr("FORCEOUTPUT") = XPRS_FORCEOUTPUT; - XPRS.attr("PRIMALOPS") = XPRS_PRIMALOPS; - XPRS.attr("DETERMINISTIC") = XPRS_DETERMINISTIC; - XPRS.attr("PREPROBING") = XPRS_PREPROBING; - XPRS.attr("TREEMEMORYLIMIT") = XPRS_TREEMEMORYLIMIT; - XPRS.attr("TREECOMPRESSION") = XPRS_TREECOMPRESSION; - XPRS.attr("TREEDIAGNOSTICS") = XPRS_TREEDIAGNOSTICS; - XPRS.attr("MAXTREEFILESIZE") = XPRS_MAXTREEFILESIZE; - XPRS.attr("PRECLIQUESTRATEGY") = XPRS_PRECLIQUESTRATEGY; - XPRS.attr("IFCHECKCONVEXITY") = XPRS_IFCHECKCONVEXITY; - XPRS.attr("PRIMALUNSHIFT") = XPRS_PRIMALUNSHIFT; - XPRS.attr("REPAIRINDEFINITEQ") = XPRS_REPAIRINDEFINITEQ; - XPRS.attr("MIPRAMPUP") = XPRS_MIPRAMPUP; - XPRS.attr("MAXLOCALBACKTRACK") = XPRS_MAXLOCALBACKTRACK; - XPRS.attr("USERSOLHEURISTIC") = XPRS_USERSOLHEURISTIC; - XPRS.attr("PRECONVERTOBJTOCONS") = XPRS_PRECONVERTOBJTOCONS; - XPRS.attr("FORCEPARALLELDUAL") = XPRS_FORCEPARALLELDUAL; - XPRS.attr("BACKTRACKTIE") = XPRS_BACKTRACKTIE; - XPRS.attr("BRANCHDISJ") = XPRS_BRANCHDISJ; - XPRS.attr("MIPFRACREDUCE") = XPRS_MIPFRACREDUCE; - XPRS.attr("CONCURRENTTHREADS") = XPRS_CONCURRENTTHREADS; - XPRS.attr("MAXSCALEFACTOR") = XPRS_MAXSCALEFACTOR; - XPRS.attr("HEURTHREADS") = XPRS_HEURTHREADS; - XPRS.attr("THREADS") = XPRS_THREADS; - XPRS.attr("HEURBEFORELP") = XPRS_HEURBEFORELP; - XPRS.attr("PREDOMROW") = XPRS_PREDOMROW; - XPRS.attr("BRANCHSTRUCTURAL") = XPRS_BRANCHSTRUCTURAL; - XPRS.attr("QUADRATICUNSHIFT") = XPRS_QUADRATICUNSHIFT; - XPRS.attr("BARPRESOLVEOPS") = XPRS_BARPRESOLVEOPS; - XPRS.attr("QSIMPLEXOPS") = XPRS_QSIMPLEXOPS; - XPRS.attr("MIPRESTART") = XPRS_MIPRESTART; - XPRS.attr("CONFLICTCUTS") = XPRS_CONFLICTCUTS; - XPRS.attr("PREPROTECTDUAL") = XPRS_PREPROTECTDUAL; - XPRS.attr("CORESPERCPU") = XPRS_CORESPERCPU; - XPRS.attr("RESOURCESTRATEGY") = XPRS_RESOURCESTRATEGY; - XPRS.attr("CLAMPING") = XPRS_CLAMPING; - XPRS.attr("PREDUPROW") = XPRS_PREDUPROW; - XPRS.attr("CPUPLATFORM") = XPRS_CPUPLATFORM; - XPRS.attr("BARALG") = XPRS_BARALG; - XPRS.attr("SIFTING") = XPRS_SIFTING; - XPRS.attr("BARKEEPLASTSOL") = XPRS_BARKEEPLASTSOL; - XPRS.attr("LPLOGSTYLE") = XPRS_LPLOGSTYLE; - XPRS.attr("RANDOMSEED") = XPRS_RANDOMSEED; - XPRS.attr("TREEQCCUTS") = XPRS_TREEQCCUTS; - XPRS.attr("PRELINDEP") = XPRS_PRELINDEP; - XPRS.attr("DUALTHREADS") = XPRS_DUALTHREADS; - XPRS.attr("PREOBJCUTDETECT") = XPRS_PREOBJCUTDETECT; - XPRS.attr("PREBNDREDQUAD") = XPRS_PREBNDREDQUAD; - XPRS.attr("PREBNDREDCONE") = XPRS_PREBNDREDCONE; - XPRS.attr("PRECOMPONENTS") = XPRS_PRECOMPONENTS; - XPRS.attr("MAXMIPTASKS") = XPRS_MAXMIPTASKS; - XPRS.attr("MIPTERMINATIONMETHOD") = XPRS_MIPTERMINATIONMETHOD; - XPRS.attr("PRECONEDECOMP") = XPRS_PRECONEDECOMP; - XPRS.attr("HEURFORCESPECIALOBJ") = XPRS_HEURFORCESPECIALOBJ; - XPRS.attr("HEURSEARCHROOTCUTFREQ") = XPRS_HEURSEARCHROOTCUTFREQ; - XPRS.attr("PREELIMQUAD") = XPRS_PREELIMQUAD; - XPRS.attr("PREIMPLICATIONS") = XPRS_PREIMPLICATIONS; - XPRS.attr("TUNERMODE") = XPRS_TUNERMODE; - XPRS.attr("TUNERMETHOD") = XPRS_TUNERMETHOD; - XPRS.attr("TUNERTARGET") = XPRS_TUNERTARGET; - XPRS.attr("TUNERTHREADS") = XPRS_TUNERTHREADS; - XPRS.attr("TUNERHISTORY") = XPRS_TUNERHISTORY; - XPRS.attr("TUNERPERMUTE") = XPRS_TUNERPERMUTE; - XPRS.attr("TUNERVERBOSE") = XPRS_TUNERVERBOSE; - XPRS.attr("TUNEROUTPUT") = XPRS_TUNEROUTPUT; - XPRS.attr("PREANALYTICCENTER") = XPRS_PREANALYTICCENTER; - XPRS.attr("LPFLAGS") = XPRS_LPFLAGS; - XPRS.attr("MIPKAPPAFREQ") = XPRS_MIPKAPPAFREQ; - XPRS.attr("OBJSCALEFACTOR") = XPRS_OBJSCALEFACTOR; - XPRS.attr("TREEFILELOGINTERVAL") = XPRS_TREEFILELOGINTERVAL; - XPRS.attr("IGNORECONTAINERCPULIMIT") = XPRS_IGNORECONTAINERCPULIMIT; - XPRS.attr("IGNORECONTAINERMEMORYLIMIT") = XPRS_IGNORECONTAINERMEMORYLIMIT; - XPRS.attr("MIPDUALREDUCTIONS") = XPRS_MIPDUALREDUCTIONS; - XPRS.attr("GENCONSDUALREDUCTIONS") = XPRS_GENCONSDUALREDUCTIONS; - XPRS.attr("PWLDUALREDUCTIONS") = XPRS_PWLDUALREDUCTIONS; - XPRS.attr("BARFAILITERLIMIT") = XPRS_BARFAILITERLIMIT; - XPRS.attr("AUTOSCALING") = XPRS_AUTOSCALING; - XPRS.attr("GENCONSABSTRANSFORMATION") = XPRS_GENCONSABSTRANSFORMATION; - XPRS.attr("COMPUTEJOBPRIORITY") = XPRS_COMPUTEJOBPRIORITY; - XPRS.attr("PREFOLDING") = XPRS_PREFOLDING; - XPRS.attr("COMPUTE") = XPRS_COMPUTE; - XPRS.attr("NETSTALLLIMIT") = XPRS_NETSTALLLIMIT; - XPRS.attr("SERIALIZEPREINTSOL") = XPRS_SERIALIZEPREINTSOL; - XPRS.attr("NUMERICALEMPHASIS") = XPRS_NUMERICALEMPHASIS; - XPRS.attr("PWLNONCONVEXTRANSFORMATION") = XPRS_PWLNONCONVEXTRANSFORMATION; - XPRS.attr("MIPCOMPONENTS") = XPRS_MIPCOMPONENTS; - XPRS.attr("MIPCONCURRENTNODES") = XPRS_MIPCONCURRENTNODES; - XPRS.attr("MIPCONCURRENTSOLVES") = XPRS_MIPCONCURRENTSOLVES; - XPRS.attr("OUTPUTCONTROLS") = XPRS_OUTPUTCONTROLS; - XPRS.attr("SIFTSWITCH") = XPRS_SIFTSWITCH; - XPRS.attr("HEUREMPHASIS") = XPRS_HEUREMPHASIS; - XPRS.attr("BARREFITER") = XPRS_BARREFITER; - XPRS.attr("COMPUTELOG") = XPRS_COMPUTELOG; - XPRS.attr("SIFTPRESOLVEOPS") = XPRS_SIFTPRESOLVEOPS; - XPRS.attr("CHECKINPUTDATA") = XPRS_CHECKINPUTDATA; - XPRS.attr("ESCAPENAMES") = XPRS_ESCAPENAMES; - XPRS.attr("IOTIMEOUT") = XPRS_IOTIMEOUT; - XPRS.attr("AUTOCUTTING") = XPRS_AUTOCUTTING; - XPRS.attr("GLOBALNUMINITNLPCUTS") = XPRS_GLOBALNUMINITNLPCUTS; - XPRS.attr("CALLBACKCHECKTIMEDELAY") = XPRS_CALLBACKCHECKTIMEDELAY; - XPRS.attr("MULTIOBJOPS") = XPRS_MULTIOBJOPS; - XPRS.attr("MULTIOBJLOG") = XPRS_MULTIOBJLOG; - XPRS.attr("BACKGROUNDMAXTHREADS") = XPRS_BACKGROUNDMAXTHREADS; - XPRS.attr("GLOBALLSHEURSTRATEGY") = XPRS_GLOBALLSHEURSTRATEGY; - XPRS.attr("GLOBALSPATIALBRANCHIFPREFERORIG") = XPRS_GLOBALSPATIALBRANCHIFPREFERORIG; - XPRS.attr("PRECONFIGURATION") = XPRS_PRECONFIGURATION; - XPRS.attr("FEASIBILITYJUMP") = XPRS_FEASIBILITYJUMP; - XPRS.attr("IISOPS") = XPRS_IISOPS; - XPRS.attr("RLTCUTS") = XPRS_RLTCUTS; - XPRS.attr("ALTERNATIVEREDCOSTS") = XPRS_ALTERNATIVEREDCOSTS; - XPRS.attr("HEURSHIFTPROP") = XPRS_HEURSHIFTPROP; - XPRS.attr("HEURSEARCHCOPYCONTROLS") = XPRS_HEURSEARCHCOPYCONTROLS; - XPRS.attr("GLOBALNLPCUTS") = XPRS_GLOBALNLPCUTS; - XPRS.attr("GLOBALTREENLPCUTS") = XPRS_GLOBALTREENLPCUTS; - XPRS.attr("BARHGOPS") = XPRS_BARHGOPS; - XPRS.attr("BARHGMAXRESTARTS") = XPRS_BARHGMAXRESTARTS; - XPRS.attr("MCFCUTSTRATEGY") = XPRS_MCFCUTSTRATEGY; - XPRS.attr("PREROOTTHREADS") = XPRS_PREROOTTHREADS; - XPRS.attr("BARITERATIVE") = XPRS_BARITERATIVE; + XPRS.attr("EXTRAROWS") = POI_XPRS_EXTRAROWS; + XPRS.attr("EXTRACOLS") = POI_XPRS_EXTRACOLS; + XPRS.attr("LPITERLIMIT") = POI_XPRS_LPITERLIMIT; + XPRS.attr("LPLOG") = POI_XPRS_LPLOG; + XPRS.attr("SCALING") = POI_XPRS_SCALING; + XPRS.attr("PRESOLVE") = POI_XPRS_PRESOLVE; + XPRS.attr("CRASH") = POI_XPRS_CRASH; + XPRS.attr("PRICINGALG") = POI_XPRS_PRICINGALG; + XPRS.attr("INVERTFREQ") = POI_XPRS_INVERTFREQ; + XPRS.attr("INVERTMIN") = POI_XPRS_INVERTMIN; + XPRS.attr("MAXNODE") = POI_XPRS_MAXNODE; + XPRS.attr("MAXMIPSOL") = POI_XPRS_MAXMIPSOL; + XPRS.attr("SIFTPASSES") = POI_XPRS_SIFTPASSES; + XPRS.attr("DEFAULTALG") = POI_XPRS_DEFAULTALG; + XPRS.attr("VARSELECTION") = POI_XPRS_VARSELECTION; + XPRS.attr("NODESELECTION") = POI_XPRS_NODESELECTION; + XPRS.attr("BACKTRACK") = POI_XPRS_BACKTRACK; + XPRS.attr("MIPLOG") = POI_XPRS_MIPLOG; + XPRS.attr("KEEPNROWS") = POI_XPRS_KEEPNROWS; + XPRS.attr("MPSECHO") = POI_XPRS_MPSECHO; + XPRS.attr("MAXPAGELINES") = POI_XPRS_MAXPAGELINES; + XPRS.attr("OUTPUTLOG") = POI_XPRS_OUTPUTLOG; + XPRS.attr("BARSOLUTION") = POI_XPRS_BARSOLUTION; + XPRS.attr("CROSSOVER") = POI_XPRS_CROSSOVER; + XPRS.attr("BARITERLIMIT") = POI_XPRS_BARITERLIMIT; + XPRS.attr("CHOLESKYALG") = POI_XPRS_CHOLESKYALG; + XPRS.attr("BAROUTPUT") = POI_XPRS_BAROUTPUT; + XPRS.attr("EXTRAMIPENTS") = POI_XPRS_EXTRAMIPENTS; + XPRS.attr("REFACTOR") = POI_XPRS_REFACTOR; + XPRS.attr("BARTHREADS") = POI_XPRS_BARTHREADS; + XPRS.attr("KEEPBASIS") = POI_XPRS_KEEPBASIS; + XPRS.attr("CROSSOVEROPS") = POI_XPRS_CROSSOVEROPS; + XPRS.attr("VERSION") = POI_XPRS_VERSION; + XPRS.attr("CROSSOVERTHREADS") = POI_XPRS_CROSSOVERTHREADS; + XPRS.attr("BIGMMETHOD") = POI_XPRS_BIGMMETHOD; + XPRS.attr("MPSNAMELENGTH") = POI_XPRS_MPSNAMELENGTH; + XPRS.attr("ELIMFILLIN") = POI_XPRS_ELIMFILLIN; + XPRS.attr("PRESOLVEOPS") = POI_XPRS_PRESOLVEOPS; + XPRS.attr("MIPPRESOLVE") = POI_XPRS_MIPPRESOLVE; + XPRS.attr("MIPTHREADS") = POI_XPRS_MIPTHREADS; + XPRS.attr("BARORDER") = POI_XPRS_BARORDER; + XPRS.attr("BREADTHFIRST") = POI_XPRS_BREADTHFIRST; + XPRS.attr("AUTOPERTURB") = POI_XPRS_AUTOPERTURB; + XPRS.attr("DENSECOLLIMIT") = POI_XPRS_DENSECOLLIMIT; + XPRS.attr("CALLBACKFROMMAINTHREAD") = POI_XPRS_CALLBACKFROMMAINTHREAD; + XPRS.attr("MAXMCOEFFBUFFERELEMS") = POI_XPRS_MAXMCOEFFBUFFERELEMS; + XPRS.attr("REFINEOPS") = POI_XPRS_REFINEOPS; + XPRS.attr("LPREFINEITERLIMIT") = POI_XPRS_LPREFINEITERLIMIT; + XPRS.attr("MIPREFINEITERLIMIT") = POI_XPRS_MIPREFINEITERLIMIT; + XPRS.attr("DUALIZEOPS") = POI_XPRS_DUALIZEOPS; + XPRS.attr("CROSSOVERITERLIMIT") = POI_XPRS_CROSSOVERITERLIMIT; + XPRS.attr("PREBASISRED") = POI_XPRS_PREBASISRED; + XPRS.attr("PRESORT") = POI_XPRS_PRESORT; + XPRS.attr("PREPERMUTE") = POI_XPRS_PREPERMUTE; + XPRS.attr("PREPERMUTESEED") = POI_XPRS_PREPERMUTESEED; + XPRS.attr("MAXMEMORYSOFT") = POI_XPRS_MAXMEMORYSOFT; + XPRS.attr("CUTFREQ") = POI_XPRS_CUTFREQ; + XPRS.attr("SYMSELECT") = POI_XPRS_SYMSELECT; + XPRS.attr("SYMMETRY") = POI_XPRS_SYMMETRY; + XPRS.attr("MAXMEMORYHARD") = POI_XPRS_MAXMEMORYHARD; + XPRS.attr("MIQCPALG") = POI_XPRS_MIQCPALG; + XPRS.attr("QCCUTS") = POI_XPRS_QCCUTS; + XPRS.attr("QCROOTALG") = POI_XPRS_QCROOTALG; + XPRS.attr("PRECONVERTSEPARABLE") = POI_XPRS_PRECONVERTSEPARABLE; + XPRS.attr("ALGAFTERNETWORK") = POI_XPRS_ALGAFTERNETWORK; + XPRS.attr("TRACE") = POI_XPRS_TRACE; + XPRS.attr("MAXIIS") = POI_XPRS_MAXIIS; + XPRS.attr("CPUTIME") = POI_XPRS_CPUTIME; + XPRS.attr("COVERCUTS") = POI_XPRS_COVERCUTS; + XPRS.attr("GOMCUTS") = POI_XPRS_GOMCUTS; + XPRS.attr("LPFOLDING") = POI_XPRS_LPFOLDING; + XPRS.attr("MPSFORMAT") = POI_XPRS_MPSFORMAT; + XPRS.attr("CUTSTRATEGY") = POI_XPRS_CUTSTRATEGY; + XPRS.attr("CUTDEPTH") = POI_XPRS_CUTDEPTH; + XPRS.attr("TREECOVERCUTS") = POI_XPRS_TREECOVERCUTS; + XPRS.attr("TREEGOMCUTS") = POI_XPRS_TREEGOMCUTS; + XPRS.attr("CUTSELECT") = POI_XPRS_CUTSELECT; + XPRS.attr("TREECUTSELECT") = POI_XPRS_TREECUTSELECT; + XPRS.attr("DUALIZE") = POI_XPRS_DUALIZE; + XPRS.attr("DUALGRADIENT") = POI_XPRS_DUALGRADIENT; + XPRS.attr("SBITERLIMIT") = POI_XPRS_SBITERLIMIT; + XPRS.attr("SBBEST") = POI_XPRS_SBBEST; + XPRS.attr("BARINDEFLIMIT") = POI_XPRS_BARINDEFLIMIT; + XPRS.attr("HEURFREQ") = POI_XPRS_HEURFREQ; + XPRS.attr("HEURDEPTH") = POI_XPRS_HEURDEPTH; + XPRS.attr("HEURMAXSOL") = POI_XPRS_HEURMAXSOL; + XPRS.attr("HEURNODES") = POI_XPRS_HEURNODES; + XPRS.attr("LNPBEST") = POI_XPRS_LNPBEST; + XPRS.attr("LNPITERLIMIT") = POI_XPRS_LNPITERLIMIT; + XPRS.attr("BRANCHCHOICE") = POI_XPRS_BRANCHCHOICE; + XPRS.attr("BARREGULARIZE") = POI_XPRS_BARREGULARIZE; + XPRS.attr("SBSELECT") = POI_XPRS_SBSELECT; + XPRS.attr("IISLOG") = POI_XPRS_IISLOG; + XPRS.attr("LOCALCHOICE") = POI_XPRS_LOCALCHOICE; + XPRS.attr("LOCALBACKTRACK") = POI_XPRS_LOCALBACKTRACK; + XPRS.attr("DUALSTRATEGY") = POI_XPRS_DUALSTRATEGY; + XPRS.attr("HEURDIVESTRATEGY") = POI_XPRS_HEURDIVESTRATEGY; + XPRS.attr("HEURSELECT") = POI_XPRS_HEURSELECT; + XPRS.attr("BARSTART") = POI_XPRS_BARSTART; + XPRS.attr("PRESOLVEPASSES") = POI_XPRS_PRESOLVEPASSES; + XPRS.attr("BARORDERTHREADS") = POI_XPRS_BARORDERTHREADS; + XPRS.attr("EXTRASETS") = POI_XPRS_EXTRASETS; + XPRS.attr("FEASIBILITYPUMP") = POI_XPRS_FEASIBILITYPUMP; + XPRS.attr("PRECOEFELIM") = POI_XPRS_PRECOEFELIM; + XPRS.attr("PREDOMCOL") = POI_XPRS_PREDOMCOL; + XPRS.attr("HEURSEARCHFREQ") = POI_XPRS_HEURSEARCHFREQ; + XPRS.attr("HEURDIVESPEEDUP") = POI_XPRS_HEURDIVESPEEDUP; + XPRS.attr("SBESTIMATE") = POI_XPRS_SBESTIMATE; + XPRS.attr("BARCORES") = POI_XPRS_BARCORES; + XPRS.attr("MAXCHECKSONMAXTIME") = POI_XPRS_MAXCHECKSONMAXTIME; + XPRS.attr("MAXCHECKSONMAXCUTTIME") = POI_XPRS_MAXCHECKSONMAXCUTTIME; + XPRS.attr("HISTORYCOSTS") = POI_XPRS_HISTORYCOSTS; + XPRS.attr("ALGAFTERCROSSOVER") = POI_XPRS_ALGAFTERCROSSOVER; + XPRS.attr("MUTEXCALLBACKS") = POI_XPRS_MUTEXCALLBACKS; + XPRS.attr("BARCRASH") = POI_XPRS_BARCRASH; + XPRS.attr("HEURDIVESOFTROUNDING") = POI_XPRS_HEURDIVESOFTROUNDING; + XPRS.attr("HEURSEARCHROOTSELECT") = POI_XPRS_HEURSEARCHROOTSELECT; + XPRS.attr("HEURSEARCHTREESELECT") = POI_XPRS_HEURSEARCHTREESELECT; + XPRS.attr("MPS18COMPATIBLE") = POI_XPRS_MPS18COMPATIBLE; + XPRS.attr("ROOTPRESOLVE") = POI_XPRS_ROOTPRESOLVE; + XPRS.attr("CROSSOVERDRP") = POI_XPRS_CROSSOVERDRP; + XPRS.attr("FORCEOUTPUT") = POI_XPRS_FORCEOUTPUT; + XPRS.attr("PRIMALOPS") = POI_XPRS_PRIMALOPS; + XPRS.attr("DETERMINISTIC") = POI_XPRS_DETERMINISTIC; + XPRS.attr("PREPROBING") = POI_XPRS_PREPROBING; + XPRS.attr("TREEMEMORYLIMIT") = POI_XPRS_TREEMEMORYLIMIT; + XPRS.attr("TREECOMPRESSION") = POI_XPRS_TREECOMPRESSION; + XPRS.attr("TREEDIAGNOSTICS") = POI_XPRS_TREEDIAGNOSTICS; + XPRS.attr("MAXTREEFILESIZE") = POI_XPRS_MAXTREEFILESIZE; + XPRS.attr("PRECLIQUESTRATEGY") = POI_XPRS_PRECLIQUESTRATEGY; + XPRS.attr("IFCHECKCONVEXITY") = POI_XPRS_IFCHECKCONVEXITY; + XPRS.attr("PRIMALUNSHIFT") = POI_XPRS_PRIMALUNSHIFT; + XPRS.attr("REPAIRINDEFINITEQ") = POI_XPRS_REPAIRINDEFINITEQ; + XPRS.attr("MIPRAMPUP") = POI_XPRS_MIPRAMPUP; + XPRS.attr("MAXLOCALBACKTRACK") = POI_XPRS_MAXLOCALBACKTRACK; + XPRS.attr("USERSOLHEURISTIC") = POI_XPRS_USERSOLHEURISTIC; + XPRS.attr("PRECONVERTOBJTOCONS") = POI_XPRS_PRECONVERTOBJTOCONS; + XPRS.attr("FORCEPARALLELDUAL") = POI_XPRS_FORCEPARALLELDUAL; + XPRS.attr("BACKTRACKTIE") = POI_XPRS_BACKTRACKTIE; + XPRS.attr("BRANCHDISJ") = POI_XPRS_BRANCHDISJ; + XPRS.attr("MIPFRACREDUCE") = POI_XPRS_MIPFRACREDUCE; + XPRS.attr("CONCURRENTTHREADS") = POI_XPRS_CONCURRENTTHREADS; + XPRS.attr("MAXSCALEFACTOR") = POI_XPRS_MAXSCALEFACTOR; + XPRS.attr("HEURTHREADS") = POI_XPRS_HEURTHREADS; + XPRS.attr("THREADS") = POI_XPRS_THREADS; + XPRS.attr("HEURBEFORELP") = POI_XPRS_HEURBEFORELP; + XPRS.attr("PREDOMROW") = POI_XPRS_PREDOMROW; + XPRS.attr("BRANCHSTRUCTURAL") = POI_XPRS_BRANCHSTRUCTURAL; + XPRS.attr("QUADRATICUNSHIFT") = POI_XPRS_QUADRATICUNSHIFT; + XPRS.attr("BARPRESOLVEOPS") = POI_XPRS_BARPRESOLVEOPS; + XPRS.attr("QSIMPLEXOPS") = POI_XPRS_QSIMPLEXOPS; + XPRS.attr("MIPRESTART") = POI_XPRS_MIPRESTART; + XPRS.attr("CONFLICTCUTS") = POI_XPRS_CONFLICTCUTS; + XPRS.attr("PREPROTECTDUAL") = POI_XPRS_PREPROTECTDUAL; + XPRS.attr("CORESPERCPU") = POI_XPRS_CORESPERCPU; + XPRS.attr("RESOURCESTRATEGY") = POI_XPRS_RESOURCESTRATEGY; + XPRS.attr("CLAMPING") = POI_XPRS_CLAMPING; + XPRS.attr("PREDUPROW") = POI_XPRS_PREDUPROW; + XPRS.attr("CPUPLATFORM") = POI_XPRS_CPUPLATFORM; + XPRS.attr("BARALG") = POI_XPRS_BARALG; + XPRS.attr("SIFTING") = POI_XPRS_SIFTING; + XPRS.attr("BARKEEPLASTSOL") = POI_XPRS_BARKEEPLASTSOL; + XPRS.attr("LPLOGSTYLE") = POI_XPRS_LPLOGSTYLE; + XPRS.attr("RANDOMSEED") = POI_XPRS_RANDOMSEED; + XPRS.attr("TREEQCCUTS") = POI_XPRS_TREEQCCUTS; + XPRS.attr("PRELINDEP") = POI_XPRS_PRELINDEP; + XPRS.attr("DUALTHREADS") = POI_XPRS_DUALTHREADS; + XPRS.attr("PREOBJCUTDETECT") = POI_XPRS_PREOBJCUTDETECT; + XPRS.attr("PREBNDREDQUAD") = POI_XPRS_PREBNDREDQUAD; + XPRS.attr("PREBNDREDCONE") = POI_XPRS_PREBNDREDCONE; + XPRS.attr("PRECOMPONENTS") = POI_XPRS_PRECOMPONENTS; + XPRS.attr("MAXMIPTASKS") = POI_XPRS_MAXMIPTASKS; + XPRS.attr("MIPTERMINATIONMETHOD") = POI_XPRS_MIPTERMINATIONMETHOD; + XPRS.attr("PRECONEDECOMP") = POI_XPRS_PRECONEDECOMP; + XPRS.attr("HEURFORCESPECIALOBJ") = POI_XPRS_HEURFORCESPECIALOBJ; + XPRS.attr("HEURSEARCHROOTCUTFREQ") = POI_XPRS_HEURSEARCHROOTCUTFREQ; + XPRS.attr("PREELIMQUAD") = POI_XPRS_PREELIMQUAD; + XPRS.attr("PREIMPLICATIONS") = POI_XPRS_PREIMPLICATIONS; + XPRS.attr("TUNERMODE") = POI_XPRS_TUNERMODE; + XPRS.attr("TUNERMETHOD") = POI_XPRS_TUNERMETHOD; + XPRS.attr("TUNERTARGET") = POI_XPRS_TUNERTARGET; + XPRS.attr("TUNERTHREADS") = POI_XPRS_TUNERTHREADS; + XPRS.attr("TUNERHISTORY") = POI_XPRS_TUNERHISTORY; + XPRS.attr("TUNERPERMUTE") = POI_XPRS_TUNERPERMUTE; + XPRS.attr("TUNERVERBOSE") = POI_XPRS_TUNERVERBOSE; + XPRS.attr("TUNEROUTPUT") = POI_XPRS_TUNEROUTPUT; + XPRS.attr("PREANALYTICCENTER") = POI_XPRS_PREANALYTICCENTER; + XPRS.attr("LPFLAGS") = POI_XPRS_LPFLAGS; + XPRS.attr("MIPKAPPAFREQ") = POI_XPRS_MIPKAPPAFREQ; + XPRS.attr("OBJSCALEFACTOR") = POI_XPRS_OBJSCALEFACTOR; + XPRS.attr("TREEFILELOGINTERVAL") = POI_XPRS_TREEFILELOGINTERVAL; + XPRS.attr("IGNORECONTAINERCPULIMIT") = POI_XPRS_IGNORECONTAINERCPULIMIT; + XPRS.attr("IGNORECONTAINERMEMORYLIMIT") = POI_XPRS_IGNORECONTAINERMEMORYLIMIT; + XPRS.attr("MIPDUALREDUCTIONS") = POI_XPRS_MIPDUALREDUCTIONS; + XPRS.attr("GENCONSDUALREDUCTIONS") = POI_XPRS_GENCONSDUALREDUCTIONS; + XPRS.attr("PWLDUALREDUCTIONS") = POI_XPRS_PWLDUALREDUCTIONS; + XPRS.attr("BARFAILITERLIMIT") = POI_XPRS_BARFAILITERLIMIT; + XPRS.attr("AUTOSCALING") = POI_XPRS_AUTOSCALING; + XPRS.attr("GENCONSABSTRANSFORMATION") = POI_XPRS_GENCONSABSTRANSFORMATION; + XPRS.attr("COMPUTEJOBPRIORITY") = POI_XPRS_COMPUTEJOBPRIORITY; + XPRS.attr("PREFOLDING") = POI_XPRS_PREFOLDING; + XPRS.attr("COMPUTE") = POI_XPRS_COMPUTE; + XPRS.attr("NETSTALLLIMIT") = POI_XPRS_NETSTALLLIMIT; + XPRS.attr("SERIALIZEPREINTSOL") = POI_XPRS_SERIALIZEPREINTSOL; + XPRS.attr("NUMERICALEMPHASIS") = POI_XPRS_NUMERICALEMPHASIS; + XPRS.attr("PWLNONCONVEXTRANSFORMATION") = POI_XPRS_PWLNONCONVEXTRANSFORMATION; + XPRS.attr("MIPCOMPONENTS") = POI_XPRS_MIPCOMPONENTS; + XPRS.attr("MIPCONCURRENTNODES") = POI_XPRS_MIPCONCURRENTNODES; + XPRS.attr("MIPCONCURRENTSOLVES") = POI_XPRS_MIPCONCURRENTSOLVES; + XPRS.attr("OUTPUTCONTROLS") = POI_XPRS_OUTPUTCONTROLS; + XPRS.attr("SIFTSWITCH") = POI_XPRS_SIFTSWITCH; + XPRS.attr("HEUREMPHASIS") = POI_XPRS_HEUREMPHASIS; + XPRS.attr("BARREFITER") = POI_XPRS_BARREFITER; + XPRS.attr("COMPUTELOG") = POI_XPRS_COMPUTELOG; + XPRS.attr("SIFTPRESOLVEOPS") = POI_XPRS_SIFTPRESOLVEOPS; + XPRS.attr("CHECKINPUTDATA") = POI_XPRS_CHECKINPUTDATA; + XPRS.attr("ESCAPENAMES") = POI_XPRS_ESCAPENAMES; + XPRS.attr("IOTIMEOUT") = POI_XPRS_IOTIMEOUT; + XPRS.attr("AUTOCUTTING") = POI_XPRS_AUTOCUTTING; + XPRS.attr("GLOBALNUMINITNLPCUTS") = POI_XPRS_GLOBALNUMINITNLPCUTS; + XPRS.attr("CALLBACKCHECKTIMEDELAY") = POI_XPRS_CALLBACKCHECKTIMEDELAY; + XPRS.attr("MULTIOBJOPS") = POI_XPRS_MULTIOBJOPS; + XPRS.attr("MULTIOBJLOG") = POI_XPRS_MULTIOBJLOG; + XPRS.attr("BACKGROUNDMAXTHREADS") = POI_XPRS_BACKGROUNDMAXTHREADS; + XPRS.attr("GLOBALLSHEURSTRATEGY") = POI_XPRS_GLOBALLSHEURSTRATEGY; + XPRS.attr("GLOBALSPATIALBRANCHIFPREFERORIG") = POI_XPRS_GLOBALSPATIALBRANCHIFPREFERORIG; + XPRS.attr("PRECONFIGURATION") = POI_XPRS_PRECONFIGURATION; + XPRS.attr("FEASIBILITYJUMP") = POI_XPRS_FEASIBILITYJUMP; + XPRS.attr("IISOPS") = POI_XPRS_IISOPS; + XPRS.attr("RLTCUTS") = POI_XPRS_RLTCUTS; + XPRS.attr("ALTERNATIVEREDCOSTS") = POI_XPRS_ALTERNATIVEREDCOSTS; + XPRS.attr("HEURSHIFTPROP") = POI_XPRS_HEURSHIFTPROP; + XPRS.attr("HEURSEARCHCOPYCONTROLS") = POI_XPRS_HEURSEARCHCOPYCONTROLS; + XPRS.attr("GLOBALNLPCUTS") = POI_XPRS_GLOBALNLPCUTS; + XPRS.attr("GLOBALTREENLPCUTS") = POI_XPRS_GLOBALTREENLPCUTS; + XPRS.attr("BARHGOPS") = POI_XPRS_BARHGOPS; + XPRS.attr("BARHGMAXRESTARTS") = POI_XPRS_BARHGMAXRESTARTS; + XPRS.attr("MCFCUTSTRATEGY") = POI_XPRS_MCFCUTSTRATEGY; + XPRS.attr("PREROOTTHREADS") = POI_XPRS_PREROOTTHREADS; + XPRS.attr("BARITERATIVE") = POI_XPRS_BARITERATIVE; /* Integer control parameters that support 64-bit values */ - XPRS.attr("EXTRAELEMS") = XPRS_EXTRAELEMS; - XPRS.attr("EXTRASETELEMS") = XPRS_EXTRASETELEMS; - XPRS.attr("BACKGROUNDSELECT") = XPRS_BACKGROUNDSELECT; - XPRS.attr("HEURSEARCHBACKGROUNDSELECT") = XPRS_HEURSEARCHBACKGROUNDSELECT; + XPRS.attr("EXTRAELEMS") = POI_XPRS_EXTRAELEMS; + XPRS.attr("EXTRASETELEMS") = POI_XPRS_EXTRASETELEMS; + XPRS.attr("BACKGROUNDSELECT") = POI_XPRS_BACKGROUNDSELECT; + XPRS.attr("HEURSEARCHBACKGROUNDSELECT") = POI_XPRS_HEURSEARCHBACKGROUNDSELECT; /* attributes for XPRSprob */ /* String attributes */ - XPRS.attr("MATRIXNAME") = XPRS_MATRIXNAME; - XPRS.attr("BOUNDNAME") = XPRS_BOUNDNAME; - XPRS.attr("RHSNAME") = XPRS_RHSNAME; - XPRS.attr("RANGENAME") = XPRS_RANGENAME; - XPRS.attr("XPRESSVERSION") = XPRS_XPRESSVERSION; - XPRS.attr("UUID") = XPRS_UUID; + XPRS.attr("MATRIXNAME") = POI_XPRS_MATRIXNAME; + XPRS.attr("BOUNDNAME") = POI_XPRS_BOUNDNAME; + XPRS.attr("RHSNAME") = POI_XPRS_RHSNAME; + XPRS.attr("RANGENAME") = POI_XPRS_RANGENAME; + XPRS.attr("XPRESSVERSION") = POI_XPRS_XPRESSVERSION; + XPRS.attr("UUID") = POI_XPRS_UUID; /* Double attributes */ - XPRS.attr("MIPSOLTIME") = XPRS_MIPSOLTIME; - XPRS.attr("TIME") = XPRS_TIME; - XPRS.attr("LPOBJVAL") = XPRS_LPOBJVAL; - XPRS.attr("SUMPRIMALINF") = XPRS_SUMPRIMALINF; - XPRS.attr("MIPOBJVAL") = XPRS_MIPOBJVAL; - XPRS.attr("BESTBOUND") = XPRS_BESTBOUND; - XPRS.attr("OBJRHS") = XPRS_OBJRHS; - XPRS.attr("MIPBESTOBJVAL") = XPRS_MIPBESTOBJVAL; - XPRS.attr("OBJSENSE") = XPRS_OBJSENSE; - XPRS.attr("BRANCHVALUE") = XPRS_BRANCHVALUE; - XPRS.attr("PENALTYVALUE") = XPRS_PENALTYVALUE; - XPRS.attr("CURRMIPCUTOFF") = XPRS_CURRMIPCUTOFF; - XPRS.attr("BARCONDA") = XPRS_BARCONDA; - XPRS.attr("BARCONDD") = XPRS_BARCONDD; - XPRS.attr("MAXABSPRIMALINFEAS") = XPRS_MAXABSPRIMALINFEAS; - XPRS.attr("MAXRELPRIMALINFEAS") = XPRS_MAXRELPRIMALINFEAS; - XPRS.attr("MAXABSDUALINFEAS") = XPRS_MAXABSDUALINFEAS; - XPRS.attr("MAXRELDUALINFEAS") = XPRS_MAXRELDUALINFEAS; - XPRS.attr("PRIMALDUALINTEGRAL") = XPRS_PRIMALDUALINTEGRAL; - XPRS.attr("MAXMIPINFEAS") = XPRS_MAXMIPINFEAS; - XPRS.attr("ATTENTIONLEVEL") = XPRS_ATTENTIONLEVEL; - XPRS.attr("MAXKAPPA") = XPRS_MAXKAPPA; - XPRS.attr("TREECOMPLETION") = XPRS_TREECOMPLETION; - XPRS.attr("PREDICTEDATTLEVEL") = XPRS_PREDICTEDATTLEVEL; - XPRS.attr("OBSERVEDPRIMALINTEGRAL") = XPRS_OBSERVEDPRIMALINTEGRAL; - XPRS.attr("CPISCALEFACTOR") = XPRS_CPISCALEFACTOR; - XPRS.attr("OBJVAL") = XPRS_OBJVAL; - XPRS.attr("WORK") = XPRS_WORK; - XPRS.attr("BARPRIMALOBJ") = XPRS_BARPRIMALOBJ; - XPRS.attr("BARDUALOBJ") = XPRS_BARDUALOBJ; - XPRS.attr("BARPRIMALINF") = XPRS_BARPRIMALINF; - XPRS.attr("BARDUALINF") = XPRS_BARDUALINF; - XPRS.attr("BARCGAP") = XPRS_BARCGAP; + XPRS.attr("MIPSOLTIME") = POI_XPRS_MIPSOLTIME; + XPRS.attr("TIME") = POI_XPRS_TIME; + XPRS.attr("LPOBJVAL") = POI_XPRS_LPOBJVAL; + XPRS.attr("SUMPRIMALINF") = POI_XPRS_SUMPRIMALINF; + XPRS.attr("MIPOBJVAL") = POI_XPRS_MIPOBJVAL; + XPRS.attr("BESTBOUND") = POI_XPRS_BESTBOUND; + XPRS.attr("OBJRHS") = POI_XPRS_OBJRHS; + XPRS.attr("MIPBESTOBJVAL") = POI_XPRS_MIPBESTOBJVAL; + XPRS.attr("OBJSENSE") = POI_XPRS_OBJSENSE; + XPRS.attr("BRANCHVALUE") = POI_XPRS_BRANCHVALUE; + XPRS.attr("PENALTYVALUE") = POI_XPRS_PENALTYVALUE; + XPRS.attr("CURRMIPCUTOFF") = POI_XPRS_CURRMIPCUTOFF; + XPRS.attr("BARCONDA") = POI_XPRS_BARCONDA; + XPRS.attr("BARCONDD") = POI_XPRS_BARCONDD; + XPRS.attr("MAXABSPRIMALINFEAS") = POI_XPRS_MAXABSPRIMALINFEAS; + XPRS.attr("MAXRELPRIMALINFEAS") = POI_XPRS_MAXRELPRIMALINFEAS; + XPRS.attr("MAXABSDUALINFEAS") = POI_XPRS_MAXABSDUALINFEAS; + XPRS.attr("MAXRELDUALINFEAS") = POI_XPRS_MAXRELDUALINFEAS; + XPRS.attr("PRIMALDUALINTEGRAL") = POI_XPRS_PRIMALDUALINTEGRAL; + XPRS.attr("MAXMIPINFEAS") = POI_XPRS_MAXMIPINFEAS; + XPRS.attr("ATTENTIONLEVEL") = POI_XPRS_ATTENTIONLEVEL; + XPRS.attr("MAXKAPPA") = POI_XPRS_MAXKAPPA; + XPRS.attr("TREECOMPLETION") = POI_XPRS_TREECOMPLETION; + XPRS.attr("PREDICTEDATTLEVEL") = POI_XPRS_PREDICTEDATTLEVEL; + XPRS.attr("OBSERVEDPRIMALINTEGRAL") = POI_XPRS_OBSERVEDPRIMALINTEGRAL; + XPRS.attr("CPISCALEFACTOR") = POI_XPRS_CPISCALEFACTOR; + XPRS.attr("OBJVAL") = POI_XPRS_OBJVAL; + XPRS.attr("WORK") = POI_XPRS_WORK; + XPRS.attr("BARPRIMALOBJ") = POI_XPRS_BARPRIMALOBJ; + XPRS.attr("BARDUALOBJ") = POI_XPRS_BARDUALOBJ; + XPRS.attr("BARPRIMALINF") = POI_XPRS_BARPRIMALINF; + XPRS.attr("BARDUALINF") = POI_XPRS_BARDUALINF; + XPRS.attr("BARCGAP") = POI_XPRS_BARCGAP; /* Integer attributes */ - XPRS.attr("ROWS") = XPRS_ROWS; - XPRS.attr("SETS") = XPRS_SETS; - XPRS.attr("PRIMALINFEAS") = XPRS_PRIMALINFEAS; - XPRS.attr("DUALINFEAS") = XPRS_DUALINFEAS; - XPRS.attr("SIMPLEXITER") = XPRS_SIMPLEXITER; - XPRS.attr("LPSTATUS") = XPRS_LPSTATUS; - XPRS.attr("MIPSTATUS") = XPRS_MIPSTATUS; - XPRS.attr("CUTS") = XPRS_CUTS; - XPRS.attr("NODES") = XPRS_NODES; - XPRS.attr("NODEDEPTH") = XPRS_NODEDEPTH; - XPRS.attr("ACTIVENODES") = XPRS_ACTIVENODES; - XPRS.attr("MIPSOLNODE") = XPRS_MIPSOLNODE; - XPRS.attr("MIPSOLS") = XPRS_MIPSOLS; - XPRS.attr("COLS") = XPRS_COLS; - XPRS.attr("SPAREROWS") = XPRS_SPAREROWS; - XPRS.attr("SPARECOLS") = XPRS_SPARECOLS; - XPRS.attr("SPAREMIPENTS") = XPRS_SPAREMIPENTS; - XPRS.attr("ERRORCODE") = XPRS_ERRORCODE; - XPRS.attr("MIPINFEAS") = XPRS_MIPINFEAS; - XPRS.attr("PRESOLVESTATE") = XPRS_PRESOLVESTATE; - XPRS.attr("PARENTNODE") = XPRS_PARENTNODE; - XPRS.attr("NAMELENGTH") = XPRS_NAMELENGTH; - XPRS.attr("QELEMS") = XPRS_QELEMS; - XPRS.attr("NUMIIS") = XPRS_NUMIIS; - XPRS.attr("MIPENTS") = XPRS_MIPENTS; - XPRS.attr("BRANCHVAR") = XPRS_BRANCHVAR; - XPRS.attr("MIPTHREADID") = XPRS_MIPTHREADID; - XPRS.attr("ALGORITHM") = XPRS_ALGORITHM; - XPRS.attr("CROSSOVERITER") = XPRS_CROSSOVERITER; - XPRS.attr("SOLSTATUS") = XPRS_SOLSTATUS; - XPRS.attr("CUTROUNDS") = XPRS_CUTROUNDS; - XPRS.attr("ORIGINALROWS") = XPRS_ORIGINALROWS; - XPRS.attr("CALLBACKCOUNT_OPTNODE") = XPRS_CALLBACKCOUNT_OPTNODE; - XPRS.attr("ORIGINALQELEMS") = XPRS_ORIGINALQELEMS; - XPRS.attr("MAXPROBNAMELENGTH") = XPRS_MAXPROBNAMELENGTH; - XPRS.attr("STOPSTATUS") = XPRS_STOPSTATUS; - XPRS.attr("ORIGINALMIPENTS") = XPRS_ORIGINALMIPENTS; - XPRS.attr("ORIGINALSETS") = XPRS_ORIGINALSETS; - XPRS.attr("SPARESETS") = XPRS_SPARESETS; - XPRS.attr("CHECKSONMAXTIME") = XPRS_CHECKSONMAXTIME; - XPRS.attr("CHECKSONMAXCUTTIME") = XPRS_CHECKSONMAXCUTTIME; - XPRS.attr("ORIGINALCOLS") = XPRS_ORIGINALCOLS; - XPRS.attr("QCELEMS") = XPRS_QCELEMS; - XPRS.attr("QCONSTRAINTS") = XPRS_QCONSTRAINTS; - XPRS.attr("ORIGINALQCELEMS") = XPRS_ORIGINALQCELEMS; - XPRS.attr("ORIGINALQCONSTRAINTS") = XPRS_ORIGINALQCONSTRAINTS; - XPRS.attr("PEAKTOTALTREEMEMORYUSAGE") = XPRS_PEAKTOTALTREEMEMORYUSAGE; - XPRS.attr("CURRENTNODE") = XPRS_CURRENTNODE; - XPRS.attr("TREEMEMORYUSAGE") = XPRS_TREEMEMORYUSAGE; - XPRS.attr("TREEFILESIZE") = XPRS_TREEFILESIZE; - XPRS.attr("TREEFILEUSAGE") = XPRS_TREEFILEUSAGE; - XPRS.attr("INDICATORS") = XPRS_INDICATORS; - XPRS.attr("ORIGINALINDICATORS") = XPRS_ORIGINALINDICATORS; - XPRS.attr("CORESPERCPUDETECTED") = XPRS_CORESPERCPUDETECTED; - XPRS.attr("CPUSDETECTED") = XPRS_CPUSDETECTED; - XPRS.attr("CORESDETECTED") = XPRS_CORESDETECTED; - XPRS.attr("PHYSICALCORESDETECTED") = XPRS_PHYSICALCORESDETECTED; - XPRS.attr("PHYSICALCORESPERCPUDETECTED") = XPRS_PHYSICALCORESPERCPUDETECTED; - XPRS.attr("OPTIMIZETYPEUSED") = XPRS_OPTIMIZETYPEUSED; - XPRS.attr("BARSING") = XPRS_BARSING; - XPRS.attr("BARSINGR") = XPRS_BARSINGR; - XPRS.attr("PRESOLVEINDEX") = XPRS_PRESOLVEINDEX; - XPRS.attr("CONES") = XPRS_CONES; - XPRS.attr("CONEELEMS") = XPRS_CONEELEMS; - XPRS.attr("PWLCONS") = XPRS_PWLCONS; - XPRS.attr("GENCONS") = XPRS_GENCONS; - XPRS.attr("TREERESTARTS") = XPRS_TREERESTARTS; - XPRS.attr("ORIGINALPWLS") = XPRS_ORIGINALPWLS; - XPRS.attr("ORIGINALGENCONS") = XPRS_ORIGINALGENCONS; - XPRS.attr("COMPUTEEXECUTIONS") = XPRS_COMPUTEEXECUTIONS; - XPRS.attr("RESTARTS") = XPRS_RESTARTS; - XPRS.attr("SOLVESTATUS") = XPRS_SOLVESTATUS; - XPRS.attr("GLOBALBOUNDINGBOXAPPLIED") = XPRS_GLOBALBOUNDINGBOXAPPLIED; - XPRS.attr("OBJECTIVES") = XPRS_OBJECTIVES; - XPRS.attr("SOLVEDOBJS") = XPRS_SOLVEDOBJS; - XPRS.attr("OBJSTOSOLVE") = XPRS_OBJSTOSOLVE; - XPRS.attr("GLOBALNLPINFEAS") = XPRS_GLOBALNLPINFEAS; - XPRS.attr("IISSOLSTATUS") = XPRS_IISSOLSTATUS; - XPRS.attr("INPUTROWS") = XPRS_INPUTROWS; - XPRS.attr("INPUTCOLS") = XPRS_INPUTCOLS; - XPRS.attr("BARITER") = XPRS_BARITER; - XPRS.attr("BARDENSECOL") = XPRS_BARDENSECOL; - XPRS.attr("BARCROSSOVER") = XPRS_BARCROSSOVER; + XPRS.attr("ROWS") = POI_XPRS_ROWS; + XPRS.attr("SETS") = POI_XPRS_SETS; + XPRS.attr("PRIMALINFEAS") = POI_XPRS_PRIMALINFEAS; + XPRS.attr("DUALINFEAS") = POI_XPRS_DUALINFEAS; + XPRS.attr("SIMPLEXITER") = POI_XPRS_SIMPLEXITER; + XPRS.attr("LPSTATUS") = POI_XPRS_LPSTATUS; + XPRS.attr("MIPSTATUS") = POI_XPRS_MIPSTATUS; + XPRS.attr("CUTS") = POI_XPRS_CUTS; + XPRS.attr("NODES") = POI_XPRS_NODES; + XPRS.attr("NODEDEPTH") = POI_XPRS_NODEDEPTH; + XPRS.attr("ACTIVENODES") = POI_XPRS_ACTIVENODES; + XPRS.attr("MIPSOLNODE") = POI_XPRS_MIPSOLNODE; + XPRS.attr("MIPSOLS") = POI_XPRS_MIPSOLS; + XPRS.attr("COLS") = POI_XPRS_COLS; + XPRS.attr("SPAREROWS") = POI_XPRS_SPAREROWS; + XPRS.attr("SPARECOLS") = POI_XPRS_SPARECOLS; + XPRS.attr("SPAREMIPENTS") = POI_XPRS_SPAREMIPENTS; + XPRS.attr("ERRORCODE") = POI_XPRS_ERRORCODE; + XPRS.attr("MIPINFEAS") = POI_XPRS_MIPINFEAS; + XPRS.attr("PRESOLVESTATE") = POI_XPRS_PRESOLVESTATE; + XPRS.attr("PARENTNODE") = POI_XPRS_PARENTNODE; + XPRS.attr("NAMELENGTH") = POI_XPRS_NAMELENGTH; + XPRS.attr("QELEMS") = POI_XPRS_QELEMS; + XPRS.attr("NUMIIS") = POI_XPRS_NUMIIS; + XPRS.attr("MIPENTS") = POI_XPRS_MIPENTS; + XPRS.attr("BRANCHVAR") = POI_XPRS_BRANCHVAR; + XPRS.attr("MIPTHREADID") = POI_XPRS_MIPTHREADID; + XPRS.attr("ALGORITHM") = POI_XPRS_ALGORITHM; + XPRS.attr("CROSSOVERITER") = POI_XPRS_CROSSOVERITER; + XPRS.attr("SOLSTATUS") = POI_XPRS_SOLSTATUS; + XPRS.attr("CUTROUNDS") = POI_XPRS_CUTROUNDS; + XPRS.attr("ORIGINALROWS") = POI_XPRS_ORIGINALROWS; + XPRS.attr("CALLBACKCOUNT_OPTNODE") = POI_XPRS_CALLBACKCOUNT_OPTNODE; + XPRS.attr("ORIGINALQELEMS") = POI_XPRS_ORIGINALQELEMS; + XPRS.attr("MAXPROBNAMELENGTH") = POI_XPRS_MAXPROBNAMELENGTH; + XPRS.attr("STOPSTATUS") = POI_XPRS_STOPSTATUS; + XPRS.attr("ORIGINALMIPENTS") = POI_XPRS_ORIGINALMIPENTS; + XPRS.attr("ORIGINALSETS") = POI_XPRS_ORIGINALSETS; + XPRS.attr("SPARESETS") = POI_XPRS_SPARESETS; + XPRS.attr("CHECKSONMAXTIME") = POI_XPRS_CHECKSONMAXTIME; + XPRS.attr("CHECKSONMAXCUTTIME") = POI_XPRS_CHECKSONMAXCUTTIME; + XPRS.attr("ORIGINALCOLS") = POI_XPRS_ORIGINALCOLS; + XPRS.attr("QCELEMS") = POI_XPRS_QCELEMS; + XPRS.attr("QCONSTRAINTS") = POI_XPRS_QCONSTRAINTS; + XPRS.attr("ORIGINALQCELEMS") = POI_XPRS_ORIGINALQCELEMS; + XPRS.attr("ORIGINALQCONSTRAINTS") = POI_XPRS_ORIGINALQCONSTRAINTS; + XPRS.attr("PEAKTOTALTREEMEMORYUSAGE") = POI_XPRS_PEAKTOTALTREEMEMORYUSAGE; + XPRS.attr("CURRENTNODE") = POI_XPRS_CURRENTNODE; + XPRS.attr("TREEMEMORYUSAGE") = POI_XPRS_TREEMEMORYUSAGE; + XPRS.attr("TREEFILESIZE") = POI_XPRS_TREEFILESIZE; + XPRS.attr("TREEFILEUSAGE") = POI_XPRS_TREEFILEUSAGE; + XPRS.attr("INDICATORS") = POI_XPRS_INDICATORS; + XPRS.attr("ORIGINALINDICATORS") = POI_XPRS_ORIGINALINDICATORS; + XPRS.attr("CORESPERCPUDETECTED") = POI_XPRS_CORESPERCPUDETECTED; + XPRS.attr("CPUSDETECTED") = POI_XPRS_CPUSDETECTED; + XPRS.attr("CORESDETECTED") = POI_XPRS_CORESDETECTED; + XPRS.attr("PHYSICALCORESDETECTED") = POI_XPRS_PHYSICALCORESDETECTED; + XPRS.attr("PHYSICALCORESPERCPUDETECTED") = POI_XPRS_PHYSICALCORESPERCPUDETECTED; + XPRS.attr("OPTIMIZETYPEUSED") = POI_XPRS_OPTIMIZETYPEUSED; + XPRS.attr("BARSING") = POI_XPRS_BARSING; + XPRS.attr("BARSINGR") = POI_XPRS_BARSINGR; + XPRS.attr("PRESOLVEINDEX") = POI_XPRS_PRESOLVEINDEX; + XPRS.attr("CONES") = POI_XPRS_CONES; + XPRS.attr("CONEELEMS") = POI_XPRS_CONEELEMS; + XPRS.attr("PWLCONS") = POI_XPRS_PWLCONS; + XPRS.attr("GENCONS") = POI_XPRS_GENCONS; + XPRS.attr("TREERESTARTS") = POI_XPRS_TREERESTARTS; + XPRS.attr("ORIGINALPWLS") = POI_XPRS_ORIGINALPWLS; + XPRS.attr("ORIGINALGENCONS") = POI_XPRS_ORIGINALGENCONS; + XPRS.attr("COMPUTEEXECUTIONS") = POI_XPRS_COMPUTEEXECUTIONS; + XPRS.attr("RESTARTS") = POI_XPRS_RESTARTS; + XPRS.attr("SOLVESTATUS") = POI_XPRS_SOLVESTATUS; + XPRS.attr("GLOBALBOUNDINGBOXAPPLIED") = POI_XPRS_GLOBALBOUNDINGBOXAPPLIED; + XPRS.attr("OBJECTIVES") = POI_XPRS_OBJECTIVES; + XPRS.attr("SOLVEDOBJS") = POI_XPRS_SOLVEDOBJS; + XPRS.attr("OBJSTOSOLVE") = POI_XPRS_OBJSTOSOLVE; + XPRS.attr("GLOBALNLPINFEAS") = POI_XPRS_GLOBALNLPINFEAS; + XPRS.attr("IISSOLSTATUS") = POI_XPRS_IISSOLSTATUS; + XPRS.attr("INPUTROWS") = POI_XPRS_INPUTROWS; + XPRS.attr("INPUTCOLS") = POI_XPRS_INPUTCOLS; + XPRS.attr("BARITER") = POI_XPRS_BARITER; + XPRS.attr("BARDENSECOL") = POI_XPRS_BARDENSECOL; + XPRS.attr("BARCROSSOVER") = POI_XPRS_BARCROSSOVER; /* Integer attributes that support 64-bit values */ - XPRS.attr("SETMEMBERS") = XPRS_SETMEMBERS; - XPRS.attr("ELEMS") = XPRS_ELEMS; - XPRS.attr("SPAREELEMS") = XPRS_SPAREELEMS; - XPRS.attr("SYSTEMMEMORY") = XPRS_SYSTEMMEMORY; - XPRS.attr("ORIGINALSETMEMBERS") = XPRS_ORIGINALSETMEMBERS; - XPRS.attr("SPARESETELEMS") = XPRS_SPARESETELEMS; - XPRS.attr("CURRENTMEMORY") = XPRS_CURRENTMEMORY; - XPRS.attr("PEAKMEMORY") = XPRS_PEAKMEMORY; - XPRS.attr("TOTALMEMORY") = XPRS_TOTALMEMORY; - XPRS.attr("AVAILABLEMEMORY") = XPRS_AVAILABLEMEMORY; - XPRS.attr("PWLPOINTS") = XPRS_PWLPOINTS; - XPRS.attr("GENCONCOLS") = XPRS_GENCONCOLS; - XPRS.attr("GENCONVALS") = XPRS_GENCONVALS; - XPRS.attr("ORIGINALPWLPOINTS") = XPRS_ORIGINALPWLPOINTS; - XPRS.attr("ORIGINALGENCONCOLS") = XPRS_ORIGINALGENCONCOLS; - XPRS.attr("ORIGINALGENCONVALS") = XPRS_ORIGINALGENCONVALS; - XPRS.attr("MEMORYLIMITDETECTED") = XPRS_MEMORYLIMITDETECTED; - XPRS.attr("BARAASIZE") = XPRS_BARAASIZE; - XPRS.attr("BARLSIZE") = XPRS_BARLSIZE; + XPRS.attr("SETMEMBERS") = POI_XPRS_SETMEMBERS; + XPRS.attr("ELEMS") = POI_XPRS_ELEMS; + XPRS.attr("SPAREELEMS") = POI_XPRS_SPAREELEMS; + XPRS.attr("SYSTEMMEMORY") = POI_XPRS_SYSTEMMEMORY; + XPRS.attr("ORIGINALSETMEMBERS") = POI_XPRS_ORIGINALSETMEMBERS; + XPRS.attr("SPARESETELEMS") = POI_XPRS_SPARESETELEMS; + XPRS.attr("CURRENTMEMORY") = POI_XPRS_CURRENTMEMORY; + XPRS.attr("PEAKMEMORY") = POI_XPRS_PEAKMEMORY; + XPRS.attr("TOTALMEMORY") = POI_XPRS_TOTALMEMORY; + XPRS.attr("AVAILABLEMEMORY") = POI_XPRS_AVAILABLEMEMORY; + XPRS.attr("PWLPOINTS") = POI_XPRS_PWLPOINTS; + XPRS.attr("GENCONCOLS") = POI_XPRS_GENCONCOLS; + XPRS.attr("GENCONVALS") = POI_XPRS_GENCONVALS; + XPRS.attr("ORIGINALPWLPOINTS") = POI_XPRS_ORIGINALPWLPOINTS; + XPRS.attr("ORIGINALGENCONCOLS") = POI_XPRS_ORIGINALGENCONCOLS; + XPRS.attr("ORIGINALGENCONVALS") = POI_XPRS_ORIGINALGENCONVALS; + XPRS.attr("MEMORYLIMITDETECTED") = POI_XPRS_MEMORYLIMITDETECTED; + XPRS.attr("BARAASIZE") = POI_XPRS_BARAASIZE; + XPRS.attr("BARLSIZE") = POI_XPRS_BARLSIZE; // Nonlinear solver related controls and attributes - XPRS.attr("NLPFUNCEVAL") = XPRS_NLPFUNCEVAL; - XPRS.attr("NLPLOG") = XPRS_NLPLOG; - XPRS.attr("NLPKEEPEQUALSCOLUMN") = XPRS_NLPKEEPEQUALSCOLUMN; - XPRS.attr("NLPEVALUATE") = XPRS_NLPEVALUATE; - XPRS.attr("NLPPRESOLVE") = XPRS_NLPPRESOLVE; - XPRS.attr("SLPLOG") = XPRS_SLPLOG; - XPRS.attr("LOCALSOLVER") = XPRS_LOCALSOLVER; - XPRS.attr("NLPSTOPOUTOFRANGE") = XPRS_NLPSTOPOUTOFRANGE; - XPRS.attr("NLPTHREADSAFEUSERFUNC") = XPRS_NLPTHREADSAFEUSERFUNC; - XPRS.attr("NLPJACOBIAN") = XPRS_NLPJACOBIAN; - XPRS.attr("NLPHESSIAN") = XPRS_NLPHESSIAN; - XPRS.attr("MULTISTART") = XPRS_MULTISTART; - XPRS.attr("MULTISTART_THREADS") = XPRS_MULTISTART_THREADS; - XPRS.attr("MULTISTART_MAXSOLVES") = XPRS_MULTISTART_MAXSOLVES; - XPRS.attr("MULTISTART_MAXTIME") = XPRS_MULTISTART_MAXTIME; - XPRS.attr("NLPMAXTIME") = XPRS_NLPMAXTIME; - XPRS.attr("NLPDERIVATIVES") = XPRS_NLPDERIVATIVES; - XPRS.attr("NLPREFORMULATE") = XPRS_NLPREFORMULATE; - XPRS.attr("NLPPRESOLVEOPS") = XPRS_NLPPRESOLVEOPS; - XPRS.attr("MULTISTART_LOG") = XPRS_MULTISTART_LOG; - XPRS.attr("MULTISTART_SEED") = XPRS_MULTISTART_SEED; - XPRS.attr("MULTISTART_POOLSIZE") = XPRS_MULTISTART_POOLSIZE; - XPRS.attr("NLPPOSTSOLVE") = XPRS_NLPPOSTSOLVE; - XPRS.attr("NLPDETERMINISTIC") = XPRS_NLPDETERMINISTIC; - XPRS.attr("NLPPRESOLVELEVEL") = XPRS_NLPPRESOLVELEVEL; - XPRS.attr("NLPPROBING") = XPRS_NLPPROBING; - XPRS.attr("NLPCALCTHREADS") = XPRS_NLPCALCTHREADS; - XPRS.attr("NLPTHREADS") = XPRS_NLPTHREADS; - XPRS.attr("NLPFINDIV") = XPRS_NLPFINDIV; - XPRS.attr("NLPLINQUADBR") = XPRS_NLPLINQUADBR; - XPRS.attr("NLPSOLVER") = XPRS_NLPSOLVER; + XPRS.attr("NLPFUNCEVAL") = POI_XPRS_NLPFUNCEVAL; + XPRS.attr("NLPLOG") = POI_XPRS_NLPLOG; + XPRS.attr("NLPKEEPEQUALSCOLUMN") = POI_XPRS_NLPKEEPEQUALSCOLUMN; + XPRS.attr("NLPEVALUATE") = POI_XPRS_NLPEVALUATE; + XPRS.attr("NLPPRESOLVE") = POI_XPRS_NLPPRESOLVE; + XPRS.attr("SLPLOG") = POI_XPRS_SLPLOG; + XPRS.attr("LOCALSOLVER") = POI_XPRS_LOCALSOLVER; + XPRS.attr("NLPSTOPOUTOFRANGE") = POI_XPRS_NLPSTOPOUTOFRANGE; + XPRS.attr("NLPTHREADSAFEUSERFUNC") = POI_XPRS_NLPTHREADSAFEUSERFUNC; + XPRS.attr("NLPJACOBIAN") = POI_XPRS_NLPJACOBIAN; + XPRS.attr("NLPHESSIAN") = POI_XPRS_NLPHESSIAN; + XPRS.attr("MULTISTART") = POI_XPRS_MULTISTART; + XPRS.attr("MULTISTART_THREADS") = POI_XPRS_MULTISTART_THREADS; + XPRS.attr("MULTISTART_MAXSOLVES") = POI_XPRS_MULTISTART_MAXSOLVES; + XPRS.attr("MULTISTART_MAXTIME") = POI_XPRS_MULTISTART_MAXTIME; + XPRS.attr("NLPMAXTIME") = POI_XPRS_NLPMAXTIME; + XPRS.attr("NLPDERIVATIVES") = POI_XPRS_NLPDERIVATIVES; + XPRS.attr("NLPREFORMULATE") = POI_XPRS_NLPREFORMULATE; + XPRS.attr("NLPPRESOLVEOPS") = POI_XPRS_NLPPRESOLVEOPS; + XPRS.attr("MULTISTART_LOG") = POI_XPRS_MULTISTART_LOG; + XPRS.attr("MULTISTART_SEED") = POI_XPRS_MULTISTART_SEED; + XPRS.attr("MULTISTART_POOLSIZE") = POI_XPRS_MULTISTART_POOLSIZE; + XPRS.attr("NLPPOSTSOLVE") = POI_XPRS_NLPPOSTSOLVE; + XPRS.attr("NLPDETERMINISTIC") = POI_XPRS_NLPDETERMINISTIC; + XPRS.attr("NLPPRESOLVELEVEL") = POI_XPRS_NLPPRESOLVELEVEL; + XPRS.attr("NLPPROBING") = POI_XPRS_NLPPROBING; + XPRS.attr("NLPCALCTHREADS") = POI_XPRS_NLPCALCTHREADS; + XPRS.attr("NLPTHREADS") = POI_XPRS_NLPTHREADS; + XPRS.attr("NLPFINDIV") = POI_XPRS_NLPFINDIV; + XPRS.attr("NLPLINQUADBR") = POI_XPRS_NLPLINQUADBR; + XPRS.attr("NLPSOLVER") = POI_XPRS_NLPSOLVER; // SLP related integer controls - XPRS.attr("SLPALGORITHM") = XPRS_SLPALGORITHM; - XPRS.attr("SLPAUGMENTATION") = XPRS_SLPAUGMENTATION; - XPRS.attr("SLPBARLIMIT") = XPRS_SLPBARLIMIT; - XPRS.attr("SLPCASCADE") = XPRS_SLPCASCADE; - XPRS.attr("SLPCASCADENLIMIT") = XPRS_SLPCASCADENLIMIT; - XPRS.attr("SLPDAMPSTART") = XPRS_SLPDAMPSTART; - XPRS.attr("SLPCUTSTRATEGY") = XPRS_SLPCUTSTRATEGY; - XPRS.attr("SLPDELTAZLIMIT") = XPRS_SLPDELTAZLIMIT; - XPRS.attr("SLPINFEASLIMIT") = XPRS_SLPINFEASLIMIT; - XPRS.attr("SLPITERLIMIT") = XPRS_SLPITERLIMIT; - XPRS.attr("SLPSAMECOUNT") = XPRS_SLPSAMECOUNT; - XPRS.attr("SLPSAMEDAMP") = XPRS_SLPSAMEDAMP; - XPRS.attr("SLPSBSTART") = XPRS_SLPSBSTART; - XPRS.attr("SLPXCOUNT") = XPRS_SLPXCOUNT; - XPRS.attr("SLPXLIMIT") = XPRS_SLPXLIMIT; - XPRS.attr("SLPDELAYUPDATEROWS") = XPRS_SLPDELAYUPDATEROWS; - XPRS.attr("SLPAUTOSAVE") = XPRS_SLPAUTOSAVE; - XPRS.attr("SLPANALYZE") = XPRS_SLPANALYZE; - XPRS.attr("SLPOCOUNT") = XPRS_SLPOCOUNT; - XPRS.attr("SLPMIPALGORITHM") = XPRS_SLPMIPALGORITHM; - XPRS.attr("SLPMIPRELAXSTEPBOUNDS") = XPRS_SLPMIPRELAXSTEPBOUNDS; - XPRS.attr("SLPMIPFIXSTEPBOUNDS") = XPRS_SLPMIPFIXSTEPBOUNDS; - XPRS.attr("SLPMIPITERLIMIT") = XPRS_SLPMIPITERLIMIT; - XPRS.attr("SLPMIPCUTOFFLIMIT") = XPRS_SLPMIPCUTOFFLIMIT; - XPRS.attr("SLPMIPOCOUNT") = XPRS_SLPMIPOCOUNT; - XPRS.attr("SLPMIPDEFAULTALGORITHM") = XPRS_SLPMIPDEFAULTALGORITHM; - XPRS.attr("SLPMIPLOG") = XPRS_SLPMIPLOG; - XPRS.attr("SLPDELTAOFFSET") = XPRS_SLPDELTAOFFSET; - XPRS.attr("SLPUPDATEOFFSET") = XPRS_SLPUPDATEOFFSET; - XPRS.attr("SLPERROROFFSET") = XPRS_SLPERROROFFSET; - XPRS.attr("SLPSBROWOFFSET") = XPRS_SLPSBROWOFFSET; - XPRS.attr("SLPVCOUNT") = XPRS_SLPVCOUNT; - XPRS.attr("SLPVLIMIT") = XPRS_SLPVLIMIT; - XPRS.attr("SLPSCALE") = XPRS_SLPSCALE; - XPRS.attr("SLPSCALECOUNT") = XPRS_SLPSCALECOUNT; - XPRS.attr("SLPECFCHECK") = XPRS_SLPECFCHECK; - XPRS.attr("SLPMIPCUTOFFCOUNT") = XPRS_SLPMIPCUTOFFCOUNT; - XPRS.attr("SLPWCOUNT") = XPRS_SLPWCOUNT; - XPRS.attr("SLPUNFINISHEDLIMIT") = XPRS_SLPUNFINISHEDLIMIT; - XPRS.attr("SLPCONVERGENCEOPS") = XPRS_SLPCONVERGENCEOPS; - XPRS.attr("SLPZEROCRITERION") = XPRS_SLPZEROCRITERION; - XPRS.attr("SLPZEROCRITERIONSTART") = XPRS_SLPZEROCRITERIONSTART; - XPRS.attr("SLPZEROCRITERIONCOUNT") = XPRS_SLPZEROCRITERIONCOUNT; - XPRS.attr("SLPLSPATTERNLIMIT") = XPRS_SLPLSPATTERNLIMIT; - XPRS.attr("SLPLSITERLIMIT") = XPRS_SLPLSITERLIMIT; - XPRS.attr("SLPLSSTART") = XPRS_SLPLSSTART; - XPRS.attr("SLPPENALTYINFOSTART") = XPRS_SLPPENALTYINFOSTART; - XPRS.attr("SLPFILTER") = XPRS_SLPFILTER; - XPRS.attr("SLPTRACEMASKOPS") = XPRS_SLPTRACEMASKOPS; - XPRS.attr("SLPLSZEROLIMIT") = XPRS_SLPLSZEROLIMIT; - XPRS.attr("SLPHEURSTRATEGY") = XPRS_SLPHEURSTRATEGY; - XPRS.attr("SLPBARCROSSOVERSTART") = XPRS_SLPBARCROSSOVERSTART; - XPRS.attr("SLPBARSTALLINGLIMIT") = XPRS_SLPBARSTALLINGLIMIT; - XPRS.attr("SLPBARSTALLINGOBJLIMIT") = XPRS_SLPBARSTALLINGOBJLIMIT; - XPRS.attr("SLPBARSTARTOPS") = XPRS_SLPBARSTARTOPS; - XPRS.attr("SLPGRIDHEURSELECT") = XPRS_SLPGRIDHEURSELECT; + XPRS.attr("SLPALGORITHM") = POI_XPRS_SLPALGORITHM; + XPRS.attr("SLPAUGMENTATION") = POI_XPRS_SLPAUGMENTATION; + XPRS.attr("SLPBARLIMIT") = POI_XPRS_SLPBARLIMIT; + XPRS.attr("SLPCASCADE") = POI_XPRS_SLPCASCADE; + XPRS.attr("SLPCASCADENLIMIT") = POI_XPRS_SLPCASCADENLIMIT; + XPRS.attr("SLPDAMPSTART") = POI_XPRS_SLPDAMPSTART; + XPRS.attr("SLPCUTSTRATEGY") = POI_XPRS_SLPCUTSTRATEGY; + XPRS.attr("SLPDELTAZLIMIT") = POI_XPRS_SLPDELTAZLIMIT; + XPRS.attr("SLPINFEASLIMIT") = POI_XPRS_SLPINFEASLIMIT; + XPRS.attr("SLPITERLIMIT") = POI_XPRS_SLPITERLIMIT; + XPRS.attr("SLPSAMECOUNT") = POI_XPRS_SLPSAMECOUNT; + XPRS.attr("SLPSAMEDAMP") = POI_XPRS_SLPSAMEDAMP; + XPRS.attr("SLPSBSTART") = POI_XPRS_SLPSBSTART; + XPRS.attr("SLPXCOUNT") = POI_XPRS_SLPXCOUNT; + XPRS.attr("SLPXLIMIT") = POI_XPRS_SLPXLIMIT; + XPRS.attr("SLPDELAYUPDATEROWS") = POI_XPRS_SLPDELAYUPDATEROWS; + XPRS.attr("SLPAUTOSAVE") = POI_XPRS_SLPAUTOSAVE; + XPRS.attr("SLPANALYZE") = POI_XPRS_SLPANALYZE; + XPRS.attr("SLPOCOUNT") = POI_XPRS_SLPOCOUNT; + XPRS.attr("SLPMIPALGORITHM") = POI_XPRS_SLPMIPALGORITHM; + XPRS.attr("SLPMIPRELAXSTEPBOUNDS") = POI_XPRS_SLPMIPRELAXSTEPBOUNDS; + XPRS.attr("SLPMIPFIXSTEPBOUNDS") = POI_XPRS_SLPMIPFIXSTEPBOUNDS; + XPRS.attr("SLPMIPITERLIMIT") = POI_XPRS_SLPMIPITERLIMIT; + XPRS.attr("SLPMIPCUTOFFLIMIT") = POI_XPRS_SLPMIPCUTOFFLIMIT; + XPRS.attr("SLPMIPOCOUNT") = POI_XPRS_SLPMIPOCOUNT; + XPRS.attr("SLPMIPDEFAULTALGORITHM") = POI_XPRS_SLPMIPDEFAULTALGORITHM; + XPRS.attr("SLPMIPLOG") = POI_XPRS_SLPMIPLOG; + XPRS.attr("SLPDELTAOFFSET") = POI_XPRS_SLPDELTAOFFSET; + XPRS.attr("SLPUPDATEOFFSET") = POI_XPRS_SLPUPDATEOFFSET; + XPRS.attr("SLPERROROFFSET") = POI_XPRS_SLPERROROFFSET; + XPRS.attr("SLPSBROWOFFSET") = POI_XPRS_SLPSBROWOFFSET; + XPRS.attr("SLPVCOUNT") = POI_XPRS_SLPVCOUNT; + XPRS.attr("SLPVLIMIT") = POI_XPRS_SLPVLIMIT; + XPRS.attr("SLPSCALE") = POI_XPRS_SLPSCALE; + XPRS.attr("SLPSCALECOUNT") = POI_XPRS_SLPSCALECOUNT; + XPRS.attr("SLPECFCHECK") = POI_XPRS_SLPECFCHECK; + XPRS.attr("SLPMIPCUTOFFCOUNT") = POI_XPRS_SLPMIPCUTOFFCOUNT; + XPRS.attr("SLPWCOUNT") = POI_XPRS_SLPWCOUNT; + XPRS.attr("SLPUNFINISHEDLIMIT") = POI_XPRS_SLPUNFINISHEDLIMIT; + XPRS.attr("SLPCONVERGENCEOPS") = POI_XPRS_SLPCONVERGENCEOPS; + XPRS.attr("SLPZEROCRITERION") = POI_XPRS_SLPZEROCRITERION; + XPRS.attr("SLPZEROCRITERIONSTART") = POI_XPRS_SLPZEROCRITERIONSTART; + XPRS.attr("SLPZEROCRITERIONCOUNT") = POI_XPRS_SLPZEROCRITERIONCOUNT; + XPRS.attr("SLPLSPATTERNLIMIT") = POI_XPRS_SLPLSPATTERNLIMIT; + XPRS.attr("SLPLSITERLIMIT") = POI_XPRS_SLPLSITERLIMIT; + XPRS.attr("SLPLSSTART") = POI_XPRS_SLPLSSTART; + XPRS.attr("SLPPENALTYINFOSTART") = POI_XPRS_SLPPENALTYINFOSTART; + XPRS.attr("SLPFILTER") = POI_XPRS_SLPFILTER; + XPRS.attr("SLPTRACEMASKOPS") = POI_XPRS_SLPTRACEMASKOPS; + XPRS.attr("SLPLSZEROLIMIT") = POI_XPRS_SLPLSZEROLIMIT; + XPRS.attr("SLPHEURSTRATEGY") = POI_XPRS_SLPHEURSTRATEGY; + XPRS.attr("SLPBARCROSSOVERSTART") = POI_XPRS_SLPBARCROSSOVERSTART; + XPRS.attr("SLPBARSTALLINGLIMIT") = POI_XPRS_SLPBARSTALLINGLIMIT; + XPRS.attr("SLPBARSTALLINGOBJLIMIT") = POI_XPRS_SLPBARSTALLINGOBJLIMIT; + XPRS.attr("SLPBARSTARTOPS") = POI_XPRS_SLPBARSTARTOPS; + XPRS.attr("SLPGRIDHEURSELECT") = POI_XPRS_SLPGRIDHEURSELECT; // Nonlinear related double controls - XPRS.attr("NLPINFINITY") = XPRS_NLPINFINITY; - XPRS.attr("NLPZERO") = XPRS_NLPZERO; - XPRS.attr("NLPDEFAULTIV") = XPRS_NLPDEFAULTIV; - XPRS.attr("NLPOPTTIME") = XPRS_NLPOPTTIME; - XPRS.attr("NLPVALIDATIONTOL_A") = XPRS_NLPVALIDATIONTOL_A; - XPRS.attr("NLPVALIDATIONTOL_R") = XPRS_NLPVALIDATIONTOL_R; - XPRS.attr("NLPVALIDATIONINDEX_A") = XPRS_NLPVALIDATIONINDEX_A; - XPRS.attr("NLPVALIDATIONINDEX_R") = XPRS_NLPVALIDATIONINDEX_R; - XPRS.attr("NLPPRIMALINTEGRALREF") = XPRS_NLPPRIMALINTEGRALREF; - XPRS.attr("NLPPRIMALINTEGRALALPHA") = XPRS_NLPPRIMALINTEGRALALPHA; - XPRS.attr("NLPOBJVAL") = XPRS_NLPOBJVAL; - XPRS.attr("NLPPRESOLVEZERO") = XPRS_NLPPRESOLVEZERO; - XPRS.attr("NLPMERITLAMBDA") = XPRS_NLPMERITLAMBDA; - XPRS.attr("MSMAXBOUNDRANGE") = XPRS_MSMAXBOUNDRANGE; - XPRS.attr("NLPVALIDATIONTOL_K") = XPRS_NLPVALIDATIONTOL_K; - XPRS.attr("NLPPRESOLVE_ELIMTOL") = XPRS_NLPPRESOLVE_ELIMTOL; - XPRS.attr("NLPVALIDATIONTARGET_R") = XPRS_NLPVALIDATIONTARGET_R; - XPRS.attr("NLPVALIDATIONTARGET_K") = XPRS_NLPVALIDATIONTARGET_K; - XPRS.attr("NLPVALIDATIONFACTOR") = XPRS_NLPVALIDATIONFACTOR; - XPRS.attr("NLPRELTOLBOUNDTHRESHOLD") = XPRS_NLPRELTOLBOUNDTHRESHOLD; + XPRS.attr("NLPINFINITY") = POI_XPRS_NLPINFINITY; + XPRS.attr("NLPZERO") = POI_XPRS_NLPZERO; + XPRS.attr("NLPDEFAULTIV") = POI_XPRS_NLPDEFAULTIV; + XPRS.attr("NLPOPTTIME") = POI_XPRS_NLPOPTTIME; + XPRS.attr("NLPVALIDATIONTOL_A") = POI_XPRS_NLPVALIDATIONTOL_A; + XPRS.attr("NLPVALIDATIONTOL_R") = POI_XPRS_NLPVALIDATIONTOL_R; + XPRS.attr("NLPVALIDATIONINDEX_A") = POI_XPRS_NLPVALIDATIONINDEX_A; + XPRS.attr("NLPVALIDATIONINDEX_R") = POI_XPRS_NLPVALIDATIONINDEX_R; + XPRS.attr("NLPPRIMALINTEGRALREF") = POI_XPRS_NLPPRIMALINTEGRALREF; + XPRS.attr("NLPPRIMALINTEGRALALPHA") = POI_XPRS_NLPPRIMALINTEGRALALPHA; + XPRS.attr("NLPOBJVAL") = POI_XPRS_NLPOBJVAL; + XPRS.attr("NLPPRESOLVEZERO") = POI_XPRS_NLPPRESOLVEZERO; + XPRS.attr("NLPMERITLAMBDA") = POI_XPRS_NLPMERITLAMBDA; + XPRS.attr("MSMAXBOUNDRANGE") = POI_XPRS_MSMAXBOUNDRANGE; + XPRS.attr("NLPVALIDATIONTOL_K") = POI_XPRS_NLPVALIDATIONTOL_K; + XPRS.attr("NLPPRESOLVE_ELIMTOL") = POI_XPRS_NLPPRESOLVE_ELIMTOL; + XPRS.attr("NLPVALIDATIONTARGET_R") = POI_XPRS_NLPVALIDATIONTARGET_R; + XPRS.attr("NLPVALIDATIONTARGET_K") = POI_XPRS_NLPVALIDATIONTARGET_K; + XPRS.attr("NLPVALIDATIONFACTOR") = POI_XPRS_NLPVALIDATIONFACTOR; + XPRS.attr("NLPRELTOLBOUNDTHRESHOLD") = POI_XPRS_NLPRELTOLBOUNDTHRESHOLD; // SLP related double controls - XPRS.attr("SLPDAMP") = XPRS_SLPDAMP; - XPRS.attr("SLPDAMPEXPAND") = XPRS_SLPDAMPEXPAND; - XPRS.attr("SLPDAMPSHRINK") = XPRS_SLPDAMPSHRINK; - XPRS.attr("SLPDELTA_A") = XPRS_SLPDELTA_A; - XPRS.attr("SLPDELTA_R") = XPRS_SLPDELTA_R; - XPRS.attr("SLPDELTA_Z") = XPRS_SLPDELTA_Z; - XPRS.attr("SLPDELTACOST") = XPRS_SLPDELTACOST; - XPRS.attr("SLPDELTAMAXCOST") = XPRS_SLPDELTAMAXCOST; - XPRS.attr("SLPDJTOL") = XPRS_SLPDJTOL; - XPRS.attr("SLPERRORCOST") = XPRS_SLPERRORCOST; - XPRS.attr("SLPERRORMAXCOST") = XPRS_SLPERRORMAXCOST; - XPRS.attr("SLPERRORTOL_A") = XPRS_SLPERRORTOL_A; - XPRS.attr("SLPEXPAND") = XPRS_SLPEXPAND; - XPRS.attr("SLPMAXWEIGHT") = XPRS_SLPMAXWEIGHT; - XPRS.attr("SLPMINWEIGHT") = XPRS_SLPMINWEIGHT; - XPRS.attr("SLPSHRINK") = XPRS_SLPSHRINK; - XPRS.attr("SLPCTOL") = XPRS_SLPCTOL; - XPRS.attr("SLPATOL_A") = XPRS_SLPATOL_A; - XPRS.attr("SLPATOL_R") = XPRS_SLPATOL_R; - XPRS.attr("SLPMTOL_A") = XPRS_SLPMTOL_A; - XPRS.attr("SLPMTOL_R") = XPRS_SLPMTOL_R; - XPRS.attr("SLPITOL_A") = XPRS_SLPITOL_A; - XPRS.attr("SLPITOL_R") = XPRS_SLPITOL_R; - XPRS.attr("SLPSTOL_A") = XPRS_SLPSTOL_A; - XPRS.attr("SLPSTOL_R") = XPRS_SLPSTOL_R; - XPRS.attr("SLPMVTOL") = XPRS_SLPMVTOL; - XPRS.attr("SLPXTOL_A") = XPRS_SLPXTOL_A; - XPRS.attr("SLPXTOL_R") = XPRS_SLPXTOL_R; - XPRS.attr("SLPDEFAULTSTEPBOUND") = XPRS_SLPDEFAULTSTEPBOUND; - XPRS.attr("SLPDAMPMAX") = XPRS_SLPDAMPMAX; - XPRS.attr("SLPDAMPMIN") = XPRS_SLPDAMPMIN; - XPRS.attr("SLPDELTACOSTFACTOR") = XPRS_SLPDELTACOSTFACTOR; - XPRS.attr("SLPERRORCOSTFACTOR") = XPRS_SLPERRORCOSTFACTOR; - XPRS.attr("SLPERRORTOL_P") = XPRS_SLPERRORTOL_P; - XPRS.attr("SLPCASCADETOL_PA") = XPRS_SLPCASCADETOL_PA; - XPRS.attr("SLPCASCADETOL_PR") = XPRS_SLPCASCADETOL_PR; - XPRS.attr("SLPCASCADETOL_Z") = XPRS_SLPCASCADETOL_Z; - XPRS.attr("SLPOTOL_A") = XPRS_SLPOTOL_A; - XPRS.attr("SLPOTOL_R") = XPRS_SLPOTOL_R; - XPRS.attr("SLPDELTA_X") = XPRS_SLPDELTA_X; - XPRS.attr("SLPERRORCOSTS") = XPRS_SLPERRORCOSTS; - XPRS.attr("SLPGRANULARITY") = XPRS_SLPGRANULARITY; - XPRS.attr("SLPMIPCUTOFF_A") = XPRS_SLPMIPCUTOFF_A; - XPRS.attr("SLPMIPCUTOFF_R") = XPRS_SLPMIPCUTOFF_R; - XPRS.attr("SLPMIPOTOL_A") = XPRS_SLPMIPOTOL_A; - XPRS.attr("SLPMIPOTOL_R") = XPRS_SLPMIPOTOL_R; - XPRS.attr("SLPESCALATION") = XPRS_SLPESCALATION; - XPRS.attr("SLPOBJTOPENALTYCOST") = XPRS_SLPOBJTOPENALTYCOST; - XPRS.attr("SLPSHRINKBIAS") = XPRS_SLPSHRINKBIAS; - XPRS.attr("SLPFEASTOLTARGET") = XPRS_SLPFEASTOLTARGET; - XPRS.attr("SLPOPTIMALITYTOLTARGET") = XPRS_SLPOPTIMALITYTOLTARGET; - XPRS.attr("SLPDELTA_INFINITY") = XPRS_SLPDELTA_INFINITY; - XPRS.attr("SLPVTOL_A") = XPRS_SLPVTOL_A; - XPRS.attr("SLPVTOL_R") = XPRS_SLPVTOL_R; - XPRS.attr("SLPETOL_A") = XPRS_SLPETOL_A; - XPRS.attr("SLPETOL_R") = XPRS_SLPETOL_R; - XPRS.attr("SLPEVTOL_A") = XPRS_SLPEVTOL_A; - XPRS.attr("SLPEVTOL_R") = XPRS_SLPEVTOL_R; - XPRS.attr("SLPDELTA_ZERO") = XPRS_SLPDELTA_ZERO; - XPRS.attr("SLPMINSBFACTOR") = XPRS_SLPMINSBFACTOR; - XPRS.attr("SLPCLAMPVALIDATIONTOL_A") = XPRS_SLPCLAMPVALIDATIONTOL_A; - XPRS.attr("SLPCLAMPVALIDATIONTOL_R") = XPRS_SLPCLAMPVALIDATIONTOL_R; - XPRS.attr("SLPCLAMPSHRINK") = XPRS_SLPCLAMPSHRINK; - XPRS.attr("SLPECFTOL_A") = XPRS_SLPECFTOL_A; - XPRS.attr("SLPECFTOL_R") = XPRS_SLPECFTOL_R; - XPRS.attr("SLPWTOL_A") = XPRS_SLPWTOL_A; - XPRS.attr("SLPWTOL_R") = XPRS_SLPWTOL_R; - XPRS.attr("SLPMATRIXTOL") = XPRS_SLPMATRIXTOL; - XPRS.attr("SLPDRFIXRANGE") = XPRS_SLPDRFIXRANGE; - XPRS.attr("SLPDRCOLTOL") = XPRS_SLPDRCOLTOL; - XPRS.attr("SLPMIPERRORTOL_A") = XPRS_SLPMIPERRORTOL_A; - XPRS.attr("SLPMIPERRORTOL_R") = XPRS_SLPMIPERRORTOL_R; - XPRS.attr("SLPCDTOL_A") = XPRS_SLPCDTOL_A; - XPRS.attr("SLPCDTOL_R") = XPRS_SLPCDTOL_R; - XPRS.attr("SLPENFORCEMAXCOST") = XPRS_SLPENFORCEMAXCOST; - XPRS.attr("SLPENFORCECOSTSHRINK") = XPRS_SLPENFORCECOSTSHRINK; - XPRS.attr("SLPDRCOLDJTOL") = XPRS_SLPDRCOLDJTOL; - XPRS.attr("SLPBARSTALLINGTOL") = XPRS_SLPBARSTALLINGTOL; - XPRS.attr("SLPOBJTHRESHOLD") = XPRS_SLPOBJTHRESHOLD; - XPRS.attr("SLPBOUNDTHRESHOLD") = XPRS_SLPBOUNDTHRESHOLD; + XPRS.attr("SLPDAMP") = POI_XPRS_SLPDAMP; + XPRS.attr("SLPDAMPEXPAND") = POI_XPRS_SLPDAMPEXPAND; + XPRS.attr("SLPDAMPSHRINK") = POI_XPRS_SLPDAMPSHRINK; + XPRS.attr("SLPDELTA_A") = POI_XPRS_SLPDELTA_A; + XPRS.attr("SLPDELTA_R") = POI_XPRS_SLPDELTA_R; + XPRS.attr("SLPDELTA_Z") = POI_XPRS_SLPDELTA_Z; + XPRS.attr("SLPDELTACOST") = POI_XPRS_SLPDELTACOST; + XPRS.attr("SLPDELTAMAXCOST") = POI_XPRS_SLPDELTAMAXCOST; + XPRS.attr("SLPDJTOL") = POI_XPRS_SLPDJTOL; + XPRS.attr("SLPERRORCOST") = POI_XPRS_SLPERRORCOST; + XPRS.attr("SLPERRORMAXCOST") = POI_XPRS_SLPERRORMAXCOST; + XPRS.attr("SLPERRORTOL_A") = POI_XPRS_SLPERRORTOL_A; + XPRS.attr("SLPEXPAND") = POI_XPRS_SLPEXPAND; + XPRS.attr("SLPMAXWEIGHT") = POI_XPRS_SLPMAXWEIGHT; + XPRS.attr("SLPMINWEIGHT") = POI_XPRS_SLPMINWEIGHT; + XPRS.attr("SLPSHRINK") = POI_XPRS_SLPSHRINK; + XPRS.attr("SLPCTOL") = POI_XPRS_SLPCTOL; + XPRS.attr("SLPATOL_A") = POI_XPRS_SLPATOL_A; + XPRS.attr("SLPATOL_R") = POI_XPRS_SLPATOL_R; + XPRS.attr("SLPMTOL_A") = POI_XPRS_SLPMTOL_A; + XPRS.attr("SLPMTOL_R") = POI_XPRS_SLPMTOL_R; + XPRS.attr("SLPITOL_A") = POI_XPRS_SLPITOL_A; + XPRS.attr("SLPITOL_R") = POI_XPRS_SLPITOL_R; + XPRS.attr("SLPSTOL_A") = POI_XPRS_SLPSTOL_A; + XPRS.attr("SLPSTOL_R") = POI_XPRS_SLPSTOL_R; + XPRS.attr("SLPMVTOL") = POI_XPRS_SLPMVTOL; + XPRS.attr("SLPXTOL_A") = POI_XPRS_SLPXTOL_A; + XPRS.attr("SLPXTOL_R") = POI_XPRS_SLPXTOL_R; + XPRS.attr("SLPDEFAULTSTEPBOUND") = POI_XPRS_SLPDEFAULTSTEPBOUND; + XPRS.attr("SLPDAMPMAX") = POI_XPRS_SLPDAMPMAX; + XPRS.attr("SLPDAMPMIN") = POI_XPRS_SLPDAMPMIN; + XPRS.attr("SLPDELTACOSTFACTOR") = POI_XPRS_SLPDELTACOSTFACTOR; + XPRS.attr("SLPERRORCOSTFACTOR") = POI_XPRS_SLPERRORCOSTFACTOR; + XPRS.attr("SLPERRORTOL_P") = POI_XPRS_SLPERRORTOL_P; + XPRS.attr("SLPCASCADETOL_PA") = POI_XPRS_SLPCASCADETOL_PA; + XPRS.attr("SLPCASCADETOL_PR") = POI_XPRS_SLPCASCADETOL_PR; + XPRS.attr("SLPCASCADETOL_Z") = POI_XPRS_SLPCASCADETOL_Z; + XPRS.attr("SLPOTOL_A") = POI_XPRS_SLPOTOL_A; + XPRS.attr("SLPOTOL_R") = POI_XPRS_SLPOTOL_R; + XPRS.attr("SLPDELTA_X") = POI_XPRS_SLPDELTA_X; + XPRS.attr("SLPERRORCOSTS") = POI_XPRS_SLPERRORCOSTS; + XPRS.attr("SLPGRANULARITY") = POI_XPRS_SLPGRANULARITY; + XPRS.attr("SLPMIPCUTOFF_A") = POI_XPRS_SLPMIPCUTOFF_A; + XPRS.attr("SLPMIPCUTOFF_R") = POI_XPRS_SLPMIPCUTOFF_R; + XPRS.attr("SLPMIPOTOL_A") = POI_XPRS_SLPMIPOTOL_A; + XPRS.attr("SLPMIPOTOL_R") = POI_XPRS_SLPMIPOTOL_R; + XPRS.attr("SLPESCALATION") = POI_XPRS_SLPESCALATION; + XPRS.attr("SLPOBJTOPENALTYCOST") = POI_XPRS_SLPOBJTOPENALTYCOST; + XPRS.attr("SLPSHRINKBIAS") = POI_XPRS_SLPSHRINKBIAS; + XPRS.attr("SLPFEASTOLTARGET") = POI_XPRS_SLPFEASTOLTARGET; + XPRS.attr("SLPOPTIMALITYTOLTARGET") = POI_XPRS_SLPOPTIMALITYTOLTARGET; + XPRS.attr("SLPDELTA_INFINITY") = POI_XPRS_SLPDELTA_INFINITY; + XPRS.attr("SLPVTOL_A") = POI_XPRS_SLPVTOL_A; + XPRS.attr("SLPVTOL_R") = POI_XPRS_SLPVTOL_R; + XPRS.attr("SLPETOL_A") = POI_XPRS_SLPETOL_A; + XPRS.attr("SLPETOL_R") = POI_XPRS_SLPETOL_R; + XPRS.attr("SLPEVTOL_A") = POI_XPRS_SLPEVTOL_A; + XPRS.attr("SLPEVTOL_R") = POI_XPRS_SLPEVTOL_R; + XPRS.attr("SLPDELTA_ZERO") = POI_XPRS_SLPDELTA_ZERO; + XPRS.attr("SLPMINSBFACTOR") = POI_XPRS_SLPMINSBFACTOR; + XPRS.attr("SLPCLAMPVALIDATIONTOL_A") = POI_XPRS_SLPCLAMPVALIDATIONTOL_A; + XPRS.attr("SLPCLAMPVALIDATIONTOL_R") = POI_XPRS_SLPCLAMPVALIDATIONTOL_R; + XPRS.attr("SLPCLAMPSHRINK") = POI_XPRS_SLPCLAMPSHRINK; + XPRS.attr("SLPECFTOL_A") = POI_XPRS_SLPECFTOL_A; + XPRS.attr("SLPECFTOL_R") = POI_XPRS_SLPECFTOL_R; + XPRS.attr("SLPWTOL_A") = POI_XPRS_SLPWTOL_A; + XPRS.attr("SLPWTOL_R") = POI_XPRS_SLPWTOL_R; + XPRS.attr("SLPMATRIXTOL") = POI_XPRS_SLPMATRIXTOL; + XPRS.attr("SLPDRFIXRANGE") = POI_XPRS_SLPDRFIXRANGE; + XPRS.attr("SLPDRCOLTOL") = POI_XPRS_SLPDRCOLTOL; + XPRS.attr("SLPMIPERRORTOL_A") = POI_XPRS_SLPMIPERRORTOL_A; + XPRS.attr("SLPMIPERRORTOL_R") = POI_XPRS_SLPMIPERRORTOL_R; + XPRS.attr("SLPCDTOL_A") = POI_XPRS_SLPCDTOL_A; + XPRS.attr("SLPCDTOL_R") = POI_XPRS_SLPCDTOL_R; + XPRS.attr("SLPENFORCEMAXCOST") = POI_XPRS_SLPENFORCEMAXCOST; + XPRS.attr("SLPENFORCECOSTSHRINK") = POI_XPRS_SLPENFORCECOSTSHRINK; + XPRS.attr("SLPDRCOLDJTOL") = POI_XPRS_SLPDRCOLDJTOL; + XPRS.attr("SLPBARSTALLINGTOL") = POI_XPRS_SLPBARSTALLINGTOL; + XPRS.attr("SLPOBJTHRESHOLD") = POI_XPRS_SLPOBJTHRESHOLD; + XPRS.attr("SLPBOUNDTHRESHOLD") = POI_XPRS_SLPBOUNDTHRESHOLD; // Nonlinear related string controls - XPRS.attr("NLPIVNAME") = XPRS_NLPIVNAME; + XPRS.attr("NLPIVNAME") = POI_XPRS_NLPIVNAME; // SLP related string controls - XPRS.attr("SLPDELTAFORMAT") = XPRS_SLPDELTAFORMAT; - XPRS.attr("SLPMINUSDELTAFORMAT") = XPRS_SLPMINUSDELTAFORMAT; - XPRS.attr("SLPMINUSERRORFORMAT") = XPRS_SLPMINUSERRORFORMAT; - XPRS.attr("SLPPLUSDELTAFORMAT") = XPRS_SLPPLUSDELTAFORMAT; - XPRS.attr("SLPPLUSERRORFORMAT") = XPRS_SLPPLUSERRORFORMAT; - XPRS.attr("SLPSBNAME") = XPRS_SLPSBNAME; - XPRS.attr("SLPTOLNAME") = XPRS_SLPTOLNAME; - XPRS.attr("SLPUPDATEFORMAT") = XPRS_SLPUPDATEFORMAT; - XPRS.attr("SLPPENALTYROWFORMAT") = XPRS_SLPPENALTYROWFORMAT; - XPRS.attr("SLPPENALTYCOLFORMAT") = XPRS_SLPPENALTYCOLFORMAT; - XPRS.attr("SLPSBLOROWFORMAT") = XPRS_SLPSBLOROWFORMAT; - XPRS.attr("SLPSBUPROWFORMAT") = XPRS_SLPSBUPROWFORMAT; - XPRS.attr("SLPTRACEMASK") = XPRS_SLPTRACEMASK; - XPRS.attr("SLPITERFALLBACKOPS") = XPRS_SLPITERFALLBACKOPS; + XPRS.attr("SLPDELTAFORMAT") = POI_XPRS_SLPDELTAFORMAT; + XPRS.attr("SLPMINUSDELTAFORMAT") = POI_XPRS_SLPMINUSDELTAFORMAT; + XPRS.attr("SLPMINUSERRORFORMAT") = POI_XPRS_SLPMINUSERRORFORMAT; + XPRS.attr("SLPPLUSDELTAFORMAT") = POI_XPRS_SLPPLUSDELTAFORMAT; + XPRS.attr("SLPPLUSERRORFORMAT") = POI_XPRS_SLPPLUSERRORFORMAT; + XPRS.attr("SLPSBNAME") = POI_XPRS_SLPSBNAME; + XPRS.attr("SLPTOLNAME") = POI_XPRS_SLPTOLNAME; + XPRS.attr("SLPUPDATEFORMAT") = POI_XPRS_SLPUPDATEFORMAT; + XPRS.attr("SLPPENALTYROWFORMAT") = POI_XPRS_SLPPENALTYROWFORMAT; + XPRS.attr("SLPPENALTYCOLFORMAT") = POI_XPRS_SLPPENALTYCOLFORMAT; + XPRS.attr("SLPSBLOROWFORMAT") = POI_XPRS_SLPSBLOROWFORMAT; + XPRS.attr("SLPSBUPROWFORMAT") = POI_XPRS_SLPSBUPROWFORMAT; + XPRS.attr("SLPTRACEMASK") = POI_XPRS_SLPTRACEMASK; + XPRS.attr("SLPITERFALLBACKOPS") = POI_XPRS_SLPITERFALLBACKOPS; // Nonlinear related integer attributes - XPRS.attr("NLPVALIDATIONSTATUS") = XPRS_NLPVALIDATIONSTATUS; - XPRS.attr("NLPSOLSTATUS") = XPRS_NLPSOLSTATUS; - XPRS.attr("NLPORIGINALROWS") = XPRS_NLPORIGINALROWS; - XPRS.attr("NLPORIGINALCOLS") = XPRS_NLPORIGINALCOLS; - XPRS.attr("NLPUFS") = XPRS_NLPUFS; - XPRS.attr("NLPIFS") = XPRS_NLPIFS; - XPRS.attr("NLPEQUALSCOLUMN") = XPRS_NLPEQUALSCOLUMN; - XPRS.attr("NLPVARIABLES") = XPRS_NLPVARIABLES; - XPRS.attr("NLPIMPLICITVARIABLES") = XPRS_NLPIMPLICITVARIABLES; - XPRS.attr("NONLINEARCONSTRAINTS") = XPRS_NONLINEARCONSTRAINTS; - XPRS.attr("NLPUSERFUNCCALLS") = XPRS_NLPUSERFUNCCALLS; - XPRS.attr("NLPUSEDERIVATIVES") = XPRS_NLPUSEDERIVATIVES; - XPRS.attr("NLPKEEPBESTITER") = XPRS_NLPKEEPBESTITER; - XPRS.attr("NLPSTATUS") = XPRS_NLPSTATUS; - XPRS.attr("LOCALSOLVERSELECTED") = XPRS_LOCALSOLVERSELECTED; - XPRS.attr("NLPMODELROWS") = XPRS_NLPMODELROWS; - XPRS.attr("NLPMODELCOLS") = XPRS_NLPMODELCOLS; - XPRS.attr("NLPJOBID") = XPRS_NLPJOBID; - XPRS.attr("MSJOBS") = XPRS_MSJOBS; - XPRS.attr("NLPSTOPSTATUS") = XPRS_NLPSTOPSTATUS; - XPRS.attr("NLPPRESOLVEELIMINATIONS") = XPRS_NLPPRESOLVEELIMINATIONS; - XPRS.attr("NLPTOTALEVALUATIONERRORS") = XPRS_NLPTOTALEVALUATIONERRORS; + XPRS.attr("NLPVALIDATIONSTATUS") = POI_XPRS_NLPVALIDATIONSTATUS; + XPRS.attr("NLPSOLSTATUS") = POI_XPRS_NLPSOLSTATUS; + XPRS.attr("NLPORIGINALROWS") = POI_XPRS_NLPORIGINALROWS; + XPRS.attr("NLPORIGINALCOLS") = POI_XPRS_NLPORIGINALCOLS; + XPRS.attr("NLPUFS") = POI_XPRS_NLPUFS; + XPRS.attr("NLPIFS") = POI_XPRS_NLPIFS; + XPRS.attr("NLPEQUALSCOLUMN") = POI_XPRS_NLPEQUALSCOLUMN; + XPRS.attr("NLPVARIABLES") = POI_XPRS_NLPVARIABLES; + XPRS.attr("NLPIMPLICITVARIABLES") = POI_XPRS_NLPIMPLICITVARIABLES; + XPRS.attr("NONLINEARCONSTRAINTS") = POI_XPRS_NONLINEARCONSTRAINTS; + XPRS.attr("NLPUSERFUNCCALLS") = POI_XPRS_NLPUSERFUNCCALLS; + XPRS.attr("NLPUSEDERIVATIVES") = POI_XPRS_NLPUSEDERIVATIVES; + XPRS.attr("NLPKEEPBESTITER") = POI_XPRS_NLPKEEPBESTITER; + XPRS.attr("NLPSTATUS") = POI_XPRS_NLPSTATUS; + XPRS.attr("LOCALSOLVERSELECTED") = POI_XPRS_LOCALSOLVERSELECTED; + XPRS.attr("NLPMODELROWS") = POI_XPRS_NLPMODELROWS; + XPRS.attr("NLPMODELCOLS") = POI_XPRS_NLPMODELCOLS; + XPRS.attr("NLPJOBID") = POI_XPRS_NLPJOBID; + XPRS.attr("MSJOBS") = POI_XPRS_MSJOBS; + XPRS.attr("NLPSTOPSTATUS") = POI_XPRS_NLPSTOPSTATUS; + XPRS.attr("NLPPRESOLVEELIMINATIONS") = POI_XPRS_NLPPRESOLVEELIMINATIONS; + XPRS.attr("NLPTOTALEVALUATIONERRORS") = POI_XPRS_NLPTOTALEVALUATIONERRORS; // SLP related integer attributes - XPRS.attr("SLPEXPLOREDELTAS") = XPRS_SLPEXPLOREDELTAS; - XPRS.attr("SLPSEMICONTDELTAS") = XPRS_SLPSEMICONTDELTAS; - XPRS.attr("SLPINTEGERDELTAS") = XPRS_SLPINTEGERDELTAS; - XPRS.attr("SLPITER") = XPRS_SLPITER; - XPRS.attr("SLPSTATUS") = XPRS_SLPSTATUS; - XPRS.attr("SLPUNCONVERGED") = XPRS_SLPUNCONVERGED; - XPRS.attr("SLPSBXCONVERGED") = XPRS_SLPSBXCONVERGED; - XPRS.attr("SLPPENALTYDELTAROW") = XPRS_SLPPENALTYDELTAROW; - XPRS.attr("SLPPENALTYDELTACOLUMN") = XPRS_SLPPENALTYDELTACOLUMN; - XPRS.attr("SLPPENALTYERRORROW") = XPRS_SLPPENALTYERRORROW; - XPRS.attr("SLPPENALTYERRORCOLUMN") = XPRS_SLPPENALTYERRORCOLUMN; - XPRS.attr("SLPCOEFFICIENTS") = XPRS_SLPCOEFFICIENTS; - XPRS.attr("SLPPENALTYDELTAS") = XPRS_SLPPENALTYDELTAS; - XPRS.attr("SLPPENALTYERRORS") = XPRS_SLPPENALTYERRORS; - XPRS.attr("SLPPLUSPENALTYERRORS") = XPRS_SLPPLUSPENALTYERRORS; - XPRS.attr("SLPMINUSPENALTYERRORS") = XPRS_SLPMINUSPENALTYERRORS; - XPRS.attr("SLPUCCONSTRAINEDCOUNT") = XPRS_SLPUCCONSTRAINEDCOUNT; - XPRS.attr("SLPMIPNODES") = XPRS_SLPMIPNODES; - XPRS.attr("SLPMIPITER") = XPRS_SLPMIPITER; - XPRS.attr("SLPTOLSETS") = XPRS_SLPTOLSETS; - XPRS.attr("SLPECFCOUNT") = XPRS_SLPECFCOUNT; - XPRS.attr("SLPDELTAS") = XPRS_SLPDELTAS; - XPRS.attr("SLPZEROESRESET") = XPRS_SLPZEROESRESET; - XPRS.attr("SLPZEROESTOTAL") = XPRS_SLPZEROESTOTAL; - XPRS.attr("SLPZEROESRETAINED") = XPRS_SLPZEROESRETAINED; - XPRS.attr("SLPNONCONSTANTCOEFFS") = XPRS_SLPNONCONSTANTCOEFFS; - XPRS.attr("SLPMIPSOLS") = XPRS_SLPMIPSOLS; + XPRS.attr("SLPEXPLOREDELTAS") = POI_XPRS_SLPEXPLOREDELTAS; + XPRS.attr("SLPSEMICONTDELTAS") = POI_XPRS_SLPSEMICONTDELTAS; + XPRS.attr("SLPINTEGERDELTAS") = POI_XPRS_SLPINTEGERDELTAS; + XPRS.attr("SLPITER") = POI_XPRS_SLPITER; + XPRS.attr("SLPSTATUS") = POI_XPRS_SLPSTATUS; + XPRS.attr("SLPUNCONVERGED") = POI_XPRS_SLPUNCONVERGED; + XPRS.attr("SLPSBXCONVERGED") = POI_XPRS_SLPSBXCONVERGED; + XPRS.attr("SLPPENALTYDELTAROW") = POI_XPRS_SLPPENALTYDELTAROW; + XPRS.attr("SLPPENALTYDELTACOLUMN") = POI_XPRS_SLPPENALTYDELTACOLUMN; + XPRS.attr("SLPPENALTYERRORROW") = POI_XPRS_SLPPENALTYERRORROW; + XPRS.attr("SLPPENALTYERRORCOLUMN") = POI_XPRS_SLPPENALTYERRORCOLUMN; + XPRS.attr("SLPCOEFFICIENTS") = POI_XPRS_SLPCOEFFICIENTS; + XPRS.attr("SLPPENALTYDELTAS") = POI_XPRS_SLPPENALTYDELTAS; + XPRS.attr("SLPPENALTYERRORS") = POI_XPRS_SLPPENALTYERRORS; + XPRS.attr("SLPPLUSPENALTYERRORS") = POI_XPRS_SLPPLUSPENALTYERRORS; + XPRS.attr("SLPMINUSPENALTYERRORS") = POI_XPRS_SLPMINUSPENALTYERRORS; + XPRS.attr("SLPUCCONSTRAINEDCOUNT") = POI_XPRS_SLPUCCONSTRAINEDCOUNT; + XPRS.attr("SLPMIPNODES") = POI_XPRS_SLPMIPNODES; + XPRS.attr("SLPMIPITER") = POI_XPRS_SLPMIPITER; + XPRS.attr("SLPTOLSETS") = POI_XPRS_SLPTOLSETS; + XPRS.attr("SLPECFCOUNT") = POI_XPRS_SLPECFCOUNT; + XPRS.attr("SLPDELTAS") = POI_XPRS_SLPDELTAS; + XPRS.attr("SLPZEROESRESET") = POI_XPRS_SLPZEROESRESET; + XPRS.attr("SLPZEROESTOTAL") = POI_XPRS_SLPZEROESTOTAL; + XPRS.attr("SLPZEROESRETAINED") = POI_XPRS_SLPZEROESRETAINED; + XPRS.attr("SLPNONCONSTANTCOEFFS") = POI_XPRS_SLPNONCONSTANTCOEFFS; + XPRS.attr("SLPMIPSOLS") = POI_XPRS_SLPMIPSOLS; // Nonlinear related double attributes - XPRS.attr("NLPVALIDATIONINDEX_K") = XPRS_NLPVALIDATIONINDEX_K; - XPRS.attr("NLPVALIDATIONNETOBJ") = XPRS_NLPVALIDATIONNETOBJ; - XPRS.attr("NLPPRIMALINTEGRAL") = XPRS_NLPPRIMALINTEGRAL; + XPRS.attr("NLPVALIDATIONINDEX_K") = POI_XPRS_NLPVALIDATIONINDEX_K; + XPRS.attr("NLPVALIDATIONNETOBJ") = POI_XPRS_NLPVALIDATIONNETOBJ; + XPRS.attr("NLPPRIMALINTEGRAL") = POI_XPRS_NLPPRIMALINTEGRAL; // SLP related double attributes - XPRS.attr("SLPCURRENTDELTACOST") = XPRS_SLPCURRENTDELTACOST; - XPRS.attr("SLPCURRENTERRORCOST") = XPRS_SLPCURRENTERRORCOST; - XPRS.attr("SLPPENALTYERRORTOTAL") = XPRS_SLPPENALTYERRORTOTAL; - XPRS.attr("SLPPENALTYERRORVALUE") = XPRS_SLPPENALTYERRORVALUE; - XPRS.attr("SLPPENALTYDELTATOTAL") = XPRS_SLPPENALTYDELTATOTAL; - XPRS.attr("SLPPENALTYDELTAVALUE") = XPRS_SLPPENALTYDELTAVALUE; + XPRS.attr("SLPCURRENTDELTACOST") = POI_XPRS_SLPCURRENTDELTACOST; + XPRS.attr("SLPCURRENTERRORCOST") = POI_XPRS_SLPCURRENTERRORCOST; + XPRS.attr("SLPPENALTYERRORTOTAL") = POI_XPRS_SLPPENALTYERRORTOTAL; + XPRS.attr("SLPPENALTYERRORVALUE") = POI_XPRS_SLPPENALTYERRORVALUE; + XPRS.attr("SLPPENALTYDELTATOTAL") = POI_XPRS_SLPPENALTYDELTATOTAL; + XPRS.attr("SLPPENALTYDELTAVALUE") = POI_XPRS_SLPPENALTYDELTAVALUE; // Nonlinear related string attributes // SLP related string attributes // Knitro's parameters - XPRS.attr("KNITRO_PARAM_NEWPOINT") = XPRS_KNITRO_PARAM_NEWPOINT; - XPRS.attr("KNITRO_PARAM_HONORBNDS") = XPRS_KNITRO_PARAM_HONORBNDS; - XPRS.attr("KNITRO_PARAM_ALGORITHM") = XPRS_KNITRO_PARAM_ALGORITHM; - XPRS.attr("KNITRO_PARAM_BAR_MURULE") = XPRS_KNITRO_PARAM_BAR_MURULE; - XPRS.attr("KNITRO_PARAM_BAR_FEASIBLE") = XPRS_KNITRO_PARAM_BAR_FEASIBLE; - XPRS.attr("KNITRO_PARAM_GRADOPT") = XPRS_KNITRO_PARAM_GRADOPT; - XPRS.attr("KNITRO_PARAM_HESSOPT") = XPRS_KNITRO_PARAM_HESSOPT; - XPRS.attr("KNITRO_PARAM_BAR_INITPT") = XPRS_KNITRO_PARAM_BAR_INITPT; - XPRS.attr("KNITRO_PARAM_MAXCGIT") = XPRS_KNITRO_PARAM_MAXCGIT; - XPRS.attr("KNITRO_PARAM_MAXIT") = XPRS_KNITRO_PARAM_MAXIT; - XPRS.attr("KNITRO_PARAM_OUTLEV") = XPRS_KNITRO_PARAM_OUTLEV; - XPRS.attr("KNITRO_PARAM_SCALE") = XPRS_KNITRO_PARAM_SCALE; - XPRS.attr("KNITRO_PARAM_SOC") = XPRS_KNITRO_PARAM_SOC; - XPRS.attr("KNITRO_PARAM_DELTA") = XPRS_KNITRO_PARAM_DELTA; - XPRS.attr("KNITRO_PARAM_BAR_FEASMODETOL") = XPRS_KNITRO_PARAM_BAR_FEASMODETOL; - XPRS.attr("KNITRO_PARAM_FEASTOL") = XPRS_KNITRO_PARAM_FEASTOL; - XPRS.attr("KNITRO_PARAM_FEASTOLABS") = XPRS_KNITRO_PARAM_FEASTOLABS; - XPRS.attr("KNITRO_PARAM_BAR_INITMU") = XPRS_KNITRO_PARAM_BAR_INITMU; - XPRS.attr("KNITRO_PARAM_OBJRANGE") = XPRS_KNITRO_PARAM_OBJRANGE; - XPRS.attr("KNITRO_PARAM_OPTTOL") = XPRS_KNITRO_PARAM_OPTTOL; - XPRS.attr("KNITRO_PARAM_OPTTOLABS") = XPRS_KNITRO_PARAM_OPTTOLABS; - XPRS.attr("KNITRO_PARAM_PIVOT") = XPRS_KNITRO_PARAM_PIVOT; - XPRS.attr("KNITRO_PARAM_XTOL") = XPRS_KNITRO_PARAM_XTOL; - XPRS.attr("KNITRO_PARAM_DEBUG") = XPRS_KNITRO_PARAM_DEBUG; - XPRS.attr("KNITRO_PARAM_MULTISTART") = XPRS_KNITRO_PARAM_MULTISTART; - XPRS.attr("KNITRO_PARAM_MSMAXSOLVES") = XPRS_KNITRO_PARAM_MSMAXSOLVES; - XPRS.attr("KNITRO_PARAM_MSMAXBNDRANGE") = XPRS_KNITRO_PARAM_MSMAXBNDRANGE; - XPRS.attr("KNITRO_PARAM_LMSIZE") = XPRS_KNITRO_PARAM_LMSIZE; - XPRS.attr("KNITRO_PARAM_BAR_MAXCROSSIT") = XPRS_KNITRO_PARAM_BAR_MAXCROSSIT; - XPRS.attr("KNITRO_PARAM_BLASOPTION") = XPRS_KNITRO_PARAM_BLASOPTION; - XPRS.attr("KNITRO_PARAM_BAR_MAXREFACTOR") = XPRS_KNITRO_PARAM_BAR_MAXREFACTOR; - XPRS.attr("KNITRO_PARAM_BAR_MAXBACKTRACK") = XPRS_KNITRO_PARAM_BAR_MAXBACKTRACK; - XPRS.attr("KNITRO_PARAM_BAR_PENRULE") = XPRS_KNITRO_PARAM_BAR_PENRULE; - XPRS.attr("KNITRO_PARAM_BAR_PENCONS") = XPRS_KNITRO_PARAM_BAR_PENCONS; - XPRS.attr("KNITRO_PARAM_MSNUMTOSAVE") = XPRS_KNITRO_PARAM_MSNUMTOSAVE; - XPRS.attr("KNITRO_PARAM_MSSAVETOL") = XPRS_KNITRO_PARAM_MSSAVETOL; - XPRS.attr("KNITRO_PARAM_MSTERMINATE") = XPRS_KNITRO_PARAM_MSTERMINATE; - XPRS.attr("KNITRO_PARAM_MSSTARTPTRANGE") = XPRS_KNITRO_PARAM_MSSTARTPTRANGE; - XPRS.attr("KNITRO_PARAM_INFEASTOL") = XPRS_KNITRO_PARAM_INFEASTOL; - XPRS.attr("KNITRO_PARAM_LINSOLVER") = XPRS_KNITRO_PARAM_LINSOLVER; - XPRS.attr("KNITRO_PARAM_BAR_DIRECTINTERVAL") = XPRS_KNITRO_PARAM_BAR_DIRECTINTERVAL; - XPRS.attr("KNITRO_PARAM_PRESOLVE") = XPRS_KNITRO_PARAM_PRESOLVE; - XPRS.attr("KNITRO_PARAM_PRESOLVE_TOL") = XPRS_KNITRO_PARAM_PRESOLVE_TOL; - XPRS.attr("KNITRO_PARAM_BAR_SWITCHRULE") = XPRS_KNITRO_PARAM_BAR_SWITCHRULE; - XPRS.attr("KNITRO_PARAM_MA_TERMINATE") = XPRS_KNITRO_PARAM_MA_TERMINATE; - XPRS.attr("KNITRO_PARAM_MSSEED") = XPRS_KNITRO_PARAM_MSSEED; - XPRS.attr("KNITRO_PARAM_BAR_RELAXCONS") = XPRS_KNITRO_PARAM_BAR_RELAXCONS; - XPRS.attr("KNITRO_PARAM_SOLTYPE") = XPRS_KNITRO_PARAM_SOLTYPE; - XPRS.attr("KNITRO_PARAM_MIP_METHOD") = XPRS_KNITRO_PARAM_MIP_METHOD; - XPRS.attr("KNITRO_PARAM_MIP_BRANCHRULE") = XPRS_KNITRO_PARAM_MIP_BRANCHRULE; - XPRS.attr("KNITRO_PARAM_MIP_SELECTRULE") = XPRS_KNITRO_PARAM_MIP_SELECTRULE; - XPRS.attr("KNITRO_PARAM_MIP_INTGAPABS") = XPRS_KNITRO_PARAM_MIP_INTGAPABS; - XPRS.attr("KNITRO_PARAM_MIP_INTGAPREL") = XPRS_KNITRO_PARAM_MIP_INTGAPREL; - XPRS.attr("KNITRO_PARAM_MIP_OUTLEVEL") = XPRS_KNITRO_PARAM_MIP_OUTLEVEL; - XPRS.attr("KNITRO_PARAM_MIP_OUTINTERVAL") = XPRS_KNITRO_PARAM_MIP_OUTINTERVAL; - XPRS.attr("KNITRO_PARAM_MIP_DEBUG") = XPRS_KNITRO_PARAM_MIP_DEBUG; - XPRS.attr("KNITRO_PARAM_MIP_IMPLICATNS") = XPRS_KNITRO_PARAM_MIP_IMPLICATNS; - XPRS.attr("KNITRO_PARAM_MIP_GUB_BRANCH") = XPRS_KNITRO_PARAM_MIP_GUB_BRANCH; - XPRS.attr("KNITRO_PARAM_MIP_KNAPSACK") = XPRS_KNITRO_PARAM_MIP_KNAPSACK; - XPRS.attr("KNITRO_PARAM_MIP_ROUNDING") = XPRS_KNITRO_PARAM_MIP_ROUNDING; - XPRS.attr("KNITRO_PARAM_MIP_ROOTALG") = XPRS_KNITRO_PARAM_MIP_ROOTALG; - XPRS.attr("KNITRO_PARAM_MIP_LPALG") = XPRS_KNITRO_PARAM_MIP_LPALG; - XPRS.attr("KNITRO_PARAM_MIP_MAXNODES") = XPRS_KNITRO_PARAM_MIP_MAXNODES; - XPRS.attr("KNITRO_PARAM_MIP_HEURISTIC") = XPRS_KNITRO_PARAM_MIP_HEURISTIC; - XPRS.attr("KNITRO_PARAM_MIP_HEUR_MAXIT") = XPRS_KNITRO_PARAM_MIP_HEUR_MAXIT; - XPRS.attr("KNITRO_PARAM_MIP_PSEUDOINIT") = XPRS_KNITRO_PARAM_MIP_PSEUDOINIT; - XPRS.attr("KNITRO_PARAM_MIP_STRONG_MAXIT") = XPRS_KNITRO_PARAM_MIP_STRONG_MAXIT; - XPRS.attr("KNITRO_PARAM_MIP_STRONG_CANDLIM") = XPRS_KNITRO_PARAM_MIP_STRONG_CANDLIM; - XPRS.attr("KNITRO_PARAM_MIP_STRONG_LEVEL") = XPRS_KNITRO_PARAM_MIP_STRONG_LEVEL; - XPRS.attr("KNITRO_PARAM_PAR_NUMTHREADS") = XPRS_KNITRO_PARAM_PAR_NUMTHREADS; + XPRS.attr("KNITRO_PARAM_NEWPOINT") = POI_XPRS_KNITRO_PARAM_NEWPOINT; + XPRS.attr("KNITRO_PARAM_HONORBNDS") = POI_XPRS_KNITRO_PARAM_HONORBNDS; + XPRS.attr("KNITRO_PARAM_ALGORITHM") = POI_XPRS_KNITRO_PARAM_ALGORITHM; + XPRS.attr("KNITRO_PARAM_BAR_MURULE") = POI_XPRS_KNITRO_PARAM_BAR_MURULE; + XPRS.attr("KNITRO_PARAM_BAR_FEASIBLE") = POI_XPRS_KNITRO_PARAM_BAR_FEASIBLE; + XPRS.attr("KNITRO_PARAM_GRADOPT") = POI_XPRS_KNITRO_PARAM_GRADOPT; + XPRS.attr("KNITRO_PARAM_HESSOPT") = POI_XPRS_KNITRO_PARAM_HESSOPT; + XPRS.attr("KNITRO_PARAM_BAR_INITPT") = POI_XPRS_KNITRO_PARAM_BAR_INITPT; + XPRS.attr("KNITRO_PARAM_MAXCGIT") = POI_XPRS_KNITRO_PARAM_MAXCGIT; + XPRS.attr("KNITRO_PARAM_MAXIT") = POI_XPRS_KNITRO_PARAM_MAXIT; + XPRS.attr("KNITRO_PARAM_OUTLEV") = POI_XPRS_KNITRO_PARAM_OUTLEV; + XPRS.attr("KNITRO_PARAM_SCALE") = POI_XPRS_KNITRO_PARAM_SCALE; + XPRS.attr("KNITRO_PARAM_SOC") = POI_XPRS_KNITRO_PARAM_SOC; + XPRS.attr("KNITRO_PARAM_DELTA") = POI_XPRS_KNITRO_PARAM_DELTA; + XPRS.attr("KNITRO_PARAM_BAR_FEASMODETOL") = POI_XPRS_KNITRO_PARAM_BAR_FEASMODETOL; + XPRS.attr("KNITRO_PARAM_FEASTOL") = POI_XPRS_KNITRO_PARAM_FEASTOL; + XPRS.attr("KNITRO_PARAM_FEASTOLABS") = POI_XPRS_KNITRO_PARAM_FEASTOLABS; + XPRS.attr("KNITRO_PARAM_BAR_INITMU") = POI_XPRS_KNITRO_PARAM_BAR_INITMU; + XPRS.attr("KNITRO_PARAM_OBJRANGE") = POI_XPRS_KNITRO_PARAM_OBJRANGE; + XPRS.attr("KNITRO_PARAM_OPTTOL") = POI_XPRS_KNITRO_PARAM_OPTTOL; + XPRS.attr("KNITRO_PARAM_OPTTOLABS") = POI_XPRS_KNITRO_PARAM_OPTTOLABS; + XPRS.attr("KNITRO_PARAM_PIVOT") = POI_XPRS_KNITRO_PARAM_PIVOT; + XPRS.attr("KNITRO_PARAM_XTOL") = POI_XPRS_KNITRO_PARAM_XTOL; + XPRS.attr("KNITRO_PARAM_DEBUG") = POI_XPRS_KNITRO_PARAM_DEBUG; + XPRS.attr("KNITRO_PARAM_MULTISTART") = POI_XPRS_KNITRO_PARAM_MULTISTART; + XPRS.attr("KNITRO_PARAM_MSMAXSOLVES") = POI_XPRS_KNITRO_PARAM_MSMAXSOLVES; + XPRS.attr("KNITRO_PARAM_MSMAXBNDRANGE") = POI_XPRS_KNITRO_PARAM_MSMAXBNDRANGE; + XPRS.attr("KNITRO_PARAM_LMSIZE") = POI_XPRS_KNITRO_PARAM_LMSIZE; + XPRS.attr("KNITRO_PARAM_BAR_MAXCROSSIT") = POI_XPRS_KNITRO_PARAM_BAR_MAXCROSSIT; + XPRS.attr("KNITRO_PARAM_BLASOPTION") = POI_XPRS_KNITRO_PARAM_BLASOPTION; + XPRS.attr("KNITRO_PARAM_BAR_MAXREFACTOR") = POI_XPRS_KNITRO_PARAM_BAR_MAXREFACTOR; + XPRS.attr("KNITRO_PARAM_BAR_MAXBACKTRACK") = POI_XPRS_KNITRO_PARAM_BAR_MAXBACKTRACK; + XPRS.attr("KNITRO_PARAM_BAR_PENRULE") = POI_XPRS_KNITRO_PARAM_BAR_PENRULE; + XPRS.attr("KNITRO_PARAM_BAR_PENCONS") = POI_XPRS_KNITRO_PARAM_BAR_PENCONS; + XPRS.attr("KNITRO_PARAM_MSNUMTOSAVE") = POI_XPRS_KNITRO_PARAM_MSNUMTOSAVE; + XPRS.attr("KNITRO_PARAM_MSSAVETOL") = POI_XPRS_KNITRO_PARAM_MSSAVETOL; + XPRS.attr("KNITRO_PARAM_MSTERMINATE") = POI_XPRS_KNITRO_PARAM_MSTERMINATE; + XPRS.attr("KNITRO_PARAM_MSSTARTPTRANGE") = POI_XPRS_KNITRO_PARAM_MSSTARTPTRANGE; + XPRS.attr("KNITRO_PARAM_INFEASTOL") = POI_XPRS_KNITRO_PARAM_INFEASTOL; + XPRS.attr("KNITRO_PARAM_LINSOLVER") = POI_XPRS_KNITRO_PARAM_LINSOLVER; + XPRS.attr("KNITRO_PARAM_BAR_DIRECTINTERVAL") = POI_XPRS_KNITRO_PARAM_BAR_DIRECTINTERVAL; + XPRS.attr("KNITRO_PARAM_PRESOLVE") = POI_XPRS_KNITRO_PARAM_PRESOLVE; + XPRS.attr("KNITRO_PARAM_PRESOLVE_TOL") = POI_XPRS_KNITRO_PARAM_PRESOLVE_TOL; + XPRS.attr("KNITRO_PARAM_BAR_SWITCHRULE") = POI_XPRS_KNITRO_PARAM_BAR_SWITCHRULE; + XPRS.attr("KNITRO_PARAM_MA_TERMINATE") = POI_XPRS_KNITRO_PARAM_MA_TERMINATE; + XPRS.attr("KNITRO_PARAM_MSSEED") = POI_XPRS_KNITRO_PARAM_MSSEED; + XPRS.attr("KNITRO_PARAM_BAR_RELAXCONS") = POI_XPRS_KNITRO_PARAM_BAR_RELAXCONS; + XPRS.attr("KNITRO_PARAM_SOLTYPE") = POI_XPRS_KNITRO_PARAM_SOLTYPE; + XPRS.attr("KNITRO_PARAM_MIP_METHOD") = POI_XPRS_KNITRO_PARAM_MIP_METHOD; + XPRS.attr("KNITRO_PARAM_MIP_BRANCHRULE") = POI_XPRS_KNITRO_PARAM_MIP_BRANCHRULE; + XPRS.attr("KNITRO_PARAM_MIP_SELECTRULE") = POI_XPRS_KNITRO_PARAM_MIP_SELECTRULE; + XPRS.attr("KNITRO_PARAM_MIP_INTGAPABS") = POI_XPRS_KNITRO_PARAM_MIP_INTGAPABS; + XPRS.attr("KNITRO_PARAM_MIP_INTGAPREL") = POI_XPRS_KNITRO_PARAM_MIP_INTGAPREL; + XPRS.attr("KNITRO_PARAM_MIP_OUTLEVEL") = POI_XPRS_KNITRO_PARAM_MIP_OUTLEVEL; + XPRS.attr("KNITRO_PARAM_MIP_OUTINTERVAL") = POI_XPRS_KNITRO_PARAM_MIP_OUTINTERVAL; + XPRS.attr("KNITRO_PARAM_MIP_DEBUG") = POI_XPRS_KNITRO_PARAM_MIP_DEBUG; + XPRS.attr("KNITRO_PARAM_MIP_IMPLICATNS") = POI_XPRS_KNITRO_PARAM_MIP_IMPLICATNS; + XPRS.attr("KNITRO_PARAM_MIP_GUB_BRANCH") = POI_XPRS_KNITRO_PARAM_MIP_GUB_BRANCH; + XPRS.attr("KNITRO_PARAM_MIP_KNAPSACK") = POI_XPRS_KNITRO_PARAM_MIP_KNAPSACK; + XPRS.attr("KNITRO_PARAM_MIP_ROUNDING") = POI_XPRS_KNITRO_PARAM_MIP_ROUNDING; + XPRS.attr("KNITRO_PARAM_MIP_ROOTALG") = POI_XPRS_KNITRO_PARAM_MIP_ROOTALG; + XPRS.attr("KNITRO_PARAM_MIP_LPALG") = POI_XPRS_KNITRO_PARAM_MIP_LPALG; + XPRS.attr("KNITRO_PARAM_MIP_MAXNODES") = POI_XPRS_KNITRO_PARAM_MIP_MAXNODES; + XPRS.attr("KNITRO_PARAM_MIP_HEURISTIC") = POI_XPRS_KNITRO_PARAM_MIP_HEURISTIC; + XPRS.attr("KNITRO_PARAM_MIP_HEUR_MAXIT") = POI_XPRS_KNITRO_PARAM_MIP_HEUR_MAXIT; + XPRS.attr("KNITRO_PARAM_MIP_PSEUDOINIT") = POI_XPRS_KNITRO_PARAM_MIP_PSEUDOINIT; + XPRS.attr("KNITRO_PARAM_MIP_STRONG_MAXIT") = POI_XPRS_KNITRO_PARAM_MIP_STRONG_MAXIT; + XPRS.attr("KNITRO_PARAM_MIP_STRONG_CANDLIM") = POI_XPRS_KNITRO_PARAM_MIP_STRONG_CANDLIM; + XPRS.attr("KNITRO_PARAM_MIP_STRONG_LEVEL") = POI_XPRS_KNITRO_PARAM_MIP_STRONG_LEVEL; + XPRS.attr("KNITRO_PARAM_PAR_NUMTHREADS") = POI_XPRS_KNITRO_PARAM_PAR_NUMTHREADS; nb::enum_(XPRS, "SOLSTATUS") .value("NOTFOUND", SOLSTATUS::NOTFOUND) diff --git a/thirdparty/solvers/xpress/function_list.txt b/thirdparty/solvers/xpress/function_list.txt new file mode 100644 index 00000000..a0b505c0 --- /dev/null +++ b/thirdparty/solvers/xpress/function_list.txt @@ -0,0 +1,131 @@ +XPRSaddcols64 +XPRSaddcuts64 +XPRSaddmanagedcuts64 +XPRSaddmipsol +XPRSaddnames +XPRSaddqmatrix64 +XPRSaddrows64 +XPRSaddsets64 +XPRSbeginlicensing +XPRSchgbounds +XPRSchgcoef +XPRSchgcoltype +XPRSchgmqobj64 +XPRSchgobj +XPRSchgobjsense +XPRSchgrhs +XPRSchgrowtype +XPRScreateprob +XPRSdelcols +XPRSdelobj +XPRSdelqmatrix +XPRSdelrows +XPRSdelsets +XPRSdestroyprob +XPRSendlicensing +XPRSfree +XPRSgetattribinfo +XPRSgetbasisval +XPRSgetcallbacksolution +XPRSgetcoef +XPRSgetcoltype +XPRSgetcontrolinfo +XPRSgetdblattrib +XPRSgetdblcontrol +XPRSgetdualray +XPRSgetduals +XPRSgetiisdata +XPRSgetintattrib64 +XPRSgetintcontrol64 +XPRSgetlasterror +XPRSgetlb +XPRSgetlicerrmsg +XPRSgetlpsol +XPRSgetnamelist +XPRSgetobj +XPRSgetprimalray +XPRSgetprobname +XPRSgetredcosts +XPRSgetrhs +XPRSgetrowtype +XPRSgetslacks +XPRSgetsolution +XPRSgetstrattrib +XPRSgetstrcontrol +XPRSgetstringattrib +XPRSgetstringcontrol +XPRSgetub +XPRSgetversion +XPRSgetversionnumbers +XPRSiisall +XPRSiisfirst +XPRSinit +XPRSinterrupt +XPRSlicense +XPRSnlpaddformulas +XPRSnlploadformulas +XPRSnlppostsolve +XPRSoptimize +XPRSpostsolve +XPRSpresolverow +XPRSsaveas +XPRSsetdblcontrol +XPRSsetintcontrol +XPRSsetintcontrol64 +XPRSsetlogfile +XPRSsetprobname +XPRSsetstrcontrol +XPRSwritebasis +XPRSwritebinsol +XPRSwriteprob +XPRSwriteprtsol +XPRSwriteslxsol +XPRSwritesol +XPRSaddcbbariteration +XPRSaddcbbarlog +XPRSaddcbafterobjective +XPRSaddcbbeforeobjective +XPRSaddcbpresolve +XPRSaddcbchecktime +XPRSaddcbchgbranchobject +XPRSaddcbcutlog +XPRSaddcbcutround +XPRSaddcbdestroymt +XPRSaddcbgapnotify +XPRSaddcbmiplog +XPRSaddcbinfnode +XPRSaddcbintsol +XPRSaddcblplog +XPRSaddcbmessage +XPRSaddcbmipthread +XPRSaddcbnewnode +XPRSaddcbnodecutoff +XPRSaddcbnodelpsolved +XPRSaddcboptnode +XPRSaddcbpreintsol +XPRSaddcbprenode +XPRSaddcbusersolnotify +XPRSremovecbbariteration +XPRSremovecbbarlog +XPRSremovecbafterobjective +XPRSremovecbbeforeobjective +XPRSremovecbpresolve +XPRSremovecbchecktime +XPRSremovecbchgbranchobject +XPRSremovecbcutlog +XPRSremovecbcutround +XPRSremovecbdestroymt +XPRSremovecbgapnotify +XPRSremovecbmiplog +XPRSremovecbinfnode +XPRSremovecbintsol +XPRSremovecblplog +XPRSremovecbmessage +XPRSremovecbmipthread +XPRSremovecbnewnode +XPRSremovecbnodecutoff +XPRSremovecbnodelpsolved +XPRSremovecboptnode +XPRSremovecbpreintsol +XPRSremovecbprenode +XPRSremovecbusersolnotify diff --git a/thirdparty/solvers/xpress/xpress_forward_decls.h b/thirdparty/solvers/xpress/xpress_forward_decls.h new file mode 100644 index 00000000..88c5b2ff --- /dev/null +++ b/thirdparty/solvers/xpress/xpress_forward_decls.h @@ -0,0 +1,1528 @@ +// Forward declarations for FICO Xpress Optimizer API +// This header provides only the minimal declarations needed by PyOptInterface +// to compile against the Xpress C API. Users must have Xpress installed +// with proper libraries for linking and runtime. +// +// This is NOT a complete Xpress header file. + +#ifndef PYOPTINTERFACE_XPRESS_FORWARD_DECLS_H +#define PYOPTINTERFACE_XPRESS_FORWARD_DECLS_H + +// Based on xprs.h version: +#define POI_XPVERSION /* Same as POI_XPVERSION_MAJOR */ 46 +#define POI_XPVERSION_MAJOR 46 +#define POI_XPVERSION_MINOR 1 +#define POI_XPVERSION_BUILD 1 +#define POI_XPVERSION_FULL 460101 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined(_WIN32) +#define XPRSint64 __int64 +#elif defined(__LP64__) || defined(_LP64) || defined(__ILP64__) || defined(_ILP64) +#define XPRSint64 long +#else +#define XPRSint64 long long +#endif + +#define POI_XPRS_PLUSINFINITY 1.0e+20 +#define POI_XPRS_MINUSINFINITY (-1.0e+20) +#define POI_XPRS_MAXINT 2147483647 +#define POI_XPRS_MAXBANNERLENGTH 512 +#define POI_XPRS_MAXMESSAGELENGTH 512 + +#define POI_XPRS_MPSRHSNAME 6001 +#define POI_XPRS_MPSOBJNAME 6002 +#define POI_XPRS_MPSRANGENAME 6003 +#define POI_XPRS_MPSBOUNDNAME 6004 +#define POI_XPRS_OUTPUTMASK 6005 +#define POI_XPRS_TUNERMETHODFILE 6017 +#define POI_XPRS_TUNEROUTPUTPATH 6018 +#define POI_XPRS_TUNERSESSIONNAME 6019 +#define POI_XPRS_COMPUTEEXECSERVICE 6022 +#define POI_XPRS_MAXCUTTIME 8149 +#define POI_XPRS_MAXSTALLTIME 8443 +#define POI_XPRS_TUNERMAXTIME 8364 +#define POI_XPRS_MATRIXTOL 7001 +#define POI_XPRS_PIVOTTOL 7002 +#define POI_XPRS_FEASTOL 7003 +#define POI_XPRS_OUTPUTTOL 7004 +#define POI_XPRS_SOSREFTOL 7005 +#define POI_XPRS_OPTIMALITYTOL 7006 +#define POI_XPRS_ETATOL 7007 +#define POI_XPRS_RELPIVOTTOL 7008 +#define POI_XPRS_MIPTOL 7009 +#define POI_XPRS_MIPTOLTARGET 7010 +#define POI_XPRS_BARPERTURB 7011 +#define POI_XPRS_MIPADDCUTOFF 7012 +#define POI_XPRS_MIPABSCUTOFF 7013 +#define POI_XPRS_MIPRELCUTOFF 7014 +#define POI_XPRS_PSEUDOCOST 7015 +#define POI_XPRS_PENALTY 7016 +#define POI_XPRS_BIGM 7018 +#define POI_XPRS_MIPABSSTOP 7019 +#define POI_XPRS_MIPRELSTOP 7020 +#define POI_XPRS_CROSSOVERACCURACYTOL 7023 +#define POI_XPRS_PRIMALPERTURB 7024 +#define POI_XPRS_DUALPERTURB 7025 +#define POI_XPRS_BAROBJSCALE 7026 +#define POI_XPRS_BARRHSSCALE 7027 +#define POI_XPRS_CHOLESKYTOL 7032 +#define POI_XPRS_BARGAPSTOP 7033 +#define POI_XPRS_BARDUALSTOP 7034 +#define POI_XPRS_BARPRIMALSTOP 7035 +#define POI_XPRS_BARSTEPSTOP 7036 +#define POI_XPRS_ELIMTOL 7042 +#define POI_XPRS_MARKOWITZTOL 7047 +#define POI_XPRS_MIPABSGAPNOTIFY 7064 +#define POI_XPRS_MIPRELGAPNOTIFY 7065 +#define POI_XPRS_BARLARGEBOUND 7067 +#define POI_XPRS_PPFACTOR 7069 +#define POI_XPRS_REPAIRINDEFINITEQMAX 7071 +#define POI_XPRS_BARGAPTARGET 7073 +#define POI_XPRS_DUMMYCONTROL 7075 +#define POI_XPRS_BARSTARTWEIGHT 7076 +#define POI_XPRS_BARFREESCALE 7077 +#define POI_XPRS_SBEFFORT 7086 +#define POI_XPRS_HEURDIVERANDOMIZE 7089 +#define POI_XPRS_HEURSEARCHEFFORT 7090 +#define POI_XPRS_CUTFACTOR 7091 +#define POI_XPRS_EIGENVALUETOL 7097 +#define POI_XPRS_INDLINBIGM 7099 +#define POI_XPRS_TREEMEMORYSAVINGTARGET 7100 +#define POI_XPRS_INDPRELINBIGM 7102 +#define POI_XPRS_RELAXTREEMEMORYLIMIT 7105 +#define POI_XPRS_MIPABSGAPNOTIFYOBJ 7108 +#define POI_XPRS_MIPABSGAPNOTIFYBOUND 7109 +#define POI_XPRS_PRESOLVEMAXGROW 7110 +#define POI_XPRS_HEURSEARCHTARGETSIZE 7112 +#define POI_XPRS_CROSSOVERRELPIVOTTOL 7113 +#define POI_XPRS_CROSSOVERRELPIVOTTOLSAFE 7114 +#define POI_XPRS_DETLOGFREQ 7116 +#define POI_XPRS_MAXIMPLIEDBOUND 7120 +#define POI_XPRS_FEASTOLTARGET 7121 +#define POI_XPRS_OPTIMALITYTOLTARGET 7122 +#define POI_XPRS_PRECOMPONENTSEFFORT 7124 +#define POI_XPRS_LPLOGDELAY 7127 +#define POI_XPRS_HEURDIVEITERLIMIT 7128 +#define POI_XPRS_BARKERNEL 7130 +#define POI_XPRS_FEASTOLPERTURB 7132 +#define POI_XPRS_CROSSOVERFEASWEIGHT 7133 +#define POI_XPRS_LUPIVOTTOL 7139 +#define POI_XPRS_MIPRESTARTGAPTHRESHOLD 7140 +#define POI_XPRS_NODEPROBINGEFFORT 7141 +#define POI_XPRS_INPUTTOL 7143 +#define POI_XPRS_MIPRESTARTFACTOR 7145 +#define POI_XPRS_BAROBJPERTURB 7146 +#define POI_XPRS_CPIALPHA 7149 +#define POI_XPRS_GLOBALSPATIALBRANCHPROPAGATIONEFFORT 7152 +#define POI_XPRS_GLOBALSPATIALBRANCHCUTTINGEFFORT 7153 +#define POI_XPRS_GLOBALBOUNDINGBOX 7154 +#define POI_XPRS_TIMELIMIT 7158 +#define POI_XPRS_SOLTIMELIMIT 7159 +#define POI_XPRS_REPAIRINFEASTIMELIMIT 7160 +#define POI_XPRS_BARHGEXTRAPOLATE 7166 +#define POI_XPRS_WORKLIMIT 7167 +#define POI_XPRS_CALLBACKCHECKTIMEWORKDELAY 7169 +#define POI_XPRS_PREROOTWORKLIMIT 7172 +#define POI_XPRS_PREROOTEFFORT 7173 +#define POI_XPRS_BARHGRELTOL 7177 +#define POI_XPRS_EXTRAROWS 8004 +#define POI_XPRS_EXTRACOLS 8005 +#define POI_XPRS_LPITERLIMIT 8007 +#define POI_XPRS_LPLOG 8009 +#define POI_XPRS_SCALING 8010 +#define POI_XPRS_PRESOLVE 8011 +#define POI_XPRS_CRASH 8012 +#define POI_XPRS_PRICINGALG 8013 +#define POI_XPRS_INVERTFREQ 8014 +#define POI_XPRS_INVERTMIN 8015 +#define POI_XPRS_MAXNODE 8018 +#define POI_XPRS_MAXMIPSOL 8021 +#define POI_XPRS_SIFTPASSES 8022 +#define POI_XPRS_DEFAULTALG 8023 +#define POI_XPRS_VARSELECTION 8025 +#define POI_XPRS_NODESELECTION 8026 +#define POI_XPRS_BACKTRACK 8027 +#define POI_XPRS_MIPLOG 8028 +#define POI_XPRS_KEEPNROWS 8030 +#define POI_XPRS_MPSECHO 8032 +#define POI_XPRS_MAXPAGELINES 8034 +#define POI_XPRS_OUTPUTLOG 8035 +#define POI_XPRS_BARSOLUTION 8038 +#define POI_XPRS_CROSSOVER 8044 +#define POI_XPRS_BARITERLIMIT 8045 +#define POI_XPRS_CHOLESKYALG 8046 +#define POI_XPRS_BAROUTPUT 8047 +#define POI_XPRS_EXTRAMIPENTS 8051 +#define POI_XPRS_REFACTOR 8052 +#define POI_XPRS_BARTHREADS 8053 +#define POI_XPRS_KEEPBASIS 8054 +#define POI_XPRS_CROSSOVEROPS 8060 +#define POI_XPRS_VERSION 8061 +#define POI_XPRS_CROSSOVERTHREADS 8065 +#define POI_XPRS_BIGMMETHOD 8068 +#define POI_XPRS_MPSNAMELENGTH 8071 +#define POI_XPRS_ELIMFILLIN 8073 +#define POI_XPRS_PRESOLVEOPS 8077 +#define POI_XPRS_MIPPRESOLVE 8078 +#define POI_XPRS_MIPTHREADS 8079 +#define POI_XPRS_BARORDER 8080 +#define POI_XPRS_BREADTHFIRST 8082 +#define POI_XPRS_AUTOPERTURB 8084 +#define POI_XPRS_DENSECOLLIMIT 8086 +#define POI_XPRS_CALLBACKFROMMAINTHREAD 8090 +#define POI_XPRS_MAXMCOEFFBUFFERELEMS 8091 +#define POI_XPRS_REFINEOPS 8093 +#define POI_XPRS_LPREFINEITERLIMIT 8094 +#define POI_XPRS_MIPREFINEITERLIMIT 8095 +#define POI_XPRS_DUALIZEOPS 8097 +#define POI_XPRS_CROSSOVERITERLIMIT 8104 +#define POI_XPRS_PREBASISRED 8106 +#define POI_XPRS_PRESORT 8107 +#define POI_XPRS_PREPERMUTE 8108 +#define POI_XPRS_PREPERMUTESEED 8109 +#define POI_XPRS_MAXMEMORYSOFT 8112 +#define POI_XPRS_CUTFREQ 8116 +#define POI_XPRS_SYMSELECT 8117 +#define POI_XPRS_SYMMETRY 8118 +#define POI_XPRS_MAXMEMORYHARD 8119 +#define POI_XPRS_MIQCPALG 8125 +#define POI_XPRS_QCCUTS 8126 +#define POI_XPRS_QCROOTALG 8127 +#define POI_XPRS_PRECONVERTSEPARABLE 8128 +#define POI_XPRS_ALGAFTERNETWORK 8129 +#define POI_XPRS_TRACE 8130 +#define POI_XPRS_MAXIIS 8131 +#define POI_XPRS_CPUTIME 8133 +#define POI_XPRS_COVERCUTS 8134 +#define POI_XPRS_GOMCUTS 8135 +#define POI_XPRS_LPFOLDING 8136 +#define POI_XPRS_MPSFORMAT 8137 +#define POI_XPRS_CUTSTRATEGY 8138 +#define POI_XPRS_CUTDEPTH 8139 +#define POI_XPRS_TREECOVERCUTS 8140 +#define POI_XPRS_TREEGOMCUTS 8141 +#define POI_XPRS_CUTSELECT 8142 +#define POI_XPRS_TREECUTSELECT 8143 +#define POI_XPRS_DUALIZE 8144 +#define POI_XPRS_DUALGRADIENT 8145 +#define POI_XPRS_SBITERLIMIT 8146 +#define POI_XPRS_SBBEST 8147 +#define POI_XPRS_BARINDEFLIMIT 8153 +#define POI_XPRS_HEURFREQ 8155 +#define POI_XPRS_HEURDEPTH 8156 +#define POI_XPRS_HEURMAXSOL 8157 +#define POI_XPRS_HEURNODES 8158 +#define POI_XPRS_LNPBEST 8160 +#define POI_XPRS_LNPITERLIMIT 8161 +#define POI_XPRS_BRANCHCHOICE 8162 +#define POI_XPRS_BARREGULARIZE 8163 +#define POI_XPRS_SBSELECT 8164 +#define POI_XPRS_IISLOG 8165 +#define POI_XPRS_LOCALCHOICE 8170 +#define POI_XPRS_LOCALBACKTRACK 8171 +#define POI_XPRS_DUALSTRATEGY 8174 +#define POI_XPRS_HEURDIVESTRATEGY 8177 +#define POI_XPRS_HEURSELECT 8178 +#define POI_XPRS_BARSTART 8180 +#define POI_XPRS_PRESOLVEPASSES 8183 +#define POI_XPRS_BARORDERTHREADS 8187 +#define POI_XPRS_EXTRASETS 8190 +#define POI_XPRS_FEASIBILITYPUMP 8193 +#define POI_XPRS_PRECOEFELIM 8194 +#define POI_XPRS_PREDOMCOL 8195 +#define POI_XPRS_HEURSEARCHFREQ 8196 +#define POI_XPRS_HEURDIVESPEEDUP 8197 +#define POI_XPRS_SBESTIMATE 8198 +#define POI_XPRS_BARCORES 8202 +#define POI_XPRS_MAXCHECKSONMAXTIME 8203 +#define POI_XPRS_MAXCHECKSONMAXCUTTIME 8204 +#define POI_XPRS_HISTORYCOSTS 8206 +#define POI_XPRS_ALGAFTERCROSSOVER 8208 +#define POI_XPRS_MUTEXCALLBACKS 8210 +#define POI_XPRS_BARCRASH 8211 +#define POI_XPRS_HEURDIVESOFTROUNDING 8215 +#define POI_XPRS_HEURSEARCHROOTSELECT 8216 +#define POI_XPRS_HEURSEARCHTREESELECT 8217 +#define POI_XPRS_MPS18COMPATIBLE 8223 +#define POI_XPRS_ROOTPRESOLVE 8224 +#define POI_XPRS_CROSSOVERDRP 8227 +#define POI_XPRS_FORCEOUTPUT 8229 +#define POI_XPRS_PRIMALOPS 8231 +#define POI_XPRS_DETERMINISTIC 8232 +#define POI_XPRS_PREPROBING 8238 +#define POI_XPRS_TREEMEMORYLIMIT 8242 +#define POI_XPRS_TREECOMPRESSION 8243 +#define POI_XPRS_TREEDIAGNOSTICS 8244 +#define POI_XPRS_MAXTREEFILESIZE 8245 +#define POI_XPRS_PRECLIQUESTRATEGY 8247 +#define POI_XPRS_IFCHECKCONVEXITY 8251 +#define POI_XPRS_PRIMALUNSHIFT 8252 +#define POI_XPRS_REPAIRINDEFINITEQ 8254 +#define POI_XPRS_MIPRAMPUP 8255 +#define POI_XPRS_MAXLOCALBACKTRACK 8257 +#define POI_XPRS_USERSOLHEURISTIC 8258 +#define POI_XPRS_PRECONVERTOBJTOCONS 8260 +#define POI_XPRS_FORCEPARALLELDUAL 8265 +#define POI_XPRS_BACKTRACKTIE 8266 +#define POI_XPRS_BRANCHDISJ 8267 +#define POI_XPRS_MIPFRACREDUCE 8270 +#define POI_XPRS_CONCURRENTTHREADS 8274 +#define POI_XPRS_MAXSCALEFACTOR 8275 +#define POI_XPRS_HEURTHREADS 8276 +#define POI_XPRS_THREADS 8278 +#define POI_XPRS_HEURBEFORELP 8280 +#define POI_XPRS_PREDOMROW 8281 +#define POI_XPRS_BRANCHSTRUCTURAL 8282 +#define POI_XPRS_QUADRATICUNSHIFT 8284 +#define POI_XPRS_BARPRESOLVEOPS 8286 +#define POI_XPRS_QSIMPLEXOPS 8288 +#define POI_XPRS_MIPRESTART 8290 +#define POI_XPRS_CONFLICTCUTS 8292 +#define POI_XPRS_PREPROTECTDUAL 8293 +#define POI_XPRS_CORESPERCPU 8296 +#define POI_XPRS_RESOURCESTRATEGY 8297 +#define POI_XPRS_CLAMPING 8301 +#define POI_XPRS_PREDUPROW 8307 +#define POI_XPRS_CPUPLATFORM 8312 +#define POI_XPRS_BARALG 8315 +#define POI_XPRS_SIFTING 8319 +#define POI_XPRS_BARKEEPLASTSOL 8323 +#define POI_XPRS_LPLOGSTYLE 8326 +#define POI_XPRS_RANDOMSEED 8328 +#define POI_XPRS_TREEQCCUTS 8331 +#define POI_XPRS_PRELINDEP 8333 +#define POI_XPRS_DUALTHREADS 8334 +#define POI_XPRS_PREOBJCUTDETECT 8336 +#define POI_XPRS_PREBNDREDQUAD 8337 +#define POI_XPRS_PREBNDREDCONE 8338 +#define POI_XPRS_PRECOMPONENTS 8339 +#define POI_XPRS_MAXMIPTASKS 8347 +#define POI_XPRS_MIPTERMINATIONMETHOD 8348 +#define POI_XPRS_PRECONEDECOMP 8349 +#define POI_XPRS_HEURFORCESPECIALOBJ 8350 +#define POI_XPRS_HEURSEARCHROOTCUTFREQ 8351 +#define POI_XPRS_PREELIMQUAD 8353 +#define POI_XPRS_PREIMPLICATIONS 8356 +#define POI_XPRS_TUNERMODE 8359 +#define POI_XPRS_TUNERMETHOD 8360 +#define POI_XPRS_TUNERTARGET 8362 +#define POI_XPRS_TUNERTHREADS 8363 +#define POI_XPRS_TUNERHISTORY 8365 +#define POI_XPRS_TUNERPERMUTE 8366 +#define POI_XPRS_TUNERVERBOSE 8370 +#define POI_XPRS_TUNEROUTPUT 8372 +#define POI_XPRS_PREANALYTICCENTER 8374 +#define POI_XPRS_LPFLAGS 8385 +#define POI_XPRS_MIPKAPPAFREQ 8386 +#define POI_XPRS_OBJSCALEFACTOR 8387 +#define POI_XPRS_TREEFILELOGINTERVAL 8389 +#define POI_XPRS_IGNORECONTAINERCPULIMIT 8390 +#define POI_XPRS_IGNORECONTAINERMEMORYLIMIT 8391 +#define POI_XPRS_MIPDUALREDUCTIONS 8392 +#define POI_XPRS_GENCONSDUALREDUCTIONS 8395 +#define POI_XPRS_PWLDUALREDUCTIONS 8396 +#define POI_XPRS_BARFAILITERLIMIT 8398 +#define POI_XPRS_AUTOSCALING 8406 +#define POI_XPRS_GENCONSABSTRANSFORMATION 8408 +#define POI_XPRS_COMPUTEJOBPRIORITY 8409 +#define POI_XPRS_PREFOLDING 8410 +#define POI_XPRS_COMPUTE 8411 +#define POI_XPRS_NETSTALLLIMIT 8412 +#define POI_XPRS_SERIALIZEPREINTSOL 8413 +#define POI_XPRS_NUMERICALEMPHASIS 8416 +#define POI_XPRS_PWLNONCONVEXTRANSFORMATION 8420 +#define POI_XPRS_MIPCOMPONENTS 8421 +#define POI_XPRS_MIPCONCURRENTNODES 8422 +#define POI_XPRS_MIPCONCURRENTSOLVES 8423 +#define POI_XPRS_OUTPUTCONTROLS 8424 +#define POI_XPRS_SIFTSWITCH 8425 +#define POI_XPRS_HEUREMPHASIS 8427 +#define POI_XPRS_BARREFITER 8431 +#define POI_XPRS_COMPUTELOG 8434 +#define POI_XPRS_SIFTPRESOLVEOPS 8435 +#define POI_XPRS_CHECKINPUTDATA 8436 +#define POI_XPRS_ESCAPENAMES 8440 +#define POI_XPRS_IOTIMEOUT 8442 +#define POI_XPRS_AUTOCUTTING 8446 +#define POI_XPRS_GLOBALNUMINITNLPCUTS 8449 +#define POI_XPRS_CALLBACKCHECKTIMEDELAY 8451 +#define POI_XPRS_MULTIOBJOPS 8457 +#define POI_XPRS_MULTIOBJLOG 8458 +#define POI_XPRS_BACKGROUNDMAXTHREADS 8461 +#define POI_XPRS_GLOBALLSHEURSTRATEGY 8464 +#define POI_XPRS_GLOBALSPATIALBRANCHIFPREFERORIG 8465 +#define POI_XPRS_PRECONFIGURATION 8470 +#define POI_XPRS_FEASIBILITYJUMP 8471 +#define POI_XPRS_IISOPS 8472 +#define POI_XPRS_RLTCUTS 8476 +#define POI_XPRS_ALTERNATIVEREDCOSTS 8478 +#define POI_XPRS_HEURSHIFTPROP 8479 +#define POI_XPRS_HEURSEARCHCOPYCONTROLS 8480 +#define POI_XPRS_GLOBALNLPCUTS 8481 +#define POI_XPRS_GLOBALTREENLPCUTS 8482 +#define POI_XPRS_BARHGOPS 8483 +#define POI_XPRS_BARHGMAXRESTARTS 8484 +#define POI_XPRS_MCFCUTSTRATEGY 8486 +#define POI_XPRS_PREROOTTHREADS 8490 +#define POI_XPRS_BARITERATIVE 8492 +#define POI_XPRS_GLOBALPRESOLVEOBBT 8494 +#define POI_XPRS_SDPCUTSTRATEGY 8497 +#define POI_XPRS_DETERMINISTICLOG 8505 +#define POI_XPRS_BARHGGPU 8506 +#define POI_XPRS_BARHGPRECISION 8507 +#define POI_XPRS_BARHGGPUBLOCKSIZE 8508 +#define POI_XPRS_GPUPLATFORM 8510 +#define POI_XPRS_EXTRAELEMS 8006 +#define POI_XPRS_EXTRASETELEMS 8191 +#define POI_XPRS_BACKGROUNDSELECT 8463 +#define POI_XPRS_HEURSEARCHBACKGROUNDSELECT 8477 + +#define POI_XPRS_MATRIXNAME 3001 +#define POI_XPRS_BOUNDNAME 3002 +#define POI_XPRS_RHSNAME 3004 +#define POI_XPRS_RANGENAME 3005 +#define POI_XPRS_XPRESSVERSION 3010 +#define POI_XPRS_UUID 3011 +#define POI_XPRS_MIPSOLTIME 1371 +#define POI_XPRS_TIME 1122 +#define POI_XPRS_LPOBJVAL 2001 +#define POI_XPRS_SUMPRIMALINF 2002 +#define POI_XPRS_MIPOBJVAL 2003 +#define POI_XPRS_BESTBOUND 2004 +#define POI_XPRS_OBJRHS 2005 +#define POI_XPRS_MIPBESTOBJVAL 2006 +#define POI_XPRS_OBJSENSE 2008 +#define POI_XPRS_BRANCHVALUE 2009 +#define POI_XPRS_PENALTYVALUE 2061 +#define POI_XPRS_CURRMIPCUTOFF 2062 +#define POI_XPRS_BARCONDA 2063 +#define POI_XPRS_BARCONDD 2064 +#define POI_XPRS_MAXABSPRIMALINFEAS 2073 +#define POI_XPRS_MAXRELPRIMALINFEAS 2074 +#define POI_XPRS_MAXABSDUALINFEAS 2075 +#define POI_XPRS_MAXRELDUALINFEAS 2076 +#define POI_XPRS_PRIMALDUALINTEGRAL 2079 +#define POI_XPRS_MAXMIPINFEAS 2083 +#define POI_XPRS_ATTENTIONLEVEL 2097 +#define POI_XPRS_MAXKAPPA 2098 +#define POI_XPRS_TREECOMPLETION 2104 +#define POI_XPRS_PREDICTEDATTLEVEL 2105 +#define POI_XPRS_OBSERVEDPRIMALINTEGRAL 2106 +#define POI_XPRS_CPISCALEFACTOR 2117 +#define POI_XPRS_OBJVAL 2118 +#define POI_XPRS_WORK 2120 +#define POI_XPRS_BARPRIMALOBJ 4001 +#define POI_XPRS_BARDUALOBJ 4002 +#define POI_XPRS_BARPRIMALINF 4003 +#define POI_XPRS_BARDUALINF 4004 +#define POI_XPRS_BARCGAP 4005 +#define POI_XPRS_ROWS 1001 +#define POI_XPRS_SETS 1004 +#define POI_XPRS_PRIMALINFEAS 1007 +#define POI_XPRS_DUALINFEAS 1008 +#define POI_XPRS_SIMPLEXITER 1009 +#define POI_XPRS_LPSTATUS 1010 +#define POI_XPRS_MIPSTATUS 1011 +#define POI_XPRS_CUTS 1012 +#define POI_XPRS_NODES 1013 +#define POI_XPRS_NODEDEPTH 1014 +#define POI_XPRS_ACTIVENODES 1015 +#define POI_XPRS_MIPSOLNODE 1016 +#define POI_XPRS_MIPSOLS 1017 +#define POI_XPRS_COLS 1018 +#define POI_XPRS_SPAREROWS 1019 +#define POI_XPRS_SPARECOLS 1020 +#define POI_XPRS_SPAREMIPENTS 1022 +#define POI_XPRS_ERRORCODE 1023 +#define POI_XPRS_MIPINFEAS 1024 +#define POI_XPRS_PRESOLVESTATE 1026 +#define POI_XPRS_PARENTNODE 1027 +#define POI_XPRS_NAMELENGTH 1028 +#define POI_XPRS_QELEMS 1030 +#define POI_XPRS_NUMIIS 1031 +#define POI_XPRS_MIPENTS 1032 +#define POI_XPRS_BRANCHVAR 1036 +#define POI_XPRS_MIPTHREADID 1037 +#define POI_XPRS_ALGORITHM 1049 +#define POI_XPRS_CROSSOVERITER 1051 +#define POI_XPRS_SOLSTATUS 1053 +#define POI_XPRS_CUTROUNDS 1121 +#define POI_XPRS_ORIGINALROWS 1124 +#define POI_XPRS_CALLBACKCOUNT_OPTNODE 1136 +#define POI_XPRS_ORIGINALQELEMS 1157 +#define POI_XPRS_MAXPROBNAMELENGTH 1158 +#define POI_XPRS_STOPSTATUS 1179 +#define POI_XPRS_ORIGINALMIPENTS 1191 +#define POI_XPRS_ORIGINALSETS 1194 +#define POI_XPRS_SPARESETS 1203 +#define POI_XPRS_CHECKSONMAXTIME 1208 +#define POI_XPRS_CHECKSONMAXCUTTIME 1209 +#define POI_XPRS_ORIGINALCOLS 1214 +#define POI_XPRS_QCELEMS 1232 +#define POI_XPRS_QCONSTRAINTS 1234 +#define POI_XPRS_ORIGINALQCELEMS 1237 +#define POI_XPRS_ORIGINALQCONSTRAINTS 1239 +#define POI_XPRS_PEAKTOTALTREEMEMORYUSAGE 1240 +#define POI_XPRS_CURRENTNODE 1248 +#define POI_XPRS_TREEMEMORYUSAGE 1251 +#define POI_XPRS_TREEFILESIZE 1252 +#define POI_XPRS_TREEFILEUSAGE 1253 +#define POI_XPRS_INDICATORS 1254 +#define POI_XPRS_ORIGINALINDICATORS 1255 +#define POI_XPRS_CORESPERCPUDETECTED 1258 +#define POI_XPRS_CPUSDETECTED 1259 +#define POI_XPRS_CORESDETECTED 1260 +#define POI_XPRS_PHYSICALCORESDETECTED 1261 +#define POI_XPRS_PHYSICALCORESPERCPUDETECTED 1262 +#define POI_XPRS_OPTIMIZETYPEUSED 1268 +#define POI_XPRS_BARSING 1281 +#define POI_XPRS_BARSINGR 1282 +#define POI_XPRS_PRESOLVEINDEX 1284 +#define POI_XPRS_CONES 1307 +#define POI_XPRS_CONEELEMS 1308 +#define POI_XPRS_PWLCONS 1325 +#define POI_XPRS_GENCONS 1327 +#define POI_XPRS_TREERESTARTS 1335 +#define POI_XPRS_ORIGINALPWLS 1336 +#define POI_XPRS_ORIGINALGENCONS 1338 +#define POI_XPRS_COMPUTEEXECUTIONS 1356 +#define POI_XPRS_RESTARTS 1381 +#define POI_XPRS_SOLVESTATUS 1394 +#define POI_XPRS_GLOBALBOUNDINGBOXAPPLIED 1396 +#define POI_XPRS_OBJECTIVES 1397 +#define POI_XPRS_SOLVEDOBJS 1399 +#define POI_XPRS_OBJSTOSOLVE 1400 +#define POI_XPRS_GLOBALNLPINFEAS 1403 +#define POI_XPRS_IISSOLSTATUS 1406 +#define POI_XPRS_INPUTROWS 1408 +#define POI_XPRS_INPUTCOLS 1409 +#define POI_XPRS_BARITER 5001 +#define POI_XPRS_BARDENSECOL 5004 +#define POI_XPRS_BARCROSSOVER 5005 +#define POI_XPRS_IIS XPRS_NUMIIS +#define POI_XPRS_SETMEMBERS 1005 +#define POI_XPRS_ELEMS 1006 +#define POI_XPRS_SPAREELEMS 1021 +#define POI_XPRS_SYSTEMMEMORY 1148 +#define POI_XPRS_ORIGINALSETMEMBERS 1195 +#define POI_XPRS_SPARESETELEMS 1204 +#define POI_XPRS_CURRENTMEMORY 1285 +#define POI_XPRS_PEAKMEMORY 1286 +#define POI_XPRS_TOTALMEMORY 1322 +#define POI_XPRS_AVAILABLEMEMORY 1324 +#define POI_XPRS_PWLPOINTS 1326 +#define POI_XPRS_GENCONCOLS 1328 +#define POI_XPRS_GENCONVALS 1329 +#define POI_XPRS_ORIGINALPWLPOINTS 1337 +#define POI_XPRS_ORIGINALGENCONCOLS 1339 +#define POI_XPRS_ORIGINALGENCONVALS 1340 +#define POI_XPRS_MEMORYLIMITDETECTED 1380 +#define POI_XPRS_BARAASIZE 5002 +#define POI_XPRS_BARLSIZE 5003 + +#define POI_XPRS_NLPFUNCEVAL 12312 +#define POI_XPRS_NLPLOG 12316 +#define POI_XPRS_NLPKEEPEQUALSCOLUMN 12325 +#define POI_XPRS_NLPEVALUATE 12334 +#define POI_XPRS_NLPPRESOLVE 12344 +#define POI_XPRS_SLPLOG 12346 +#define POI_XPRS_LOCALSOLVER 12352 +#define POI_XPRS_NLPSTOPOUTOFRANGE 12354 +#define POI_XPRS_NLPTHREADSAFEUSERFUNC 12359 +#define POI_XPRS_NLPJACOBIAN 12360 +#define POI_XPRS_NLPHESSIAN 12361 +#define POI_XPRS_MULTISTART 12362 +#define POI_XPRS_MULTISTART_THREADS 12363 +#define POI_XPRS_MULTISTART_MAXSOLVES 12364 +#define POI_XPRS_MULTISTART_MAXTIME 12365 +#define POI_XPRS_NLPMAXTIME 12366 +#define POI_XPRS_NLPDERIVATIVES 12373 +#define POI_XPRS_NLPREFORMULATE 12392 +#define POI_XPRS_NLPPRESOLVEOPS 12393 +#define POI_XPRS_MULTISTART_LOG 12395 +#define POI_XPRS_MULTISTART_SEED 12396 +#define POI_XPRS_MULTISTART_POOLSIZE 12397 +#define POI_XPRS_NLPPOSTSOLVE 12398 +#define POI_XPRS_NLPDETERMINISTIC 12399 +#define POI_XPRS_NLPPRESOLVELEVEL 12402 +#define POI_XPRS_NLPPROBING 12403 +#define POI_XPRS_NLPCALCTHREADS 12405 +#define POI_XPRS_NLPTHREADS 12406 +#define POI_XPRS_NLPFINDIV 12413 +#define POI_XPRS_NLPLINQUADBR 12414 +#define POI_XPRS_NLPSOLVER 12417 +#define POI_XPRS_SLPALGORITHM 12301 +#define POI_XPRS_SLPAUGMENTATION 12302 +#define POI_XPRS_SLPBARLIMIT 12303 +#define POI_XPRS_SLPCASCADE 12304 +#define POI_XPRS_SLPCASCADENLIMIT 12306 +#define POI_XPRS_SLPDAMPSTART 12308 +#define POI_XPRS_SLPCUTSTRATEGY 12310 +#define POI_XPRS_SLPDELTAZLIMIT 12311 +#define POI_XPRS_SLPINFEASLIMIT 12314 +#define POI_XPRS_SLPITERLIMIT 12315 +#define POI_XPRS_SLPSAMECOUNT 12317 +#define POI_XPRS_SLPSAMEDAMP 12319 +#define POI_XPRS_SLPSBSTART 12320 +#define POI_XPRS_SLPXCOUNT 12321 +#define POI_XPRS_SLPXLIMIT 12322 +#define POI_XPRS_SLPDELAYUPDATEROWS 12329 +#define POI_XPRS_SLPAUTOSAVE 12330 +#define POI_XPRS_SLPANALYZE 12332 +#define POI_XPRS_SLPOCOUNT 12333 +#define POI_XPRS_SLPMIPALGORITHM 12336 +#define POI_XPRS_SLPMIPRELAXSTEPBOUNDS 12337 +#define POI_XPRS_SLPMIPFIXSTEPBOUNDS 12338 +#define POI_XPRS_SLPMIPITERLIMIT 12339 +#define POI_XPRS_SLPMIPCUTOFFLIMIT 12340 +#define POI_XPRS_SLPMIPOCOUNT 12341 +#define POI_XPRS_SLPMIPDEFAULTALGORITHM 12343 +#define POI_XPRS_SLPMIPLOG 12347 +#define POI_XPRS_SLPDELTAOFFSET 12348 +#define POI_XPRS_SLPUPDATEOFFSET 12349 +#define POI_XPRS_SLPERROROFFSET 12350 +#define POI_XPRS_SLPSBROWOFFSET 12351 +#define POI_XPRS_SLPVCOUNT 12356 +#define POI_XPRS_SLPVLIMIT 12357 +#define POI_XPRS_SLPSCALE 12367 +#define POI_XPRS_SLPSCALECOUNT 12368 +#define POI_XPRS_SLPECFCHECK 12369 +#define POI_XPRS_SLPMIPCUTOFFCOUNT 12370 +#define POI_XPRS_SLPWCOUNT 12374 +#define POI_XPRS_SLPUNFINISHEDLIMIT 12376 +#define POI_XPRS_SLPCONVERGENCEOPS 12377 +#define POI_XPRS_SLPZEROCRITERION 12378 +#define POI_XPRS_SLPZEROCRITERIONSTART 12379 +#define POI_XPRS_SLPZEROCRITERIONCOUNT 12380 +#define POI_XPRS_SLPLSPATTERNLIMIT 12381 +#define POI_XPRS_SLPLSITERLIMIT 12382 +#define POI_XPRS_SLPLSSTART 12383 +#define POI_XPRS_SLPPENALTYINFOSTART 12384 +#define POI_XPRS_SLPFILTER 12387 +#define POI_XPRS_SLPTRACEMASKOPS 12388 +#define POI_XPRS_SLPLSZEROLIMIT 12389 +#define POI_XPRS_SLPHEURSTRATEGY 12400 +#define POI_XPRS_SLPBARCROSSOVERSTART 12408 +#define POI_XPRS_SLPBARSTALLINGLIMIT 12409 +#define POI_XPRS_SLPBARSTALLINGOBJLIMIT 12410 +#define POI_XPRS_SLPBARSTARTOPS 12411 +#define POI_XPRS_SLPGRIDHEURSELECT 12412 +#define POI_XPRS_NLPINFINITY 12119 +#define POI_XPRS_NLPZERO 12123 +#define POI_XPRS_NLPDEFAULTIV 12145 +#define POI_XPRS_NLPOPTTIME 12147 +#define POI_XPRS_NLPVALIDATIONTOL_A 12165 +#define POI_XPRS_NLPVALIDATIONTOL_R 12166 +#define POI_XPRS_NLPVALIDATIONINDEX_A 12167 +#define POI_XPRS_NLPVALIDATIONINDEX_R 12168 +#define POI_XPRS_NLPPRIMALINTEGRALREF 12175 +#define POI_XPRS_NLPPRIMALINTEGRALALPHA 12176 +#define POI_XPRS_NLPOBJVAL 12179 +#define POI_XPRS_NLPPRESOLVEZERO 12193 +#define POI_XPRS_NLPMERITLAMBDA 12197 +#define POI_XPRS_MSMAXBOUNDRANGE 12204 +#define POI_XPRS_NLPVALIDATIONTOL_K 12205 +#define POI_XPRS_NLPPRESOLVE_ELIMTOL 12206 +#define POI_XPRS_NLPVALIDATIONTARGET_R 12209 +#define POI_XPRS_NLPVALIDATIONTARGET_K 12210 +#define POI_XPRS_NLPVALIDATIONFACTOR 12211 +#define POI_XPRS_NLPRELTOLBOUNDTHRESHOLD 12215 +#define POI_XPRS_SLPDAMP 12103 +#define POI_XPRS_SLPDAMPEXPAND 12104 +#define POI_XPRS_SLPDAMPSHRINK 12105 +#define POI_XPRS_SLPDELTA_A 12106 +#define POI_XPRS_SLPDELTA_R 12107 +#define POI_XPRS_SLPDELTA_Z 12108 +#define POI_XPRS_SLPDELTACOST 12109 +#define POI_XPRS_SLPDELTAMAXCOST 12110 +#define POI_XPRS_SLPDJTOL 12112 +#define POI_XPRS_SLPERRORCOST 12113 +#define POI_XPRS_SLPERRORMAXCOST 12114 +#define POI_XPRS_SLPERRORTOL_A 12116 +#define POI_XPRS_SLPEXPAND 12118 +#define POI_XPRS_SLPMAXWEIGHT 12120 +#define POI_XPRS_SLPMINWEIGHT 12121 +#define POI_XPRS_SLPSHRINK 12122 +#define POI_XPRS_SLPCTOL 12124 +#define POI_XPRS_SLPATOL_A 12125 +#define POI_XPRS_SLPATOL_R 12126 +#define POI_XPRS_SLPMTOL_A 12127 +#define POI_XPRS_SLPMTOL_R 12128 +#define POI_XPRS_SLPITOL_A 12129 +#define POI_XPRS_SLPITOL_R 12130 +#define POI_XPRS_SLPSTOL_A 12131 +#define POI_XPRS_SLPSTOL_R 12132 +#define POI_XPRS_SLPMVTOL 12133 +#define POI_XPRS_SLPXTOL_A 12134 +#define POI_XPRS_SLPXTOL_R 12135 +#define POI_XPRS_SLPDEFAULTSTEPBOUND 12136 +#define POI_XPRS_SLPDAMPMAX 12137 +#define POI_XPRS_SLPDAMPMIN 12138 +#define POI_XPRS_SLPDELTACOSTFACTOR 12139 +#define POI_XPRS_SLPERRORCOSTFACTOR 12140 +#define POI_XPRS_SLPERRORTOL_P 12141 +#define POI_XPRS_SLPCASCADETOL_PA 12142 +#define POI_XPRS_SLPCASCADETOL_PR 12143 +#define POI_XPRS_SLPCASCADETOL_Z 12144 +#define POI_XPRS_SLPOTOL_A 12150 +#define POI_XPRS_SLPOTOL_R 12151 +#define POI_XPRS_SLPDELTA_X 12152 +#define POI_XPRS_SLPERRORCOSTS 12153 +#define POI_XPRS_SLPGRANULARITY 12157 +#define POI_XPRS_SLPMIPCUTOFF_A 12158 +#define POI_XPRS_SLPMIPCUTOFF_R 12159 +#define POI_XPRS_SLPMIPOTOL_A 12160 +#define POI_XPRS_SLPMIPOTOL_R 12161 +#define POI_XPRS_SLPESCALATION 12169 +#define POI_XPRS_SLPOBJTOPENALTYCOST 12170 +#define POI_XPRS_SLPSHRINKBIAS 12171 +#define POI_XPRS_SLPFEASTOLTARGET 12172 +#define POI_XPRS_SLPOPTIMALITYTOLTARGET 12173 +#define POI_XPRS_SLPDELTA_INFINITY 12174 +#define POI_XPRS_SLPVTOL_A 12177 +#define POI_XPRS_SLPVTOL_R 12178 +#define POI_XPRS_SLPETOL_A 12180 +#define POI_XPRS_SLPETOL_R 12181 +#define POI_XPRS_SLPEVTOL_A 12182 +#define POI_XPRS_SLPEVTOL_R 12183 +#define POI_XPRS_SLPDELTA_ZERO 12184 +#define POI_XPRS_SLPMINSBFACTOR 12185 +#define POI_XPRS_SLPCLAMPVALIDATIONTOL_A 12186 +#define POI_XPRS_SLPCLAMPVALIDATIONTOL_R 12187 +#define POI_XPRS_SLPCLAMPSHRINK 12188 +#define POI_XPRS_SLPECFTOL_A 12189 +#define POI_XPRS_SLPECFTOL_R 12190 +#define POI_XPRS_SLPWTOL_A 12191 +#define POI_XPRS_SLPWTOL_R 12192 +#define POI_XPRS_SLPMATRIXTOL 12194 +#define POI_XPRS_SLPDRFIXRANGE 12195 +#define POI_XPRS_SLPDRCOLTOL 12196 +#define POI_XPRS_SLPMIPERRORTOL_A 12198 +#define POI_XPRS_SLPMIPERRORTOL_R 12199 +#define POI_XPRS_SLPCDTOL_A 12200 +#define POI_XPRS_SLPCDTOL_R 12201 +#define POI_XPRS_SLPENFORCEMAXCOST 12202 +#define POI_XPRS_SLPENFORCECOSTSHRINK 12203 +#define POI_XPRS_SLPDRCOLDJTOL 12208 +#define POI_XPRS_SLPBARSTALLINGTOL 12212 +#define POI_XPRS_SLPOBJTHRESHOLD 12213 +#define POI_XPRS_SLPBOUNDTHRESHOLD 12214 +#define POI_XPRS_NLPIVNAME 12453 +#define POI_XPRS_SLPDELTAFORMAT 12452 +#define POI_XPRS_SLPMINUSDELTAFORMAT 12456 +#define POI_XPRS_SLPMINUSERRORFORMAT 12457 +#define POI_XPRS_SLPPLUSDELTAFORMAT 12458 +#define POI_XPRS_SLPPLUSERRORFORMAT 12459 +#define POI_XPRS_SLPSBNAME 12460 +#define POI_XPRS_SLPTOLNAME 12461 +#define POI_XPRS_SLPUPDATEFORMAT 12462 +#define POI_XPRS_SLPPENALTYROWFORMAT 12463 +#define POI_XPRS_SLPPENALTYCOLFORMAT 12464 +#define POI_XPRS_SLPSBLOROWFORMAT 12467 +#define POI_XPRS_SLPSBUPROWFORMAT 12468 +#define POI_XPRS_SLPTRACEMASK 12472 +#define POI_XPRS_SLPITERFALLBACKOPS 12474 +#define POI_XPRS_NLPVALIDATIONSTATUS 11986 +#define POI_XPRS_NLPSOLSTATUS 11987 +#define POI_XPRS_NLPORIGINALROWS 11999 +#define POI_XPRS_NLPORIGINALCOLS 12000 +#define POI_XPRS_NLPUFS 12007 +#define POI_XPRS_NLPIFS 12008 +#define POI_XPRS_NLPEQUALSCOLUMN 12013 +#define POI_XPRS_NLPVARIABLES 12014 +#define POI_XPRS_NLPIMPLICITVARIABLES 12015 +#define POI_XPRS_NONLINEARCONSTRAINTS 12026 +#define POI_XPRS_NLPUSERFUNCCALLS 12031 +#define POI_XPRS_NLPUSEDERIVATIVES 12037 +#define POI_XPRS_NLPKEEPBESTITER 12042 +#define POI_XPRS_NLPSTATUS 12044 +#define POI_XPRS_LOCALSOLVERSELECTED 12075 +#define POI_XPRS_NLPMODELROWS 12079 +#define POI_XPRS_NLPMODELCOLS 12080 +#define POI_XPRS_NLPJOBID 12081 +#define POI_XPRS_MSJOBS 12082 +#define POI_XPRS_NLPSTOPSTATUS 12089 +#define POI_XPRS_NLPPRESOLVEELIMINATIONS 12090 +#define POI_XPRS_NLPTOTALEVALUATIONERRORS 12093 +#define POI_XPRS_SLPEXPLOREDELTAS 11993 +#define POI_XPRS_SLPSEMICONTDELTAS 11994 +#define POI_XPRS_SLPINTEGERDELTAS 11995 +#define POI_XPRS_SLPITER 12001 +#define POI_XPRS_SLPSTATUS 12002 +#define POI_XPRS_SLPUNCONVERGED 12003 +#define POI_XPRS_SLPSBXCONVERGED 12004 +#define POI_XPRS_SLPPENALTYDELTAROW 12009 +#define POI_XPRS_SLPPENALTYDELTACOLUMN 12010 +#define POI_XPRS_SLPPENALTYERRORROW 12011 +#define POI_XPRS_SLPPENALTYERRORCOLUMN 12012 +#define POI_XPRS_SLPCOEFFICIENTS 12016 +#define POI_XPRS_SLPPENALTYDELTAS 12017 +#define POI_XPRS_SLPPENALTYERRORS 12018 +#define POI_XPRS_SLPPLUSPENALTYERRORS 12019 +#define POI_XPRS_SLPMINUSPENALTYERRORS 12020 +#define POI_XPRS_SLPUCCONSTRAINEDCOUNT 12021 +#define POI_XPRS_SLPMIPNODES 12022 +#define POI_XPRS_SLPMIPITER 12023 +#define POI_XPRS_SLPTOLSETS 12028 +#define POI_XPRS_SLPECFCOUNT 12035 +#define POI_XPRS_SLPDELTAS 12041 +#define POI_XPRS_SLPZEROESRESET 12046 +#define POI_XPRS_SLPZEROESTOTAL 12047 +#define POI_XPRS_SLPZEROESRETAINED 12048 +#define POI_XPRS_SLPNONCONSTANTCOEFFS 12058 +#define POI_XPRS_SLPMIPSOLS 12088 +#define POI_XPRS_NLPVALIDATIONINDEX_K 12718 +#define POI_XPRS_NLPVALIDATIONNETOBJ 12722 +#define POI_XPRS_NLPPRIMALINTEGRAL 12726 +#define POI_XPRS_SLPCURRENTDELTACOST 12701 +#define POI_XPRS_SLPCURRENTERRORCOST 12702 +#define POI_XPRS_SLPPENALTYERRORTOTAL 12704 +#define POI_XPRS_SLPPENALTYERRORVALUE 12705 +#define POI_XPRS_SLPPENALTYDELTATOTAL 12706 +#define POI_XPRS_SLPPENALTYDELTAVALUE 12707 + +#define POI_XPRS_TOK_EOF 0 +#define POI_XPRS_TOK_CON 1 +#define POI_XPRS_TOK_COL 10 +#define POI_XPRS_TOK_FUN 11 +#define POI_XPRS_TOK_IFUN 12 +#define POI_XPRS_TOK_LB 21 +#define POI_XPRS_TOK_RB 22 +#define POI_XPRS_TOK_DEL 24 +#define POI_XPRS_TOK_OP 31 +#define POI_XPRS_OP_UMINUS 1 +#define POI_XPRS_OP_EXPONENT 2 +#define POI_XPRS_OP_MULTIPLY 3 +#define POI_XPRS_OP_DIVIDE 4 +#define POI_XPRS_OP_PLUS 5 +#define POI_XPRS_OP_MINUS 6 +#define POI_XPRS_DEL_COMMA 1 +#define POI_XPRS_DEL_COLON 2 +#define POI_XPRS_IFUN_LOG10 14 +#define POI_XPRS_IFUN_LN 15 +#define POI_XPRS_IFUN_EXP 16 +#define POI_XPRS_IFUN_ABS 17 +#define POI_XPRS_IFUN_SQRT 18 +#define POI_XPRS_IFUN_SIN 27 +#define POI_XPRS_IFUN_COS 28 +#define POI_XPRS_IFUN_TAN 29 +#define POI_XPRS_IFUN_ARCSIN 30 +#define POI_XPRS_IFUN_ARCCOS 31 +#define POI_XPRS_IFUN_ARCTAN 32 +#define POI_XPRS_IFUN_MIN 33 +#define POI_XPRS_IFUN_MAX 34 +#define POI_XPRS_IFUN_PWL 35 +#define POI_XPRS_IFUN_SUM 36 +#define POI_XPRS_IFUN_PROD 37 +#define POI_XPRS_IFUN_SIGN 46 +#define POI_XPRS_IFUN_ERF 49 +#define POI_XPRS_IFUN_ERFC 50 +#define POI_XPRS_SLPTOLSET_TC 0 +#define POI_XPRS_SLPTOLSET_TA 1 +#define POI_XPRS_SLPTOLSET_RA 2 +#define POI_XPRS_SLPTOLSET_TM 3 +#define POI_XPRS_SLPTOLSET_RM 4 +#define POI_XPRS_SLPTOLSET_TI 5 +#define POI_XPRS_SLPTOLSET_RI 6 +#define POI_XPRS_SLPTOLSET_TS 7 +#define POI_XPRS_SLPTOLSET_RS 8 +#define POI_XPRS_SLPTOLSETBIT_TC 0x001 +#define POI_XPRS_SLPTOLSETBIT_TA 0x002 +#define POI_XPRS_SLPTOLSETBIT_RA 0x004 +#define POI_XPRS_SLPTOLSETBIT_TM 0x008 +#define POI_XPRS_SLPTOLSETBIT_RM 0x010 +#define POI_XPRS_SLPTOLSETBIT_TI 0x020 +#define POI_XPRS_SLPTOLSETBIT_RI 0x040 +#define POI_XPRS_SLPTOLSETBIT_TS 0x080 +#define POI_XPRS_SLPTOLSETBIT_RS 0x100 +#define POI_XPRS_SLPTOLSET_DELETE 0x10000 +#define POI_XPRS_SLPCONVERGEBIT_CTOL 0x1 +#define POI_XPRS_SLPCONVERGEBIT_ATOL 0x2 +#define POI_XPRS_SLPCONVERGEBIT_MTOL 0x4 +#define POI_XPRS_SLPCONVERGEBIT_ITOL 0x8 +#define POI_XPRS_SLPCONVERGEBIT_STOL 0x10 +#define POI_XPRS_SLPCONVERGEBIT_USER 0x20 +#define POI_XPRS_SLPCONVERGEBIT_VTOL 0x40 +#define POI_XPRS_SLPCONVERGEBIT_XTOL 0x80 +#define POI_XPRS_SLPCONVERGEBIT_OTOL 0x100 +#define POI_XPRS_SLPCONVERGEBIT_WTOL 0x200 +#define POI_XPRS_SLPCONVERGEBIT_EXTENDEDSCALING 0x400 +#define POI_XPRS_SLPCONVERGEBIT_VALIDATION 0x800 +#define POI_XPRS_SLPCONVERGEBIT_VALIDATION_K 0x1000 +#define POI_XPRS_SLPCONVERGEBIT_NOQUADCHECK 0x2000 +#define POI_XPRS_SLPCONVERGEBIT_REQUIRE_OTOL_R 0x8000 +#define POI_XPRS_SLPHASNOCOEFS 0x01 +#define POI_XPRS_SLPHASDELTA 0x02 +#define POI_XPRS_SLPHASIV 0x04 +#define POI_XPRS_SLPHASCALCIV 0x08 +#define POI_XPRS_SLPISDELTA 0x0100 +#define POI_XPRS_SLPISPLUSPENALTYDELTA 0x0200 +#define POI_XPRS_SLPISMINUSPENALTYDELTA 0x0400 +#define POI_XPRS_SLPISPENALTYDELTA 0x0600 +#define POI_XPRS_SLPISPLUSERRORVECTOR 0x0800 +#define POI_XPRS_SLPISMINUSERRORVECTOR 0x1000 +#define POI_XPRS_SLPISERRORVECTOR 0x1800 +#define POI_XPRS_SLPISMISCVECTOR 0x2000 +#define POI_XPRS_SLPISEQUALSCOLUMN 0x4000 +#define POI_XPRS_NLPPRESOLVEPROTECT 0x8000 +#define POI_XPRS_SLPHASCONVERGED 0x10000 +#define POI_XPRS_SLPACTIVESTEPBOUND 0x20000 +#define POI_XPRS_SLPACTIVESBROW 0x40000 +#define POI_XPRS_SLPELIMINATEDCOL 0x80000 +#define POI_XPRS_SLPISSTRUCTURALCOLUMN 0x200000 +#define POI_XPRS_SLPISINCOEFS 0x400000 +#define POI_XPRS_SLPISINGLOBAL 0x800000 +#define POI_XPRS_SLPHASZEROBOUND 0x1000000 +#define POI_XPRS_SLPFIXEDVAR 0x2000000 +#define POI_XPRS_SLPBOUNDSSET 0x4000000 +#define POI_XPRS_SLPUSEFULDELTA 0x8000000 +#define POI_XPRS_SLPNOUSEFULDELTA 0x8000000 +#define POI_XPRS_SLPISINTEGER 0x10000000 +#define POI_XPRS_SLPCASCADECONTRACTION 0x20000000 +#define POI_XPRS_SLPISUPDATEROW 0x02 +#define POI_XPRS_SLPISPENALTYROW 0x04 +#define POI_XPRS_SLPISMISCROW 0x40 +#define POI_XPRS_SLPISSBROW 0x80 +#define POI_XPRS_SLPHASPLUSERROR 0x100 +#define POI_XPRS_SLPHASMINUSERROR 0x200 +#define POI_XPRS_SLPHASERROR 0x300 +#define POI_XPRS_SLPISDETERMININGROW 0x400 +#define POI_XPRS_SLPNOERRORVECTORS 0x800 +#define POI_XPRS_SLPHASNONZEROCOEF 0x1000 +#define POI_XPRS_SLPREDUNDANTROW 0x2000 +#define POI_XPRS_SLPUNCONVERGEDROW 0x4000 +#define POI_XPRS_SLPACTIVEPENALTY 0x8000 +#define POI_XPRS_SLPHASSLPELEMENT 0x10000 +#define POI_XPRS_SLPTRANSFERROW 0x40000 +#define POI_XPRS_SLPMINIMUMAUGMENTATION 0x01 +#define POI_XPRS_SLPEVENHANDEDAUGMENTATION 0x02 +#define POI_XPRS_SLPEQUALITYERRORVECTORS 0x04 +#define POI_XPRS_SLPALLERRORVECTORS 0x08 +#define POI_XPRS_SLPPENALTYDELTAVECTORS 0x10 +#define POI_XPRS_SLPAMEANWEIGHT 0x20 +#define POI_XPRS_SLPSBFROMVALUES 0x40 +#define POI_XPRS_SLPSBFROMABSVALUES 0x80 +#define POI_XPRS_SLPSTEPBOUNDROWS 0x100 +#define POI_XPRS_SLPALLROWERRORVECTORS 0x200 +#define POI_XPRS_SLPNOUPDATEIFONLYIV 0x400 +#define POI_XPRS_SLPSKIPIVLPHEURISTICS 0x1000 +#define POI_XPRS_SLPNOSTEPBOUNDS 0x01 +#define POI_XPRS_SLPSTEPBOUNDSASREQUIRED 0x02 +#define POI_XPRS_SLPESTIMATESTEPBOUNDS 0x04 +#define POI_XPRS_SLPDYNAMICDAMPING 0x08 +#define POI_XPRS_SLPHOLDVALUES 0x10 +#define POI_XPRS_SLPRETAINPREVIOUSVALUE 0x20 +#define POI_XPRS_SLPRESETDELTAZ 0x40 +#define POI_XPRS_SLPQUICKCONVERGENCECHECK 0x80 +#define POI_XPRS_SLPESCALATEPENALTIES 0x100 +#define POI_XPRS_SLPSWITCHTOPRIMAL 0x200 +#define POI_XPRS_SLPNONZEROBOUND 0x400 +#define POI_XPRS_SLPMAXCOSTOPTION 0x800 +#define POI_XPRS_SLPRESIDUALERRORS 0x1000 +#define POI_XPRS_SLPNOLPPOLISHING 0x2000 +#define POI_XPRS_SLPCASCADEDBOUNDS 0x4000 +#define POI_XPRS_SLPCLAMPEXTENDEDACTIVESB 0x8000 +#define POI_XPRS_SLPCLAMPEXTENDEDALL 0x10000 +#define POI_XPRS_SLPMIPINITIALSLP 0x01 +#define POI_XPRS_SLPMIPINITIALRELAXSLP 0x04 +#define POI_XPRS_SLPMIPINITIALFIXSLP 0x08 +#define POI_XPRS_SLPMIPNODERELAXSLP 0x10 +#define POI_XPRS_SLPMIPNODEFIXSLP 0x20 +#define POI_XPRS_SLPMIPNODELIMITSLP 0x40 +#define POI_XPRS_SLPMIPFINALRELAXSLP 0x80 +#define POI_XPRS_SLPMIPFINALFIXSLP 0x100 +#define POI_XPRS_SLPMIPWITHINSLP 0x200 +#define POI_XPRS_SLPSLPTHENMIP 0x400 +#define POI_XPRS_SLPROOTMIPDRIVEN 0x1000 +#define POI_XPRS_SLPSTATUS_CONVERGEDOBJUCC 0x01 +#define POI_XPRS_SLPSTATUS_CONVERGEDOBJSBX 0x02 +#define POI_XPRS_SLPSTATUS_LPINFEASIBLE 0x04 +#define POI_XPRS_SLPSTATUS_LPUNFINISHED 0x08 +#define POI_XPRS_SLPSTATUS_MAXSLPITERATIONS 0x10 +#define POI_XPRS_SLPSTATUS_INTEGERINFEASIBLE 0x20 +#define POI_XPRS_SLPSTATUS_RESIDUALPENALTIES 0x40 +#define POI_XPRS_SLPSTATUS_CONVERGEDOBJOBJ 0x80 +#define POI_XPRS_SLPSTATUS_MAXTIME 0x200 +#define POI_XPRS_SLPSTATUS_USER 0x400 +#define POI_XPRS_SLPSTATUS_VARSLINKEDINACTIVE 0x800 +#define POI_XPRS_SLPSTATUS_NOVARSINACTIVE 0x1000 +#define POI_XPRS_SLPSTATUS_OTOL 0x2000 +#define POI_XPRS_SLPSTATUS_VTOL 0x4000 +#define POI_XPRS_SLPSTATUS_XTOL 0x8000 +#define POI_XPRS_SLPSTATUS_WTOL 0x10000 +#define POI_XPRS_SLPSTATUS_ERROTOL 0x20000 +#define POI_XPRS_SLPSTATUS_EVTOL 0x40000 +#define POI_XPRS_SLPSTATUS_POLISHED 0x80000 +#define POI_XPRS_SLPSTATUS_POLISH_FAILURE 0x100000 +#define POI_XPRS_SLPSTATUS_ENFORCED 0x200000 +#define POI_XPRS_SLPSTATUS_CONSECUTIVE_INFEAS 0x400000 +#define POI_XPRS_SLPSTATUS_KEEPBEST 0x800000 +#define POI_XPRS_SLPSTATUS_CLAMPING 0x1000000 +#define POI_XPRS_SLPSTATUS_ADAPTIVEITERS 0x2000000 +#define POI_XPRS_SLPSTATUS_OBJQNONCONVEX 0x4000000 +#define POI_XPRS_NLPSTATUS_UNSTARTED 0 +#define POI_XPRS_NLPSTATUS_SOLUTION 1 +#define POI_XPRS_NLPSTATUS_LOCALLY_OPTIMAL 1 +#define POI_XPRS_NLPSTATUS_OPTIMAL 2 +#define POI_XPRS_NLPSTATUS_NOSOLUTION 3 +#define POI_XPRS_NLPSTATUS_LOCALLY_INFEASIBLE 3 +#define POI_XPRS_NLPSTATUS_INFEASIBLE 4 +#define POI_XPRS_NLPSTATUS_UNBOUNDED 5 +#define POI_XPRS_NLPSTATUS_UNFINISHED 6 +#define POI_XPRS_NLPSTATUS_UNSOLVED 7 +#define POI_XPRS_NLPSOLSTATUS_NONE 0 +#define POI_XPRS_NLPSOLSTATUS_SOLUTION_NODUALS 1 +#define POI_XPRS_NLPSOLSTATUS_LOCALLYOPTIMAL_WITHDUALS 2 +#define POI_XPRS_NLPSOLSTATUS_GLOBALLYOPTIMAL_NODUALS 3 +#define POI_XPRS_NLPSOLSTATUS_GLOBALLYOPTIMAL_WITHDUALS 4 +#define POI_XPRS_SLPGRIDENUMERATE 1 +#define POI_XPRS_SLPGRIDCYCLIC 2 +#define POI_XPRS_SLPGRIDANNEALING 4 +#define POI_XPRS_NLPRECALC 0x08 +#define POI_XPRS_NLPTOLCALC 0x10 +#define POI_XPRS_NLPALLCALCS 0x20 +#define POI_XPRS_NLP2DERIVATIVE 0x40 +#define POI_XPRS_NLP1DERIVATIVE 0x80 +#define POI_XPRS_NLPALLDERIVATIVES 0x100 +#define POI_XPRS_NLPINSTANCEFUNCTION 0x200 +#define POI_XPRS_NLPPRESOLVEOPS_GENERAL 0x01 +#define POI_XPRS_NLPPRESOLVEFIXZERO 0x02 +#define POI_XPRS_NLPPRESOLVEFIXALL 0x04 +#define POI_XPRS_NLPPRESOLVESETBOUNDS 0x08 +#define POI_XPRS_NLPPRESOLVEINTBOUNDS 0x10 +#define POI_XPRS_NLPPRESOLVEDOMAIN 0x20 +#define POI_XPRS_SLPNOPRESOLVECOEFFICIENTS 0x100 +#define POI_XPRS_SLPNOPRESOLVEDELTAS 0x200 +#define POI_XPRS_NLPPRESOLVEOPS_NO_DUAL_SIDE 0x400 +#define POI_XPRS_NLPPRESOLVEOPS_ELIMINATIONS 0x800 +#define POI_XPRS_NLPPRESOLVEOPS_NOLINEAR 0x1000 +#define POI_XPRS_NLPPRESOLVEOPS_NOSIMPLIFIER 0x2000 +#define POI_XPRS_NLPPRESOLVELEVEL_LOCALIZED 1 +#define POI_XPRS_NLPPRESOLVELEVEL_BASIC 2 +#define POI_XPRS_NLPPRESOLVELEVEL_LINEAR 3 +#define POI_XPRS_NLPPRESOLVELEVEL_FULL 4 +#define POI_XPRS_SLPCASCADE_ALL 0x01 +#define POI_XPRS_SLPCASCADE_COEF_VAR 0x02 +#define POI_XPRS_SLPCASCADE_ALL_COEF_VAR 0x04 +#define POI_XPRS_SLPCASCADE_STRUCT_VAR 0x08 +#define POI_XPRS_SLPCASCADE_ALL_STRUCT_VAR 0x10 +#define POI_XPRS_SLPCASCADE_SECONDARY_GROUPS 0x20 +#define POI_XPRS_SLPCASCADE_DRCOL_PREVOUSVALUE 0x40 +#define POI_XPRS_SLPCASCADE_DRCOL_PVRANGE 0x80 +#define POI_XPRS_SLPCASCADE_AUTOAPPLY 0x100 +#define POI_XPRS_LOCALSOLVER_AUTO -1 +#define POI_XPRS_LOCALSOLVER_XSLP 0 +#define POI_XPRS_LOCALSOLVER_KNITRO 1 +#define POI_XPRS_LOCALSOLVER_OPTIMIZER 2 +#define POI_XPRS_MSSET_INITIALVALUES 0 +#define POI_XPRS_MSSET_SOLVERS 1 +#define POI_XPRS_MSSET_SLP_BASIC 2 +#define POI_XPRS_MSSET_SLP_EXTENDED 3 +#define POI_XPRS_MSSET_KNITRO_BASIC 4 +#define POI_XPRS_MSSET_KNITRO_EXTENDED 5 +#define POI_XPRS_MSSET_INITIALFILTERED 6 +#define POI_XPRS_KKT_CALCULATION_RECALCULATE_RDJ 0 +#define POI_XPRS_KKT_CALCULATION_MINIMZE_KKT_ERROR 1 +#define POI_XPRS_KKT_CALCULATION_MEASURE_BOTH 2 +#define POI_XPRS_KKT_CALCULATION_ACTIVITY_BASED 0 +#define POI_XPRS_KKT_CALCULATION_RESPECT_BASIS 1 +#define POI_XPRS_KKT_CALCULATION_ACTIVITY_BOTH 2 +#define POI_XPRS_KKT_JUST_CALCULATE 0 +#define POI_XPRS_KKT_UPDATE_MULTIPLIERS 1 +#define POI_XPRS_SLPTRACEMASK_GENERALFIT 0x1 +#define POI_XPRS_SLPTRACEMASK_ROWS 0x2 +#define POI_XPRS_SLPTRACEMASK_COLS 0x4 +#define POI_XPRS_SLPTRACEMASK_CASCADE 0x8 +#define POI_XPRS_SLPTRACEMASK_TYPE 0x10 +#define POI_XPRS_SLPTRACEMASK_SLACK 0x20 +#define POI_XPRS_SLPTRACEMASK_DUAL 0x40 +#define POI_XPRS_SLPTRACEMASK_WEIGHT 0x80 +#define POI_XPRS_SLPTRACEMASK_SOLUTION 0x100 +#define POI_XPRS_SLPTRACEMASK_REDUCEDCOST 0x200 +#define POI_XPRS_SLPTRACEMASK_SLPVALUE 0x400 +#define POI_XPRS_SLPTRACEMASK_STEPBOUND 0x800 +#define POI_XPRS_SLPTRACEMASK_CONVERGE 0x1000 +#define POI_XPRS_SLPTRACEMASK_LINESEARCH 0x2000 +#define POI_XPRS_SLPFILTER_KEEPBEST 0x1 +#define POI_XPRS_SLPFILTER_CASCADE 0x2 +#define POI_XPRS_SLPFILTER_ZEROLINESEARCH 0x4 +#define POI_XPRS_SLPFILTER_ZEROLINESEARCHTR 0x8 +#define POI_XPRS_SLPANALYZE_RECORDLINEARIZATION 0x1 +#define POI_XPRS_SLPANALYZE_RECORDCASCADE 0x2 +#define POI_XPRS_SLPANALYZE_RECORDLINESEARCH 0x4 +#define POI_XPRS_SLPANALYZE_EXTENDEDFINALSUMMARY 0x8 +#define POI_XPRS_SLPANALYZE_INFEASIBLE_ITERATION 0x10 +#define POI_XPRS_SLPANALYZE_AUTOSAVEPOOL 0x20 +#define POI_XPRS_SLPANALYZE_SAVELINEARIZATIONS 0x40 +#define POI_XPRS_SLPANALYZE_SAVEITERBASIS 0x80 +#define POI_XPRS_SLPANALYZE_SAVEFILE 0x100 +#define POI_XPRS_NLPREFORMULATE_SLP2QP 0x1 +#define POI_XPRS_NLPREFORMULATE_QP2SLP 0x2 +#define POI_XPRS_NLPREFORMULATE_SLP2QCQP 0x4 +#define POI_XPRS_NLPREFORMULATE_QCQP2SLP 0x8 +#define POI_XPRS_NLPREFORMULATE_SOCP2SLP 0x10 +#define POI_XPRS_NLPREFORMULATE_QPSOLVE 0x20 +#define POI_XPRS_NLPREFORMULATE_PWL 0x40 +#define POI_XPRS_NLPREFORMULATE_ABS 0x80 +#define POI_XPRS_NLPREFORMULATE_MINMAX 0x100 +#define POI_XPRS_NLPREFORMULATE_ALLABS 0x200 +#define POI_XPRS_NLPREFORMULATE_ALLMINMAX 0x400 +#define POI_XPRS_SLPDELTA_CONT 0 +#define POI_XPRS_SLPDELTA_SEMICONT 1 +#define POI_XPRS_SLPDELTA_INTEGER 2 +#define POI_XPRS_SLPDELTA_EXPLORE 3 +#define POI_XPRS_SLPROWINFO_SLACK 1 +#define POI_XPRS_SLPROWINFO_DUAL 2 +#define POI_XPRS_SLPROWINFO_NUMPENALTYERRORS 3 +#define POI_XPRS_SLPROWINFO_MAXPENALTYERROR 4 +#define POI_XPRS_SLPROWINFO_TOTALPENALTYERROR 5 +#define POI_XPRS_SLPROWINFO_CURRENTPENALTYERROR 6 +#define POI_XPRS_SLPROWINFO_CURRENTPENALTYFACTOR 7 +#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNPLUS 8 +#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNPLUSVALUE 9 +#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNPLUSDJ 10 +#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNMINUS 11 +#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNMINUSVALUE 12 +#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNMINUSDJ 13 +#define POI_XPRS_SLPCOLINFO_VALUE 1 +#define POI_XPRS_SLPCOLINFO_RDJ 2 +#define POI_XPRS_SLPCOLINFO_DELTAINDEX 3 +#define POI_XPRS_SLPCOLINFO_DELTA 4 +#define POI_XPRS_SLPCOLINFO_DELTADJ 5 +#define POI_XPRS_SLPCOLINFO_UPDATEROW 6 +#define POI_XPRS_SLPCOLINFO_SB 7 +#define POI_XPRS_SLPCOLINFO_SBDUAL 8 +#define POI_XPRS_SLPCOLINFO_LPVALUE 9 +#define POI_XPRS_SLPCOLINFO_DETROW 10 +#define POI_XPRS_SLPCOLINFO_CONVERGENCESTATUS 11 +#define POI_XPRS_USERFUNCTION_MAP 1 +#define POI_XPRS_USERFUNCTION_VECMAP 2 +#define POI_XPRS_USERFUNCTION_MULTIMAP 3 +#define POI_XPRS_USERFUNCTION_MAPDELTA 4 +#define POI_XPRS_USERFUNCTION_VECMAPDELTA 5 +#define POI_XPRS_USERFUNCTION_MULTIMAPDELTA 6 +#define POI_XPRS_NLPUSERFUNCNAMES 7 +#define POI_XPRS_NLPINTERNALFUNCNAMES 8 +#define POI_XPRS_NLPUSERFUNCNAMESNOCASE 9 +#define POI_XPRS_NLPINTERNALFUNCNAMESNOCASE 10 +#define POI_XPRS_NLPFORMULACOEFFCOLUMNINDEX -1000 +#define POI_XPRS_NLPOBJECTIVEROWINDEX -1 +#define POI_XPRS_NLPSOLVER_AUTOMATIC -1 +#define POI_XPRS_NLPSOLVER_LOCAL 1 +#define POI_XPRS_NLPSOLVER_GLOBAL 2 + +#define POI_XPRS_SOLSTATUS_NOTFOUND 0 +#define POI_XPRS_SOLSTATUS_OPTIMAL 1 +#define POI_XPRS_SOLSTATUS_FEASIBLE 2 +#define POI_XPRS_SOLSTATUS_INFEASIBLE 3 +#define POI_XPRS_SOLSTATUS_UNBOUNDED 4 + +#define POI_XPRS_SOLVESTATUS_UNSTARTED 0 +#define POI_XPRS_SOLVESTATUS_STOPPED 1 +#define POI_XPRS_SOLVESTATUS_FAILED 2 +#define POI_XPRS_SOLVESTATUS_COMPLETED 3 + +#define POI_XPRS_LP_UNSTARTED 0 +#define POI_XPRS_LP_OPTIMAL 1 +#define POI_XPRS_LP_INFEAS 2 +#define POI_XPRS_LP_CUTOFF 3 +#define POI_XPRS_LP_UNFINISHED 4 +#define POI_XPRS_LP_UNBOUNDED 5 +#define POI_XPRS_LP_CUTOFF_IN_DUAL 6 +#define POI_XPRS_LP_UNSOLVED 7 +#define POI_XPRS_LP_NONCONVEX 8 + +#define POI_XPRS_MIP_NOT_LOADED 0 +#define POI_XPRS_MIP_LP_NOT_OPTIMAL 1 +#define POI_XPRS_MIP_LP_OPTIMAL 2 +#define POI_XPRS_MIP_NO_SOL_FOUND 3 +#define POI_XPRS_MIP_SOLUTION 4 +#define POI_XPRS_MIP_INFEAS 5 +#define POI_XPRS_MIP_OPTIMAL 6 +#define POI_XPRS_MIP_UNBOUNDED 7 + +#define POI_XPRS_IIS_UNSTARTED 0 +#define POI_XPRS_IIS_FEASIBLE 1 +#define POI_XPRS_IIS_COMPLETED 2 +#define POI_XPRS_IIS_UNFINISHED 3 + +#define POI_XPRS_SOLAVAILABLE_NOTFOUND 0 +#define POI_XPRS_SOLAVAILABLE_OPTIMAL 1 +#define POI_XPRS_SOLAVAILABLE_FEASIBLE 2 + +#define POI_XPRS_OPTIMIZETYPE_NONE -1 +#define POI_XPRS_OPTIMIZETYPE_LP 0 +#define POI_XPRS_OPTIMIZETYPE_MIP 1 +#define POI_XPRS_OPTIMIZETYPE_LOCAL 2 +#define POI_XPRS_OPTIMIZETYPE_GLOBAL 3 + +#define POI_XPRS_TYPE_NOTDEFINED 0 +#define POI_XPRS_TYPE_INT 1 +#define POI_XPRS_TYPE_INT64 2 +#define POI_XPRS_TYPE_DOUBLE 3 +#define POI_XPRS_TYPE_STRING 4 + +#define POI_XPRS_NAMES_ROW 1 +#define POI_XPRS_NAMES_COLUMN 2 +#define POI_XPRS_NAMES_SET 3 +#define POI_XPRS_NAMES_PWLCONS 4 +#define POI_XPRS_NAMES_GENCONS 5 +#define POI_XPRS_NAMES_OBJECTIVE 6 +#define POI_XPRS_NAMES_USERFUNC 7 +#define POI_XPRS_NAMES_INTERNALFUNC 8 +#define POI_XPRS_NAMES_USERFUNCNOCASE 9 +#define POI_XPRS_NAMES_INTERNALFUNCNOCASE 10 + +#define POI_XPRS_BASISSTATUS_NONBASIC_LOWER 0 +#define POI_XPRS_BASISSTATUS_BASIC 1 +#define POI_XPRS_BASISSTATUS_NONBASIC_UPPER 2 +#define POI_XPRS_BASISSTATUS_SUPERBASIC 3 + +#define POI_XPRS_STOP_NONE 0 +#define POI_XPRS_STOP_TIMELIMIT 1 +#define POI_XPRS_STOP_CTRLC 2 +#define POI_XPRS_STOP_NODELIMIT 3 +#define POI_XPRS_STOP_ITERLIMIT 4 +#define POI_XPRS_STOP_MIPGAP 5 +#define POI_XPRS_STOP_SOLLIMIT 6 +#define POI_XPRS_STOP_GENERICERROR 7 +#define POI_XPRS_STOP_MEMORYERROR 8 +#define POI_XPRS_STOP_USER 9 +#define POI_XPRS_STOP_SOLVECOMPLETE 10 +#define POI_XPRS_STOP_LICENSELOST 11 +#define POI_XPRS_STOP_NUMERICALERROR 13 +#define POI_XPRS_STOP_WORKLIMIT 14 +#define POI_XPRS_STOP_NEXTOBJECTIVE 15 + +#define POI_XPRS_OBJ_MINIMIZE 1 +#define POI_XPRS_OBJ_MAXIMIZE -1 + +#define POI_XPRS_KNITRO_PARAM_NEWPOINT 101001 +#define POI_XPRS_KNITRO_PARAM_HONORBNDS 101002 +#define POI_XPRS_KNITRO_PARAM_ALGORITHM 101003 +#define POI_XPRS_KNITRO_PARAM_BAR_MURULE 101004 +#define POI_XPRS_KNITRO_PARAM_BAR_FEASIBLE 101006 +#define POI_XPRS_KNITRO_PARAM_GRADOPT 101007 +#define POI_XPRS_KNITRO_PARAM_HESSOPT 101008 +#define POI_XPRS_KNITRO_PARAM_BAR_INITPT 101009 +#define POI_XPRS_KNITRO_PARAM_MAXCGIT 101013 +#define POI_XPRS_KNITRO_PARAM_MAXIT 101014 +#define POI_XPRS_KNITRO_PARAM_OUTLEV 101015 +#define POI_XPRS_KNITRO_PARAM_SCALE 101017 +#define POI_XPRS_KNITRO_PARAM_SOC 101019 +#define POI_XPRS_KNITRO_PARAM_DELTA 101020 +#define POI_XPRS_KNITRO_PARAM_BAR_FEASMODETOL 101021 +#define POI_XPRS_KNITRO_PARAM_FEASTOL 101022 +#define POI_XPRS_KNITRO_PARAM_FEASTOLABS 101023 +#define POI_XPRS_KNITRO_PARAM_BAR_INITMU 101025 +#define POI_XPRS_KNITRO_PARAM_OBJRANGE 101026 +#define POI_XPRS_KNITRO_PARAM_OPTTOL 101027 +#define POI_XPRS_KNITRO_PARAM_OPTTOLABS 101028 +#define POI_XPRS_KNITRO_PARAM_PIVOT 101029 +#define POI_XPRS_KNITRO_PARAM_XTOL 101030 +#define POI_XPRS_KNITRO_PARAM_DEBUG 101031 +#define POI_XPRS_KNITRO_PARAM_MULTISTART 101033 +#define POI_XPRS_KNITRO_PARAM_MSMAXSOLVES 101034 +#define POI_XPRS_KNITRO_PARAM_MSMAXBNDRANGE 101035 +#define POI_XPRS_KNITRO_PARAM_LMSIZE 101038 +#define POI_XPRS_KNITRO_PARAM_BAR_MAXCROSSIT 101039 +#define POI_XPRS_KNITRO_PARAM_BLASOPTION 101042 +#define POI_XPRS_KNITRO_PARAM_BAR_MAXREFACTOR 101043 +#define POI_XPRS_KNITRO_PARAM_BAR_MAXBACKTRACK 101044 +#define POI_XPRS_KNITRO_PARAM_BAR_PENRULE 101049 +#define POI_XPRS_KNITRO_PARAM_BAR_PENCONS 101050 +#define POI_XPRS_KNITRO_PARAM_MSNUMTOSAVE 101051 +#define POI_XPRS_KNITRO_PARAM_MSSAVETOL 101052 +#define POI_XPRS_KNITRO_PARAM_MSTERMINATE 101054 +#define POI_XPRS_KNITRO_PARAM_MSSTARTPTRANGE 101055 +#define POI_XPRS_KNITRO_PARAM_INFEASTOL 101056 +#define POI_XPRS_KNITRO_PARAM_LINSOLVER 101057 +#define POI_XPRS_KNITRO_PARAM_BAR_DIRECTINTERVAL 101058 +#define POI_XPRS_KNITRO_PARAM_PRESOLVE 101059 +#define POI_XPRS_KNITRO_PARAM_PRESOLVE_TOL 101060 +#define POI_XPRS_KNITRO_PARAM_BAR_SWITCHRULE 101061 +#define POI_XPRS_KNITRO_PARAM_MA_TERMINATE 101063 +#define POI_XPRS_KNITRO_PARAM_MSSEED 101066 +#define POI_XPRS_KNITRO_PARAM_BAR_RELAXCONS 101077 +#define POI_XPRS_KNITRO_PARAM_SOLTYPE 101161 +#define POI_XPRS_KNITRO_PARAM_MIP_METHOD 102001 +#define POI_XPRS_KNITRO_PARAM_MIP_BRANCHRULE 102002 +#define POI_XPRS_KNITRO_PARAM_MIP_SELECTRULE 102003 +#define POI_XPRS_KNITRO_PARAM_MIP_INTGAPABS 102004 +#define POI_XPRS_KNITRO_PARAM_MIP_INTGAPREL 102005 +#define POI_XPRS_KNITRO_PARAM_MIP_OUTLEVEL 102010 +#define POI_XPRS_KNITRO_PARAM_MIP_OUTINTERVAL 102011 +#define POI_XPRS_KNITRO_PARAM_MIP_DEBUG 102013 +#define POI_XPRS_KNITRO_PARAM_MIP_IMPLICATNS 102014 +#define POI_XPRS_KNITRO_PARAM_MIP_GUB_BRANCH 102015 +#define POI_XPRS_KNITRO_PARAM_MIP_KNAPSACK 102016 +#define POI_XPRS_KNITRO_PARAM_MIP_ROUNDING 102017 +#define POI_XPRS_KNITRO_PARAM_MIP_ROOTALG 102018 +#define POI_XPRS_KNITRO_PARAM_MIP_LPALG 102019 +#define POI_XPRS_KNITRO_PARAM_MIP_MAXNODES 102021 +#define POI_XPRS_KNITRO_PARAM_MIP_HEURISTIC 102022 +#define POI_XPRS_KNITRO_PARAM_MIP_HEUR_MAXIT 102023 +#define POI_XPRS_KNITRO_PARAM_MIP_PSEUDOINIT 102026 +#define POI_XPRS_KNITRO_PARAM_MIP_STRONG_MAXIT 102027 +#define POI_XPRS_KNITRO_PARAM_MIP_STRONG_CANDLIM 102028 +#define POI_XPRS_KNITRO_PARAM_MIP_STRONG_LEVEL 102029 +#define POI_XPRS_KNITRO_PARAM_PAR_NUMTHREADS 103001 + + typedef struct xo_prob_struct *XPRSprob; + typedef struct xo_user_branch_entity_s *XPRSbranchobject; + + int XPRSaddcols64(XPRSprob prob, int ncols, XPRSint64 ncoefs, const double objcoef[], + const XPRSint64 start[], const int rowind[], const double rowcoef[], + const double lb[], const double ub[]); + int XPRSaddcuts64(XPRSprob prob, int ncuts, const int cuttype[], const char rowtype[], + const double rhs[], const XPRSint64 start[], const int colind[], + const double cutcoef[]); + int XPRSaddmanagedcuts64(XPRSprob prob, int globalvalid, int ncuts, const char rowtype[], + const double rhs[], const XPRSint64 start[], const int colind[], + const double cutcoef[]); + int XPRSaddmipsol(XPRSprob prob, int length, const double solval[], const int colind[], + const char *name); + int XPRSaddnames(XPRSprob prob, int type, const char names[], int first, int last); + int XPRSaddqmatrix64(XPRSprob prob, int row, XPRSint64 ncoefs, const int rowqcol1[], + const int rowqcol2[], const double rowqcoef[]); + int XPRSaddrows64(XPRSprob prob, int nrows, XPRSint64 ncoefs, const char rowtype[], + const double rhs[], const double rng[], const XPRSint64 start[], + const int colind[], const double rowcoef[]); + int XPRSaddsets64(XPRSprob prob, int nsets, XPRSint64 nelems, const char settype[], + const XPRSint64 start[], const int colind[], const double refval[]); + int XPRSbeginlicensing(int *p_notyet); + int XPRSchgbounds(XPRSprob prob, int nbounds, const int colind[], const char bndtype[], + const double bndval[]); + int XPRSchgcoef(XPRSprob prob, int row, int col, double coef); + int XPRSchgcoltype(XPRSprob prob, int ncols, const int colind[], const char coltype[]); + int XPRSchgmqobj64(XPRSprob prob, XPRSint64 ncoefs, const int objqcol1[], const int objqcol2[], + const double objqcoef[]); + int XPRSchgobj(XPRSprob prob, int ncols, const int colind[], const double objcoef[]); + int XPRSchgobjsense(XPRSprob prob, int objsense); + int XPRSchgrhs(XPRSprob prob, int nrows, const int rowind[], const double rhs[]); + int XPRSchgrowtype(XPRSprob prob, int nrows, const int rowind[], const char rowtype[]); + int XPRScreateprob(XPRSprob *p_prob); + int XPRSdelcols(XPRSprob prob, int ncols, const int colind[]); + int XPRSdelobj(XPRSprob prob, int objidx); + int XPRSdelqmatrix(XPRSprob prob, int row); + int XPRSdelrows(XPRSprob prob, int nrows, const int rowind[]); + int XPRSdelsets(XPRSprob prob, int nsets, const int setind[]); + int XPRSdestroyprob(XPRSprob prob); + int XPRSendlicensing(void); + int XPRSfree(void); + int XPRSgetattribinfo(XPRSprob prob, const char *name, int *p_id, int *p_type); + int XPRSgetbasisval(XPRSprob prob, int row, int col, int *p_rowstat, int *p_colstat); + int XPRSgetcallbacksolution(XPRSprob prob, int *p_available, double x[], int first, int last); + int XPRSgetcoef(XPRSprob prob, int row, int col, double *p_coef); + int XPRSgetcoltype(XPRSprob prob, char coltype[], int first, int last); + int XPRSgetcontrolinfo(XPRSprob prob, const char *name, int *p_id, int *p_type); + int XPRSgetdblattrib(XPRSprob prob, int attrib, double *p_value); + int XPRSgetdblcontrol(XPRSprob prob, int control, double *p_value); + int XPRSgetdualray(XPRSprob prob, double ray[], int *p_hasray); + int XPRSgetduals(XPRSprob prob, int *status, double duals[], int first, int last); + int XPRSgetiisdata(XPRSprob prob, int iis, int *p_nrows, int *p_ncols, int rowind[], + int colind[], char contype[], char bndtype[], double duals[], double djs[], + char isolationrows[], char isolationcols[]); + int XPRSgetintattrib64(XPRSprob prob, int attrib, XPRSint64 *p_value); + int XPRSgetintcontrol64(XPRSprob prob, int control, XPRSint64 *p_value); + int XPRSgetlasterror(XPRSprob prob, char *errmsg); + int XPRSgetlb(XPRSprob prob, double lb[], int first, int last); + int XPRSgetlicerrmsg(char *buffer, int maxbytes); + int XPRSgetlpsol(XPRSprob prob, double x[], double slack[], double duals[], double djs[]); + int XPRSgetnamelist(XPRSprob prob, int type, char names[], int maxbytes, int *p_nbytes, + int first, int last); + int XPRSgetobj(XPRSprob prob, double objcoef[], int first, int last); + int XPRSgetprimalray(XPRSprob prob, double ray[], int *p_hasray); + int XPRSgetprobname(XPRSprob prob, char *name); + int XPRSgetredcosts(XPRSprob prob, int *status, double djs[], int first, int last); + int XPRSgetrhs(XPRSprob prob, double rhs[], int first, int last); + int XPRSgetrowtype(XPRSprob prob, char rowtype[], int first, int last); + int XPRSgetslacks(XPRSprob prob, int *status, double slacks[], int first, int last); + int XPRSgetsolution(XPRSprob prob, int *status, double x[], int first, int last); + int XPRSgetstrattrib(XPRSprob prob, int attrib, char *value); + int XPRSgetstrcontrol(XPRSprob prob, int control, char *value); + int XPRSgetstringattrib(XPRSprob prob, int attrib, char *value, int maxbytes, int *p_nbytes); + int XPRSgetstringcontrol(XPRSprob prob, int control, char *value, int maxbytes, int *p_nbytes); + int XPRSgetub(XPRSprob prob, double ub[], int first, int last); + int XPRSgetversion(char *version); + int XPRSgetversionnumbers(int *p_major, int *p_minor, int *p_build); + int XPRSiisall(XPRSprob prob); + int XPRSiisfirst(XPRSprob prob, int mode, int *p_status); + int XPRSinit(const char *path); + int XPRSinterrupt(XPRSprob prob, int reason); + int XPRSlicense(int *p_i, char *p_c); + int XPRSnlpaddformulas(XPRSprob prob, int ncoefs, const int rowind[], const int formulastart[], + int parsed, const int type[], const double value[]); + int XPRSnlploadformulas(XPRSprob prob, int nnlpcoefs, const int rowind[], + const int formulastart[], int parsed, const int type[], + const double value[]); + int XPRSnlppostsolve(XPRSprob prob); + int XPRSoptimize(XPRSprob prob, const char *flags, int *solvestatus, int *solstatus); + int XPRSpostsolve(XPRSprob prob); + int XPRSpresolverow(XPRSprob prob, char rowtype, int norigcoefs, const int origcolind[], + const double origrowcoef[], double origrhs, int maxcoefs, int *p_ncoefs, + int colind[], double rowcoef[], double *p_rhs, int *p_status); + int XPRSsaveas(XPRSprob prob, const char *filename); + int XPRSsetdblcontrol(XPRSprob prob, int control, double value); + int XPRSsetintcontrol(XPRSprob prob, int control, int value); + int XPRSsetintcontrol64(XPRSprob prob, int control, XPRSint64 value); + int XPRSsetlogfile(XPRSprob prob, const char *filename); + int XPRSsetprobname(XPRSprob prob, const char *probname); + int XPRSsetstrcontrol(XPRSprob prob, int control, const char *value); + int XPRSwritebasis(XPRSprob prob, const char *filename, const char *flags); + int XPRSwritebinsol(XPRSprob prob, const char *filename, const char *flags); + int XPRSwriteprob(XPRSprob prob, const char *filename, const char *flags); + int XPRSwriteprtsol(XPRSprob prob, const char *filename, const char *flags); + int XPRSwriteslxsol(XPRSprob prob, const char *filename, const char *flags); + int XPRSwritesol(XPRSprob prob, const char *filename, const char *flags); + int XPRSaddcbbariteration(XPRSprob prob, + void (*bariteration)(XPRSprob cbprob, void *cbdata, int *p_action), + void *data, int priority); + int XPRSaddcbbarlog(XPRSprob prob, int (*barlog)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcbafterobjective(XPRSprob prob, + void (*afterobjective)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcbbeforeobjective(XPRSprob prob, + void (*beforeobjective)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcbpresolve(XPRSprob prob, void (*presolve)(XPRSprob cbprob, void *cbdata), + void *data, int priority); + int XPRSaddcbchecktime(XPRSprob prob, int (*checktime)(XPRSprob cbprob, void *cbdata), + void *data, int priority); + int XPRSaddcbchgbranchobject(XPRSprob prob, + void (*chgbranchobject)(XPRSprob cbprob, void *cbdata, + XPRSbranchobject branch, + XPRSbranchobject *p_newbranch), + void *data, int priority); + int XPRSaddcbcutlog(XPRSprob prob, int (*cutlog)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcbcutround(XPRSprob prob, + void (*cutround)(XPRSprob cbprob, void *cbdata, int ifxpresscuts, + int *p_action), + void *data, int priority); + int XPRSaddcbdestroymt(XPRSprob prob, void (*destroymt)(XPRSprob cbprob, void *cbdata), + void *data, int priority); + int XPRSaddcbgapnotify(XPRSprob prob, + void (*gapnotify)(XPRSprob cbprob, void *cbdata, + double *p_relgapnotifytarget, + double *p_absgapnotifytarget, + double *p_absgapnotifyobjtarget, + double *p_absgapnotifyboundtarget), + void *data, int priority); + int XPRSaddcbmiplog(XPRSprob prob, int (*miplog)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcbinfnode(XPRSprob prob, void (*infnode)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcbintsol(XPRSprob prob, void (*intsol)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcblplog(XPRSprob prob, int (*lplog)(XPRSprob cbprob, void *cbdata), void *data, + int priority); + int XPRSaddcbmessage(XPRSprob prob, + void (*message)(XPRSprob cbprob, void *cbdata, const char *msg, int msglen, + int msgtype), + void *data, int priority); + int XPRSaddcbmipthread(XPRSprob prob, + void (*mipthread)(XPRSprob cbprob, void *cbdata, XPRSprob threadprob), + void *data, int priority); + int XPRSaddcbnewnode(XPRSprob prob, + void (*newnode)(XPRSprob cbprob, void *cbdata, int parentnode, int node, + int branch), + void *data, int priority); + int XPRSaddcbnodecutoff(XPRSprob prob, + void (*nodecutoff)(XPRSprob cbprob, void *cbdata, int node), void *data, + int priority); + int XPRSaddcbnodelpsolved(XPRSprob prob, void (*nodelpsolved)(XPRSprob cbprob, void *cbdata), + void *data, int priority); + int XPRSaddcboptnode(XPRSprob prob, + void (*optnode)(XPRSprob cbprob, void *cbdata, int *p_infeasible), + void *data, int priority); + int XPRSaddcbpreintsol(XPRSprob prob, + void (*preintsol)(XPRSprob cbprob, void *cbdata, int soltype, + int *p_reject, double *p_cutoff), + void *data, int priority); + int XPRSaddcbprenode(XPRSprob prob, + void (*prenode)(XPRSprob cbprob, void *cbdata, int *p_infeasible), + void *data, int priority); + int XPRSaddcbusersolnotify(XPRSprob prob, + void (*usersolnotify)(XPRSprob cbprob, void *cbdata, + const char *solname, int status), + void *data, int priority); + int XPRSremovecbbariteration(XPRSprob prob, + void (*bariteration)(XPRSprob cbprob, void *cbdata, int *p_action), + void *data); + int XPRSremovecbbarlog(XPRSprob prob, int (*barlog)(XPRSprob cbprob, void *cbdata), void *data); + int XPRSremovecbafterobjective(XPRSprob prob, + void (*afterobjective)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecbbeforeobjective(XPRSprob prob, + void (*beforeobjective)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecbpresolve(XPRSprob prob, void (*presolve)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecbchecktime(XPRSprob prob, int (*checktime)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecbchgbranchobject(XPRSprob prob, + void (*chgbranchobject)(XPRSprob cbprob, void *cbdata, + XPRSbranchobject branch, + XPRSbranchobject *p_newbranch), + void *data); + int XPRSremovecbcutlog(XPRSprob prob, int (*cutlog)(XPRSprob cbprob, void *cbdata), void *data); + int XPRSremovecbcutround(XPRSprob prob, + void (*cutround)(XPRSprob cbprob, void *cbdata, int ifxpresscuts, + int *p_action), + void *data); + int XPRSremovecbdestroymt(XPRSprob prob, void (*destroymt)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecbgapnotify(XPRSprob prob, + void (*gapnotify)(XPRSprob cbprob, void *cbdata, + double *p_relgapnotifytarget, + double *p_absgapnotifytarget, + double *p_absgapnotifyobjtarget, + double *p_absgapnotifyboundtarget), + void *data); + int XPRSremovecbmiplog(XPRSprob prob, int (*miplog)(XPRSprob cbprob, void *cbdata), void *data); + int XPRSremovecbinfnode(XPRSprob prob, void (*infnode)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecbintsol(XPRSprob prob, void (*intsol)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecblplog(XPRSprob prob, int (*lplog)(XPRSprob cbprob, void *cbdata), void *data); + int XPRSremovecbmessage(XPRSprob prob, + void (*message)(XPRSprob cbprob, void *cbdata, const char *msg, + int msglen, int msgtype), + void *data); + int XPRSremovecbmipthread(XPRSprob prob, + void (*mipthread)(XPRSprob cbprob, void *cbdata, XPRSprob threadprob), + void *data); + int XPRSremovecbnewnode(XPRSprob prob, + void (*newnode)(XPRSprob cbprob, void *cbdata, int parentnode, int node, + int branch), + void *data); + int XPRSremovecbnodecutoff(XPRSprob prob, + void (*nodecutoff)(XPRSprob cbprob, void *cbdata, int node), + void *data); + int XPRSremovecbnodelpsolved(XPRSprob prob, void (*nodelpsolved)(XPRSprob cbprob, void *cbdata), + void *data); + int XPRSremovecboptnode(XPRSprob prob, + void (*optnode)(XPRSprob cbprob, void *cbdata, int *p_infeasible), + void *data); + int XPRSremovecbpreintsol(XPRSprob prob, + void (*preintsol)(XPRSprob cbprob, void *cbdata, int soltype, + int *p_reject, double *p_cutoff), + void *data); + int XPRSremovecbprenode(XPRSprob prob, + void (*prenode)(XPRSprob cbprob, void *cbdata, int *p_infeasible), + void *data); + int XPRSremovecbusersolnotify(XPRSprob prob, + void (*usersolnotify)(XPRSprob cbprob, void *cbdata, + const char *solname, int status), + void *data); +#ifdef __cplusplus +} +#endif +#endif // PYOPTINTERFACE_XPRESS_FORWARD_DECLS_H