2013-08-05 9 views
10

पर एक numpy सूचक (dtype = np.bool) पास करने के लिए मैं साइंटर के माध्यम से अपने पॉइंटर को पास करके C++ में प्रकार के बूल के एक numpy सरणी का उपयोग करना चाहता हूं। मुझे पहले से ही पता है कि इसे uint8 जैसे अन्य डेटाटाइप के साथ कैसे किया जाए। बुलियन के साथ ऐसा ही करना यह काम नहीं करता है। मैं संकलन करने में सक्षम हूँ, लेकिन निम्नलिखित अपवाद रनटाइम के दौरान होती है: ++ विधिसी ++

Traceback (most recent call last): 
    File "test.py", line 15, in <module> 
    c = r.count(b, 4) 
    File "rect.pyx", line 41, in rect.PyRectangle.count (rect.cpp:1865) 
    def count(self, np.ndarray[bool, ndim=1, mode="c"] array not None, int size): 
ValueError: Does not understand character buffer dtype format string ('?') 

यहाँ मेरी सी है:

void Rectangle::count(bool * array, int size) 
{ 
    for (int i = 0; i < size; i++){ 
     std::cout << array[i] << std::endl; 
    } 
} 

Cython फ़ाइल:

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

import numpy as np 
cimport numpy as np 

from libcpp cimport bool 

cdef extern from "Rectangle.h" namespace "shapes": 
    cdef cppclass Rectangle: 
     Rectangle(int, int, int, int) except + 
     int x0, y0, x1, y1 
     void count(bool*, int) 

cdef class PyRectangle: 
    cdef Rectangle *thisptr  # hold a C++ instance which we're wrapping 
    def __cinit__(self, int x0, int y0, int x1, int y1): 
     self.thisptr = new Rectangle(x0, y0, x1, y1) 
    def __dealloc__(self): 
     del self.thisptr 

    def count(self, np.ndarray[bool, ndim=1, mode="c"] array not None, int size): 
     self.thisptr.count(&array[0], size) 

और यहाँ अजगर स्क्रिप्ट जो विधि को कॉल करता है और त्रुटि उत्पन्न करता है:

import numpy as np 
import rect 

b = np.array([True, False, False, True]) 
c = r.count(b, 4) 

अगर आपको अधिक जानकारी चाहिए तो कृपया मुझे बताएं। धन्यवाद!

उत्तर

9

ऐसा लगता है कि समस्या सरणी प्रकार की घोषणा के साथ है। https://cython.readthedocs.org/en/latest/src/tutorial/numpy.html पर प्रलेखन के अनुसार बूलियन मेष अभी तक समर्थित नहीं हैं, लेकिन आप उन्हें बिना हस्ताक्षरित आठ बिट पूर्णांक के सरणी के रूप में कास्टिंग करके उनका उपयोग कर सकते हैं। यहाँ एक सरल उदाहरण है कि बूलियन मूल्यों की एक -1 डी सरणी

from numpy cimport ndarray as ar 
cimport numpy as np 
cimport cython 

@cython.boundscheck(False) 
@cython.wraparound(False) 
def cysum(ar[np.uint8_t,cast=True] A): 
    cdef int i, n=A.size, tot=0 
    for i in xrange(n): 
     tot += A[i] 
    return tot 

अपने सी ++ कोड में, आप क्या कर रहे हैं पर निर्भर करता है (एक बूलियन NumPy सरणी के लिए होगा sum() विधि के रूप में ही) की राशि लेता है, तो आप पॉइंटर को वापस एक बूल में डालने की आवश्यकता हो सकती है, मुझे यकीन नहीं है।

संपादित करें: साइथन में पॉइंटर को कैसे डालना है इसका एक उदाहरण यहां दिया गया है, जो आपको चाहिए जो करना चाहिए। मुझे अभी भी सरणी को एक हस्ताक्षरित 8 बिट पूर्णांक के रूप में टाइप करना पड़ा, लेकिन फिर मैंने पॉइंटर को वापस एक बूल में डाला।

from numpy cimport ndarray as ar 
cimport numpy as np 
from libcpp cimport bool 
cimport cython 

def cysum(ar[np.uint8_t,cast=True] A): 
    cdef int i, n=A.size, tot=0 
    cdef bool *bptr 
    bptr = <bool*> &A[0] 
    for i in xrange(n): 
     tot += bptr[i] 
    return tot 

आप सूचक के रूप में में सरणी पास करना चाहते हैं, तो आप सिर्फ निम्नलिखित समारोह अपने Cython फ़ाइल में इस्तेमाल कर सकते हैं:

cdef bool* arptr(np.uint8_t* uintptr): 
    cdef bool *bptr 
    bptr = <bool*> uintptr 
    return bptr 

कौन सा

arptr(&A[0]) 
के रूप में कहा जा सकता है