Coding the Matrix Week 3 The Matrix 矩阵
本周共有三次作业。所花费的时间为一天左右,还算可以,需要注意的是考虑一些特殊情况,写出能够通用的程序,这就行了。
体会
set()和{}结果相同,可以通用,可以采取后者。
>>> type({}) <class 'dict'> >>> type(set()) <class 'set'> >>> type(dict()) <class 'dict'> >>> {}==set() False >>> {}==dict() True
作业1 hw3
这一节讲的是矩阵的运算。值得注意的是左乘和右乘稀疏矩阵的意义,和矩阵求逆的方法和线性方程组的通解。
左乘矩阵,对于这个稀疏矩阵的任意点(i,j),相当于把矩阵第j行加到结果的i行。右乘矩阵,对于点(i,j),相当于把矩阵第i列加到结果的j列。用来计算包含稀疏矩阵的乘法十分方便。
代码如下
# version code 893 # Please fill out this stencil and submit using the provided submission script. from mat import Mat from vec import Vec from matutil import * ## Problem 1 # Please represent your solutions as lists. vector_matrix_product_1 = [1,0] vector_matrix_product_2 = [0,4.44] vector_matrix_product_3 = [14,20,26] ## Problem 2 # Represent your solution as a list of rows. # For example, the identity matrix would be [[1,0],[0,1]]. M_swap_two_vector = [[0,1],[1,0]] ## Problem 3 three_by_three_matrix = [[1,0,1],[0,1,0],[1,0,0]] # Represent with a list of rows lists. ## Problem 4 multiplied_matrix = [[2,0,0],[0,4,0],[0,0,3]] # Represent with a list of row lists. ## Problem 5 # Please enter a boolean representing if the multiplication is valid. # If it is not valid, please enter None for the dimensions. part_1_valid = False # True or False part_1_number_rows = None # Integer or None part_1_number_cols = None # Integer or None part_2_valid = False part_2_number_rows = None part_2_number_cols = None part_3_valid = True part_3_number_rows = 1 part_3_number_cols = 2 part_4_valid = True part_4_number_rows = 2 part_4_number_cols = 1 part_5_valid = False part_5_number_rows = None part_5_number_cols = None part_6_valid = True part_6_number_rows = 1 part_6_number_cols = 1 part_7_valid = True part_7_number_rows = 3 part_7_number_cols = 3 ## Problem 6 # Please represent your answer as a list of row lists. small_mat_mult_1 = [[8,13],[8,14]] small_mat_mult_2 = [[24,11,4],[1,3,0]] small_mat_mult_3 = [[3,13]] small_mat_mult_4 = [[14]] small_mat_mult_5 = [[1,2,3],[2,4,6],[3,6,9]] small_mat_mult_6 = [[-2,4],[1,1],[1,-3]] ## Problem 7 # Please represent your solution as a list of row lists. part_1_AB = [[5,2,0,1],[2,1,-4,6],[2,3,0,-4],[-2,3,4,0]] part_1_BA = [[1,-4,6,2],[3,0,-4,2],[3,4,0,-2],[2,0,1,5]] part_2_AB = [[5,1,0,2],[2,6,-4,1],[2,-4,0,3],[-2,0,4,3]] part_2_BA = [[3,4,0,-2],[3,0,-4,2],[1,-4,6,2],[2,0,1,5]] part_3_AB = [[1,0,5,2],[6,-4,2,1],[-4,0,2,3],[0,4,-2,3]] part_3_BA = [[3,4,0,-2],[1,-4,6,2],[2,0,1,5],[3,0,-4,2]] ## Problem 8 # Please represent your answer as a list of row lists. # Please represent the variables a and b as strings. # Represent multiplication of the variables, make them one string. # For example, the sum of 'a' and 'b' would be 'a+b'. matrix_matrix_mult_1 = [[1,'a+b'],[0,1]] matrix_matrix_mult_2_A2 = [[1,2],[0,1]] matrix_matrix_mult_2_A3 = [[1,3],[0,1]] # Use the string 'n' to represent variable the n in A^n. matrix_matrix_mult_2_An = [[1,'n'],[0,1]] ## Problem 9 # Please represent your answer as a list of row lists. your_answer_a_AB = [[0,0,2,0],[0,0,5,0],[0,0,4,0],[0,0,6,0]] your_answer_a_BA = [[0,0,0,0],[4,4,4,0],[0,0,0,0],[0,0,0,0]] your_answer_b_AB = [[0,2,-1,0],[0,5,3,0],[0,4,0,0],[0,6,-5,0]] your_answer_b_BA = [[0,0,0,0],[1,5,-2,3],[0,0,0,0],[4,4,4,0]] your_answer_c_AB = [[6,0,0,0],[6,0,0,0],[8,0,0,0],[5,0,0,0]] your_answer_c_BA = [[4,2,1,-1],[4,2,1,-1],[0,0,0,0],[0,0,0,0]] your_answer_d_AB = [[0,3,0,4],[0,4,0,1],[0,4,0,4],[0,-6,0,-1]] your_answer_d_BA = [[0,11,0,-2],[0,0,0,0],[0,0,0,0],[1,5,-2,3]] your_answer_e_AB = [[0,3,0,8],[0,-9,0,2],[0,0,0,8],[0,15,0,-2]] your_answer_e_BA = [[-2,12,4,-10],[0,0,0,0],[0,0,0,0],[-3,-15,6,-9]] your_answer_f_AB = [[-4,4,2,-3],[-1,10,-4,9],[-4,8,8,0],[1,12,4,-15]] your_answer_f_BA = [[-4,-2,-1,1],[2,10,-4,6],[8,8,8,0],[-3,18,6,-15]] ## Problem 10 column_row_vector_multiplication1 = Vec({0, 1}, {0:13,1:20}) column_row_vector_multiplication2 = Vec({0, 1, 2}, {0:24,1:11,2:4}) column_row_vector_multiplication3 = Vec({0, 1, 2, 3}, {0:4,1:8,2:11,3:3}) column_row_vector_multiplication4 = Vec({0,1}, {0:30,1:16}) column_row_vector_multiplication5 = Vec({0, 1, 2}, {0:-3,1:1,2:9}) ## Problem 11 def lin_comb_mat_vec_mult(M, v): assert(M.D[1] == v.D) nm=mat2coldict(M) return sum([v[x]*nm[x] for x in M.D[1]]) ## Problem 12 def lin_comb_vec_mat_mult(v, M): assert(v.D == M.D[0]) nm=mat2rowdict(M) return sum([v[x]*nm[x] for x in M.D[0]]) ## Problem 13 def dot_product_mat_vec_mult(M, v): assert(M.D[1] == v.D) nm=mat2rowdict(M) return Vec(M.D[0],{x:v*nm[x] for x in M.D[0]}) ## Problem 14 def dot_product_vec_mat_mult(v, M): assert(v.D == M.D[0]) nm=mat2coldict(M) return Vec(M.D[1],{x:v*nm[x] for x in M.D[1]}) ## Problem 15 def Mv_mat_mat_mult(A, B): assert A.D[1] == B.D[0] nm=mat2coldict(B) return coldict2mat({x:A*nm[x] for x in B.D[1]}) ## Problem 16 def vM_mat_mat_mult(A, B): assert A.D[1] == B.D[0] na=mat2rowdict(A) return rowdict2mat({x:na[x]*B for x in A.D[0]}) ## Problem 17 def dot_prod_mat_mat_mult(A, B): assert A.D[1] == B.D[0] nb=mat2coldict(B) na=mat2rowdict(A) return Mat((A.D[0],B.D[1]),{(x,y):na[x]*nb[y] for x in A.D[0] for y in B.D[1]}) ## Problem 18 solving_systems_x1 = -0.2 solving_systems_x2 = 0.4 solving_systems_y1 = 0.8 solving_systems_y2 = -0.6 solving_systems_m = Mat(({0, 1}, {0, 1}), {(0,0):-0.2,(0,1):0.8,(1,0):0.4,(1,1):-0.6}) solving_systems_a = Mat(({0, 1}, {0, 1}), {(0,0):3,(0,1):4,(1,0):2,(1,1):1}) solving_systems_a_times_m = Mat(({0, 1}, {0, 1}), {(0,0):1,(0,1):0,(1,0):0,(1,1):1}) solving_systems_m_times_a = Mat(({0, 1}, {0, 1}), {(0,0):1,(0,1):0,(1,0):0,(1,1):1}) ## Problem 19 # Please write your solutions as booleans (True or False) are_inverses1 = True are_inverses2 = True are_inverses3 = False are_inverses4 = False
作业2 mat
这个作业是完成mat class,重载了很多运算符。值得注意的是,getitem对于程序中的稀疏存储方式,在dict中如无法找到对应项应该返回0.做的时候注意细节。
代码如下:
from vec import Vec from GF2 import one def getitem(M, k): "Returns the value of entry k in M. The value of k should be a pair." assert k[0] in M.D[0] and k[1] in M.D[1] return M.f[k] if k in M.f.keys() else 0 def setitem(M, k, val): "Sets the element of v with label k to be val. The value of k should be a pair" assert k[0] in M.D[0] and k[1] in M.D[1] M.f[k]=val def add(A, B): "Returns the sum of A and B" assert A.D == B.D return Mat(A.D,{(x,y):A[x,y]+B[x,y] for x in A.D[0] for y in A.D[1]}) def scalar_mul(M, alpha): "Returns the product of scalar alpha with M" return Mat(M.D,{x:y*alpha for x,y in M.f.items()}) def equal(A, B): "Returns true iff A is equal to B" assert A.D == B.D for x in A.D[0]: for y in A.D[1]: if A[x,y]!=B[x,y]:return False return True def transpose(M): "Returns the transpose of M" return Mat((M.D[1],M.D[0]),{(b,a):y for (a,b),y in M.f.items()}) def vector_matrix_mul(v, M): "Returns the product of vector v and matrix M" assert M.D[0] == v.D return Vec(M.D[1],{x:sum([v[y]*M[y,x] for y in M.D[0]]) for x in M.D[1]}) def matrix_vector_mul(M, v): "Returns the product of matrix M and vector v" assert M.D[1] == v.D return Vec(M.D[0],{x:sum([v[y]*M[x,y] for y in M.D[1]]) for x in M.D[0]}) def matrix_matrix_mul(A, B): "Returns the product of A and B" assert A.D[1] == B.D[0] return Mat((A.D[0],B.D[1]),{(x,y):sum([A[x,t]*B[t,y] for t in A.D[1]]) for x in A.D[0] for y in B.D[1]}) ################################################################################ class Mat: def __init__(self, labels, function): self.D = labels self.f = function __getitem__ = getitem __setitem__ = setitem transpose = transpose def __neg__(self): return (-1)*self def __mul__(self,other): if Mat == type(other): return matrix_matrix_mul(self,other) elif Vec == type(other): return matrix_vector_mul(self,other) else: return scalar_mul(self,other) #this will only be used if other is scalar (or not-supported). mat and vec both have __mul__ implemented def __rmul__(self, other): if Vec == type(other): return vector_matrix_mul(other, self) else: # Assume scalar return scalar_mul(self, other) __add__ = add def __sub__(a,b): return a+(-b) __eq__ = equal def copy(self): return Mat(self.D, self.f.copy()) def __str__(M, rows=None, cols=None): "string representation for print()" if rows == None: try: rows = sorted(M.D[0]) except TypeError: rows = sorted(M.D[0], key=hash) if cols == None: try: cols = sorted(M.D[1]) except TypeError: cols = sorted(M.D[1], key=hash) separator = ' | ' numdec = 3 pre = 1+max([len(str(r)) for r in rows]) colw = {col:(1+max([len(str(col))] + [len('{0:.{1}G}'.format(M[row,col],numdec)) if isinstance(M[row,col], int) or isinstance(M[row,col], float) else len(str(M[row,col])) for row in rows])) for col in cols} s1 = ' '*(1+ pre + len(separator)) s2 = ''.join(['{0:>{1}}'.format(c,colw[c]) for c in cols]) s3 = ' '*(pre+len(separator)) + '-'*(sum(list(colw.values())) + 1) s4 = ''.join(['{0:>{1}} {2}'.format(r, pre,separator)+''.join(['{0:>{1}.{2}G}'.format(M[r,c],colw[c],numdec) if isinstance(M[r,c], int) or isinstance(M[r,c], float) else '{0:>{1}}'.format(M[r,c], colw[c]) for c in cols])+'\n' for r in rows]) return '\n' + s1 + s2 + '\n' + s3 + '\n' + s4 def pp(self, rows, cols): print(self.__str__(rows, cols)) def __repr__(self): "evaluatable representation" return "Mat(" + str(self.D) +", " + str(self.f) + ")"
作业3 ecc_lab
这个是相对来说比较难一点,因为是关于汉明码编码译码的。做的时候花了不少时间,不过把编译码的过程弄清楚就没有问题了,回头来看还是比较简单的。
代码如下:
from vec import Vec from mat import Mat from bitutil import * from GF2 import one from matutil import * ## Task 1 part 1 """ Create an instance of Mat representing the generator matrix G. You can use the procedure listlist2mat in the matutil module (be sure to import first). Since we are working over GF (2), you should use the value one from the GF2 module to represent 1""" G = listlist2mat([[one,0,one,one],[one,one,0,one],[0,0,0,one],[one,one,one,0],[0,0,one,0],[0,one,0,0],[one,0,0,0]]) ## Task 1 part 2 # Please write your answer as a list. Use one from GF2 and 0 as the elements. encoding_1001 = [0,0,one,one,0,0,one] ## Task 2 # Express your answer as an instance of the Mat class. R = listlist2mat([[0,0,0,0,0,0,one],[0,0,0,0,0,one,0],[0,0,0,0,one,0,0],[0,0,one,0,0,0,0]]) ## Task 3 # Create an instance of Mat representing the check matrix H. H = listlist2mat([[0,0,0,one,one,one,one],[0,one,one,0,0,one,one],[one,0,one,0,one,0,one]]) ## Task 4 part 1 def find_error(e): """ Input: an error syndrome as an instance of Vec Output: the corresponding error vector e Examples: >>> find_error(Vec({0,1,2}, {0:one})) Vec({0, 1, 2, 3, 4, 5, 6},{3: one}) >>> find_error(Vec({0,1,2}, {2:one})) Vec({0, 1, 2, 3, 4, 5, 6},{0: one}) >>> find_error(Vec({0,1,2}, {1:one, 2:one})) Vec({0, 1, 2, 3, 4, 5, 6},{2: one}) """ nh=mat2coldict(H) for t in H.D[1]: if nh[t]==e: return Vec(H.D[1],{t:one}) return Vec(H.D[1],{}) ## Task 4 part 2 # Use the Vec class for your answers. non_codeword = Vec({0,1,2,3,4,5,6}, {0: one, 1:0, 2:one, 3:one, 4:0, 5:one, 6:one}) error_vector = Vec({0, 1, 2, 3, 4, 5, 6},{6: one}) code_word = Vec({0, 1, 2, 3, 4, 5, 6},{0: one, 1: 0, 2: one, 3: one, 4: 0, 5: one, 6: 0}) original = Vec({0, 1, 2, 3},{0: 0, 1: one, 2: 0, 3: one}) # R * code_word ## Task 5 def find_error_matrix(S): """ Input: a matrix S whose columns are error syndromes Output: a matrix whose cth column is the error corresponding to the cth column of S. Example: >>> S = listlist2mat([[0,one,one,one],[0,one,0,0],[0,0,0,one]]) >>> find_error_matrix(S) Mat(({0, 1, 2, 3, 4, 5, 6}, {0, 1, 2, 3}), {(1, 2): 0, (3, 2): one, (0, 0): 0, (4, 3): one, (3, 0): 0, (6, 0): 0, (2, 1): 0, (6, 2): 0, (2, 3): 0, (5, 1): one, (4, 2): 0, (1, 0): 0, (0, 3): 0, (4, 0): 0, (0, 1): 0, (3, 3): 0, (4, 1): 0, (6, 1): 0, (3, 1): 0, (1, 1): 0, (6, 3): 0, (2, 0): 0, (5, 0): 0, (2, 2): 0, (1, 3): 0, (5, 3): 0, (5, 2): 0, (0, 2): 0}) """ return coldict2mat({x:find_error(mat2coldict(S)[x]) for x in S.D[1]}) ## Task 6 s = "I'm trying to free your mind, Neo. But I can only show you the door. You’re the one that has to walk through it." P = bits2mat(str2bits(s)) ## Task 7 C = G*P bits_before = 896 bits_after = 1568 ## Ungraded Task CTILDE = None ## Task 8 def correct(A): """ Input: a matrix A each column of which differs from a codeword in at most one bit Output: a matrix whose columns are the corresponding valid codewords. Example: >>> A = Mat(({0,1,2,3,4,5,6}, {1,2,3}), {(0,3):one, (2, 1): one, (5, 2):one, (5,3):one, (0,2): one}) >>> correct(A) Mat(({0, 1, 2, 3, 4, 5, 6}, {1, 2, 3}), {(0, 1): 0, (1, 2): 0, (3, 2): 0, (1, 3): 0, (3, 3): 0, (5, 2): one, (6, 1): 0, (3, 1): 0, (2, 1): 0, (0, 2): one, (6, 3): one, (4, 2): 0, (6, 2): one, (2, 3): 0, (4, 3): 0, (2, 2): 0, (5, 1): 0, (0, 3): one, (4, 1): 0, (1, 1): 0, (5, 3): one}) """ return find_error_matrix(H*A)+A