2017-09-22 2 views
2

J'ai du mal à utiliser le concept de pointeur dans mon code cython. L'exemple suivant est la version simplifiée de ce que j'essaie de faire. J'ai une fonction func que je voudrais nourrir dans une fonction (une fonction de distribution) comme un paramètre d'entrée. La distribution a deux vecteurs pointeurs comme variables d'entrée.Impossible d'affecter le type 'myFuncDef *' à 'void (*) (double *, double *)'

from cpython cimport array 
import cython 
import ctypes 
cimport numpy as np 

ctypedef void (*myFuncDef)(double *, double *) 
from cython.parallel import prange 
cdef void func(int* x, double* hx, void(*func)(double*, double*), int n): 
     def int i 
     for i from 0 <= i < n: 
      func[0](&x[i], &hx[i]) 
     return 

cpdef void Lognormal(double* u, 
        double* yu): 
     #evaluate log of normal distribution 
     yu=-u*u*0.5 
     return 

def foo(np.ndarray[ndim=1, dtype=np.float64_t] x, 
     np.ndarray[ndim=1, dtype=np.float64_t] hx, 
     myFuncDef distribution, int k): 
    cdef np.ndarray[ndim=1, dtype=np.float64_t] sp 
    cdef int num=len(x) 
    cdef int j 
    for j from 0 <= j <k: 
     func(&x[0],&hx[0],&distribution, num) 
     sp[j]=hx[0] 
    return sp 

Je voudrais utiliser la fonction Lognormal comme une entrée pour foo fonction. Je reçois le message d'erreur suivant:

Cannot assign type 'myFuncDef *' to 'void (*)(double *, double *)' 

J'apprécierai pour toute suggestion pour corriger ce bug.

+0

Votre code a beaucoup d'erreurs de compilation, alors peut-être que vous devriez commencer petit, en compilant une fonction après l'autre. 'myFuncDef distribution' ne fonctionne pas? N'utilisez donc pas le ctypedef de fantaisie, utilisez directement 'void (* distribution) (double *, double *)'. Lorsque tout se compile, vous pouvez revenir en arrière et ajouter du sucre syntaxique. – ead

+0

@ead lorsque je compile la fonction foo avec votre changement de suggestion Je reçois cette erreur: Impossible de convertir l'argument objet Python en type 'void (*) (double *, double *)' parce que c'est une fonction 'python', toute autre suggestion réparer ce bug? – Dalek

+0

Alors peut-être 'foo' ne peut pas être une fonction python mais doit être' cdef'? – ead

Répondre

2

Vous avez un trop de couches de pointeur (le problème standard est soulevé pour contrer typedef s pour les pointeurs). Il suffit de déposer le & de &distribution; c'est déjà le pointeur de fonction que vous voulez.

+0

Merci pour la réponse. Il résout ce bug mais je reçois un nouveau message d'erreur concernant la fonction 'foo' comme suit:' Impossible de convertir l'argument de l'objet Python en type 'myFuncDef'. Toute suggestion pour se débarrasser de cela? – Dalek

+0

Non sans voir l'appel qui produit l'erreur ... –

+0

'Erreur lors de la compilation du fichier Cython: def foo (np.ndarray [ndim = 1, dtype = np.float64_t] x, np.ndarray [ndim = 1, dtype = np.float64_t] hx, myFuncDef distribution, int k): ' – Dalek