I want to rewrite a class in cython format and save it as demo.pyx. The input parameter for the class would be either a 2D np.array with an Nx2
shape, e.g. a=np.array([[0.2,-0.8],[3.7,0.02],..,[-0.92,-3.33]])
, or a list for instance a=[0.1,2.7]
.
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
def __init__(self, np.ndarray[np.float64_t,ndim=2,mode='c'] positions):
self.x = &positions[:,0]
self.y = &positions[:,1]
What I have tried to write causes error message as following:
running build_ext
cythoning demo.pyx to demo.c
Error compiling Cython file:
------------------------------------------------------------
...
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
^
------------------------------------------------------------
demo.pyx:5:9: Unrecognised type modifier combination
Error compiling Cython file:
------------------------------------------------------------
...
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
^
------------------------------------------------------------
demo.pyx:6:9: Unrecognised type modifier combination
Error compiling Cython file:
------------------------------------------------------------
...
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
def __init__(self, np.ndarray[np.float64_t,ndim=2,mode='c'] positions):
self.x = &positions[:,0]
^
------------------------------------------------------------
demo.pyx:8:17: Cannot take address of Python variable
Error compiling Cython file:
------------------------------------------------------------
...
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
def __init__(self, np.ndarray[np.float64_t,ndim=2,mode='c'] positions):
self.x = &positions[:,0]
self.y = &positions[:,1]
^
------------------------------------------------------------
demo.pyx:9:17: Cannot take address of Python variable
I know there is a problem with the way I have used pointers, but if I want to keep the type of x
and y
ambiguous, I need to use this. How could I make my class
work?
An answer which I got from cython.group in google works perfectly:
import cython
cimport cython
import numpy as np
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef double [:] _x
property x:
def __get__(self):
return np.array(self._x)
def __set__(self, np.ndarray[DTYPE_t, ndim=1] x):
self._x = x
cdef double [:] _y
property y:
def __get__(self):
return np.array(self._y)
def __set__(self, np.ndarray[DTYPE_t, ndim=1] y):
self._y = y
def __init__(self, np.ndarray[DTYPE_t,ndim=2] positions):
self._x = positions[:,0]
self._y = positions[:,1]
def debug(self):
print self.x, self.y