作为我学习的一部分,我创建了这个 Matrix 类。为了测试结果,我提供了一个“test.py”文件。
我现在的问题是测试文件总是给我这个错误:
> --------------------------------------------------------------------------- AttributeError Traceback (most recent call
> last) <ipython-input-7-daeb08264590> in <module>()
> 6 # and then selecting matrix.py
> 7
> ----> 8 import test
>
> /home/workspace/test.py in <module>()
> 76 return True
> 77
> ---> 78 test()
>
> /home/workspace/test.py in test()
> 57 assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
> 58 """
> ---> 59 assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
> 60 assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
> 61 assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
>
> /home/workspace/test.py in equal(m1, m2)
> 68
> 69 def equal(m1, m2):
> ---> 70 if len(m1.g) != len(m2.g): return False
> 71 if len(m1.g[0]) != len(m2.g[0]): return False
> 72 for r1, r2 in zip(m1.g, m2.g):
>
> AttributeError: 'list' object has no attribute 'g'
但是,当自己测试案例时,它可以工作并显示相同的结果。
矩阵.py
import math
from math import sqrt
import numbers
def zeroes(height, width):
"""
Creates a matrix of zeroes.
"""
g = [[0.0 for _ in range(width)] for __ in range(height)]
return Matrix(g)
def identity(n):
"""
Creates a n x n identity matrix.
"""
I = zeroes(n, n)
for i in range(n):
I.g[i][i] = 1.0
return I
class Matrix(object):
# Constructor
def __init__(self, grid):
self.g = grid
self.h = len(grid)
self.w = len(grid[0])
#
# Primary matrix math methods
#############################
def determinant(self):
if not self.is_square():
raise(ValueError, "Cannot calculate determinant of non-square matrix.")
if self.h > 2:
raise(NotImplementedError, "Calculating determinant not implemented for matrices largerer than 2x2.")
if self.h == 1:
return self.g[0][0]
elif self.h == 2:
return (self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
def trace(self):
if not self.is_square():
raise(ValueError, "Cannot calculate the trace of a non-square matrix.")
sum_trace = 0
for i in range(self.h):
for j in range(self.w):
if i == j:
sum_trace = sum_trace + self.g[i][j]
return sum_trace
def inverse(self):
if not self.is_square():
raise(ValueError, "Non-square Matrix does not have an inverse.")
if self.h > 2:
raise(NotImplementedError, "inversion not implemented for matrices larger than 2x2.")
if self.h == 2:
if self.g[0][0] * self.g[1][1] == self.g[0][1] * self.g[1][0]:
return "ad = bc. Therefore Matrix does not have an inverse"
else:
det_A = 1/(self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
inverse = [[det_A*self.g[1][1],det_A*-self.g[0][1]],[det_A*-self.g[1][0],det_A*self.g[0][0]]]
elif self.h == 1:
inverse = [[1/self.g[0][0]]]
def T(self):
matrix_transpose = []
#Iterate through columns (e.g. j=0)
for j in range(self.w):
#Reset row for each itteration
new_row = []
#Iterate through rows (e.g. j = 0, i loops 0;1)
for i in range(self.h):
#i = 0, j = 0; i = 1, j = 0 > new row created out of matrix columns
new_row.append(self.g[i][j])
#new_row appended to matrix_transpose
matrix_transpose.append(new_row)
return matrix_transpose
def is_square(self):
return self.h == self.w
#
# Begin Operator Overloading
############################
def __getitem__(self,idx):
return self.g[idx]
def __repr__(self):
s = ""
for row in self.g:
s += " ".join(["{} ".format(x) for x in row])
s += "\n"
return s
def __add__(self,other):
if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be added if the dimensions are the same")
matrix_addition = []
for i in range(self.h):
new_row = []
for j in range(self.w):
addition = self.g[i][j] + other.g[i][j]
new_row.append(addition)
matrix_addition.append(new_row)
return Matrix(matrix_addition)
def __neg__(self):
for i in range(self.h):
for j in range(self.w):
self.g[i][j] *= -1
return Matrix(self.g)
def __sub__(self, other):
if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be substracted if the dimensions are the same")
matrix_substraction = []
for i in range(self.h):
new_row = []
for j in range(self.w):
addition = self.g[i][j] - other.g[i][j]
new_row.append(addition)
matrix_substraction.append(new_row)
return Matrix(matrix_substraction)
def __mul__(self, other):
#dot_product func
def dot_product(vector_one, vector_two):
dot_product = 0
for i in range(len(vector_one)):
dot_product += vector_one[i] * vector_two[i]
return dot_product
#get_row func
def get_row(matrix, row):
return matrix[row]
#get_column func
def get_column(matrix, column_number):
column = []
for i in range(len(matrix)):
column.append(matrix[i][column_number])
return column
result = []
for i in range(self.h):
row_result = []
for j in range(self.w):
vector_one = get_row(self.g, i)
vector_two = get_column(other.g, j)
calulated_dot_product = dot_product(vector_one, vector_two)
row_result.append(calulated_dot_product)
result.append(row_result)
return Matrix(result)
def __rmul__(self, other):
if isinstance(other, numbers.Number):
pass
for i in range(self.h):
for j in range(self.w):
self.g[i][j] = 2 * self.g[i][j]
return Matrix(self.g)
测试文件
import matrix as m
def test():
I2 = m.Matrix([
[1, 0],
[0, 1]
])
I2_neg = m.Matrix([
[-1, 0],
[0, -1]
])
zero = m.Matrix([
[0,0],
[0,0]
])
m1 = m.Matrix([
[1,2,3],
[4,5,6]
])
m2 = m.Matrix([
[7,-2],
[-3,-5],
[4,1]
])
m1_x_m2 = m.Matrix([
[ 13, -9],
[ 37, -27]])
m2_x_m1 = m.Matrix([
[ -1, 4, 9],
[-23, -31, -39],
[ 8, 13, 18]])
m1_m2_inv = m.Matrix([
[1.5, -0.5],
[2.0555556, -0.722222222]
])
top_ones = m.Matrix([
[1,1],
[0,0],
])
left_ones = m.Matrix([
[1,0],
[1,0]
])
assert equal(-I2, I2_neg), "Error in your __neg__ function"
assert equal(I2 + I2_neg, zero), "Error in your __add__ function"
assert equal(m1 * m2, m1_x_m2), "Error in your __mul__ function"
assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
assert equal(left_ones.T(), top_ones), "Error in your T function (transpose)"
assert equal(top_ones - left_ones.T(), m.zeroes(2,2)), "Error in your __sub__ function"
assert (4*m.identity(5))[0][0] == 4, "Error in your __rmul__ function"
assert (4*m.identity(5)).trace() == 20 , "Error in your trace function"
print("Congratulations! All tests pass. Your Matrix class is working as expected.")
def equal(m1, m2):
if len(m1.g) != len(m2.g): return False
if len(m1.g[0]) != len(m2.g[0]): return False
for r1, r2 in zip(m1.g, m2.g):
for v1, v2 in zip(r1, r2):
if abs(v1 - v2) > 0.0001:
return False
return True
test()
Playground.py(测试并导入两个文件)
# Run this cell but don't modify it.
%load_ext autoreload
%autoreload 2
from matrix import Matrix, zeroes, identity
# Try running this code. You should get an assertion error.
# You will continue to get assertion errors until all the
# methods in matrix.py are correctly implemented.
# You can open matrix.py by selecting File > Open...
# and then selecting matrix.py
import test
我试图分解问题,所以我可以减少我必须在这里与你分享的代码。但是无论我尝试更改什么,我都会从 test.py 中返回错误。我希望你们中的任何人都可以研究它,也许知道问题出在哪里。
/马克
在代码库的快速检查表明,这些方法inverse
和T
该的Matrix
类不返回Matrix
的情况下,但裸露的网格(2D- lists
); 当然,g
当equal
测试中的函数试图将它们与Matrix
实例进行比较时,这些网格没有属性。将这两个方法的返回值包装成矩阵:
class Matrix(object):
def inverse(self):
# ....
# not: return inverse
return Matrix(inverse)
def T(self):
# ...
# not: return matrix_transpose
return Matrix(matrix_transpose)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句