Some shared library functionality is accessible directly from python. This code shows how to access a useful portion of the gsl from python3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | '''
module gls_setup, file gsl_setup.py
load the gsl shared libraries and ctypes
consider gsl_set_error_handler_off();
(gsl errors cause core dumps which I choose to live with for now)
'''
import sys
if sys.version_info[0] != 3:
raise Exception('This code has been tried in python version 3')
from ctypes import *
from array import array
# probably add some OS specific code here to encompass more than linux
# load dependencies first, making the symbols available.
gslcblas = CDLL('libgslcblas.so',mode=RTLD_GLOBAL)
gsl = CDLL('libgsl.so')
def setup(f,argument_types_list,result_type=c_long):
f.argtypes = argument_types_list
f.restype = result_type
return f
def as_array(a,typecode='d'):
return (
a if (isinstance(a,array) and a.typecode == typecode)
else array(typecode,a)
)
def ADDRESS(a):
return a.buffer_info()[0]
|
I have not been able to use scipy on all the computer systems on which I need it, nor have I succeeded with py_gsl. The module I present here gives access to some of the gnu scientific library using python3k. (Python3k is, at time of writing, in the release candidate stage.) Much of the gsl is accessible directly from python without c or external interface construction programs.
Scope---
Operating system: Works on linux, probably also on cygwin, untried on other systems.
Routines available are those which use any of the simple types: c pointers to double become python array.array('d'). The python ctypes module handles the rest.
Not investigated yet: vector or view data structures gsl_complex_...
Not implemented here, please write! Callbacks to python for quadrature, optimization. I think some c code is needed.
Use---
from gsl_setup import *
# access a variable in the gsl
rngType = c_void_p.in_dll(gsl,'gsl_rng_default')
# use a function of no args directly
# /* void or ignored */ gsl_rng_env_setup(void);
gsl.gsl_rng_env_setup()
#prepare a void function---omit setup third argument
#void gsl_rng_set (const gsl_rng * r, unsigned long int seed);
set = setup(gsl.gsl_rng_set,[c_voidp,c_ulong])
#prepare a function with pointers and returning a value
#blas ddot: interface changed to suit my needs
# (name becomes dot, eliminated stride, no argument tests)
#double cblas_ddot(
# const int N, const double * x, const int incx,
# const double * y, const int incy)
def dot(a,b,f=setup(gslcblas.cblas_ddot,
[c_ulong,c_void_p,c_long,c_void_p,c_long],
c_double)):
'''
>>> dot(range(3),(4,5,6))
17.0
'''
return f(len(a),ADDRESS(as_array(a)),1,ADDRESS(as_array(b)),1)
#and use it, as the doc string shows.
dot(list(range(10))[1::2],[1,]*4) == sum((1,3,5,7,9))
Additional examples will follow these shorties in separate recipes.
As with many of the recipes, some reindenting of the code is needed. Please fix this, ActiveState. The "'''" in "dot" definition needs moved right.
Just a comment on how you coded this, not a criticism --
It is better form to use the dl module instead of ctypes for loading dynamic libraries, since dl is part of the standard library.
Answering Collin Stocks: This recipe states Python version 3 in the title. As I recall, I submitted the recipe while python 3 was still a beta release. ctypes was and is a part of the standard python 3 distribution. (I certainly wrote the code before the official release of python 3.)