Thanks a lot Chris! I didn't use the properties of __get__ and __set__ functions to pass the python array declaration to cython object. Back to my another problem, I have written another cython class which has again problem and I think I need the opinion of one expert. I used cython_gsl to improve the speed of my code (
cnfw_model.pyx
) which one of its bottleneck in python version was the integration in Da instance:
import numpy as np
from cython_gsl cimport *
ctypedef double * double_ptr
ctypedef void * void_ptr
cdef class Cosmology(object):
cdef double omega_c
def __init__(self, double omega_m=0.3, double omega_lam=0.7):
# no quintessence, no radiation in this universe!
self.omega_m = omega_m
self.omega_lam = omega_lam
self.omega_c = (1. - omega_m - omega_lam)
cdef double a(self, double z):
return 1./(1+z)
cdef double E(self, double a):
return (self.omega_m*a**(-3) + self.omega_c*a**(-2) + self.omega_lam)**0.5
cdef double __angKernel(self, double x, void * params) nogil:
cdef double alpha, f
alpha = (<double_ptr> params)[0]
f=self.E(alpha*x**-1)**-1
return f
cdef double Da(self, int size, double *z, double z_ref=0):
cdef gsl_integration_workspace *w
cdef double result, error, expected, alpha
w = gsl_integration_workspace_alloc (1000)
cdef gsl_function F
if size>1:
da = np.zeros(size)
for i in range(size):
da[i] = self.Da(1, &z[i], z_ref)
return da
else:
if z[0] < 0:
raise ValueError("Redshift z must not be negative")
if z[0] < z_ref:
raise ValueError("Redshift z must not be smaller than the reference redshift")
expected = -4.0
alpha = 1
F.function = &self.__angKernel
F.params = &alpha
gsl_integration_qags (&F, z_ref+1, z[0]+1, 0, 1e-7, 1000, w, &result, &error)
d=result
rk = (abs(self.omega_c))**0.5
if (rk*d > 0.01):
if self.omega_c > 0:
d = sinh(rk*d)/rk
if self.omega_c < 0:
d = sin(rk*d)/rk
return d/(1+z[0])
When I tried to build this code, I got this error message:
...
raise ValueError("Redshift z must not be smaller than the reference redshift")
expected = -4.0
alpha = 1
F.function = &self.__angKernel
^
------------------------------------------------------------
cnfw_model.pyx:102:24: Cannot assign type 'double (*)(Cosmology, double, void *) nogil' to 'double (*)(double, void *) nogil'
...
cdef double __angKernel(self, double x, void * params) nogil:
cdef double alpha, f
alpha = (<double_ptr> params)[0]
"""Integration kernel for angular diameter distance computation.
"""
f=self.E(alpha*x**-1)**-1
^
------------------------------------------------------------
cnfw_model.pyx:73:16: Calling gil-requiring function not allowed without gil