你確定你的minor
返回一個新的對象,而不是對原始矩陣對象的引用嗎?我使用了你的確切的行列式方法,併爲你的課程實施了一個minor
方法,它對我來說工作得很好。
下面是你的矩陣類的快速/髒實現,因爲我沒有你的實現。爲了簡潔起見,我選擇了僅用於方矩陣,在這種情況下,我們正在處理的決定因素應該不重要。注意det
方法,那就是你的一樣,和minor
方法(方法其餘的都是有便於實現和測試):
class matrix:
def __init__(self, n):
self.data = [0.0 for i in range(n*n)]
self.dim = n
@classmethod
def rand(self, n):
import random
a = matrix(n)
for i in range(n):
for j in range(n):
a[i,j] = random.random()
return a
@classmethod
def eye(self, n):
a = matrix(n)
for i in range(n):
a[i,i] = 1.0
return a
def __repr__(self):
n = self.dim
for i in range(n):
print str(self.data[i*n: i*n+n])
return ''
def __getitem__(self,(i,j)):
assert i < self.dim and j < self.dim
return self.data[self.dim*i + j]
def __setitem__(self, (i, j), val):
assert i < self.dim and j < self.dim
self.data[self.dim*i + j] = float(val)
#
def minor(self, i,j):
n = self.dim
assert i < n and j < n
a = matrix(self.dim-1)
for k in range(n):
for l in range(n):
if k == i or l == j: continue
if k < i:
K = k
else:
K = k-1
if l < j:
L = l
else:
L = l-1
a[K,L] = self[k,l]
return a
def det(self, i=0):
n = self.dim
if n == 1:
return self[0,0]
d = 0
for j in range(n):
d += ((-1)**(i+j))*(self[i,j])*((self.minor(i,j)).det())
return d
def __mul__(self, v):
n = self.dim
a = matrix(n)
for i in range(n):
for j in range(n):
a[i,j] = v * self[i,j]
return a
__rmul__ = __mul__
現在測試
import numpy as np
a = matrix(3)
# same matrix from the Wikipedia page
a[0,0] = 1
a[0,1] = 2
a[0,2] = 3
a[1,0] = 4
a[1,1] = 5
a[1,2] = 6
a[2,0] = 7
a[2,1] = 8
a[2,2] = 9
a.det() # returns 0.0
# trying with numpy the same matrix
A = np.array(a.data).reshape([3,3])
print np.linalg.det(A) # returns -9.51619735393e-16
的在numpy情況下的殘差是因爲它通過(高斯)消除方法而不是拉普拉斯擴展來計算行列式。您也可以比較隨機矩陣,結果看到你的決定功能和numpy的公司之間的差異不增長超過float
精度:
import numpy as np
a = 10*matrix.rand(4)
A = np.array(a.data).reshape([4,4])
print (np.linalg.det(A) - a.det())/a.det() # varies between zero and 1e-14
是否'self.minor(I,J)'實際上變換'self' ? – 2013-05-12 17:43:54
是的。你是對的。我會改變這一點,並再次檢查。謝謝 – user2375340 2013-05-12 17:44:36
我建議不要使用這樣的assert。第一個('assert isinstance(self,Matrix)')什麼都不做 - 這是'Matrix'的一個方法,所以你肯定知道'self'是一個'Matrix'。第二個可以更好地處理像'if n!= m:raise ValueError(「Matrix is not square」)這樣的事情,因爲異常對於問題更具體(並且更容易被捕獲)。 – 2013-05-12 18:32:12