2012-02-28 50 views
5

Tôi đang cố gắng xây dựng một ma trận kiểu int python, một số nguyên có dấu 64 bit.loại cython/numpy của một mảng

cdef matrix33(): 
    return np.zeros((3,3),dtype=int) 

cdef do_stuf(np.ndarray[int, ndim=2] matrix): 
    ... 
    return some_value 

def start(): 
    print do_stuf(matrix33()) 

Nó biên dịch đúng, nhưng khi tôi chạy nó tôi tiếp tục nhận được lỗi này:

ValueError: Buffer dtype mismatch, expected 'int' but got 'long' 

tôi không thể làm việc với của trăn dài, nhưng tôi không biết làm thế nào để chuyển đổi đúng cách để một 64 int.

CẬP NHẬT

Okey. Tôi khá chắc chắn rằng tôi đã sử dụng Cython đúng cách. Mã mà tôi đã viết là cho một tìm kiếm minmax trong trò chơi chụp go/atari đi.

Bởi đến nay gọi là hầu hết các chức năng sau đây:

cdef isThere_greedy_move(np.ndarray[np.int64_t, ndim=2]board, int player): 
    cdef int i, j 
    for i in xrange(len(board)): 
     for j in xrange(len(board)): 
      if board[i,j] == 0: 
       board[i,j] = player 
       if player in score(board): 
        board[i,j] = 0 
        return True 
       board[i,j] = 0 
    return False 


# main function of the scoring system. 
# returns list of players that eat a stone 
cdef score(np.ndarray[np.int64_t, ndim=2] board): 
    scores = [] 
    cdef int i,j 
    cdef np.ndarray[np.int64_t, ndim = 2] checked 
    checked = np.zeros((board.shape[0], board.shape[1]), dtype = int) 
    for i in xrange(len(board)): 
     for j in xrange(len(board)): 
      if checked[i,j] == 0 and board[i,j] !=0: 
       life, newly_checked = check_life(i,j,board,[]) 
       if not life: 
        if -board[i,j] not in scores: 
         scores.append(-board[i,j]) 
         if len(scores) == 2: 
          return scores 
       checked = update_checked(checked, newly_checked) 
    return scores 

# helper functions of score/1 
cdef check_life(int i, int j, np.ndarray[np.int64_t, ndim=2] board, checked): 
    checked.append((i,j)) 
    if liberty(i,j,board): 
     return True, checked 
    for pos in [[1,0],[0,1],[-1,0],[0,-1]]: 
     pos = np.array([i,j]) + np.array(pos) 
     if check_index(pos[0],pos[1],len(board)) and board[pos[0],pos[1]] == board[i,j] and (pos[0],pos[1]) not in checked: 
      life, newly_checked = check_life(pos[0],pos[1],board,checked) 
      if life: 
       checked = checked + newly_checked    
       return life, checked 
    return False, [] # [] is a dummy. 

cdef liberty(int i,int j, np.ndarray[np.int64_t, ndim=2] board): 
    for pos in [np.array([1,0]),np.array([0,1]),np.array([-1,0]),np.array([0,-1])]: 
     pos = np.array([i,j]) - pos 
     if check_index(pos[0],pos[1],len(board)) and board[pos[0],pos[1]] == 0: 
      return True 
    return False 

tôi sẽ thực sự có thể nghĩ rằng đây sẽ là một cơ hội để tỏa sáng cho cython. Để giải quyết chụp 3x3 đi:

Python 2.7 hiện một phù 2,28 giây, với cython nó là một phù 2,03 Cả hai đã được thử nghiệm với các mô-đun thời gian trăn và trên một bộ xử lý i7 dưới 60C °

Bây giờ câu hỏi cho tôi là nếu tôi chuyển sang Haskell hoặc C++ cho dự án này ...

Trả lời

6

Cython's int loại giống như C int, tức là thường (nhưng không nhất thiết) 32-bit. Bạn nên khai báo dtype trong matrix33 như np.int64 và trong do_stuf như người đồng C của nó, np.int64_t:

cimport numpy as np 
import numpy as np 

cdef do_stuff(np.ndarray[np.int64_t, ndim=2] matrix): 
    pass 

cdef matrix33(): 
    return np.zeros((3,3), dtype=int) 

def start(): 
    print do_stuff(matrix33()) 
+0

Cảm ơn bạn, mã bây giờ chạy đúng. Nhưng, nó chạy nhanh như khi tôi tuyên bố mọi thứ dài. Tôi biết các đối tượng dài không phải là nhanh, vì nó không thể tràn và được điều trị khác nhau (sử dụng nhiều chu kỳ). Tôi muốn sử dụng một int có thể tràn và đó là nhanh hơn so với loại python dài. – Ihmahr

+0

Ngoài ra, tốc độ lên trên python giải thích là chỉ dưới 10%, mà làm cho tôi nghi ngờ rằng tôi không hoàn toàn có các loại quyền ... – Ihmahr

+0

@ user1020753: các loại là đúng. Tốc độ phụ thuộc vào những gì bạn đang làm trong các chức năng của bạn. –

Các vấn đề liên quan