| 12 | |
| 13 | namespace uno { |
| 14 | void define_Model(py::module& module) { |
| 15 | py::class_<PythonUserModel>(module, "Model") |
| 16 | // constructor with bounds |
| 17 | // https://stackoverflow.com/a/62310838/16037994 |
| 18 | .def(py::init<>([](const std::string& problem_type, uno_int number_variables, std::vector<double> variables_lower_bounds, |
| 19 | std::vector<double> variables_upper_bounds, uno_int base_indexing) { |
| 20 | PythonUserModel model(problem_type.data(), number_variables, base_indexing); |
| 21 | model.variables_lower_bounds = std::move(variables_lower_bounds); |
| 22 | model.variables_upper_bounds = std::move(variables_upper_bounds); |
| 23 | model.initial_primal_iterate.resize(static_cast<size_t>(number_variables), 0.); |
| 24 | return model; |
| 25 | }), "Constructor") |
| 26 | |
| 27 | // constructor without bounds |
| 28 | .def(py::init<>([](const std::string& problem_type, uno_int number_variables, uno_int base_indexing) { |
| 29 | PythonUserModel model(problem_type.data(), number_variables, base_indexing); |
| 30 | const size_t unsigned_number_variables = static_cast<size_t>(number_variables); |
| 31 | model.variables_lower_bounds.resize(unsigned_number_variables, -INF<double>); |
| 32 | model.variables_upper_bounds.resize(unsigned_number_variables, INF<double>); |
| 33 | model.initial_primal_iterate.resize(unsigned_number_variables, 0.); |
| 34 | return model; |
| 35 | }), "Constructor") |
| 36 | |
| 37 | // methods |
| 38 | .def("set_variables_lower_bounds", [](PythonUserModel& user_model, std::vector<double> variables_lower_bounds) { |
| 39 | if (static_cast<uno_int>(variables_lower_bounds.size()) != user_model.number_variables) { |
| 40 | throw std::invalid_argument("Dimension mismatch in variables_lower_bounds."); |
| 41 | } |
| 42 | user_model.variables_lower_bounds = std::move(variables_lower_bounds); |
| 43 | }) |
| 44 | |
| 45 | .def("set_variables_upper_bounds", [](PythonUserModel& user_model, std::vector<double> variables_upper_bounds) { |
| 46 | if (static_cast<uno_int>(variables_upper_bounds.size()) != user_model.number_variables) { |
| 47 | throw std::invalid_argument("Dimension mismatch in variables_upper_bounds."); |
| 48 | } |
| 49 | user_model.variables_upper_bounds = std::move(variables_upper_bounds); |
| 50 | }) |
| 51 | |
| 52 | .def("set_variable_lower_bound", [](PythonUserModel& user_model, uno_int variable_index, double lower_bound) { |
| 53 | if (variable_index < 0 || variable_index >= user_model.number_variables) { |
| 54 | throw std::invalid_argument("Please specify a valid index."); |
| 55 | } |
| 56 | user_model.variables_lower_bounds[static_cast<size_t>(variable_index)] = lower_bound; |
| 57 | }) |
| 58 | |
| 59 | .def("set_variable_upper_bound", [](PythonUserModel& user_model, uno_int variable_index, double upper_bound) { |
| 60 | if (variable_index < 0 || variable_index >= user_model.number_variables) { |
| 61 | throw std::invalid_argument("Please specify a valid index."); |
| 62 | } |
| 63 | user_model.variables_upper_bounds[static_cast<size_t>(variable_index)] = upper_bound; |
| 64 | }) |
| 65 | |
| 66 | .def("set_objective", [](PythonUserModel& user_model, uno_int optimization_sense, Objective objective_function, |
| 67 | ObjectiveGradient objective_gradient) { |
| 68 | if (optimization_sense != UNO_MINIMIZE && optimization_sense != UNO_MAXIMIZE) { |
| 69 | throw std::invalid_argument("Please specify a valid objective sense."); |
| 70 | } |
| 71 | user_model.optimization_sense = optimization_sense; |
no test coverage detected