Screenshot instructions:
Windows
Mac
Red Hat Linux
Ubuntu
Click URL instructions:
Rightclick on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)
From: Jörg F. Unger <joerg.unger@un...>  20090825 14:05:21

I would like to write an optimizer in python and c++. The optimizer is actually a c++ class Optimizer, whose interface is exposed to python via swig in module nuto. Within the optimizer, I need to evaluate the objective function and the gradient of the objective function. For that purpose, I would like to call a callback routine, so that I can define the optimization problem on the python level. The python file looks something like that import nuto def objective_function (parameters): objective = 0 for i in range(0,parameters.size()): objective += parameters[i]*parameters[i] return objective def gradient_function(parameters, gradient): for i in range(0,parameters.size()): gradient[i] = 2.*parameters[i] #define optimization routine with two variables initialized with zero Opt = nuto.Optimizer(2) #set callbacks Opt.set_callbacks(objective_function,gradient_function) #call optimization procedure Opt.optimize() I define a function objective_function, which calculates from the current set of parameters to be optimized the objective function (in this case sum_i parameters[i]^2, where parameters is an std::vector exposed to python via vector.i in the modul. The problem actually is that when calling the callback function from c in python, I have to wrap the std::vector to a python object (but I just want the pointer to be wrapped, so that no data copying is required). Via this wrapping, the Parameter vector is exposed to the callback routine in python, which then calculates the objective function. In a similar way, the callback gradient routine for the gradient is called and stores the gradient directly in the std::vector, which is just wrapped on the python level. Any ideas including modifications of the algorithm are welcome! The only important thing is that I want to avoid extensive data copying everytime a callback routine is called. The header file and the cpp file of the optimizer is are given in http://pastebin.com/m21d6a04c http://pastebin.com/d7be2394d  ********************************************** * Jörg F. Unger * * BauhausUniversity Weimar * * Institute of Structural Mechanics * * Marienstraße 15 * * 99423 Weimar * * GERMANY * * * * phone : +493643584512 * * fax : +493643584514 * * email : joerg.unger@... * ********************************************** 
From: Jörg F. Unger <joerg.unger@un...>  20090908 07:10:37

This time with a complete list of all the files included. I would like to write an optimizer in python and c++. The optimizer is actually a c++ class Optimizer, whose interface is exposed to python via swig in module nuto. Within the optimizer, I need to evaluate the objective function and the gradient of the objective function. For that purpose, I would like to call a callback routine, so that I can define the optimization problem on the python level. The python file looks something like that import nuto def objective_function (parameters): objective = 0 for i in range(0,parameters.size()): objective += parameters[i]*parameters[i] return objective def gradient_function(parameters, gradient): for i in range(0,parameters.size()): gradient[i] = 2.*parameters[i] #define optimization routine with two variables initialized with zero Opt = nuto.Optimizer(2) #set callbacks Opt.set_callbacks(objective_function,gradient_function) #call optimization procedure Opt.optimize() I define a function objective_function, which calculates from the current set of parameters to be optimized the objective function (in this case sum_i parameters[i]2, where parameters is an std::vector exposed to python via vector.i in the modul. The problem actually is that when calling the callback function from c in python, I have to wrap the std::vector to a python object (but I just want the pointer to be wrapped, so that no data copying is required). Via this wrapping, the Parameter vector is exposed to the callback routine in python, which then calculates the objective function. In a similar way, the callback gradient routine for the gradient is called and stores the gradient directly in the std::vector, which is just wrapped on the python level. Any ideas including modifications of the algorithm are welcome! The only important thing is that I want to avoid extensive data copying everytime a callback routine is called. The header file and the cpp file of the optimizer is are given as // Optimizer.h #ifndef Optimizer_H #define Optimizer_H #include <Python.h> #include <vector> #include "Optimizer.h" namespace NuTo { class Optimizer { public: Optimizer(unsigned int numParameters) { callback_objective=0; callback_gradient=0; Parameters.resize(numParameters); Gradient.resize(numParameters); } void set_callbacks(PyObject *args_objective,PyObject *args_gradient); double call_callback_objective_from_C(); void call_callback_gradient_from_C(std::vector<double>& gradient); void optimize(); private: PyObject *callback_objective; PyObject *callback_gradient; std::vector<double> Parameters; double Objective; std::vector<double> Gradient; }; } //namespace NuTo #endif // Optimizer_H // Optimizer.cpp #include "nuto/optimize/Optimizer.h" namespace NuTo { void Optimizer::set_callbacks(PyObject *args_objective,PyObject *args_gradient) { // check if objective routine is callable if (!PyCallable_Check(args_objective)) { exit(0); } Py_XINCREF(args_objective); // Add a reference to new callback Py_XDECREF(callback_objective); // Dispose of previous callback callback_objective = args_objective; // Remember new callback if (!PyCallable_Check(args_gradient)) { exit(0); } Py_XINCREF(args_gradient); // Add a reference to new callback Py_XDECREF(callback_gradient); // Dispose of previous callback callback_gradient = args_gradient; // Remember new callback } double Optimizer::call_callback_objective_from_C() { double objective; // create python object as wrapper from std:vector<double> PyObject *arglist = Py_BuildValue("(dd)",Parameters[0],Parameters[1]); // call external python function printf("object routine %p\n",callback_objective); PyObject *result = PyObject_CallObject(callback_objective, arglist); if (result==0) { printf("error calling callback objective"); exit(0); } objective = PyFloat_AsDouble(result); // decrease reference count for arglist Py_DECREF(arglist); // decrease reference count for result Py_DECREF(result); return objective; } void Optimizer::call_callback_gradient_from_C(std::vector<double>& gradient) { // create python object as wrapper from std:vector<double> PyObject *pygradient; //= wrap_to_python(gradient) ?? // build argument list for call of python function PyObject *arglist = Py_BuildValue("(o)", pygradient); // call external python function PyObject *result = PyObject_CallObject(callback_gradient, arglist); if (result==0) { printf("error calling callback gradient"); exit(0); } //no result required, since it is written in the vector externally given // decrease reference count for arglist Py_DECREF(arglist); // decrease reference count for result Py_DECREF(result); } void Optimizer::optimize() { double lambda = 1.0; for (int theCycle=0; theCycle<10;theCycle++ ) { // calculate objective in python routine Objective = call_callback_objective_from_C(); // calculate gradient of objective function in python routine call_callback_gradient_from_C(Gradient); // modify parameters in negative gradient direction with a certain step length for (unsigned int count=0; count<Parameters.size(); count++) Parameters[count]=lambda*Gradient[count]; } } } 
From: William S Fulton <wsf@fu...>  20090831 19:50:20

