Skip to content

Commit

Permalink
Move evaluation of f0 and m_nlcon to C++
Browse files Browse the repository at this point in the history
  • Loading branch information
nbelakovski committed Mar 18, 2024
1 parent c7c6ec0 commit 655f1c7
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 19 deletions.
19 changes: 10 additions & 9 deletions python/_prima.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ PYBIND11_MODULE(_prima, m) {
const py::object& nonlinear_constraint_function,
const py::object& python_callback_function,
const py::object& options_dict,
const py::object& nlconstr0,
const py::object& m_nlcon,
const py::object& f0)
const py::object& nlconstr0)
{
// Reference for how to go from a python function to a C style function pointer: https://stackoverflow.com/questions/74480093
// Basically, we need to create a function with a C signature that calls the python function, and
Expand Down Expand Up @@ -175,8 +173,8 @@ PYBIND11_MODULE(_prima, m) {
prima_algorithm_t algorithm = pystr_method_to_algorithm(method);

if ( algorithm == PRIMA_COBYLA ) {
if (python_nonlinear_constraint_function_holder.is_none() || nlconstr0.is_none() || m_nlcon.is_none() || f0.is_none()) {
throw std::invalid_argument("nonlinear_constraint_function, nlconstr0, m_nlcon, and f0 must be provided if nonlinear constraints are provided");
if (python_nonlinear_constraint_function_holder.is_none() || nlconstr0.is_none()) {
throw std::invalid_argument("nonlinear_constraint_function and nlconstr0 must both be provided if nonlinear constraints are provided");
}

auto nlconstr0_buffer_info = nlconstr0.cast<py::buffer>().request();
Expand All @@ -185,8 +183,12 @@ PYBIND11_MODULE(_prima, m) {
throw std::invalid_argument("nlconstr0 must be a double array");
}
problem.nlconstr0 = (double*) nlconstr0_buffer_info.ptr;
problem.m_nlcon = m_nlcon.cast<int>();
problem.f0 = f0.cast<double>();
problem.m_nlcon = nlconstr0_buffer_info.size;
if (args.size() > 0) {
problem.f0 = python_objective_function_holder(py_x0, args).cast<double>();
} else {
problem.f0 = python_objective_function_holder(py_x0).cast<double>();
}

problem.calcfc = [](const double x[], double *f, double constr[], const void *data) {
// In order for xlist to not copy the data from x, we need to provide a dummy base object
Expand Down Expand Up @@ -325,7 +327,6 @@ PYBIND11_MODULE(_prima, m) {
"lb"_a=py::none(), "ub"_a=py::none(), "A_eq"_a=py::none(), "b_eq"_a=py::none(),
"A_ineq"_a=py::none(), "b_ineq"_a=py::none(),
"nonlinear_constraint_function"_a=py::none(),
"callback"_a=nullptr, "options"_a=py::none(), "nlconstr0"_a=py::none(),
"m_nlcon"_a=py::none(), "f0"_a=py::none()
"callback"_a=nullptr, "options"_a=py::none(), "nlconstr0"_a=py::none()
);
}
11 changes: 1 addition & 10 deletions python/prima/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,6 @@ def minimize(fun, x0, args=(), method=None, bounds=None, constraints=(), callbac
A_eq, b_eq, A_ineq, b_ineq = separate_LC_into_eq_and_ineq(linear_constraint)
else:
A_eq, b_eq, A_ineq, b_ineq = None, None, None, None

if nonlinear_constraint_function is not None:
m_nlcon = len(nlconstr0)
f0 = fun(x0)
else:
m_nlcon = 0
f0 = None

return _minimize(
fun,
Expand All @@ -150,7 +143,5 @@ def minimize(fun, x0, args=(), method=None, bounds=None, constraints=(), callbac
nonlinear_constraint_function,
callback,
options,
nlconstr0,
m_nlcon,
f0,
nlconstr0
)

0 comments on commit 655f1c7

Please sign in to comment.