def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' D = rowlist[0].D x = zero_vec(D) num_labels = len(label_list) for j in reversed(range(len(D))): if j > len(rowlist)-1: continue row = rowlist[j] if row == zero_vec(D): continue # in the row find the label of the column with the first non-zero entry for i in range(num_labels): if row[label_list[i]] == one: break c = label_list[i] x[c] = (b[j] - x*row)/row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' D = rowlist[0].D ncols = len(D) x = zero_vec(D) # remove all zero rows at the bottom i = len(rowlist) while rowlist[i-1] == zero_vec(D): i -= 1 for j in reversed(range(i)): row = rowlist[j] pivot_index = 0 # lowest possible pivot index (should be set to j) c = label_list[pivot_index] while row[c] == 0: pivot_index += 1 c = label_list[pivot_index] x[c] = (b[j] - x*row)/row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' from vecutil import zero_vec D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(rowlist))): index_row = 0 non_zero = False row = rowlist[j] while (index_row < len(D) and non_zero != True): if row[label_list[index_row]] != 0: non_zero = True c = label_list[index_row] x[c] = (b[j] - x * row) / row[c] index_row += 1 return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(b))): row = rowlist[j] l = [(i,row[i]) for i in label_list if row[i] !=0] if len(l)> 0: nonzero = l[0] else: continue c = nonzero[0] x[c] = (b[j] - x*row)/nonzero[1] return x
def echelon_solve(row_list, label_list, b): ''' Input: - row_list: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in row_list - b: a vector (represented as a list) Output: - Vec x such that row_list * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True ''' D = row_list[0].D x = zero_vec(D) for j in reversed(range(len(row_list))): row = row_list[j] for c in label_list: if row[c] != 0: x[c] = (b[j] - x*row) / row[c] break return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' from vecutil import zero_vec D = rowlist[0].D x = zero_vec(D) k = label_list c = len(k) for j in reversed(range(len(rowlist))): row = rowlist[j] for i in range(len(k)): if row[k[i]] != 0 and i < c: x[k[i]] = b[j] - row * x c = i return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(rowlist))): c = label_list[j] row = rowlist[j] for l in label_list: if l in row.f and row.f[l] == one: c = l break if row[c] != 0: x[c] = (b[j] - x * row) / row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' def find_first_non_zero_col(row, label_list): for c in label_list: if (row[c]) != 0: return c return None D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(rowlist))): row = rowlist[j] c = find_first_non_zero_col(row, label_list) if c is None: continue else: x[c] = (b[j] - x * row) / row[c] return x
def echelon_solve(row_list, label_list, b): ''' Input: - row_list: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in row_list - b: a vector (represented as a list) Output: - Vec x such that row_list * x is b D = {'A','B','C','D','E'} U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] b_list = [one,0,one] cols = ['A', 'B', 'C', 'D', 'E'] echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True ''' x = zero_vec(row_list[0].D) #print (x,len(row_list[0].D)) for j in reversed(range(len(row_list))): #c = label_list[j] #print(j,row_list[j]) d=row_list[j].f #print (d) for z in label_list: if d.get(z,0) !=0: #print (z,d,d.get(z,0)) x[z] = (b[j] - x*row_list[j])/d.get(z,0) break #print (x) return x
def triangular_solve_n(rowlist, b): ''' Solves an upper-triangular linear system. rowlist is a nonempty list of Vecs. Let n = len(rowlist). The domain D of all these Vecs is {0,1, ..., n-1}. b is an n-element list or a Vec whose domain is {0,1, ..., n-1}. The linear equations are: rowlist[0] * x = b[0] ... rowlist[n-1] * x = b[n-1] The system is triangular. That means rowlist[i][j] is zero for all i, j in {0,1, ..., n-1} such that i >j. This procedure assumes that rowlist[j][j] != 0 for j=0,1, ..., n-1. The procedure returns the Vec x that is the unique solution to the linear system. ''' D = rowlist[0].D n = len(D) assert D == set(range(n)) x = zero_vec(D) for j in reversed(range(n)): x[j] = (b[j] - rowlist[j] * x)/rowlist[j][j] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' D = set(label_list) x = zero_vec(D) for j, row in enumerate(reversed(rowlist)): j = len(rowlist) - j - 1 c = -1 for label in label_list: if row[label] != 0: c = label break if c == -1: continue x[c] = (b[j] - x * row) / row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' sorted_ll = sorted(label_list) solution = zero_vec(set(label_list)) for r in range(len(rowlist) - 1, -1, -1): indexOfFirstNonZero = 0 firstNonZeroFound = False for c in sorted_ll: if rowlist[r][c] != 0: firstNonZeroFound = True indexOfFirstNonZero = c break if firstNonZeroFound: solution[indexOfFirstNonZero] = b[r] - solution * rowlist[ r] # if it's not GF(2) then divide rhs by coeff which is rowlist[r][c] return solution
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' from vecutil import zero_vec D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(rowlist))): index_row = 0 non_zero = False row = rowlist[j] while ( index_row < len(D) and non_zero != True ): if row[label_list[index_row]] != 0: non_zero = True c = label_list[index_row] x[c] = (b[j] - x*row)/row[c] index_row+=1 return x
def echelon_solve(row_list, label_list, b): ''' Input: - row_list: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in row_list - b: a vector (represented as a list) Output: - Vec x such that row_list * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True ''' D = row_list[0].D assert D == set(label_list) x = zero_vec(D) for i in reversed(range(len(row_list))): row = row_list[i] for j in (range(len(D))): if row[label_list[j]] != 0 : c = label_list[j] x[c] = (b[i] - x*row)/row[c] break return x
def triangular_solve(rowlist, label_list, b): ''' Solves an upper-triangular linear system. rowlist is a nonempty list of Vecs. Let n = len(rowlist). b is an n-element list or a Vec over domain {0,1, ..., n-1}. The linear equations are: rowlist[0] * x = b[0] ... rowlist[n-1] * x = b[n-1] label_list is a list consisting of all the elements of D, where D is the domain of each of the vectors in rowlist. The system is triangular with respect to the ordering given by label_list. That means rowlist[n-1][d] is zero for every element d of D except for the last element of label_list, rowlist[n-2][d] is zero for every element d of D except for the last two elements of label_list, and so on. This procedure assumes that rowlist[j][label_list[j]] != 0 for j = 0,1, ..., n-1. The procedure returns the Vec x that is the unique solution to the linear system. ''' print() D = rowlist[0].D print(D) x = zero_vec(D) print(x) for j in reversed(range(len(D) - 1)): c = label_list[j] row = rowlist[j] x[c] = (b[j] - x*row)/row[c] return x
def echelon_solve(rowlist, label_list, b): """ Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) """ x = zero_vec(set(label_list)) for i in reversed(range(len(rowlist))): row = rowlist[i] j = next((l for l in label_list if row[l] != 0), None) # first non-zero element of row if j == None: continue res = row * x x[j] = (b[i] - res) / row[j] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' new_rowlist = [] new_b = [] rows_left = set(range(len(rowlist))) new_label_list = [] for c in label_list: rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0] if rows_with_nonzero != []: pivot = rows_with_nonzero[0] rows_left.remove(pivot) new_rowlist.append(rowlist[pivot]) new_b.append(b[pivot]) new_label_list.append(c) from vecutil import zero_vec D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(new_b))): c = new_label_list[j] row = new_rowlist[j] x[c] = (new_b[j] - x*row)/row[c] return x
def echelon_solve(row_list, label_list, b): ''' Input: - row_list: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in row_list - b: a vector (represented as a list) Output: - Vec x such that row_list * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True ''' D = label_list x = zero_vec(row_list[0].D) b_len = len(row_list) for j in reversed(range(len(row_list))): c = label_list[j] row = row_list[j] try: x[c] = (b[j] - x * row) / row[c] except ZeroDivisionError: pass return x
def triangular_solve(rowlist, label_list, b): ''' Solves an upper-triangular linear system. rowlist is a nonempty list of Vecs. Let n = len(rowlist). b is an n-element list or a Vec over domain {0,1, ..., n-1}. The linear equations are: rowlist[0] * x = b[0] ... rowlist[n-1] * x = b[n-1] label_list is a list consisting of the elements of D, where D is the domain of each of the vectors in rowlist. The system is triangular with respect to the ordering given by label_list. That means rowlist[n-1][d] is zero for every element d of D except for the last element of label_list, rowlist[n-2][d] is zero for every element d of D except for the last two elements of label_list, and so on. This procedure assumes that rowlist[j][label_list[j]] != 0 for j = 0,1, ..., n-1. The procedure returns the Vec x that is the unique solution to the linear system. ''' D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(D))): c = label_list[j] row = rowlist[j] x[c] = (b[j] - x*row)/row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' sorted_ll = sorted(label_list) solution = zero_vec(set(label_list)) for r in range(len(rowlist)-1,-1,-1): indexOfFirstNonZero=0 firstNonZeroFound=False for c in sorted_ll: if rowlist[r][c] != 0: firstNonZeroFound=True indexOfFirstNonZero=c break if firstNonZeroFound: solution[indexOfFirstNonZero] = b[r] - solution*rowlist[r] # if it's not GF(2) then divide rhs by coeff which is rowlist[r][c] return solution
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' Dom = rowlist[0].D n = len(rowlist) x = vu.zero_vec(Dom) for j in reversed(range(n)): row = rowlist[j] cList = [i for i in range(len(Dom)) if row[label_list[i]] != 0] if len(cList) > 0: c = label_list[cList[0]] x[c] = (b[j] - x * row)/row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' Dom = rowlist[0].D n = len(rowlist) x = vu.zero_vec(Dom) for j in reversed(range(n)): row = rowlist[j] cList = [i for i in range(len(Dom)) if row[label_list[i]] != 0] if len(cList) > 0: c = label_list[cList[0]] x[c] = (b[j] - x * row) / row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' D = set(label_list) x = zero_vec(D) for j, row in enumerate(reversed(rowlist)): j = len(rowlist) - j - 1 c = -1 for label in label_list: if row[label] != 0: c = label break if c == -1: continue x[c] = (b[j] - x*row)/row[c] return x
def echelon_solve(row_list, label_list, b): ''' Input: - row_list: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in row_list - b: a vector (represented as a list) Output: - Vec x such that row_list * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True ''' D = row_list[0].D x = zero_vec(D) for j in reversed(range(len(row_list))): r = row_list[j] for c in label_list: if (r[c] != 0): #print('c={0}, r[c]={1}, j={4}, b[j]={2}, x*r={3}'.format(c,r[c],b[j],x*r,j)) x[c] = b[j] - x * r break return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one]>>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' new_rowlist = [] new_b = [] rows_left = set(range(len(rowlist))) new_label_list = [] for c in label_list: rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0] if rows_with_nonzero != []: pivot = rows_with_nonzero[0] rows_left.remove(pivot) new_rowlist.append(rowlist[pivot]) new_b.append(b[pivot]) new_label_list.append(c) from vecutil import zero_vec D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(new_b))): c = new_label_list[j] row = new_rowlist[j] x[c] = (new_b[j] - x * row) / row[c] return x
def triangular_solve(rowlist, label_list, b): D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(D))): c = label_list[j] row = rowlist[j] x[c] = (b[j] - x*row)/row[c] if row[c] != 0 else 1 return x
def triangular_solve(rowlist, label_list, b): D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(D))): c = label_list[j] row = rowlist[j] x[c] = (b[j] - x * row) / row[c] return x
def triangular_solve_n(rowlist, b): D = rowlist[0].D n = len(D) assert D == set(range(n)) x = zero_vec(D) for j in reversed(range(n)): x[j] = (b[j] - rowlist[j] * x)/rowlist[j][j] return x
def signum(u): v = zero_vec(u.D) for i in v.D: if u[i] >= 0: v[i] = 1 else: v[i] = -1 return v
def triangular_solve_n(rowlist, b): D = rowlist[0].D n = len(D) assert D == set(range(n)) x = zero_vec(D) for i in reversed(range(n)): x[i] = (b[i] - rowlist[i] * x) / rowlist[i][i] return x
def find_null_basis(A): Q, R = factor(A) R_inverse = find_matrix_inverse(R) R_inverse_list = mat2coldict(R_inverse) Q_list = mat2coldict(Q) zero_vector = zero_vec(Q_list[0].D) return [ R_inverse_list[i] for i in range(len(Q_list)) if Q_list[i] is zero_vector ]
def vec_sum(veclist, D): ''' >>> D = {'a','b','c'} >>> v1 = Vec(D, {'a': 1}) >>> v2 = Vec(D, {'a': 0, 'b': 1}) >>> v3 = Vec(D, { 'b': 2}) >>> v4 = Vec(D, {'a': 10, 'b': 10}) >>> vec_sum([v1, v2, v3, v4], D) == Vec(D, {'b': 13, 'a': 11}) True ''' return sum(veclist, zero_vec(D))
def vec_sum(veclist, D): ''' >>> D = {'a', 'b', 'c'} >>> veclist = [ Vec(D, {'a':10, 'b':20, 'c':30}), Vec(D, {'a':5, 'b':12, 'c':19}), Vec(D, {'a':11, 'b':22, 'c':33}) ] >>> vec_sum(veclist, D) == Vec(D, {'a':26, 'b':54, 'c':82}) True ''' vector_sum = zero_vec(D) for d in D: vector_sum[d] = sum([v[d] for v in veclist]) return vector_sum
def vector_matrix_mul(v, M): "Returns the product of vector v and matrix M" assert M.D[0] == v.D vec = zero_vec(M.D[1]) for mr,mc in M.f.keys(): for vc in v.f.keys(): if mr == vc: vec[mc] += v[vc] * M[(mr,mc)] return vec
def basis_AT(A): basis = [] M = transformation(A) U = M * A M_rowdict = mat2rowdict(M) U_rowdict = mat2rowdict(U) M_rowlist = [M_rowdict[i] for i in sorted(M_rowdict)] U_rowlist = [U_rowdict[i] for i in sorted(U_rowdict)] zero_vector = zero_vec(U_rowlist[0].D) for i in range(len(U_rowlist)): if (U_rowlist[i] == zero_vector): basis.append(M_rowlist[i]) return basis
def vec_sum(veclist, D): ''' >>> D = {'a','b','c'} >>> v1 = Vec(D, {'a': 1}) >>> v2 = Vec(D, {'a': 0, 'b': 1}) >>> v3 = Vec(D, { 'b': 2}) >>> v4 = Vec(D, {'a': 10, 'b': 10}) >>> vec_sum([v1, v2, v3, v4], D) == Vec(D, {'b': 13, 'a': 11}) True ''' from vecutil import zero_vec return sum(veclist,zero_vec(D))
def matrix_vector_mul(M, v): "Returns the product of matrix M and vector v" assert M.D[1] == v.D rows = M.D[0] vec = zero_vec(rows) for vr in v.f.keys(): for mr,mc in M.f.keys(): if vr == mc: vec[mr] += v[vr] * M[(mr,mc)] return vec
def lin_comb_vec_mat_mult(v, M): "Returns the product of vector v and matrix M" assert M.D[0] == v.D rows = M.D[0] cols = M.D[1] vec = zero_vec(cols) for c in cols: for r in rows: vec[c] += v[c] * M[(r,c)] return vec
def lin_comb_mat_vec_mult(M, v): "Returns the product of matrix M and vector v" assert M.D[1] == v.D rows = M.D[0] cols = M.D[1] vec = zero_vec(rows) for r in rows: for c in cols: vec[r] += M([r,c]) * v[r] return vec
def echelon_solve(row_list, label_list, b): ''' Input: - row_list: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in row_list - b: a vector (represented as a list) Output: - Vec x such that row_list * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True >>> U_rows == [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] True >>> b_list == [one,0,one] True ''' x = zero_vec(label_list) n = len(label_list) - len(row_list) zero_list = [x for i in range(n)] row_list = row_list + zero_list for j in reversed(range(len(label_list))): c = label_list[j] row = row_list[j] if (row == zero_vec(label_list)): continue else: x[c] = (b[j] - x*row)/row[c] return x
def find_error(syndrome): """ 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}) True >>> find_error(Vec({0,1,2}, {2:one})) == Vec({0, 1, 2, 3, 4, 5, 6},{0: one}) True >>> find_error(Vec({0,1,2}, {1:one, 2:one})) == Vec({0, 1, 2, 3, 4, 5, 6},{2: one}) True >>> find_error(Vec({0,1,2}, {})) == Vec({0,1,2,3,4,5,6}, {}) True """ return Vec(set(range(7)), {} if syndrome == zero_vec(set(range(3))) else {sum((2 ** (2 - k) for k, v in syndrome.f.items() if v == one)) - 1: one})
def echelon_solve(rowlist, label_list, b): x = zero_vec(label_list) entry_col = [] label_row = range(len(rowlist)) assert is_echelon(rowlist) for i in label_row: for j in label_list: if rowlist[i][j] is not 0: entry_col.append(j) break for i in reversed(label_row): for c in reversed(entry_col): row = rowlist[i] x[c] = (b[i] - x * row) / row[c] entry_col.remove(c) break return x
def echelon_solve(row_list, label_list, b): ''' Input: - row_list: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in row_list - b: a vector (represented as a list) Output: - Vec x such that row_list * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) True >>> U_rows == [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] True >>> b_list == [one,0,one] True >>> U_rows= [Vec(D,{'A':one,'C':one,'D':one}), Vec(D,{'B':one,'E':one}),Vec(D,{'C':one,'E':one}), Vec(D,{'E':one})] >>> b_list= [one,0,one,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': one, 'E': one, 'A': one}) True >>> U_list = [Vec({'B', 'E', 'C', 'D', 'A'},{0: one, 1: 0, 2: one, 3: one, 4: 0}), Vec({'B', 'E', 'C', 'D', 'A'},{0: 0, 1: one, 2: 0, 3: 0, 4: one}), Vec({'B', 'E', 'C', 'D', 'A'},{0: 0, 1: 0, 2: one, 3: 0, 4: one}), Vec({'B', 'E', 'C', 'D', 'A'},{0: 0, 1: 0, 2: 0, 3: 0, 4: one})] >>> b_list = [one,0,one,one] >>> echelon_solve(U_list, cols, b_list) == Vec({'B', 'E', 'C', 'D', 'A'},{0: one, 1: one, 2: 0, 3: 0, 4: one}) True ''' D = row_list[0].D x = zero_vec(D) for j in reversed(range(len(row_list))): for c in label_list: row = row_list[j] if row[c] != 0: x[c] = (b[j] - x * row) / row[c] break return x
def direct_sum_decompose(U_basis, V_basis, w): ''' input: A list of Vecs, U_basis, containing a basis for a vector space, U. A list of Vecs, V_basis, containing a basis for a vector space, V. A Vec, w, that belongs to the direct sum of these spaces. output: A pair, (u, v), such that u+v=w and u is an element of U and v is an element of V. >>> U_basis = [Vec({0, 1, 2, 3, 4, 5},{0: 2, 1: 1, 2: 0, 3: 0, 4: 6, 5: 0}), Vec({0, 1, 2, 3, 4, 5},{0: 11, 1: 5, 2: 0, 3: 0, 4: 1, 5: 0}), Vec({0, 1, 2, 3, 4, 5},{0: 3, 1: 1.5, 2: 0, 3: 0, 4: 7.5, 5: 0})] >>> V_basis = [Vec({0, 1, 2, 3, 4, 5},{0: 0, 1: 0, 2: 7, 3: 0, 4: 0, 5: 1}), Vec({0, 1, 2, 3, 4, 5},{0: 0, 1: 0, 2: 15, 3: 0, 4: 0, 5: 2})] >>> w = Vec({0, 1, 2, 3, 4, 5},{0: 2, 1: 5, 2: 0, 3: 0, 4: 1, 5: 0}) >>> direct_sum_decompose(U_basis, V_basis, w) == (Vec({0, 1, 2, 3, 4, 5},{0: 2.0, 1: 4.999999999999972, 2: 0.0, 3: 0.0, 4: 1.0, 5: 0.0}), Vec({0, 1, 2, 3, 4, 5},{0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0, 5: 0.0})) True ''' M = rowdict2mat(U_basis+V_basis) solution=solve(M.transpose(),w) zero=[zero_vec(U_basis[0].D)] uvec=solution*rowdict2mat(U_basis+zero*len(V_basis)) vvec=solution*rowdict2mat(zero*len(U_basis)+V_basis) return (uvec,vvec)
def direct_sum_decompose(U_basis, V_basis, w): ''' input: A list of Vecs, U_basis, containing a basis for a vector space, U. A list of Vecs, V_basis, containing a basis for a vector space, V. A Vec, w, that belongs to the direct sum of these spaces. output: A pair, (u, v), such that u+v=w and u is an element of U and v is an element of V. >>> U_basis = [Vec({0, 1, 2, 3, 4, 5},{0: 2, 1: 1, 2: 0, 3: 0, 4: 6, 5: 0}), Vec({0, 1, 2, 3, 4, 5},{0: 11, 1: 5, 2: 0, 3: 0, 4: 1, 5: 0}), Vec({0, 1, 2, 3, 4, 5},{0: 3, 1: 1.5, 2: 0, 3: 0, 4: 7.5, 5: 0})] >>> V_basis = [Vec({0, 1, 2, 3, 4, 5},{0: 0, 1: 0, 2: 7, 3: 0, 4: 0, 5: 1}), Vec({0, 1, 2, 3, 4, 5},{0: 0, 1: 0, 2: 15, 3: 0, 4: 0, 5: 2})] >>> w = Vec({0, 1, 2, 3, 4, 5},{0: 2, 1: 5, 2: 0, 3: 0, 4: 1, 5: 0}) >>> direct_sum_decompose(U_basis, V_basis, w) == (Vec({0, 1, 2, 3, 4, 5},{0: 2.0, 1: 4.999999999999972, 2: 0.0, 3: 0.0, 4: 1.0, 5: 0.0}), Vec({0, 1, 2, 3, 4, 5},{0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0, 5: 0.0})) True ''' M = rowdict2mat(U_basis + V_basis) solution = solve(M.transpose(), w) zero = [zero_vec(U_basis[0].D)] uvec = solution * rowdict2mat(U_basis + zero * len(V_basis)) vvec = solution * rowdict2mat(zero * len(U_basis) + V_basis) return (uvec, vvec)
def GF2_span(D, S): ''' >>> from GF2 import one >>> D = {'a', 'b', 'c'} >>> GF2_span(D, {Vec(D, {'a':one, 'c':one}), Vec(D, {'c':one})}) == {Vec({'a', 'b', 'c'},{}), Vec({'a', 'b', 'c'},{'a': one, 'c': one}), Vec({'a', 'b', 'c'},{'c': one}), Vec({'a', 'b', 'c'},{'a': one})} True >>> GF2_span(D, {Vec(D, {'a': one, 'b': one}), Vec(D, {'a':one}), Vec(D, {'b':one})}) == {Vec({'a', 'b', 'c'},{'a': one, 'b': one}), Vec({'a', 'b', 'c'},{'b': one}), Vec({'a', 'b', 'c'},{'a': one}), Vec({'a', 'b', 'c'},{})} True >>> S={Vec({0,1},{0:one}), Vec({0,1},{1:one})} >>> GF2_span({0,1}, S) == {Vec({0, 1},{0: one, 1: one}), Vec({0, 1},{1: one}), Vec({0, 1},{0: one}), Vec({0, 1},{})} True >>> S == {Vec({0, 1},{1: one}), Vec({0, 1},{0: one})} True ''' if len(S) == 0: return set([zero_vec(D)]) else: newS = set(S) v = newS.pop() part_sol = GF2_span(D, newS) return part_sol | {v + x for x in part_sol}
def vector_matrix_mul(v, M): """ returns the product of vector v and matrix M >>> v1 = Vec({1, 2, 3}, {1: 1, 2: 8}) >>> M1 = Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7}) >>> v1*M1 == Vec({'a', 'b', 'c'},{'a': -8, 'b': 2, 'c': 0}) True >>> v1 == Vec({1, 2, 3}, {1: 1, 2: 8}) True >>> M1 == Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7}) True >>> v2 = Vec({'a','b'}, {}) >>> M2 = Mat(({'a','b'}, {0, 2, 4, 6, 7}), {}) >>> v2*M2 == Vec({0, 2, 4, 6, 7},{}) True """ assert M.D[0] == v.D ans = zero_vec(M.D[1]) for i, j in M.f: ans[j] += v[i] * M[i, j] return ans
def triangular_solve(rowlist, label_list, b): ''' Solves an upper-triangular linear system. rowlist is a nonempty list of Vecs. Let n = len(rowlist). b is an n-element list or a Vec over domain {0,1, ..., n-1}. The linear equations are: rowlist[0] * x = b[0] ... rowlist[n-1] * x = b[n-1] label_list is a list consisting of all the elements of D, where D is the domain of each of the vectors in rowlist. The system is triangular with respect to the ordering given by label_list. That means rowlist[n-1][d] is zero for every element d of D except for the last element of label_list, rowlist[n-2][d] is zero for every element d of D except for the last two elements of label_list, and so on. This procedure assumes that rowlist[j][label_list[j]] != 0 for j = 0,1, ..., n-1. The procedure returns the Vec x that is the unique solution to the linear system. >>> label_list = ['a','b','c','d'] >>> D = set(label_list) >>> rowlist=[Vec(D,{'a':4, 'b':-2,'c':0.5,'d':1}), Vec(D,{'b':2,'c':3,'d':3}), \ Vec(D,{'c':5, 'd':1}), Vec(D,{'d':2.})] >>> b = [6, -4, 3, -8] >>> triangular_solve(rowlist, label_list, b) Vec({'d', 'b', 'c', 'a'},{'d': -4.0, 'b': 1.9, 'c': 1.4, 'a': 3.275}) ''' D = rowlist[0].D x = zero_vec(D) for j in reversed(range(len(D))): c = label_list[j] row = rowlist[j] x[c] = (b[j] - x*row)/row[c] return x
def echelon_solve(rowlist, label_list, b): ''' Input: - rowlist: a list of Vecs - label_list: a list of labels establishing an order on the domain of Vecs in rowlist - b: a vector (represented as a list) Output: - Vec x such that rowlist * x is b >>> D = {'A','B','C','D','E'} >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] >>> b_list = [one,0,one] >>> cols = ['A', 'B', 'C', 'D', 'E'] >>> echelon_solve(U_rows, cols, b_list) Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) ''' solved_vec = zero_vec(set(label_list)) for i in reversed(range(len(rowlist))): for j in label_list: if getitem(rowlist[i],j) != 0: solved_vec.f[j] = (b[i] - solved_vec * rowlist[i])/getitem(rowlist[i], j) break return solved_vec
def has_solution(rowlist, b): zero_vector = zero_vec(rowlist[0].D) for i in range(len(rowlist)): if (rowlist[i] == zero_vector and b[i] is not 0): return False return True
class Vec: def __init__(self, labels, function): self.D = labels self.f = function v0 = Vec({'A', 'B', 'C'}, {'A': 1}) # quiz 2.7.1 def zero_vec(D): f = {_: 0 for _ in D} return Vec(D, f) v1 = zero_vec({'a', 'b', 'c'}) def setitem(v, d, val): v.f[d] = val setitem(v0, 'B', 2) def getitem(v, d): if d in v.f: return v.f[d] else: return 0