Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use scipy.weave.inline together with external C libraries?

I am trying to understand weave.inline to wrap C code in my Python programs. The code below simply takes the Numpy array and multiplicates all of its elements by 2.

inl.py

import numpy
import scipy.weave

a = numpy.array([1.0, 2.0, 3.0])
N = a.shape[0]

print a
code = \
  """
  int i;
  for(i = 0; i < N; i++)
  {
    a[i] = a[i] * 2;
  }
  """

scipy.weave.inline(code, ['a','N'])
print a

Then I want to carry some functions from inline code to external libraries. Let it be the trivial multiplication by 2. So I create two files:

mult.c

#include "mult.h"

float mult(float n)
{
  return n * 2;
}

mult.h

float inc(float n);

Now I want to use function mult in my inline code. But I don't know how do I link my C files with Python inline code. I tried to compile C files as shared library and pass them as headers and libraries in weave, but that was in vain. Any suggestions?

like image 508
user517893 Avatar asked Nov 23 '10 20:11

user517893


1 Answers

I have successfully done this, calling math functions from R via weave.inline() code (under Ubuntu Linux).

First, compile your C functions as a shared library. In my case, I grabbed a recent release of R from CRAN, and did

./configure --enable-R-static-lib --enable-static --with-readline=no
cd src/nmath/standalone/
make

You should now have a file called libRmath.so. If libpath is a string with the directory that holds libRmath.so, you can do something like

code = 'return_val = pbinom(100, 20000, 100./20000., 0, 1);'
support_code = 'extern "C" double pbinom(double x, double n, double p, int lower_tail, int log_p);'
weave.inline(code, support_code=support_code,
    library_dirs=[libpath], libraries=["Rmath"], runtime_library_dirs=[libpath])

Note a couple things. The header declarations have to go in support_code, not code (I don't know why), and they have to be prefixed with extern "C" because they're C code, not C++ (this is standard). It should be possible to include headers files instead of using support_code (check the docs for weave.inline), but I haven't tried it. The library name is Rmath, but the shared library file is libRmath.so, in the usual Unix convention. And the path to the library is specified twice, once for linking, and once for execution.

Hope this helps!

like image 189
Ian Avatar answered Sep 21 '22 08:09

Ian