Sunday, December 18, 2011

Extend Numpy with ctypes

The idea is to write extend numpy with c. Thus, you can enjoy the performance of c and also employ any c only libs. Passing data between numpy and c with numpy arrays and c pointers.

PS: ctypes dose not recognize c++ symbols. Make sure to put your wrap function between extern "C" { and }

Here is the example.
We need 3 files.
C implimentation func.c;
Python wrapping func.py;
and Python calling interface test.py.

/*func.c*/
/* You can complie it with the following command*/
/* gcc -O2 -fPIC func.c -shared -o libfunc.so */
#ifdef __cplusplus
extern "C" {
#endif
int skew_symmetric_matrix(double *t, double *tx)
{
    tx[0] = 0;
    tx[1] = -t[2];
    tx[2] = t[1];
    tx[3] = t[2];
    tx[4] = 0;
    tx[5] = -t[0];
    tx[6] = -t[1];
    tx[7] = t[0];
    tx[8] = 0;
    return 0;
}
#ifdef __cplusplus
}
#endif

##Python wrapping file
##func.py
import numpy as np
import ctypes as ct

##load the s
_func = np.ctypeslib.load_library('libfunc', '.')
ndpointer = np.ctypeslib.ndpointer
array_double = ndpointer(dtype = ct.POINTER(ct.c_double), flags='CONTIGUOUS,ALIGNED')
##Specify the arg types the numpy arrays which have to be aligned continuously. 
##Passing a[::2] directly might not work. Using a[::2].copy() instead.
##There also other arg types such as [array_double, ct.c_int, ct.c_double]
_func.skew_symmetric_matrix.argtypes = [array_double] * 2

##Define python wrapping funcion
##ctypes can only see pointers but no size or shape of your numpy array
def skew_symmetric_matrix(t):
if t.size != 3:
return None
tx = np.zeros((3, 3), dtype=np.double)
_func.skew_symmetric_matrix(t, tx)
return tx

##Python interface
##test.py
import scipy as sp, numpy as np
import func

t = np.array([1.0, 2.0, 3.0])
tx = func.skew_symmetric_matrix(t)
print (t)
print (tx)




Saturday, December 10, 2011

cblas of gotoblas2

According to
"http://shimingyoung.blogspot.com/2010/01/gotoblas-and-lapackwrapper.html"

Also edit the cblas.h by adding one line
#define blasint int
And edit the f2c.h by changing the line on the 10th line to
typedef int integer;

Otherwise, blasint is not defined while compiling.