Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use SWIG to wrap C++ <vector> as python NumPy array

Tags:

c++

numpy

swig

I have a C++ library that defines the following (and more like them) types:

typedef std::vector< double > DoubleVec;

typedef std::vector< DoubleVec > DoubleVecVec;

typedef std::vector< int > IntVec;

typedef std::vector< IntVec > IntVecVec;

I am trying to create a python interface to a library that handles objects like that. As the title states, I would like my interface to convert to/from C++ std::vector and numpy ndarray.

I have seen both numpy.i provided by the numpy people and std_vector.i from the SWIG people. The problems are that numpy.i was created to handle C/C++ arrays (not C++ vectors) and std_vector.i doesn't do conversion directly to/from numpy arrays.

Any ideas?

I have seen that the FEniCS project has done something like this, but their project is so large that I am having a hard time finding out just how they do this specific task.

like image 403
spencerlyon2 Avatar asked May 04 '13 18:05

spencerlyon2


People also ask

How to use wrapping C/C++ for Python using SWIG?

Wrapping C/C++ for Python using SWIG 1 Installation. ... 2 My c file is example.c 3 Interface file: Now, if you want to add you c file to your preferred language, you need to write an “interface file” which is the input to SWIG. 4 example.i. ... 5 Header file. ... 6 example.h 7 Setup file: 8 Creating the wrapper. ... 9 Built the extension. ...

How to use Swig wrapper generator to create Swig interface?

So, for the given task – Swig Wrapper Generator is used. Swig operates by parsing C header files and automatically creating extension code. C-header file is needed first, to use Swig. Give an example of C-header file in the code below. After having the header file, the next step is to write a Swig “interface” file.

Why does Swig unify all types of objects in Python?

In Python, there is no detailed distinction like this--specifically, there are only "objects". There are no pointers, references, arrays, and so forth. Because of this, SWIG unifies all of these types together in the wrapper code. For instance, if you actually had the above functions, it is perfectly legal to do this:

Why is Swig not converting my C++ arguments to Python?

When SWIG does not convert them, it will generate code to obtain them from the C++ layer as if python:cdefaultargs was specified. This will happen if just one argument cannot be converted into a Python equivalent. This occurs typically when the argument is not fully numeric, such as int (1) :


1 Answers

Try this as a starting point.

%include "numpy.i"

%apply (size_t DIM1, double* IN_ARRAY1) {(size_t len_, double* vec_)}

%rename (foo) my_foo;
%inline %{
int my_foo(size_t len_, double* vec_) {
    std::vector<double> v;
    v.insert(v.end(), vec_, vec_ + len_);
    return foo(v);
}
%}

%apply (size_t DIM1, size_t DIM2, double* IN_ARRAY2) {(size_t len1_, size_t len2_, double* vec_)}

%rename (bar) my_bar;
%inline %{
int my_bar(size_t len1_, size_t len2_, double* vec_) {
    std::vector< std::vector<double> > v (len1_);
    for (size_t i = 0; i < len1_; ++i) {
        v[i].insert(v[i].end(), vec_ + i*len2_, vec_ + (i+1)*len2_);
    }
    return bar(v);
}
%}
like image 116
Oktalist Avatar answered Nov 15 '22 01:11

Oktalist