Оберните двойную ** c ++ функцию с помощью Cython - PullRequest
0 голосов
/ 30 мая 2018

У меня есть функция C ++, которая возвращает указатель double** - в частности, многомерная матрица - и я хотел бы обернуть ее в некоторый код Python с использованием Cython.Как мне действовать?

Вот пример с функцией с указателем double* для простоты.

Мой код C ++ fib.cpp:

double add(double a, double b)
{
 return a+b;
}

double p[]= {1,2,3,4}; 

double* mult(double a)    
{
p[0]=p[0]*a;
p[1]=p[1]*a;
return p; 
}

Тогда есть fib.hpp file:

double add(double a,double b);
double* mult(double a);

Затем файл pxd fib.pxd:

cdef extern from "fib.hpp":
     double add(double a,double b);
     double* mult(double a);

В конце файл pyx

# distutils: language = c++
# distutils: sources = fib.cpp 

cimport fib 

def add(a,b):
    return fib.add(a,b)
def mult(a):           # dropping these lines
    return fib.mult(a) # the code works without the double* function

Все компилируется сдовольно стандартный setup.py:

from distutils.core import setup, Extension
from Cython.Build import cythonize

ext = Extension("fib2cpp",
            sources=["fib.pyx", "fib.cpp"],
            language="c++")

setup(name="fib",
ext_modules=cythonize(ext))

Когда я компилирую код:

setup.py build_ext -if

Невозможно преобразовать 'double *' в объект python.

Когда я пытаюсь использовать функцию double**, я получаю ту же ошибку.Что мне делать?

1 Ответ

0 голосов
/ 01 июня 2018

Я нашел решение для дела double *.Прежде всего, файл fib.pxd бесполезен.Затем нам нужен новый fib.pyx файл:

# distutils: language = c++
# distutils: sources = fib.cpp


import numpy as np 
cimport numpy as cnp 



cdef extern from "fib.hpp":
     double fib(int n)
     double add (double a, double b)
     double* mult(double a)



def make_mult(double a):
    cdef double[:] mv = <double[:4]> mult(a) # the 4 stands for
    return np.asarray(mv)   # the dimension of the array defined in fib.cpp 

В случае функции, которая возвращает матрицу nrows * ncols;например, double* make_mat(int nrows, int ncols), вторая строка функции make_mult должна быть переписана следующим образом:

cdef double[:,:] mv=<double[:nrows,:ncols]> make_mat(nrows, ncols) 

К сожалению, если у меня есть функция double** make_mat(int nrows, int ncols), которая всегда возвращает матрицу, тогда предыдущий кодвыдает ошибку:

Базовый тип указателя не совпадает с базовым типом cython.array

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...