Python has a very useful optimization library called nevergrad
, which I wanted to try using in a project written in C++. A simple test case on nevergrad
:
import nevergrad as ng
# optimization function
def square(x):
return sum((x - 0.5) ** 2)
# solve method
def solve():
optimizer = ng.optimizers.NGOpt(parametrization=2, budget=100)
return optimizer.minimize(square).value
The peculiarity of my task is that the minimization function that I want to use instead of square must call a method from the C++ project. Visually it looks like this:
If the call from C++ is done using Embedded Python, then the reverse call is done using boost.python
. But the difficulty is that the C++ project has already been launched by the time it accesses python, and Class 2
has been initialized accordingly. However, in most boost.python
usage examples, the C++ class initialization is done in python.
Is it possible to execute the sequence of calls shown in the picture C++ > Python > C++ and get the result in reverse order?
I did not try this out by myself, but reading the boost.Python docs, I guess the following approach should work (at least, in principle):
In your C++ code, instantiate your Class2 object as a wrapped object:
object myClass2Object = (class_<Class2> ...,
start the embedded Python interpreter and create the __main__
module
retrieve the main namespace and add your Class2 object to it:
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
main_namespace["myClass2Object"]=myClass2Object;
import nevergrad
into the interpreter as well as a Python solve
function which expects a myClass2Object
in the main namespace and uses it as for the target function
use exec or eval to call the solve function
object result = eval("solve()", main_namespace);
and extract the results into native C++ variables from there.
It would be nice if you can tell me how far this works, or if I am off-track with this answer.