Jörg F. Unger wrote: > I would like to write an optimizer in python and c++. > The optimizer is actually a c++ class Optimizer, whose interface is > exposed to python via swig in module nuto. Within the optimizer, I need > to evaluate the objective function and the gradient of the objective > function. For that purpose, I would like to call a callback routine, so > that I can define the optimization problem on the python level. > > The python file looks something like that > > import nuto > > def objective_function (parameters): > objective = 0 > for i in range(0,parameters.size()): > objective += parameters[i]*parameters[i] > return objective > > def gradient_function(parameters, gradient): > for i in range(0,parameters.size()): > gradient[i] = 2.*parameters[i] > > > #define optimization routine with two variables initialized with zero > Opt = nuto.Optimizer(2) > #set callbacks > Opt.set_callbacks(objective_function,gradient_function) > > #call optimization procedure > Opt.optimize() > > > I define a function objective_function, which calculates from the > current set of parameters to be optimized the objective function (in > this case sum_i parameters[i]^2, where parameters is an std::vector > exposed to python via vector.i in the modul. > > > The problem actually is that when calling the callback function from c > in python, I have to wrap the std::vector to a python object (but I just > want the pointer to be wrapped, so that no data copying is required). > Via this wrapping, the Parameter vector is exposed to the callback > routine in python, which then calculates the objective function. In a > similar way, the callback gradient routine for the gradient is called > and stores the gradient directly in the std::vector, which is just > wrapped on the python level. > > Any ideas including modifications of the algorithm are welcome! The only > important thing is that I want to avoid extensive data copying everytime > a callback routine is called. > > > The header file and the cpp file of the optimizer is are given in > http://pastebin.com/m21d6a04c > http://pastebin.com/d7be2394d > The 2nd pastebin doesn't work so I don't really know what you are doing... pastebin code is not viewable in the email archives, so is best avoided. So all I can suggest is to take a look at directors for the callback and don't %include std_vector.i if you don't want std::vector marshalled into Python lists, as the default handling without std_vector.i is to use a simple pointer. Then maybe you can add some additional helper C++ methods for accessing the std::vector elements, eg: %inline %{ double getNthValue(size_t n, const std::vector<double>& v) { return v[n]; } %} William 
Sign up for the SourceForge newsletter:
No, thanks