2012-02-28 22 views
5

Próbuję zbudować macierz Pythona typu int, 64-bitowa liczba ze znakiem.Cython/numpy Typ tablicy

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()) 

To kompiluje prawo, ale kiedy go uruchomić Wciąż dostaję ten błąd:

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

nie mogę pracować z Python Longa, ale nie wiem jak poprawnie konwertować do 64 int.

UPDATE

Okey. Jestem pewien, że poprawnie użyłem Cythona. Kod, który napisałem, był przeznaczony do wyszukiwania minmax w grze capture go/atari go.

zdecydowanie najbardziej zwane funkcje są takie:

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 

ja naprawdę myślałem, że będzie to szansa, aby błyszczeć na Cython. Aby rozwiązać wychwytywania 3x3 przejść:

Pythona 2.7 ma spójnego 2.28 sekund, przy Cython jest zgodny 2,03 obydwa przeciwciała zbadano z modułem czasowym pyton i na i7 mniejszej niż 60 ° C °

teraz pytanie dla mnie jest, jeśli mam zamiar przełączyć się Haskell lub C++ dla tego projektu ...

Odpowiedz

6

Cython za int typ jest taki sam jak C int, czyli zwykle (ale nie koniecznie) 32-bit. Należy zadeklarować dtype w matrix33 jako np.int64 oraz w do_stuf jak jego odpowiednik, np.int64_t C:

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

Dziękuję, kod działa teraz poprawne. Ale działa tak szybko, jak to się dzieje, gdy deklaruję wszystko długo. Wiem, że długi obiekt nie jest szybki, ponieważ nie może przepełnić i jest traktowany inaczej (wykorzystuje więcej cykli). Chciałbym użyć typu int, który może przepełnić i jest szybszy niż typ Pythona. – Ihmahr

+0

Ponadto przyspieszenie w stosunku do interpretowanego pythona wynosi nieco poniżej 10%, co sprawia, że ​​podejrzewam, że nie mam odpowiednich typów ... – Ihmahr

+0

@ user1020753: typy mają rację. Przyspieszenie zależy od tego, co robisz w swoich funkcjach. –

Powiązane problemy