2013-04-27 12 views
5

Chciałbym przetestować, czy określony typ macierzy losowej jest odwracalny w stosunku do pola skończonego, w szczególności F_2. Mogę sprawdzić, czy macierz jest odwracalna w stosunku do reali, używając następującego prostego kodu.Sprawdź, czy macierz jest odwracalna nad skończonym polem.

import random 
from scipy.linalg import toeplitz 
import numpy as np 
n=10 
column = [random.choice([0,1]) for x in xrange(n)] 
row = [column[0]]+[random.choice([0,1]) for x in xrange(n-1)] 
matrix = toeplitz(column, row) 
if (np.linalg.matrix_rank(matrix) < n): 
    print "Not invertible!" 

Czy jest jakiś sposób osiągnięcia tego samego, ale ponad F_2?

+2

Można to zrobić z Sage dość łatwo ([Przykład] (http://aleph.sagemath.org/?z=eJzzDVawVfBNLCnKrAguSExO1XB30zDS1FEwBiJNXq7yjMycVIWQotJUK14uBSDwBSkP1itKzEvJz41PzUnNTc0r0dCESGamKfjqZRbHZ-aVpRaVZCblpGpoQvWBQFJRamI2gsvLVVCUmVeioO5rpQ5j-yIEgYYgieuBzSxOBVkFU6GFpkZBC1UdABH6PRM=&lang=sage)). Będę zainteresowany, aby sprawdzić, czy istnieje całkiem sprytne rozwiązanie na stosie nauki (numpy/scipy/sympy/mpmath/pandas itp.). – DSM

+1

Myślę, że jeśli uznasz macierz za F_2 jako macierz nad Z, używając tylko 0 i 1, to wyznacznik przez F_2 powinien być wyznacznikiem ponad Z modulo 2 (tzn. Sprawdzenie staje się jeśli wyznacznik ponad Z jest równy lub nieparzysty) . To może nie być optymalne algorytmicznie. –

+0

@ArminRigo Niestety nie mogę uruchomić tego pomysłu. Ustaw n = 100 w powyższym kodzie i wydrukuj linalg.det (macierz), linalg.det (macierz)% 2. Zawsze otrzymuję 0 dla linalg.det (macierzy)% 2, co jest prawdopodobnie spowodowane problemami zmiennoprzecinkowymi. Czy istnieje dokładna funkcja wyznaczająca liczbę całkowitą? – marshall

Odpowiedz

4

Byłoby lepiej użyć Sage lub innego odpowiedniego narzędzia do tego.

Poniżej tylko naiwny non-ekspert próba zrobienia czegoś, ale obrócony eliminacji Gaussa należy podać dokładny wynik do odwracalności:

import random 
from scipy.linalg import toeplitz 
import numpy as np 

def is_invertible_F2(a): 
    """ 
    Determine invertibility by Gaussian elimination 
    """ 
    a = np.array(a, dtype=np.bool_) 
    n = a.shape[0] 
    for i in range(n): 
     pivots = np.where(a[i:,i])[0] 
     if len(pivots) == 0: 
      return False 

     # swap pivot 
     piv = i + pivots[0] 
     row = a[piv,i:].copy() 
     a[piv,i:] = a[i,i:] 
     a[i,i:] = row 

     # eliminate 
     a[i+1:,i:] -= a[i+1:,i,None]*row[None,:] 

    return True 

n = 10 
column = [random.choice([0,1]) for x in xrange(n)] 
row = [column[0]]+[random.choice([0,1]) for x in xrange(n-1)] 
matrix = toeplitz(column, row) 

print(is_invertible_F2(matrix)) 
print(int(np.round(np.linalg.det(matrix))) % 2) 

Zauważ, że np.bool_ jest analogiczna do F_2 tylko w ograniczonym znaczeniu - - operacja binarna + w F_2 jest - dla bool, a unary op - jest +. Mnożenie jest jednak takie samo.

>>> x = np.array([0, 1], dtype=np.bool_) 
>>> x[:,None] - x[None,:] 
array([[False, True], 
     [ True, False]], dtype=bool) 
>>> x[:,None] * x[None,:] 
array([[False, False], 
     [False, True]], dtype=bool) 

Powyższa gausjańska eliminacja wykorzystuje tylko te operacje, więc działa.

+0

Dziękuję. Nie mam nic przeciwko importowaniu zewnętrznych bibliotek do tego konkretnego zadania, jeśli jest to słuszne. Nigdy nie używałam szałwii i nie mam pojęcia, jak dobrze on współdziała z matrycami scipy na przykład. – marshall

+0

+ i - to samo w F_2. – asmeurer

+0

@asmeuer: tak, ale nie dla booleans. –

1

Niestety, SymPy nie może jeszcze obsłużyć skończonych pól w macierzach, chociaż wsparcie jest planowane.

Jak zauważyli niektórzy komentatorzy, można po prostu sprawdzić wyznacznik na liczbach całkowitych. Jeśli jest 1 (mod 2), macierz jest odwracalna. Aby faktycznie znaleźć odwrotność, możesz po prostu przyjąć normalną odwrotność w stosunku do liczb całkowitych, pomnożyć przez wyznacznik (tak, abyś nie miał ułamków) i zmodyfikować każdy element przez 2. Nie mogę sobie wyobrazić, że byłoby to zbyt wydajne, i prawdopodobnie mógłbyś użyć dowolnej biblioteki macierzowej, nawet numerycznej (zaokrąglając do najbliższej liczby całkowitej). SymPy może również wykonać każdy z tych kroków.

Należy zauważyć, że w ogólnych cyklicznych polach skończonych część "mnożenie przez wyznacznik" będzie musiała zostać cofnięta poprzez pomnożenie przez odwrotny mod p (jest to niepotrzebny mod 2, ponieważ jedyną możliwością jest 1).

+0

Dzięki, to interesujące.Przypuszczam, że dobrym dodatkiem byłoby scipy może obliczyć wyznacznik na liczbach całkowitych. – marshall