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 r = Vec(M.D[1], {}) for (p,q), value in M.f.items(): if p in v.f: r = r + Vec(M.D[1], {q:value*v.f[p]}) return r
def cvecs( self ): """ Return centering vectors for this space group. """ typ = self.mydata['symb'][0] ##TODO: find vectors for B and test for A and C and R ##TODO: http://img.chem.ucl.ac.uk/sgp/large/146az1.htm ##TODO: http://img.chem.ucl.ac.uk/sgp/large/ortho.htm << extended list of space groups vs = { 'A':[ Vec( 0, 0.5, 0.5 ) ], 'B':[ Vec( 0.5, 0, 0.5 ) ], 'C':[ Vec( 0.5, 0.5, 0 ) ], 'F':[ Vec( 0, 0.5, 0.5 ),Vec( 0.5, 0, 0.5 ), Vec( 0.5, 0.5, 0 ) ], 'I':[ Vec( 0.5, 0.5, 0.5 ) ], 'P':[], } if typ in vs: return vs[ typ ] elif typ == 'R': if self.snum == 2: return [] elif self.snum == 1: return [ Vec( 2/3.0, 1/3.0, 1/3.0 ), Vec( 1/3.0, 2/3.0, 2/3.0 ) ]
def vector_matrix_mul(v, M): "Returns the product of vector v and matrix M" assert M.D[0] == v.D dict_store = {} for j in M.D[1]: res = 0 for i in M.D[0]: if i in v.f: if (i, j) in M.f: res += v.f[i] * M.f[(i, j)] if res != 0: dict_store.update({j: res}) return Vec(M.D[1], dict_store)
def matrix_vector_mul(M, v): "Returns the product of matrix M and vector v" assert M.D[1] == v.D dict_store = {} for i in M.D[0]: res = 0 for j in M.D[1]: if j in v.f: if (i, j) in M.f: res += M.f[(i, j)] * v.f[j] if res != 0: dict_store.update({i: res}) return Vec(M.D[0], dict_store)
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}) 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 """ H_col = matutil.mat2coldict(H) return Vec({0, 1, 2, 3, 4, 5, 6}, {i: one for i in range(7) if e == H_col[i]})
def find_matrix_inverse(A): ''' Input: - A: an invertible Mat over GF(2) Output: - A Mat that is the inverse of A Examples: >>> M1 = Mat(({0,1,2}, {0,1,2}), {(0, 1): one, (1, 0): one, (2, 2): one}) >>> find_matrix_inverse(M1) == Mat(M1.D, {(0, 1): one, (1, 0): one, (2, 2): one}) True ''' B = {i: Vec(A.D[0], {i: one}) for i in A.D[1]} B_dict = dict() for key in B.keys(): B_dict[key] = solve(A, B[key]) return coldict2mat(B_dict)
def find_triangular_matrix_inverse(A): ''' Supporting GF2 is not required. Input: - A: an upper triangular Mat with nonzero diagonal elements Output: - Mat that is the inverse of A Example: >>> A = listlist2mat([[1, .5, .2, 4],[0, 1, .3, .9],[0,0,1,.1],[0,0,0,1]]) >>> find_triangular_matrix_inverse(A) == Mat(({0, 1, 2, 3}, {0, 1, 2, 3}), {(0, 1): -0.5, (1, 2): -0.3, (3, 2): 0.0, (0, 0): 1.0, (3, 3): 1.0, (3, 0): 0.0, (3, 1): 0.0, (2, 1): 0.0, (0, 2): -0.05000000000000002, (2, 0): 0.0, (1, 3): -0.87, (2, 3): -0.1, (2, 2): 1.0, (1, 0): 0.0, (0, 3): -3.545, (1, 1): 1.0}) True ''' id_vecs = [Vec(A.D[0], {i: 1}) for i in A.D[0]] return coldict2mat([solve(A, v) for v in id_vecs])
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 ''' result = Vec(D.copy(), dict()) for d in D: result[d] = 0 for v in veclist: result[d] += v[d] return result
def signum(u): ''' Input: - u: Vec Output: - v: Vec such that: if u[d] >= 0, then v[d] = 1 if u[d] < 0, then v[d] = -1 Example: >>> signum(Vec({1,2,3},{1:2, 2:-1})) == Vec({1,2,3},{1:1,2:-1,3:1}) True ''' return Vec( u.D, {key: 1 if key not in u.f or u.f[key] >= 0 else -1 for key in u.D})
def make_Vec(primeset, factors): ''' Input: - primeset: a set of primes - factors: a list of factors [(p_1,a_1), ..., (p_n, a_n)] with p_i in primeset Output: - a vector v over GF(2) with domain primeset such that v[p_i] = int2GF2(a_i) for all i Example: >>> make_Vec({2,3,11}, [(2,3), (3,2)]) == Vec({2,3,11},{2:one}) True ''' return Vec(primeset, {k: int2GF2(v) for k, v in factors if int2GF2(v) == one})
def scale_vecs(vecdict): ''' >>> v1 = Vec({1,2,3}, {2: 9}) >>> v2 = Vec({1,2,4}, {1: 1, 2: 2, 4: 8}) >>> scale_vecs({3: v1, 5: v2}) == [Vec({1,2,3},{2: 3.0}), Vec({1,2,4},{1: 0.2, 2: 0.4, 4: 1.6})] True ''' scaledList = [] for key, val in vecdict.items(): scaledVec = {} for k, v in val.f.items(): scaledVec[k] = v / key scaledList.append(Vec(val.D, scaledVec)) return scaledList
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 """ col_dict = mat2coldict(H) return Vec(H.D[1], {err: one for err in col_dict if col_dict[err] == syndrome})
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 """ n = sum([2**i if syndrome[2 - i] == one else 0 for i in range(3)]) return Vec(set(range(7)), {n - 1: one} if n > 0 else dict())
def mat2rowdict(A): """ Given a matrix, return a dictionary mapping row labels of A to rows of A e.g.: >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) >>> mat2rowdict(M) {0: Vec({0, 1},{0: 3, 1: 1}), 1: Vec({0, 1},{0: 4, 1: 0}), 2: Vec({0, 1},{0: 8, 1: -2})} >>> mat2rowdict(Mat(({0,1},{0,1}),{})) {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} """ return { row: Vec(A.D[1], {col: A[row, col] for col in A.D[1]}) for row in A.D[0] }
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 find_matrix_inverse(A): ''' Input: - A: an invertible Mat over GF(2) Output: - A Mat that is the inverse of A Examples: >>> M1 = Mat(({0,1,2}, {0,1,2}), {(0, 1): one, (1, 0): one, (2, 2): one}) >>> find_matrix_inverse(M1) == Mat(M1.D, {(0, 1): one, (1, 0): one, (2, 2): one}) True >>> M2 = Mat(({0,1,2,3},{0,1,2,3}),{(0,1):one,(1,0):one,(2,2):one}) >>> find_matrix_inverse(M2) == Mat(M2.D, {(0, 1): one, (1, 0): one, (2, 2): one}) True ''' id_vecs = [Vec(A.D[0], {i: one}) for i in A.D[0]] return coldict2mat([solve(A, v) for v in id_vecs])
def is_superfluous(S, v): ''' Input: - S: set of vectors as instances of Vec class - v: vector in S as instance of Vec class Output: True if the span of the vectors of S is the same as the span of the vectors of S, excluding v. False otherwise. Examples: >>> from vec import Vec >>> D={'a','b','c','d'} >>> S = {Vec(D, {'a':1,'b':-1}), Vec(D, {'c':-1,'b':1}), Vec(D, {'c':1,'d':-1}), Vec(D, {'a':-1,'d':1}), Vec(D, {'b':1, 'c':1, 'd':-1})} >>> is_superfluous(S,Vec(D, {'b':1, 'c':1, 'd':-1})) False >>> is_superfluous(S,Vec(D, {'a':-1,'d':1})) True >>> is_superfluous(S,Vec(D, {'c':1,'d':-1})) True >>> S == {Vec(D,{'a':1,'b':-1}),Vec(D,{'c':-1,'b':1}),Vec(D,{'c':1,'d':-1}),Vec(D, {'a':-1,'d':1}),Vec(D,{'b':1, 'c':1, 'd':-1})} True >>> is_superfluous({Vec({0,1}, {})}, Vec({0,1}, {})) True >>> is_superfluous({Vec({0,1}, {0:1})}, Vec({0,1}, {0:1})) False >>> from GF2 import one >>> from vecutil import list2vec >>> S = {list2vec(v) for v in [[one,0,0,0],[0,one,0,0],[0,0,one,0],[0,0,0,one],[one,one,one,0]]} >>> is_superfluous(S, list2vec([one,0,0,0])) True >>> is_superfluous(S, list2vec([one,one,one,0])) True >>> is_superfluous(S, list2vec([0,0,0,one])) False ''' assert v in S if (v == Vec(v.D, {})): return True if (len(S) == 1): return False m = coldict2mat([v1 for v1 in S if v1 != v]) result = solve(m, v) return (v - m * result).is_almost_zero()
def aug_orthonormalize(L): ''' Input: - L: a list of Vecs Output: - A pair Qlist, Rlist such that: * coldict2mat(L) == coldict2mat(Qlist) * coldict2mat(Rlist) * Qlist = orthonormalize(L) >>> from vec import Vec >>> D={'a','b','c','d'} >>> L = [Vec(D, {'a':4,'b':3,'c':1,'d':2}), Vec(D, {'a':8,'b':9,'c':-5,'d':-5}), Vec(D, {'a':10,'b':1,'c':-1,'d':5})] >>> Qlist, Rlist = aug_orthonormalize(L) >>> from matutil import coldict2mat >>> print(coldict2mat(Qlist)) <BLANKLINE> 0 1 2 --------------------- a | 0.73 0.187 0.528 b | 0.548 0.403 -0.653 c | 0.183 -0.566 -0.512 d | 0.365 -0.695 0.181 <BLANKLINE> >>> print(coldict2mat(Rlist)) <BLANKLINE> 0 1 2 ------------------ 0 | 5.48 8.03 9.49 1 | 0 11.4 -0.636 2 | 0 0 6.04 <BLANKLINE> >>> print(coldict2mat(Qlist)*coldict2mat(Rlist)) <BLANKLINE> 0 1 2 --------- a | 4 8 10 b | 3 9 1 c | 1 -5 -1 d | 2 -5 5 <BLANKLINE> ''' (a, b) = aug_orthogonalize(L) norms = [sqrt(v * v) for v in a] Qlist = [a[i] / norms[i] for i in range(len(a))] scaler = coldict2mat([Vec(b[i].D, {i: norms[i]}) for i in range(len(b))]) Rlist = [scaler * v for v in b] return (Qlist, Rlist)
def GF2_span(D, S): ''' >>> from GF2 import one >>> D = {'a', 'b', 'c'} >>> S = [Vec(D, {'a': one, 'c' :one}), Vec(D, {'b':one})] >>> len(GF2_span(D,S)) 4 >>> 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 ''' ''' pseudo code: 1.create a list of lists(of len S) of all possible combinations of 0 and ones. (use itertools.product) 2.create a convert_list by converting set S to a list 3.create an empty result set 4.create an empty sum set -- this will be used to add vectors multiplied by possible combinations of zeros and ones 5 iterate over each combination in a combinations list iterate over a list of indexes in a combination multiply current element of convert_list by current element in current combination list add a sum of vectors in a sum_set to a result set you need to reset the sum_set and now you have a result set to return ''' if len(S) == 0: return {Vec(D, {})} r = set() # for i in product({0,one}, repeat=len(S)): # r.update(sum([u*v for (u,v) in zip(i,S)])) # return r # return [sum([a*v for (a,v) in zip(i,S)]) for i in product({0,one},repeat=len(S))] if len(S) !=0 else Vec(D,{}) # probably spent eight hours trying to grok this; simple solution hantempo s = S.copy() k = s.pop() s = GF2_span(D, s) r.update(s) r.update({v + k for v in s}) return r
def dot_product_vec_mat_mult(v, M): ''' The following doctests are not comprehensive; they don't test the main question, which is whether the procedure uses the appropriate dot-product definition of vector-matrix multiplication. Examples: >>> M=Mat(({'a','b'},{0,1}), {('a',0):7, ('a',1):1, ('b',0):-5, ('b',1):2}) >>> v=Vec({'a','b'},{'a':2, 'b':-1}) >>> dot_product_vec_mat_mult(v,M) == Vec({0, 1},{0: 19, 1: 0}) True >>> M1=Mat(({'a','b'},{0,1}), {('a',0):8, ('a',1):2, ('b',0):-2, ('b',1):1}) >>> v1=Vec({'a','b'},{'a':4,'b':3}) >>> dot_product_vec_mat_mult(v1,M1) == Vec({0, 1},{0: 26, 1: 11}) True ''' assert(v.D == M.D[0]) return Vec(M.D[1], {x:y*v for x,y in mat2coldict(M).items()})
def find_matrix_inverse(A): ''' input: An invertible matrix, A, over GF(2) output: Inverse of A >>> M = Mat(({0, 1, 2}, {0, 1, 2}), {(0, 1): one, (1, 2): 0, (0, 0): 0, (2, 0): 0, (1, 0): one, (2, 2): one, (0, 2): 0, (2, 1): 0, (1, 1): 0}) >>> find_matrix_inverse(M) == Mat(({0, 1, 2}, {0, 1, 2}), {(0, 1): one, (2, 0): 0, (0, 0): 0, (2, 2): one, (1, 0): one, (1, 2): 0, (1, 1): 0, (2, 1): 0, (0, 2): 0}) True ''' # A * [b1|b2|b3] = I I_col_dict = {i:Vec(A.D[0],{i:one}) for i in A.D[1]} #print (I_basis_list) B_coldict = dict() for key in I_col_dict.keys(): B_coldict[key] = solve(A,I_col_dict[key]) return coldict2mat(B_coldict)
def find_num_links(L): ''' Input: - L: a square matrix representing link structure Output: - A vector mapping each column label of L to the number of non-zero entries in the corresponding column of L Example: >>> from matutil import listlist2mat >>> find_num_links(listlist2mat([[1,1,1],[1,1,0],[1,0,0]])) Vec({0, 1, 2},{0: 3, 1: 2, 2: 1}) ''' num_links_vec = Vec(L.D[1], {}) for ((row, col), num_links) in L.f.items(): num_links_vec[col] += num_links return num_links_vec
def power_method(A, i): ''' Input: - A1: a matrix - i: number of iterations to perform Output: - An approximation to the stationary distribution Example: >>> from matutil import listlist2mat >>> power_method(listlist2mat([[0.6,0.5],[0.4,0.5]]), 10) Vec({0, 1},{0: 0.5464480874307794, 1: 0.45355191256922034}) ''' v = Vec(A.D[1],{c:1 for c in A.D[1]}) for i in range(k): w = A*v v = w/sqrt(w*w) return v
def render(self, screen, font): description_surf = font.render(self.description, False, (255, 255, 255)) description_border_surf = font.render(self.description, False, (0, 0, 0)) #I round the variable so that it does not go off the screen var_surf = font.render(str(round(self.variable.var, 2)), False, (255, 255, 255)) var_border_surf = font.render(str(round(self.variable.var, 2)), False, (0, 0, 0)) #Draw the description and variable with a border utils.render_bordered(screen, description_surf, description_border_surf, self.pos) utils.render_bordered(screen, var_surf, var_border_surf, Vec(self.pos.x, self.pos.y + 20))
def scale_vecs(vecdict): ''' >>> v1 = Vec({1,2,4}, {2: 9}) >>> v2 = Vec({1,2,4}, {1: 1, 2: 2, 4: 8}) >>> result = scale_vecs({3: v1, 5: v2}) >>> len(result) 2 >>> [v in [Vec({1,2,4},{2: 3.0}), Vec({1,2,4},{1: 0.2, 2: 0.4, 4: 1.6})] for v in result] [True, True] ''' result = [] for key in vecdict.keys(): temp_vec = Vec(vecdict[key].D, {}) for element in vecdict[key].f.keys(): temp_vec[element] = vecdict[key][element] / key result.append(temp_vec) return result
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}) """ d = sum([0 if e[i] == 0 else 2**(2-i) for i in {0,1,2}]) e = Vec({0,1,2,3,4,5,6},{}) if d > 0: e[d-1] = one return e
def find_error(err_syndrome): ret = Vec({0, 1, 2, 3, 4, 5, 6}, { 0: zero, 1: zero, 2: zero, 3: zero, 4: zero, 5: zero, 6: zero }) err = H * err_syndrome H_dict = mat2coldict(H) for k in H_dict.keys(): if (err == H_dict[k]): ret[k] = one break return ret
def matrix_matrix_mul(A, B): """ Returns the result of the matrix-matrix multiplication, A*B. Consider using brackets notation A[...] and B[...] in your procedure to access entries of the input matrices. This avoids some sparsity bugs. >>> A = Mat(({0,1,2}, {0,1,2}), {(1,1):4, (0,0):0, (1,2):1, (1,0):5, (0,1):3, (0,2):2}) >>> B = Mat(({0,1,2}, {0,1,2}), {(1,0):5, (2,1):3, (1,1):2, (2,0):0, (0,0):1, (0,1):4}) >>> A*B == Mat(({0,1,2}, {0,1,2}), {(0,0):15, (0,1):12, (1,0):25, (1,1):31}) True >>> C = Mat(({0,1,2}, {'a','b'}), {(0,'a'):4, (0,'b'):-3, (1,'a'):1, (2,'a'):1, (2,'b'):-2}) >>> D = Mat(({'a','b'}, {'x','y'}), {('a','x'):3, ('a','y'):-2, ('b','x'):4, ('b','y'):-1}) >>> C*D == Mat(({0,1,2}, {'x','y'}), {(0,'y'):-5, (1,'x'):3, (1,'y'):-2, (2,'x'):-5}) True >>> M = Mat(({0, 1}, {'a', 'c', 'b'}), {}) >>> N = Mat(({'a', 'c', 'b'}, {(1, 1), (2, 2)}), {}) >>> M*N == Mat(({0,1}, {(1,1), (2,2)}), {}) True >>> E = Mat(({'a','b'},{'A','B'}), {('a','A'):1,('a','B'):2,('b','A'):3,('b','B'):4}) >>> F = Mat(({'A','B'},{'c','d'}),{('A','d'):5}) >>> E*F == Mat(({'a', 'b'}, {'d', 'c'}), {('b', 'd'): 15, ('a', 'd'): 5}) True >>> F.transpose()*E.transpose() == Mat(({'d', 'c'}, {'a', 'b'}), {('d', 'b'): 15, ('d', 'a'): 5}) True """ assert A.D[1] == B.D[0] #make a vector of each matrix row #from matutil #{row:Vec(A.D[1], {col:A[row,col] for col in A.D[1]}) for row in A.D[0]} #treat it like multiple vector_matrix_mul problems where each row of matrix is a vector #DONE ==> convert list of vector-rows into matrix #Mat(({0,1}, a.D), {(i,j): ab[i].f[j] for i in {0,1} for j in a.D}) rowdomain = A.D[0] columndomain = B.D[1] if A.f == {} or B.f == {}: return Mat((rowdomain, columndomain), {}) else: mat2vecsdict = {row:Vec(A.D[1], {col:A[row,col] for col in A.D[1] if A[row,col] != 0}) for row in A.D[0]} mat2vecs = [v for v in mat2vecsdict.values()] #does this always maintain the order of rows? mat = [v * B for v in mat2vecs] return Mat((rowdomain, columndomain), {(list(rowdomain)[i],j): mat[i].f[j] for i in range(len(rowdomain)) for j in columndomain if j in mat[i].f.keys()})
def matrix_vector_mul(M, v): """ Returns the product of matrix M and vector v. >>> N1 = Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1}) >>> u1 = Vec({'a', 'b'}, {'a': 1, 'b': 2}) >>> N1*u1 == Vec({1, 3, 5, 7},{1: 3, 3: 9, 5: -2, 7: 3}) True >>> N1 == Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1}) True >>> u1 == Vec({'a', 'b'}, {'a': 1, 'b': 2}) True >>> N2 = Mat(({('a', 'b'), ('c', 'd')}, {1, 2, 3, 5, 8}), {}) >>> u2 = Vec({1, 2, 3, 5, 8}, {}) >>> N2*u2 == Vec({('a', 'b'), ('c', 'd')},{}) True """ assert M.D[1] == v.D return Vec(M.D[0], {i: sum([M[i, j] * v[j] for j in v.D]) for i in M.D[0]})
def make_Vec(primeset, factors): ''' Input: - primeset: a set of primes - factors: a list of factors [(p_1,a_1), ..., (p_n, a_n)] with p_i in primeset Output: - a vector v over GF(2) with domain primeset such that v[p_i] = int2GF2(a_i) for all i Example: >>> make_Vec({2,3,11}, [(2,3), (3,2)]) == Vec({2,3,11},{2:one}) True ''' returnVecSet = {} for entry in factors: returnVecSet[entry[0]] = int2GF2(entry[1]) return Vec(primeset, returnVecSet)