これには、Sageや他の適切なツールを使用する方がよいでしょう。 np.bool_
だけ狭義にF_2に類似していることを
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)
注 - :
次は何かをやっ時だけ洗練されていない非専門家の試みですが、ガウスの消去法を旋回さは、可逆性のために、正確な結果を与える必要があります - Foolのバイナリ操作+
はブールの場合は-
、単精度の場合は-
は+
です。しかし、乗算は同じです。
>>> 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)
上記のガウス消去法は、これらの演算のみを使用するため、動作します。
あなたは簡単に十分な([例](http://aleph.sagemath.org/?z=eJzzDVawVfBNLCnKrAguSExO1XB30zDS1FEwBiJNXq7yjMycVIWQotJUK14uBSDwBSkP1itKzEvJz41PzUnNTc0r0dCESGamKfjqZRbHZ-aVpRaVZCblpGpoQvWBQFJRamI2gsvLVVCUmVeioO5rpQ5j-yIEgYYgieuBzSxOBVkFU6GFpkZBC1UdABH6PRM=&lang=sage))セージでそれを行うことができます。私は科学的なスタック(numpy/scipy/sympy/mpmath/pandasなど)に滑らかな解決策があるかどうかを知ることに興味があります。 – DSM
F_2の行列を0と1だけを使ってZ上の行列と見なすと、F_2の行列式はZの法2を満たす行列式になるはずです(つまり、Zの行列式が偶数か奇数かどうかのチェックになります) 。これはアルゴリズム的に最適ではないかもしれません。 –
@ArminRigo残念ながら私はこの考え方を働かせることはできません。上記のコードでn = 100に設定し、linalg.det(matrix)、linalg.det(matrix)%2を出力します。おそらく浮動小数点の問題のために、私は常にlinalg.det(行列)%2に対して0を得る。正確な整数行列式関数はありますか? – marshall