Sarebbe meglio usare Sage o qualche altro strumento adeguato per questo.
che segue è solo ingenuo tentativo non esperto a fare qualcosa, ma imperniato eliminazione di Gauss dovrebbe dare il risultato esatto per invertibilit'a:
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)
noti che np.bool_
è analogo a F_2 solo in un senso ristretto - - l'operazione binaria +
in F_2 è -
per bool, mentre la versione unaria -
è +
. La moltiplicazione è la stessa, però.
>>> 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)
L'eliminazione gaussiana sopra utilizza solo queste operazioni, quindi funziona.
Si potrebbe fare con Sage abbastanza facilmente ([es] (http://aleph.sagemath.org/?z=eJzzDVawVfBNLCnKrAguSExO1XB30zDS1FEwBiJNXq7yjMycVIWQotJUK14uBSDwBSkP1itKzEvJz41PzUnNTc0r0dCESGamKfjqZRbHZ-aVpRaVZCblpGpoQvWBQFJRamI2gsvLVVCUmVeioO5rpQ5j-yIEgYYgieuBzSxOBVkFU6GFpkZBC1UdABH6PRM=&lang=sage)). Sarò interessato a vedere se c'è una soluzione lucida sullo stack scientifico (numpy/scipy/sympy/mpmath/panda ecc.), Però. – DSM
Penso che se consideri la matrice su F_2 come una matrice su Z usando solo 0 e 1, allora il determinante su F_2 dovrebbe essere il determinante su Z modulo 2 (cioè il controllo diventa se il determinante su Z è pari o dispari) . Questo potrebbe non essere algoritmicamente ottimale. –
@ArminRigo Purtroppo non riesco a far funzionare questa idea. Impostare n = 100 nel codice sopra e stampare linalg.det (matrice), linalg.det (matrice)% 2. Ottengo sempre 0 per linalg.det (matrice)% 2 che è presumibilmente a causa di problemi in virgola mobile. Esiste una funzione determinante intera esatta? – marshall