I am working with Toby Segaran's collective intelligence code for genetic programming and I wanted to speed it up using Cython. I'm starting to realize I probably bit off more than I can chew for a first time Cython project. I've Googled and searched for an answer to how to make this work, but just can't seem to find the right combination of examples.
Here is the actual code in question:
# Function Wrapper Code
class fwrapper:
def __init__(self, funct, params, name):
self.function = funct
self.params = params
self.name = name
# Functions with 2 parameters
addw = fwrapper(lambda p: p[0] + p[1], 2, 'add')
subw = fwrapper(lambda p: p[0] - p[1], 2, 'subtract')
mulw = fwrapper(lambda p: p[0] * p[1], 2, 'multiply')
# If and > Function
def iffunc(l):
if l[0] > 0:
return l[1]
else:
return l[2]
ifw = fwrapper(iffunc, 3, 'if')
def isgreater(l):
if l[0] > l[1]:
return 1
else:
return 0
gtw = fwrapper(isgreater, 2, 'isgreater')
# List of possible functions
flist = [addw, mulw, ifw, gtw, subw]
So because Toby uses a Python class as a wrapper for the functions he uses in his genetic programming algorithm, I have to first "Cythonize" (I don't mean the actual cythonize call) the class itself. But the function wrapper class passes a function in. Worse yet, that function that is getting passed in wants a single parameter that is a Python list.
So trying to speed this up in Cython is problematic due to the fact that it requires some advanced topics that I can't seem to figure out.
First problem: I can't figure out how to pass in a c-style function into a "cythonized" version of this class. This solution will work, but isn't fast because it still treats the function I pass in as a slow python function:
# Function Wrapper Code
cdef class fwrapper:
cdef public object function
cdef public int params
cdef public object name
def __init__(self, funct, int params, name):
self.function = funct
self.params = params
self.name = name
# Functions with 2 parameters
cdef add(double param1, double param2):
return param1 + param2
addw = fwrapper(add, 2, 'add')
cdef subtract(double param1, double param2):
return param1 - param2
subw = fwrapper(subtract, 2, 'subtract')
cdef multiply(double param1, double param2):
return param1 * param2
mulw = fwrapper(multiply, 2, 'multiply')
# If and > Function - 3 parameter functions
cdef iffunc(double param1, double param2, double param3):
if param1 > 0:
return param2
else:
return param3
ifw = fwrapper(iffunc, 3, 'if')
cdef isgreater(double param1, double param2):
if param1 > param2:
return 1
else:
return 0
gtw = fwrapper(isgreater, 2, 'isgreater')
# List of possible functions
flist = [addw, mulw, ifw, gtw, subw]
I've tried playing with ctypedef to no avail. That's probably the correct answer, but following this link (Cython: How to expose void* and function pointer in struct?) doesn't seem to work out right.