views:

113

answers:

2

I am trying to pass data around the numpy and boost::ublas layers. I have written an ultra thin wrapper because swig cannot parse ublas' header correctly. The code is shown below

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/lexical_cast.hpp>
#include <algorithm>
#include <sstream>
#include <string>

using std::copy;
using namespace boost;

typedef boost::numeric::ublas::matrix<double> dm;
typedef boost::numeric::ublas::vector<double> dv;

class dvector : public dv{
 public:
 dvector(const int rhs):dv(rhs){;};
 dvector();
 dvector(const int size, double* ptr):dv(size){
   copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));
 }
 ~dvector(){}
};

with the SWIG interface that looks something like

%apply(int DIM1, double* INPLACE_ARRAY1) {(const int size, double* ptr)}
class dvector{
 public:
 dvector(const int rhs);
 dvector();
 dvector(const int size, double* ptr);
       %newobject toString;
 char* toString();
       ~dvector();
};

I have compiled them successfully via gcc 4.3 and vc++9.0. However when I simply run

a = dvector(array([1.,2.,3.]))

it gives me a segfault. This is the first time I use swigh with numpy and not have fully understanding between the data conversion and memory buffer passing. Does anyone see something obvious I have missed? I have tried to trace through with a debugger but it crashed within the assmeblys of python.exe. I have no clue if this is a swig problem or of my simple wrapper. Anything is appreciated.

+1  A: 

You may want to replace

copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));

by

copy(ptr, ptr+size, &(dv::data()[0]));

Remember that in C/C++ adding or subtracting from a pointer moves it by a multiple of the size of the datatype it points to.

Best,

Ugo
+1  A: 

You may be interested in looking at the pyublas module. It does the conversion between numpy arrays and ublas data types seamlessly and without copying.

celil