├── README.md ├── Week0-The_Function_and_the_Field ├── Inverse_Index_Lab │ ├── dictutil.py │ ├── inverse_index_lab.pdf │ ├── inverse_index_lab.py │ ├── inverse_index_lab_git.py │ ├── stories_big.txt │ └── stories_small.txt ├── Python_Lab │ ├── python_lab.pdf │ └── python_lab.py ├── The_Field_Problems │ ├── GF2.py │ ├── The_Field_problems.pdf │ ├── The_Field_problems.py │ ├── image.py │ ├── img01.png │ ├── plotting.py │ └── png.py └── The_Function_Problems │ ├── The_Function_problems.pdf │ └── The_Function_problems.py ├── Week1-The_Vector ├── Politics_Lab │ ├── UN_voting_data.txt │ ├── US_Senate_voting_data_109.txt │ ├── politics_lab.pdf │ ├── politics_lab.py │ └── voting_record_dump109.txt ├── The_Vector_Problems │ ├── The_Vector_problems.pdf │ └── The_Vector_problems.py └── Vector_Class_Homework │ ├── vec.pdf │ └── vec.py ├── Week2-The_Vector_Space ├── The_Vector_Space_Problems │ ├── The_Vector_Space_problems.pdf │ ├── The_Vector_Space_problems.py │ ├── vec.py │ └── vecutil.py ├── coursera_submit.py └── profile.txt ├── Week3-The_Matrix ├── Error_Correcting_Code_Lab │ ├── bitutil.py │ ├── ecc_lab.pdf │ ├── ecc_lab.py │ ├── mat.py │ ├── matutil.py │ └── vec.py ├── Matrix_Class_Homework │ ├── mat.pdf │ ├── mat.py │ └── mat_sparsity.py └── The_Matrix_Problems │ ├── The_Matrix_problems.pdf │ ├── The_Matrix_problems.py │ ├── UN_voting_data.txt │ ├── mat.py │ ├── matutil.py │ ├── solver.py │ └── vec.py ├── Week4-The_Basis ├── Geometry_Lab │ ├── geometry_lab.pdf │ ├── geometry_lab.py │ ├── image_mat_util.py │ ├── mat.py │ ├── png.py │ └── vec.py └── The_Basis_Problems │ ├── The_Basis_problems.pdf │ ├── The_Basis_problems.py │ ├── mat.py │ ├── matutil.py │ ├── solver.py │ └── vec.py ├── Week5-Dimension ├── Dimension_Problems │ ├── Dimension_problems.pdf │ ├── Dimension_problems.py │ ├── independence.py │ ├── mat.py │ ├── solver.py │ ├── triangular.py │ └── vec.py └── Perspective_Lab │ ├── board.png │ ├── cit.png │ ├── image_mat_util.py │ ├── mat.py │ ├── perspective_lab.pdf │ ├── perspective_lab.py │ ├── png.py │ └── vec.py ├── Week6-Gaussian_Elimination_and_the_Inner_Product ├── Gaussian_Elimination_Problems │ ├── Gaussian_Elimination_problems.pdf │ ├── Gaussian_Elimination_problems.py │ ├── cracking_rand.py │ ├── echelon.py │ ├── gaussian_examples.py │ ├── mat.py │ └── vec.py ├── Integer_Factoring_Lab │ ├── factoring_lab.pdf │ ├── factoring_lab.py │ ├── factoring_support.py │ ├── mat.py │ └── vec.py ├── Secret_Sharing_Lab │ ├── bitutil.py │ ├── cracking_rand.py │ ├── echelon.py │ ├── gaussian_examples.py │ ├── mat.py │ ├── secret_sharing_lab.pdf │ ├── secret_sharing_lab.py │ └── vec.py └── The_Inner_Product_Problems │ ├── The_Inner_Product_problems.pdf │ ├── The_Inner_Product_problems.py │ ├── mat.py │ ├── orthogonalization.py │ └── vec.py ├── Week7-Orthogonalization ├── Machine_Learning_Lab │ ├── cancer_data.py │ ├── machine_learning_lab.pdf │ ├── machine_learning_lab.py │ ├── mat.py │ ├── orthogonalization.py │ ├── train.data │ ├── validate.data │ └── vec.py └── Orthogonalization_Problems │ ├── GF2.py │ ├── Orthogonalization_problems.pdf │ ├── Orthogonalization_problems.py │ ├── Orthogonalization_problems.py.bak │ ├── QR.py │ ├── age-height.txt │ ├── bitutil.py │ ├── cancer_data.py │ ├── coursera_submit.py │ ├── dictutil.py │ ├── echelon.py │ ├── independence.py │ ├── machine_learning_lab.pdf │ ├── machine_learning_lab.py │ ├── mat.py │ ├── matutil.py │ ├── orthogonalization.py │ ├── python_lab.py │ ├── read_data.py │ ├── solver.py │ ├── train.data │ ├── triangular.py │ ├── validate.data │ ├── vec.py │ └── vecutil.py └── coursera_submit.py /README.md: -------------------------------------------------------------------------------- 1 | # Coding-the-Matrix 2 | This is a Coursera course, Coding the Matrix: Linear Algebra through Computer Science Applications by Philip Klein of Brown University. 3 | 4 | The cousrse id is matrix-002, 2015. Here are the Programing Assignments of the course.I hope you can do it by yourself. 5 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/Inverse_Index_Lab/dictutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | def dict2list(dct, keylist): return [ dct[i] for i in keylist ]¬ 3 | def list2dict(L, keylist): return { keylist[i]:L[i] for i in range(len(L)) } 4 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/Inverse_Index_Lab/inverse_index_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week0-The_Function_and_the_Field/Inverse_Index_Lab/inverse_index_lab.pdf -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/Inverse_Index_Lab/inverse_index_lab.py: -------------------------------------------------------------------------------- 1 | from random import randint # version code d345910f07ae 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | 6 | 7 | 8 | 9 | ## 1: (Task 1) Movie Review 10 | ## Task 1 11 | def movie_review(name): 12 | """ 13 | Input: the name of a movie 14 | Output: a string (one of the review options), selected at random using randint 15 | """ 16 | movie_reviews=['See it!', 'A gem!', 'Ideological claptrapl!'] 17 | return movie_reviews[randint(0, len(movie_reviews)-1)] 18 | 19 | 20 | 21 | 22 | ## 2: (Task 2) Make Inverse Index 23 | def makeInverseIndex(strlist): 24 | """ 25 | Input: a list of documents as strings 26 | Output: a dictionary that maps each word in any document to the set consisting of the 27 | document ids (ie, the index in the strlist) for all documents containing the word. 28 | Distinguish between an occurence of a string (e.g. "use") in the document as a word 29 | (surrounded by spaces), and an occurence of the string as a substring of a word (e.g. "because"). 30 | Only the former should be represented in the inverse index. 31 | Feel free to use a loop instead of a comprehension. 32 | 33 | Example: 34 | >>> makeInverseIndex(['hello world','hello','hello cat','hellolot of cats']) == {'hello': {0, 1, 2}, 'cat': {2}, 'of': {3}, 'world': {0}, 'cats': {3}, 'hellolot': {3}} 35 | True 36 | """ 37 | words=set() 38 | tmpsets={} 39 | for tmplist in strlist: 40 | words |= set(tmplist.split()) 41 | for w in words: 42 | tmpsetsVal=set() 43 | for i in range(len(strlist)): 44 | if w in strlist[i] and w in strlist[i].split(): 45 | tmpsetsVal |= {i} 46 | tmpsets[w] = set(tmpsetsVal) 47 | 48 | return tmpsets 49 | 50 | ## 3: (Task 3) Or Search 51 | def orSearch(inverseIndex, query): 52 | """ 53 | Input: an inverse index, as created by makeInverseIndex, and a list of words to query 54 | Output: the set of document ids that contain _any_ of the specified words 55 | Feel free to use a loop instead of a comprehension. 56 | >>> idx = makeInverseIndex(['Johann Sebastian Bach', 'Johannes Brahms', 'Johann Strauss the Younger', 'Johann Strauss the Elder', ' Johann Christian Bach', 'Carl Philipp Emanuel Bach']) 57 | >>> orSearch(idx, ['Bach','the']) 58 | {0, 2, 3, 4, 5} 59 | >>> orSearch(idx, ['Johann', 'Carl']) 60 | {0, 2, 3, 4, 5} 61 | """ 62 | qSets=set() 63 | for i in range(len(query)): 64 | if query[i] in list(inverseIndex.keys()): 65 | qSets |= inverseIndex[query[i]] 66 | return qSets 67 | 68 | ## 4: (Task 4) And Search 69 | def andSearch(inverseIndex, query): 70 | """ 71 | Input: an inverse index, as created by makeInverseIndex, and a list of words to query 72 | Output: the set of all document ids that contain _all_ of the specified words 73 | Feel free to use a loop instead of a comprehension. 74 | 75 | >>> idx = makeInverseIndex(['Johann Sebastian Bach', 'Johannes Brahms', 'Johann Strauss the Younger', 'Johann Strauss the Elder', ' Johann Christian Bach', 'Carl Philipp Emanuel Bach']) 76 | >>> andSearch(idx, ['Johann', 'the']) 77 | {2, 3} 78 | >>> andSearch(idx, ['Johann', 'Bach']) 79 | {0, 4} 80 | """ 81 | qSets=set(range(len(inverseIndex))) 82 | for i in range(len(query)): 83 | if query[i] in list(inverseIndex.keys()): 84 | qSets &= inverseIndex[query[i]] 85 | return qSets 86 | 87 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/Inverse_Index_Lab/inverse_index_lab_git.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | from dictutil import * 3 | 4 | ## Task 1 5 | def movie_review(name): 6 | """ 7 | Input: the name of a movie 8 | Output: a string (one of the review options), selected at random using randint 9 | """ 10 | review_options = ["See it!", "A gem!", "Ideological claptrap!"] 11 | return review_options[randint(0,len(review_options)-1)] 12 | 13 | ## Tasks 2 and 3 are in dictutil.py 14 | 15 | ## Task 4 16 | def makeInverseIndex(strlist): 17 | """ 18 | Input: a list of documents as strings 19 | Output: a dictionary that maps each word in any document to the set consisting of the 20 | document ids (ie, the index in the strlist) for all documents containing the word. 21 | Note that to test your function, you are welcome to use the files stories_small.txt 22 | or stories_big.txt included in the download. 23 | """ 24 | dict_inversed = {} 25 | for i in range(len(strlist)): 26 | strlist[i] = strlist[i].split() 27 | for j in range(len(strlist[i])): 28 | if strlist[i][j] not in dict_inversed: 29 | dict_inversed[strlist[i][j]] = {i} 30 | else: 31 | dict_inversed[strlist[i][j]] |= {i} 32 | return dict_inversed 33 | 34 | ## Task 5 35 | def orSearch(inverseIndex, query): 36 | """ 37 | Input: an inverse index, as created by makeInverseIndex, and a list of words to query 38 | Output: the set of document ids that contain _any_ of the specified words 39 | """ 40 | result = set() 41 | result |= inverseIndex[query[0]] 42 | for i in range(1, len(query)): 43 | result |= inverseIndex[query[i]] 44 | return result 45 | 46 | ## Task 6 47 | def andSearch(inverseIndex, query): 48 | """ 49 | Input: an inverse index, as created by makeInverseIndex, and a list of words to query 50 | Output: the set of all document ids that contain _all_ of the specified words 51 | """ 52 | result = set() 53 | result |= inverseIndex[query[0]] 54 | for i in range(1, len(query)): 55 | result &= inverseIndex[query[i]] 56 | return result -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/Python_Lab/python_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week0-The_Function_and_the_Field/Python_Lab/python_lab.pdf -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/Python_Lab/python_lab.py: -------------------------------------------------------------------------------- 1 | # version code a212a0defa59+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | 6 | 7 | 8 | 9 | ## 1: (Task 1) Minutes in a Week 10 | minutes_in_week = 60*24*7 11 | 12 | 13 | 14 | ## 2: (Task 2) Remainder 15 | remainder_without_mod = 2304811 - 2304811//47 *47 16 | 17 | 18 | 19 | ## 3: (Task 3) Divisibility 20 | divisible_by_3 = (673 % 3 == 0) and (909 % 3 == 0) 21 | 22 | 23 | 24 | ## 4: (Task 4) Conditional Expression 25 | x = -9 26 | y = 1/2 27 | expression_val = 2**(y+1/2) if x+10<0 else 2**(y-1/2) 28 | 29 | 30 | 31 | ## 5: (Task 5) Squares Set Comprehension 32 | first_five_squares = { x**2 for x in {1,2,3,4,5} } 33 | 34 | 35 | 36 | ## 6: (Task 6) Powers-of-2 Set Comprehension 37 | first_five_pows_two = { 2**x for x in {0,1,2,3,4} } 38 | 39 | 40 | 41 | ## 7: (Task 7) Double comprehension evaluating to nine-element set 42 | X1 = {1, 2, 3 } 43 | Y1 = { 5, 6 ,7} 44 | 45 | 46 | 47 | ## 8: (Task 8) Double comprehension evaluating to five-element set 48 | X2 = {1, 2, 4 } 49 | Y2 = {0, 8, 16 } 50 | 51 | 52 | 53 | ## 9: (Task 9) Set intersection as a comprehension 54 | S = {1, 2, 3, 4} 55 | T = {3, 4, 5, 6} 56 | # Replace { ... } with a one-line set comprehension that evaluates to the intersection of S and T 57 | S_intersect_T = { x for x in S if x in S and x in T } 58 | 59 | 60 | 61 | ## 10: (Task 10) Average 62 | list_of_numbers = [20, 10, 15, 75] 63 | # Replace ... with a one-line expression that evaluates to the average of list_of_numbers. 64 | # Your expression should refer to the variable list_of_numbers, and should work 65 | # for a list of any length greater than zero. 66 | list_average = sum(list_of_numbers) / len(list_of_numbers) 67 | 68 | 69 | 70 | ## 11: (Task 11) Cartesian-product comprehension 71 | # Replace ... with a double list comprehension over ['A','B','C'] and [1,2,3] 72 | cartesian_product = [ [x, y] for x in ['A','B','C'] for y in [1,2,3] ] 73 | 74 | 75 | 76 | ## 12: (Task 12) Sum of numbers in list of list of numbers 77 | LofL = [[.25, .75, .1], [-1, 0], [4, 4, 4, 4]] 78 | # Replace ... with a one-line expression of the form sum([sum(...) ... ]) that 79 | # includes a comprehension and evaluates to the sum of all numbers in all the lists. 80 | LofL_sum = sum([sum(x) for x in LofL]) 81 | 82 | 83 | 84 | ## 13: (Task 13) Three-element tuples summing to zero 85 | S = {-4, -2, 1, 2, 5, 0} 86 | # Replace [ ... ] with a one-line list comprehension in which S appears 87 | zero_sum_list = [ (i,j,k) for i in S for j in S for k in S if i+j+k == 0 ] 88 | 89 | 90 | 91 | ## 14: (Task 14) Nontrivial three-element tuples summing to zero 92 | S = {-4, -2, 1, 2, 5, 0} 93 | # Replace [ ... ] with a one-line list comprehension in which S appears 94 | exclude_zero_list = [ (i,j,k) for i in S for j in S for k in S if i+j+k == 0 if i != 0 or j !=0 or k != 0] 95 | 96 | 97 | 98 | ## 15: (Task 15) One nontrivial three-element tuple summing to zero 99 | S = {-4, -2, 1, 2, 5, 0} 100 | # Replace ... with a one-line expression that uses a list comprehension in which S appears 101 | first_of_tuples_list = [ (i,j,k) for i in S for j in S for k in S if i+j+k == 0 if i != j if j != k ][0] 102 | 103 | 104 | ## 16: (Task 16) List and set differ 105 | # Assign to example_L a list such that len(example_L) != len(list(set(example_L))) 106 | example_L = [0, 0, 1,2,3] 107 | 108 | 109 | 110 | ## 17: (Task 17) Odd numbers 111 | # Replace {...} with a one-line set comprehension over a range of the form range(n) 112 | odd_num_list_range = { i for i in range(100) if i % 2 == 1 } 113 | 114 | 115 | 116 | ## 18: (Task 18) Using range and zip 117 | # In the line below, replace ... with an expression that does not include a comprehension. 118 | # Instead, it should use zip and range. 119 | # Note: zip() does not return a list. It returns an 'iterator of tuples' 120 | L = ['A','B','C','D','E'] 121 | #range_and_zip = [(a, b) for (a, b) in zip(range(5), L) ] 122 | range_and_zip = list(zip(range(len(L)), L)) 123 | 124 | 125 | 126 | ## 19: (Task 19) Using zip to find elementwise sums 127 | A = [10, 25, 40] 128 | B = [1, 15, 20] 129 | # Replace [...] with a one-line comprehension that uses zip together with the variables A and B. 130 | # The comprehension should evaluate to a list whose ith element is the ith element of 131 | # A plus the ith element of B. 132 | list_sum_zip = [ sum(i) for i in zip(A,B) ] 133 | 134 | 135 | 136 | ## 20: (Task 20) Extracting the value corresponding to key k from each dictionary in a list 137 | dlist = [{'James':'Sean', 'director':'Terence'}, {'James':'Roger', 'director':'Lewis'}, {'James':'Pierce', 'director':'Roger'}] 138 | k = 'James' 139 | # Replace [...] with a one-line comprehension that uses dlist and k 140 | # and that evaluates to ['Sean','Roger','Pierce'] 141 | value_list = [ i[k] for i in dlist] 142 | 143 | 144 | 145 | ## 21: (Task 21) Extracting the value corresponding to k when it exists 146 | dlist = [{'Bilbo':'Ian','Frodo':'Elijah'},{'Bilbo':'Martin','Thorin':'Richard'}] 147 | k = 'Bilbo' 148 | #Replace [...] with a one-line comprehension 149 | value_list_modified_1 = [ i[k] if k in i else 'NOT PRESENT' for i in dlist ] # <-- Use the same expression here 150 | k = 'Frodo' 151 | value_list_modified_2 = [i.get(k,'NOT PRESENT') for i in dlist] # <-- as you do here 152 | 153 | 154 | 155 | ## 22: (Task 22) A dictionary mapping integers to their squares 156 | # Replace {...} with a one-line dictionary comprehension 157 | square_dict = { x:x*x for x in range(100) } 158 | 159 | 160 | 161 | ## 23: (Task 23) Making the identity function 162 | D = {'red','white','blue'} 163 | # Replace {...} with a one-line dictionary comprehension 164 | identity_dict = {x:x for x in D} 165 | 166 | 167 | 168 | ## 24: (Task 24) Mapping integers to their representation over a given base 169 | base = 10 170 | digits = set(range(base)) 171 | # Replace { ... } with a one-line dictionary comprehension 172 | # Your comprehension should use the variables 'base' and 'digits' so it will work correctly if these 173 | # are assigned different values (e.g. base = 2 and digits = {0,1}) 174 | representation_dict = {i:(i//base//base,i//base%base,i%base) for i in range(base*base*base) } 175 | 176 | 177 | 178 | ## 25: (Task 25) A dictionary mapping names to salaries 179 | id2salary = {0:1000.0, 1:1200.50, 2:990} 180 | names = ['Larry', 'Curly', 'Moe'] 181 | # Replace { ... } with a one-line dictionary comprehension that uses id2salary and names. 182 | listdict2dict = { names[k]:id2salary.get(k) for k in id2salary.keys()} 183 | 184 | 185 | 186 | ## 26: (Task 26) Procedure nextInts 187 | # Complete the procedure definition by replacing [ ... ] with a one-line list comprehension 188 | def nextInts(L): return [ i+1 for i in L ] 189 | 190 | 191 | 192 | ## 27: (Task 27) Procedure cubes 193 | # Complete the procedure definition by replacing [ ... ] with a one-line list comprehension 194 | def cubes(L): return [ i*i*i for i in L ] 195 | 196 | 197 | 198 | ## 28: (Task 28) Procedure dict2list 199 | # Input: a dictionary dct and a list keylist consisting of the keys of dct 200 | # Output: the list L such that L[i] is the value associated in dct with keylist[i] 201 | # Example: dict2list({'a':'A', 'b':'B', 'c':'C'},['b','c','a']) should equal ['B','C','A'] 202 | # Complete the procedure definition by replacing [ ... ] with a one-line list comprehension 203 | def dict2list(dct, keylist): return [ dct[i] for i in keylist ] 204 | 205 | 206 | 207 | ## 29: (Task 29) Procedure list2dict 208 | # Input: a list L and a list keylist of the same length 209 | # Output: the dictionary that maps keylist[i] to L[i] for i=0,1,...len(L)-1 210 | # Example: list2dict(['A','B','C'],['a','b','c']) should equal {'a':'A', 'b':'B', 'c':'C'} 211 | # Complete the procedure definition by replacing { ... } with a one-line dictionary comprehension 212 | def list2dict(L, keylist): return { keylist[i]:L[i] for i in range(len(L)) } 213 | 214 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Field_Problems/GF2.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from numbers import Number 3 | 4 | class One: 5 | def __add__(self, other): return self if other == 0 else 0 6 | __sub__ = __add__ 7 | def __mul__(self, other): 8 | if isinstance(other, Number): 9 | return 0 if other == 0 else self 10 | return other 11 | def __div__(self, other): 12 | if other == 0: raise ZeroDivisionError 13 | return self 14 | __truediv__ = __div__ 15 | def __rdiv__(self,other): return other 16 | __rtruediv__ = __rdiv__ 17 | __radd__ = __add__ 18 | __rsub__ = __add__ 19 | __rmul__ = __mul__ 20 | #hack to ensure not (one < 1e-16) by ensuring not (one < x) for every x 21 | def __lt__(self,other): return False 22 | 23 | def __str__(self): return 'one' 24 | __repr__ = __str__ 25 | def __neg__(self): return self 26 | def __bool__(self): return True 27 | def __format__(self, format_spec): return format(str(self),format_spec) 28 | 29 | one = One() 30 | zero = 0 31 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Field_Problems/The_Field_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week0-The_Function_and_the_Field/The_Field_Problems/The_Field_problems.pdf -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Field_Problems/The_Field_problems.py: -------------------------------------------------------------------------------- 1 | # version code 75eb0ae74c69 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | 6 | 7 | 8 | 9 | ## 1: (Problem 1) Python Comprehensions: Filtering 10 | def myFilter(L, num): 11 | ''' 12 | Input: 13 | -L: a list of numbers 14 | -num: a positive integer 15 | Output: 16 | -a list of numbers not containing a multiple of num 17 | Examples: 18 | >>> myFilter([1,2,4,5,7],2) 19 | [1, 5, 7] 20 | >>> myFilter([10,15,20,25],10) 21 | [15, 25] 22 | ''' 23 | return [ x for x in L if x%num != 0] 24 | 25 | 26 | ## 2: (Problem 2) Python Comprehensions: Lists of Lists 27 | 28 | def my_lists(L): 29 | ''' 30 | >>> my_lists([1,2,4]) 31 | [[1], [1, 2], [1, 2, 3, 4]] 32 | >>> my_lists([0,3]) 33 | [[], [1, 2, 3]] 34 | ''' 35 | return [ [x+1 for x in range(i)] for i in L] 36 | 37 | 38 | ## 3: (Problem 3) Python Comprehensions: Function Composition 39 | def myFunctionComposition(f, g): 40 | ''' 41 | Input: 42 | -f: a function represented as a dictionary such that g of f exists 43 | -g: a function represented as a dictionary such that g of f exists 44 | Output: 45 | -a dictionary that represents a function g of f 46 | Examples: 47 | >>> f = {0:'a',1:'b'} 48 | >>> g = {'a':'apple','b':'banana'} 49 | >>> myFunctionComposition(f,g) == {0:'apple',1:'banana'} 50 | True 51 | 52 | >>> a = {'x':24,'y':25} 53 | >>> b = {24:'twentyfour',25:'twentyfive'} 54 | >>> myFunctionComposition(a,b) == {'x':'twentyfour','y':'twentyfive'} 55 | True 56 | ''' 57 | #return { k1:v2 for k1 in f.keys() for v2 in g.values() if f.get(k1)==g.get } 58 | k1=list(f.keys()) 59 | v1=list(f.values()) 60 | k2=list(g.keys()) 61 | v2=list(g.values()) 62 | res={} 63 | for i in range(len(f)): 64 | for j in range(len(g)): 65 | if v1[i]==k2[j]: 66 | res[k1[i]]=v2[j] 67 | return res 68 | ## 4: (Problem 4) Summing numbers in a list 69 | def mySum(L): 70 | ''' 71 | Input: 72 | a list L of numbers 73 | Output: 74 | sum of the numbers in L 75 | Be sure your procedure works for the empty list. 76 | Examples: 77 | >>> mySum([1,2,3,4]) 78 | 10 79 | >>> mySum([3,5,10]) 80 | 18 81 | ''' 82 | current = 0 83 | for x in L: 84 | current = current + x 85 | return current 86 | 87 | 88 | ## 5: (Problem 5) Multiplying numbers in a list 89 | def myProduct(L): 90 | ''' 91 | Input: 92 | -L: a list of numbers 93 | Output: 94 | -the product of the numbers in L 95 | Be sure your procedure works for the empty list. 96 | Examples: 97 | >>> myProduct([1,3,5]) 98 | 15 99 | >>> myProduct([-3,2,4]) 100 | -24 101 | ''' 102 | current = 1 103 | for x in L: 104 | current = current * x 105 | return current 106 | 107 | 108 | 109 | ## 6: (Problem 6) Minimum of a list 110 | def myMin(L): 111 | ''' 112 | Input: 113 | a list L of numbers 114 | Output: 115 | the minimum number in L 116 | Be sure your procedure works for the empty list. 117 | Hint: The value of the Python expression float('infinity') is infinity. 118 | Examples: 119 | >>> myMin([1,-100,2,3]) 120 | -100 121 | >>> myMin([0,3,5,-2,-5]) 122 | -5 123 | ''' 124 | cur = L[0] 125 | for i in range(1,len(L)): 126 | if cur > L[i]: 127 | cur = L[i] 128 | return cur 129 | 130 | 131 | 132 | ## 7: (Problem 7) Concatenation of a List 133 | def myConcat(L): 134 | ''' 135 | Input: 136 | -L:a list of strings 137 | Output: 138 | -the concatenation of all the strings in L 139 | Be sure your procedure works for the empty list. 140 | Examples: 141 | >>> myConcat(['hello','world']) 142 | 'helloworld' 143 | >>> myConcat(['what','is','up']) 144 | 'whatisup' 145 | ''' 146 | S='' 147 | for x in L: 148 | S = S + x 149 | return S 150 | 151 | 152 | ## 8: (Problem 8) Union of Sets in a List 153 | def myUnion(L): 154 | ''' 155 | Input: 156 | -L:a list of sets 157 | Output: 158 | -the union of all sets in L 159 | Be sure your procedure works for the empty list. 160 | Examples: 161 | >>> myUnion([{1,2},{2,3}]) 162 | {1, 2, 3} 163 | >>> myUnion([set(),{3,5},{3,5}]) 164 | {3, 5} 165 | ''' 166 | U=set() 167 | for x in L: 168 | U = U | x 169 | return U 170 | 171 | 172 | ## 9: (Problem 9) Complex Addition Practice 173 | # Each answer should be a Python expression whose value is a complex number. 174 | 175 | complex_addition_a = 5+3j 176 | complex_addition_b = 0+1j 177 | complex_addition_c = -1+0.001j 178 | complex_addition_d = 0.001+9j 179 | 180 | 181 | ## 10: (Problem 10) Combining Complex Operations 182 | #Write a procedure that evaluates ax+b for all elements in L 183 | 184 | def transform(a, b, L): 185 | ''' 186 | Input: 187 | -a: a number 188 | -b: a number 189 | -L: a list of numbers 190 | Output: 191 | -a list of elements where each element is ax+b where x is an element in L 192 | Examples: 193 | >>> transform(3,2,[1,2,3]) 194 | [5, 8, 11] 195 | ''' 196 | return [ a*z+b for z in L] 197 | 198 | 199 | ## 11: (Problem 11) GF(2) Arithmetic 200 | GF2_sum_1 = 1# answer with 0 or 1 201 | GF2_sum_2 = 0 202 | GF2_sum_3 = 0 203 | 204 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Field_Problems/image.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | """ 3 | Basic types: 4 | file - a png file on disk 5 | image - a list of list of pixels. pixels can be triples of RGB intensities, 6 | or single grayscale values. 7 | display - not a type per se, but rather causing the type to be shown on screen 8 | 9 | Functions convert between these formats, and also can write to temporary files 10 | and display them with a web browser. 11 | """ 12 | 13 | # To do: check types of arguments, check that image has no alpha channel 14 | # Note that right now, we ignore the alpha channel, but allow it. - @dbp 15 | 16 | import png 17 | import numbers 18 | import collections 19 | 20 | # Native imports 21 | import webbrowser 22 | import tempfile 23 | import os 24 | import atexit 25 | 26 | # Round color coordinate to nearest int and clamp to [0, 255] 27 | def _color_int(col): 28 | return max(min(round(col), 255), 0) 29 | 30 | # utility conversions, between boxed pixel and flat pixel formats 31 | # the png library uses flat, we use boxed. 32 | def _boxed2flat(row): 33 | return [_color_int(x) for box in row for x in box] 34 | 35 | def _flat2boxed(row): 36 | # Note we skip every 4th element, thus eliminating the alpha channel 37 | return [tuple(row[i:i+3]) for i in range(0, len(row), 4)] 38 | 39 | ## Image conversions 40 | def isgray(image): 41 | "tests whether the image is grayscale" 42 | col = image[0][0] 43 | if isinstance(col, numbers.Number): 44 | return True 45 | elif isinstance(col, collections.Iterable) and len(col) == 3: 46 | return False 47 | else: 48 | raise TypeError('Unrecognized image type') 49 | 50 | def color2gray(image): 51 | """ Converts a color image to grayscale """ 52 | # we use HDTV grayscale conversion as per https://en.wikipedia.org/wiki/Grayscale 53 | image = [[x for x in row] for row in image] 54 | return [[int(0.2126*p[0] + 0.7152*p[1] + 0.0722*p[2]) for p in row] 55 | for row in image] 56 | 57 | def gray2color(image): 58 | """ Converts a grayscale image to color """ 59 | return [[(p,p,p) for p in row] for row in image] 60 | 61 | #extracting and combining color channels 62 | def rgbsplit(image): 63 | """ Converts an RGB image to a 3-element list of grayscale images, one for each color channel""" 64 | return [[[pixel[i] for pixel in row] for row in image] for i in (0,1,2)] 65 | 66 | def rgpsplice(R,G,B): 67 | return [[(R[row][col],G[row][col],B[row][col]) for col in range(len(R[0]))] for row in range(len(R))] 68 | 69 | ## To and from files 70 | def file2image(path): 71 | """ Reads an image into a list of lists of pixel values (tuples with 72 | three values). This is a color image. """ 73 | (w, h, p, m) = png.Reader(filename = path).asRGBA() # force RGB and alpha 74 | return [_flat2boxed(r) for r in p] 75 | 76 | 77 | def image2file(image, path): 78 | """ Writes an image in list of lists format to a file. Will work with 79 | either color or grayscale. """ 80 | if isgray(image): 81 | img = gray2color(image) 82 | else: 83 | img = image 84 | with open(path, 'wb') as f: 85 | png.Writer(width=len(image[0]), height=len(image)).write(f, 86 | [_boxed2flat(r) for r in img]) 87 | 88 | ## Display functions 89 | def image2display(image, browser=None): 90 | """ Stores an image in a temporary location and displays it on screen 91 | using a web browser. """ 92 | path = _create_temp('.png') 93 | image2file(image, path) 94 | hpath = _create_temp('.html') 95 | with open(hpath, 'w') as h: 96 | h.writelines(["" % path]) 97 | openinbrowser('file://%s' % hpath, browser) 98 | print("Hit Enter once the image is displayed.... ", end="") 99 | input() 100 | 101 | _browser = None 102 | 103 | def setbrowser(browser=None): 104 | """ Registers the given browser and saves it as the module default. 105 | This is used to control which browser is used to display the plot. 106 | The argument should be a value that can be passed to webbrowser.get() 107 | to obtain a browser. If no argument is given, the default is reset 108 | to the system default. 109 | 110 | webbrowser provides some predefined browser names, including: 111 | 'firefox' 112 | 'opera' 113 | 114 | If the browser string contains '%s', it is interpreted as a literal 115 | browser command line. The URL will be substituted for '%s' in the command. 116 | For example: 117 | 'google-chrome %s' 118 | 'cmd "start iexplore.exe %s"' 119 | 120 | See the webbrowser documentation for more detailed information. 121 | 122 | Note: Safari does not reliably work with the webbrowser module, 123 | so we recommend using a different browser. 124 | """ 125 | global _browser 126 | if browser is None: 127 | _browser = None # Use system default 128 | else: 129 | webbrowser.register(browser, None, webbrowser.get(browser)) 130 | _browser = browser 131 | 132 | def getbrowser(): 133 | """ Returns the module's default browser """ 134 | return _browser 135 | 136 | def openinbrowser(url, browser=None): 137 | if browser is None: 138 | browser = _browser 139 | webbrowser.get(browser).open(url) 140 | 141 | # Create a temporary file that will be removed at exit 142 | # Returns a path to the file 143 | def _create_temp(suffix='', prefix='tmp', dir=None): 144 | _f, path = tempfile.mkstemp(suffix, prefix, dir) 145 | os.close(_f) 146 | _remove_at_exit(path) 147 | return path 148 | 149 | # Register a file to be removed at exit 150 | def _remove_at_exit(path): 151 | atexit.register(os.remove, path) 152 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Field_Problems/img01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week0-The_Function_and_the_Field/The_Field_Problems/img01.png -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Field_Problems/plotting.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | """ 3 | This file contains a simple plotting interface, which uses a browser with SVG to 4 | present a plot of points represented as either complex numbers or 2-vectors. 5 | 6 | """ 7 | 8 | import webbrowser 9 | from numbers import Number 10 | 11 | import tempfile 12 | import os 13 | import atexit 14 | 15 | _browser = None 16 | 17 | def plot(L, scale=4, dot_size = 3, browser=None): 18 | """ plot takes a list of points, optionally a scale (relative to a 200x200 frame), 19 | optionally a dot size (diameter) in pixels, and optionally a browser name. 20 | It produces an html file with SVG representing the given plot, 21 | and opens the file in a web browser. It returns nothing. 22 | """ 23 | scalar = 200./scale 24 | origin = (210, 210) 25 | hpath = create_temp('.html') 26 | with open(hpath, 'w') as h: 27 | h.writelines( 28 | ['\n' 29 | ,'\n' 30 | ,'plot\n' 31 | ,'\n' 32 | ,'\n' 33 | ,'\n' 34 | ,'\n' 36 | ,'\n']) 38 | for pt in L: 39 | if isinstance(pt, Number): 40 | x,y = pt.real, pt.imag 41 | else: 42 | if isinstance(pt, tuple) or isinstance(pt, list): 43 | x,y = pt 44 | else: 45 | raise ValueError 46 | h.writelines(['\n' 47 | % (origin[0]+scalar*x,origin[1]-scalar*y,dot_size)]) 48 | h.writelines(['\n\n']) 49 | if browser is None: 50 | browser = _browser 51 | webbrowser.get(browser).open('file://%s' % hpath) 52 | 53 | def setbrowser(browser=None): 54 | """ Registers the given browser and saves it as the module default. 55 | This is used to control which browser is used to display the plot. 56 | The argument should be a value that can be passed to webbrowser.get() 57 | to obtain a browser. If no argument is given, the default is reset 58 | to the system default. 59 | 60 | webbrowser provides some predefined browser names, including: 61 | 'firefox' 62 | 'opera' 63 | 64 | If the browser string contains '%s', it is interpreted as a literal 65 | browser command line. The URL will be substituted for '%s' in the command. 66 | For example: 67 | 'google-chrome %s' 68 | 'cmd "start iexplore.exe %s"' 69 | 70 | See the webbrowser documentation for more detailed information. 71 | 72 | Note: Safari does not reliably work with the webbrowser module, 73 | so we recommend using a different browser. 74 | """ 75 | global _browser 76 | if browser is None: 77 | _browser = None # Use system default 78 | else: 79 | webbrowser.register(browser, None, webbrowser.get(browser)) 80 | _browser = browser 81 | 82 | def getbrowser(): 83 | """ Returns the module's default browser """ 84 | return _browser 85 | 86 | # Create a temporary file that will be removed at exit 87 | # Returns a path to the file 88 | def create_temp(suffix='', prefix='tmp', dir=None): 89 | _f, path = tempfile.mkstemp(suffix, prefix, dir) 90 | os.close(_f) 91 | remove_at_exit(path) 92 | return path 93 | 94 | # Register a file to be removed at exit 95 | def remove_at_exit(path): 96 | atexit.register(os.remove, path) 97 | -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Function_Problems/The_Function_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week0-The_Function_and_the_Field/The_Function_Problems/The_Function_problems.pdf -------------------------------------------------------------------------------- /Week0-The_Function_and_the_Field/The_Function_Problems/The_Function_problems.py: -------------------------------------------------------------------------------- 1 | # version code 3e169d60c2de+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | 6 | 7 | 8 | 9 | ## 1: (Problem 0.8.3) Tuple Sum 10 | def tuple_sum(A, B): 11 | ''' 12 | Input: 13 | -A: a list of tuples 14 | -B: a list of tuples 15 | Output: 16 | -list of pairs (x,y) in which the first element of the 17 | ith pair is the sum of the first element of the ith pair in 18 | A and the first element of the ith pair in B 19 | Examples: 20 | >>> tuple_sum([(1,2), (10,20)],[(3,4), (30,40)]) 21 | [(4, 6), (40, 60)] 22 | ''' 23 | s=[] 24 | for i in range(len(A)): 25 | s.append((A[i][0]+B[i][0],A[i][1]+B[i][1])) 26 | return s 27 | 28 | 29 | ## 2: (Problem 0.8.4) Inverse Dictionary 30 | def inv_dict(d): 31 | ''' 32 | Input: 33 | -d: dictionary representing an invertible function f 34 | Output: 35 | -dictionary representing the inverse of f, the returned dictionary's 36 | keys are the values of d and its values are the keys of d 37 | Example: 38 | >>> inv_dict({'goodbye': 'au revoir', 'thank you': 'merci'}) == {'merci':'thank you', 'au revoir':'goodbye'} 39 | ''' 40 | dd={} 41 | k=list(d.keys()) 42 | v=list(d.values()) 43 | for i in range(len(d)): 44 | dd[v[i]]=k[i] 45 | return dd 46 | 47 | 48 | ## 3: (Problem 0.8.5) Nested Comprehension 49 | def row(p, n): 50 | ''' 51 | Input: 52 | -p: a number 53 | -n: a number 54 | Output: 55 | - n-element list such that element i is p+i 56 | Examples: 57 | >>> row(10,4) 58 | [10, 11, 12, 13] 59 | ''' 60 | s=[] 61 | for i in range(n): 62 | s.append(p+i) 63 | return s 64 | comprehension_with_row = [ row(i,20) for i in range(15) ] 65 | 66 | comprehension_without_row = [ [i+j for j in range(20)] for i in range(15) ] 67 | 68 | 69 | 70 | ## 4: (Problem 0.8.10) Probability Exercise 1 71 | Pr_f_is_even = 0.7 72 | Pr_f_is_odd = 0.3 73 | 74 | 75 | 76 | ## 5: (Problem 0.8.11) Probability Exercise 2 77 | Pr_g_is_1 = 0.4 78 | Pr_g_is_0or2 = 0.6 79 | 80 | -------------------------------------------------------------------------------- /Week1-The_Vector/Politics_Lab/politics_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week1-The_Vector/Politics_Lab/politics_lab.pdf -------------------------------------------------------------------------------- /Week1-The_Vector/The_Vector_Problems/The_Vector_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week1-The_Vector/The_Vector_Problems/The_Vector_problems.pdf -------------------------------------------------------------------------------- /Week1-The_Vector/The_Vector_Problems/The_Vector_problems.py: -------------------------------------------------------------------------------- 1 | # version code ef5291f09f60+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # Some of the GF2 problems require use of the value GF2.one so the stencil imports it. 6 | 7 | from GF2 import one 8 | 9 | 10 | 11 | ## 1: (Problem 1) Vector Addition Practice 1 12 | #Please express each answer as a list of numbers 13 | p1_v = [-1, 3] 14 | p1_u = [0, 4] 15 | p1_v_plus_u = [-1,7] 16 | p1_v_minus_u = [-1, -1] 17 | p1_three_v_minus_two_u = [-3, 1] 18 | 19 | 20 | 21 | ## 2: (Problem 2) Vector Addition Practice 2 22 | p2_u = [-1, 1, 1] 23 | p2_v = [ 2, -1, 5] 24 | p2_v_plus_u = [1, 0, 6] 25 | p2_v_minus_u = [3, -2, 4] 26 | p2_two_v_minus_u = [5, -3, 9] 27 | p2_v_plus_two_u = [0,1,7] 28 | 29 | 30 | 31 | ## 3: (Problem 3) Vector Addition Practice 3 32 | # Write your answer using GF2's one instead of the number 1 33 | p3_vector_sum_1 = [one, 0, 0] 34 | p3_vector_sum_2 = [0, one, one] 35 | 36 | 37 | 38 | ## 4: (Problem 4) GF2 Vector Addition A 39 | # Please express your solution as a subset of the letters {'a','b','c','d','e','f'}. 40 | # For example, {'a','b','c'} is the subset consisting of: 41 | # a (1100000), b (0110000), and c (0011000). 42 | # The answer should be an empty set, written set(), if the given vector u cannot 43 | # be written as the sum of any subset of the vectors a, b, c, d, e, and f. 44 | 45 | u_0010010 = {'c','d','e'} 46 | u_0100010 = {'b','c','d','e'} 47 | 48 | 49 | ## 5: (Problem 5) GF2 Vector Addition B 50 | # Use the same format as the previous problem 51 | 52 | v_0010010 = {'c','d'} 53 | v_0100010 = set() 54 | 55 | 56 | 57 | ## 6: (Problem 6) Solving Linear Equations over GF(2) 58 | #You should be able to solve this without using a computer. 59 | x_gf2 = [1,0,0,0] 60 | 61 | 62 | 63 | ## 7: (Problem 7) Formulating Equations using Dot-Product 64 | #Please provide each answer as a list of numbers 65 | v1 = [2, 3, -4, 1] 66 | v2 = [1, -5, 2, 0] 67 | v3 = [4, 1, -1, -1] 68 | 69 | 70 | 71 | ## 8: (Problem 8) Practice with Dot-Product 72 | uv_a = 5 73 | uv_b = 6 74 | uv_c = 16 75 | uv_d = -1 76 | 77 | -------------------------------------------------------------------------------- /Week1-The_Vector/Vector_Class_Homework/vec.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week1-The_Vector/Vector_Class_Homework/vec.pdf -------------------------------------------------------------------------------- /Week1-The_Vector/Vector_Class_Homework/vec.py: -------------------------------------------------------------------------------- 1 | # version code 24ea27739109+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # Copyright 2013 Philip N. Klein 6 | 7 | def getitem(v,k): 8 | """ 9 | Return the value of entry k in v. 10 | Be sure getitem(v,k) returns 0 if k is not represented in v.f. 11 | 12 | >>> v = Vec({'a','b','c', 'd'},{'a':2,'c':1,'d':3}) 13 | >>> v['d'] 14 | 3 15 | >>> v['b'] 16 | 0 17 | """ 18 | return v.f[k] if k in v.f.keys() else 0 19 | def setitem(v,k,val): 20 | """ 21 | Set the element of v with label d to be val. 22 | setitem(v,d,val) should set the value for key d even if d 23 | is not previously represented in v.f. 24 | 25 | >>> v = Vec({'a', 'b', 'c'}, {'b':0}) 26 | >>> v['b'] = 5 27 | >>> v['b'] 28 | 5 29 | >>> v['a'] = 1 30 | >>> v['a'] 31 | 1 32 | >>> v['a'] = 0 33 | >>> v['a'] 34 | 0 35 | """ 36 | v.f[k]=val 37 | 38 | def equal(u,v): 39 | """ 40 | Return true iff u is equal to v. 41 | Because of sparse representation, it is not enough to compare dictionaries 42 | 43 | >>> Vec({'a', 'b', 'c'}, {'a':0}) == Vec({'a', 'b', 'c'}, {'b':0}) 44 | True 45 | 46 | Be sure that equal(u, v) check equalities for all keys from u.f and v.f even if 47 | some keys in u.f do not exist in v.f (or vice versa) 48 | 49 | >>> Vec({'x','y','z'},{'y':1,'x':2}) == Vec({'x','y','z'},{'y':1,'z':0}) 50 | False 51 | >>> Vec({'a','b','c'}, {'a':0,'c':1}) == Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) 52 | False 53 | >>> Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) == Vec({'a','b','c'}, {'a':0,'c':1}) 54 | False 55 | 56 | The keys matter: 57 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'b':1}) 58 | False 59 | 60 | The values matter: 61 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'a':2}) 62 | False 63 | 64 | """ 65 | assert u.D == v.D 66 | for k in u.D: 67 | if getitem(u,k)!=getitem(v,k): 68 | return False 69 | return True 70 | 71 | def add(u,v): 72 | """ 73 | Returns the sum of the two vectors. 74 | Make sure to add together values for all keys from u.f and v.f even if some keys in u.f do not 75 | exist in v.f (or vice versa) 76 | 77 | >>> a = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 78 | >>> b = Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 79 | >>> c = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2,'o':4,'u':7}) 80 | >>> a + b == c 81 | True 82 | >>> a == Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 83 | True 84 | >>> b == Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 85 | True 86 | >>> d = Vec({'x','y','z'}, {'x':2,'y':1}) 87 | >>> e = Vec({'x','y','z'}, {'z':4,'y':-1}) 88 | >>> f = Vec({'x','y','z'}, {'x':2,'y':0,'z':4}) 89 | >>> d + e == f 90 | True 91 | >>> b + Vec({'a','e','i','o','u'}, {}) == b 92 | True 93 | """ 94 | assert u.D == v.D 95 | s=u.copy() 96 | for k in u.D: 97 | setitem(s,k,getitem(u,k)+getitem(v,k)) 98 | return s 99 | def dot(u,v): 100 | """ 101 | Returns the dot product of the two vectors. 102 | 103 | >>> u1 = Vec({'a','b'}, {'a':1, 'b':2}) 104 | >>> u2 = Vec({'a','b'}, {'b':2, 'a':1}) 105 | >>> u1*u2 106 | 5 107 | >>> u1 == Vec({'a','b'}, {'a':1, 'b':2}) 108 | True 109 | >>> u2 == Vec({'a','b'}, {'b':2, 'a':1}) 110 | True 111 | >>> v1 = Vec({'p','q','r','s'}, {'p':2,'s':3,'q':-1,'r':0}) 112 | >>> v2 = Vec({'p','q','r','s'}, {'p':-2,'r':5}) 113 | >>> v1*v2 114 | -4 115 | >>> w1 = Vec({'a','b','c'}, {'a':2,'b':3,'c':4}) 116 | >>> w2 = Vec({'a','b','c'}, {'a':12,'b':8,'c':6}) 117 | >>> w1*w2 118 | 72 119 | 120 | The pairwise products should not be collected in a set before summing 121 | because a set eliminates duplicates 122 | >>> v1 = Vec({1, 2}, {1 : 3, 2 : 6}) 123 | >>> v2 = Vec({1, 2}, {1 : 2, 2 : 1}) 124 | >>> v1 * v2 125 | 12 126 | """ 127 | assert u.D == v.D 128 | s=0 129 | for k in u.D: 130 | s+= getitem(u,k)*getitem(v,k) 131 | return s 132 | 133 | def scalar_mul(v, alpha): 134 | """ 135 | Returns the scalar-vector product alpha times v. 136 | 137 | >>> zero = Vec({'x','y','z','w'}, {}) 138 | >>> u = Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 139 | >>> 0*u == zero 140 | True 141 | >>> 1*u == u 142 | True 143 | >>> 0.5*u == Vec({'x','y','z','w'},{'x':0.5,'y':1,'z':1.5,'w':2}) 144 | True 145 | >>> u == Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 146 | True 147 | """ 148 | u=v.copy() 149 | for k in v.D: 150 | setitem(u,k, alpha*getitem(v,k)) 151 | return u 152 | 153 | def neg(v): 154 | """ 155 | Returns the negation of a vector. 156 | 157 | >>> u = Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 158 | >>> -u 159 | Vec({8, 2, 4, 6},{8: -4, 2: -1, 4: -2, 6: -3}) 160 | >>> u == Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 161 | True 162 | >>> -Vec({'a','b','c'}, {'a':1}) == Vec({'a','b','c'}, {'a':-1}) 163 | True 164 | 165 | """ 166 | u=v.copy() 167 | for k in v.D: 168 | setitem(u,k, -1*getitem(v,k)) 169 | return u 170 | 171 | ############################################################################################################################### 172 | 173 | class Vec: 174 | """ 175 | A vector has two fields: 176 | D - the domain (a set) 177 | f - a dictionary mapping (some) domain elements to field elements 178 | elements of D not appearing in f are implicitly mapped to zero 179 | """ 180 | def __init__(self, labels, function): 181 | self.D = labels 182 | self.f = function 183 | 184 | __getitem__ = getitem 185 | __setitem__ = setitem 186 | __neg__ = neg 187 | __rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar 188 | 189 | def __mul__(self,other): 190 | #If other is a vector, returns the dot product of self and other 191 | if isinstance(other, Vec): 192 | return dot(self,other) 193 | else: 194 | return NotImplemented # Will cause other.__rmul__(self) to be invoked 195 | 196 | def __truediv__(self,other): # Scalar division 197 | return (1/other)*self 198 | 199 | __add__ = add 200 | 201 | def __radd__(self, other): 202 | "Hack to allow sum(...) to work with vectors" 203 | if other == 0: 204 | return self 205 | 206 | def __sub__(a,b): 207 | "Returns a vector which is the difference of a and b." 208 | return a+(-b) 209 | 210 | __eq__ = equal 211 | 212 | def is_almost_zero(self): 213 | s = 0 214 | for x in self.f.values(): 215 | if isinstance(x, int) or isinstance(x, float): 216 | s += x*x 217 | elif isinstance(x, complex): 218 | s += x*x.conjugate() 219 | else: return False 220 | return s < 1e-20 221 | 222 | def __str__(v): 223 | "pretty-printing" 224 | D_list = sorted(v.D, key=repr) 225 | numdec = 3 226 | wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list]) 227 | s1 = ''.join(['{0:>{1}}'.format(str(k),wd[k]) for k in D_list]) 228 | s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list]) 229 | return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2 230 | 231 | def __hash__(self): 232 | "Here we pretend Vecs are immutable so we can form sets of them" 233 | h = hash(frozenset(self.D)) 234 | for k,v in sorted(self.f.items(), key = lambda x:repr(x[0])): 235 | if v != 0: 236 | h = hash((h, hash(v))) 237 | return h 238 | 239 | def __repr__(self): 240 | return "Vec(" + str(self.D) + "," + str(self.f) + ")" 241 | 242 | def copy(self): 243 | "Don't make a new copy of the domain D" 244 | return Vec(self.D, self.f.copy()) 245 | -------------------------------------------------------------------------------- /Week2-The_Vector_Space/The_Vector_Space_Problems/The_Vector_Space_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week2-The_Vector_Space/The_Vector_Space_Problems/The_Vector_Space_problems.pdf -------------------------------------------------------------------------------- /Week2-The_Vector_Space/The_Vector_Space_Problems/The_Vector_Space_problems.py: -------------------------------------------------------------------------------- 1 | # version code 565cc389e900+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | from vec import Vec 6 | from itertools import * 7 | from GF2 import one 8 | 9 | 10 | ## 1: (Problem 1) Vector Comprehension and Sum 11 | def vec_select(veclist, k): 12 | ''' 13 | >>> D = {'a','b','c'} 14 | >>> v1 = Vec(D, {'a': 1}) 15 | >>> v2 = Vec(D, {'a': 0, 'b': 1}) 16 | >>> v3 = Vec(D, { 'b': 2}) 17 | >>> v4 = Vec(D, {'a': 10, 'b': 10}) 18 | >>> vec_select([v1, v2, v3, v4], 'a') == [Vec(D,{'b': 1}), Vec(D,{'b': 2})] 19 | True 20 | ''' 21 | V_L = [ v for v in veclist if v[k]==0] 22 | for v in V_L: 23 | v.f = { x:y for (x,y) in v.f.items() if x!=k } 24 | return V_L 25 | 26 | def vec_sum(veclist, D): 27 | ''' 28 | >>> D = {'a','b','c'} 29 | >>> v1 = Vec(D, {'a': 1}) 30 | >>> v2 = Vec(D, {'a': 0, 'b': 1}) 31 | >>> v3 = Vec(D, { 'b': 2}) 32 | >>> v4 = Vec(D, {'a': 10, 'b': 10}) 33 | >>> vec_sum([v1, v2, v3, v4], D) == Vec(D, {'b': 13, 'a': 11}) 34 | True 35 | ''' 36 | S=Vec(D,{}) 37 | for v in veclist: 38 | S += v 39 | return S 40 | def vec_select_sum(veclist, k, D): 41 | ''' 42 | >>> D = {'a','b','c'} 43 | >>> v1 = Vec(D, {'a': 1}) 44 | >>> v2 = Vec(D, {'a': 0, 'b': 1}) 45 | >>> v3 = Vec(D, { 'b': 2}) 46 | >>> v4 = Vec(D, {'a': 10, 'b': 10}) 47 | >>> vec_select_sum([v1, v2, v3, v4], 'a', D) == Vec(D, {'b': 3}) 48 | True 49 | ''' 50 | return vec_sum(vec_select(veclist,k), D) 51 | 52 | 53 | ## 2: (Problem 2) Vector Dictionary 54 | def scale_vecs(vecdict): 55 | ''' 56 | >>> v1 = Vec({1,2,4}, {2: 9}) 57 | >>> v2 = Vec({1,2,4}, {1: 1, 2: 2, 4: 8}) 58 | >>> result = scale_vecs({3: v1, 5: v2}) 59 | >>> len(result) 60 | 2 61 | >>> [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] 62 | [True, True] 63 | ''' 64 | #return [ Vec(v.D, { x:y/scale for (x,y) in v.f.items() }) for (scale, v) in vecdict.items() ] 65 | return [ 1/scale*v for (scale, v) in vecdict.items() ] 66 | 67 | ## 3: (Problem 3) Constructing span of given vectors over GF(2) 68 | def GF2_span(D, S): 69 | ''' 70 | >>> from GF2 import one 71 | >>> D = {'a', 'b', 'c'} 72 | >>> 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})} 73 | True 74 | >>> 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'},{})} 75 | True 76 | >>> S={Vec({0,1},{0:one}), Vec({0,1},{1:one})} 77 | >>> 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},{})} 78 | True 79 | >>> S == {Vec({0, 1},{1: one}), Vec({0, 1},{0: one})} 80 | True 81 | ''' 82 | Span=set() 83 | for Coef in list(product([0, one], repeat=len(S))): 84 | Span.add(vec_sum([x[0]*x[1] for x in zip(Coef, S)], D)) 85 | return Span 86 | 87 | ## 4: (Problem 4) Is it a vector space 1 88 | # Answer with a boolean, please. 89 | is_a_vector_space_1 = False 90 | 91 | 92 | 93 | ## 5: (Problem 5) Is it a vector space 2 94 | # Answer with a boolean, please. 95 | is_a_vector_space_2 = True 96 | 97 | 98 | 99 | ## 6: (Problem 6) Is it a vector space 3 100 | # Answer with a boolean, please. 101 | is_a_vector_space_3 = False 102 | 103 | 104 | 105 | ## 7: (Problem 7) Is it a vector space 4 106 | # Answer with a boolean, please. 107 | is_a_vector_space_4a = True 108 | is_a_vector_space_4b = False 109 | 110 | -------------------------------------------------------------------------------- /Week2-The_Vector_Space/The_Vector_Space_Problems/vecutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | 4 | def list2vec(L): 5 | """Given a list L of field elements, return a Vec with domain {0...len(L)-1} 6 | whose entry i is L[i] 7 | 8 | >>> list2vec([10, 20, 30]) 9 | Vec({0, 1, 2},{0: 10, 1: 20, 2: 30}) 10 | """ 11 | return Vec(set(range(len(L))), {k:L[k] for k in range(len(L))}) 12 | 13 | def zero_vec(D): 14 | """Returns a zero vector with the given domain 15 | """ 16 | return Vec(D, {}) 17 | -------------------------------------------------------------------------------- /Week2-The_Vector_Space/profile.txt: -------------------------------------------------------------------------------- 1 | USERNAME liuqunxyz@gmail.com 2 | PASSWORD J5k9bcq2KM -------------------------------------------------------------------------------- /Week3-The_Matrix/Error_Correcting_Code_Lab/bitutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | """ 3 | Implements several convenience operations for use with the ECC lab. 4 | 5 | Author: Landon Judkins (ljudkins) 6 | Date: Spring 2009 7 | Updated by Nick Gaya, Spring 2013 8 | 9 | Requires: fields matutil 10 | """ 11 | 12 | from GF2 import zero, one 13 | import mat 14 | import random 15 | 16 | def str2bits(inp): 17 | """ 18 | Convert a string into a list of bits, with each character's bits in order 19 | of increasing significance. 20 | """ 21 | bs = [1<>> find_error(Vec({0,1,2}, {0:one})) == Vec({0, 1, 2, 3, 4, 5, 6},{3: one}) 37 | True 38 | >>> find_error(Vec({0,1,2}, {2:one})) == Vec({0, 1, 2, 3, 4, 5, 6},{0: one}) 39 | True 40 | >>> find_error(Vec({0,1,2}, {1:one, 2:one})) == Vec({0, 1, 2, 3, 4, 5, 6},{2: one}) 41 | True 42 | >>> find_error(Vec({0,1,2}, {})) == Vec({0,1,2,3,4,5,6}, {}) 43 | True 44 | """ 45 | #return Vec({0,1,2,3,4,5,6},{}) if syndrome.f()=={} else Vec({0,1,2,3,4,5,6}, {sum[x]:one 46 | index = sum([2**(2-x) for x in syndrome.f.keys() if syndrome.f[x]==one]) 47 | if index==0: 48 | return Vec({0,1,2,3,4,5,6},{}) 49 | else: 50 | return Vec({0,1,2,3,4,5,6},{index-1:one}) 51 | ## Task 6 52 | # Use the Vec class for your answers. 53 | non_codeword = Vec({0,1,2,3,4,5,6}, {0: one, 1:0, 2:one, 3:one, 4:0, 5:one, 6:one}) 54 | error_vector = find_error(H*non_codeword) 55 | code_word = non_codeword+error_vector 56 | original = R*code_word # R * code_word 57 | #print(error_vector) 58 | #print(code_word) 59 | #print(original) 60 | 61 | ## Task 7 62 | def find_error_matrix(S): 63 | """ 64 | Input: a matrix S whose columns are error syndromes 65 | Output: a matrix whose cth column is the error corresponding to the cth column of S. 66 | Example: 67 | >>> S = listlist2mat([[0,one,one,one],[0,one,0,0],[0,0,0,one]]) 68 | >>> find_error_matrix(S) == Mat(({0, 1, 2, 3, 4, 5, 6}, {0, 1, 2, 3}), {(1, 3): 0, (3, 0): 0, (2, 1): 0, (6, 2): 0, (5, 1): one, (0, 3): 0, (4, 0): 0, (1, 2): 0, (3, 3): 0, (6, 3): 0, (5, 0): 0, (2, 2): 0, (4, 1): 0, (1, 1): 0, (3, 2): one, (0, 0): 0, (6, 0): 0, (2, 3): 0, (4, 2): 0, (1, 0): 0, (5, 3): 0, (0, 1): 0, (6, 1): 0, (3, 1): 0, (2, 0): 0, (4, 3): one, (5, 2): 0, (0, 2): 0}) 69 | True 70 | """ 71 | return coldict2mat({k: find_error(mat2coldict(S)[k]) for k in mat2coldict(S).keys()}) 72 | 73 | ## Task 8 74 | 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." 75 | P = bits2mat(str2bits(s)) 76 | 77 | ## Task 9 78 | C = G*P 79 | bits_before =len(str2bits(s)) 80 | bits_after = len(mat2bits(C)) 81 | 82 | 83 | ## Ungraded Task 84 | CTILDE = C + noise(C, 0.02) 85 | #print(s) 86 | #print(bits2str(mat2bits(CTILDE))) 87 | 88 | 89 | ## Task 10 90 | def correct(A): 91 | """ 92 | Input: a matrix A each column of which differs from a codeword in at most one bit 93 | Output: a matrix whose columns are the corresponding valid codewords. 94 | Example: 95 | >>> 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}) 96 | >>> 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}) 97 | True 98 | """ 99 | return A + find_error_matrix(H*A) 100 | 101 | #print(bits2str(mat2bits(R*correct(CTILDE)))) 102 | -------------------------------------------------------------------------------- /Week3-The_Matrix/Error_Correcting_Code_Lab/matutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from mat import Mat 4 | 5 | def efficient_rowdict2mat(rowdict): 6 | col_labels = value(rowdict).D 7 | M = Mat((set(keys(rowdict)), col_labels), {}) 8 | for r in rowdict: 9 | for c in rowdict[r].f: 10 | M[r,c] = rowdict[r][c] 11 | return M 12 | 13 | def identity(D, one): 14 | """Given a set D and the field's one, returns the DxD identity matrix 15 | e.g.: 16 | 17 | >>> identity({0,1,2}, 1) 18 | Mat(({0, 1, 2}, {0, 1, 2}), {(0, 0): 1, (1, 1): 1, (2, 2): 1}) 19 | """ 20 | return Mat((D,D), {(d,d):one for d in D}) 21 | 22 | def keys(d): 23 | """Given a dict, returns something that generates the keys; given a list, 24 | returns something that generates the indices. Intended for coldict2mat and rowdict2mat. 25 | """ 26 | return d.keys() if isinstance(d, dict) else range(len(d)) 27 | 28 | def value(d): 29 | """Given either a dict or a list, returns one of the values. 30 | Intended for coldict2mat and rowdict2mat. 31 | """ 32 | return next(iter(d.values())) if isinstance(d, dict) else d[0] 33 | 34 | def mat2rowdict(A): 35 | """Given a matrix, return a dictionary mapping row labels of A to rows of A 36 | e.g.: 37 | 38 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 39 | >>> mat2rowdict(M) 40 | {0: Vec({0, 1},{0: 3, 1: 1}), 1: Vec({0, 1},{0: 4, 1: 0}), 2: Vec({0, 1},{0: 8, 1: -2})} 41 | >>> mat2rowdict(Mat(({0,1},{0,1}),{})) 42 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 43 | """ 44 | return {row:Vec(A.D[1], {col:A[row,col] for col in A.D[1]}) for row in A.D[0]} 45 | 46 | def mat2coldict(A): 47 | """Given a matrix, return a dictionary mapping column labels of A to columns of A 48 | e.g.: 49 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 50 | >>> mat2coldict(M) 51 | {0: Vec({0, 1, 2},{0: 3, 1: 4, 2: 8}), 1: Vec({0, 1, 2},{0: 1, 1: 0, 2: -2})} 52 | >>> mat2coldict(Mat(({0,1},{0,1}),{})) 53 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 54 | """ 55 | return {col:Vec(A.D[0], {row:A[row,col] for row in A.D[0]}) for col in A.D[1]} 56 | 57 | def coldict2mat(coldict): 58 | """ 59 | Given a dictionary or list whose values are Vecs, returns the Mat having these 60 | Vecs as its columns. This is the inverse of mat2coldict. 61 | Assumes all the Vecs have the same label-set. 62 | Assumes coldict is nonempty. 63 | If coldict is a dictionary then its keys will be the column-labels of the Mat. 64 | If coldict is a list then {0...len(coldict)-1} will be the column-labels of the Mat. 65 | e.g.: 66 | 67 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 68 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 69 | >>> mat2coldict(coldict2mat(A)) == A 70 | True 71 | >>> coldict2mat(A) 72 | Mat(({0, 1}, {0, 1}), {(0, 1): 3, (1, 0): 2, (0, 0): 1, (1, 1): 4}) 73 | >>> coldict2mat(A) == coldict2mat(B) 74 | True 75 | """ 76 | row_labels = value(coldict).D 77 | return Mat((row_labels, set(keys(coldict))), {(r,c):coldict[c][r] for c in keys(coldict) for r in row_labels}) 78 | 79 | def rowdict2mat(rowdict): 80 | """ 81 | Given a dictionary or list whose values are Vecs, returns the Mat having these 82 | Vecs as its rows. This is the inverse of mat2rowdict. 83 | Assumes all the Vecs have the same label-set. 84 | Assumes row_dict is nonempty. 85 | If rowdict is a dictionary then its keys will be the row-labels of the Mat. 86 | If rowdict is a list then {0...len(rowdict)-1} will be the row-labels of the Mat. 87 | e.g.: 88 | 89 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 90 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 91 | >>> mat2rowdict(rowdict2mat(A)) == A 92 | True 93 | >>> rowdict2mat(A) 94 | Mat(({0, 1}, {0, 1}), {(0, 1): 2, (1, 0): 3, (0, 0): 1, (1, 1): 4}) 95 | >>> rowdict2mat(A) == rowdict2mat(B) 96 | True 97 | """ 98 | col_labels = value(rowdict).D 99 | return Mat((set(keys(rowdict)), col_labels), {(r,c):rowdict[r][c] for r in keys(rowdict) for c in col_labels}) 100 | 101 | def listlist2mat(L): 102 | """Given a list of lists of field elements, return a matrix whose ith row consists 103 | of the elements of the ith list. The row-labels are {0...len(L)}, and the 104 | column-labels are {0...len(L[0])} 105 | >>> A=listlist2mat([[10,20,30,40],[50,60,70,80]]) 106 | >>> print(A) 107 | 108 | 0 1 2 3 109 | ------------- 110 | 0 | 10 20 30 40 111 | 1 | 50 60 70 80 112 | 113 | """ 114 | m,n = len(L), len(L[0]) 115 | return Mat((set(range(m)),set(range(n))), {(r,c):L[r][c] for r in range(m) for c in range(n)}) 116 | 117 | def submatrix(M, rows, cols): 118 | return Mat((M.D[0]&rows, M.D[1]&cols), {(r,c):val for (r,c),val in M.f.items() if r in rows and c in cols}) 119 | -------------------------------------------------------------------------------- /Week3-The_Matrix/Matrix_Class_Homework/mat.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week3-The_Matrix/Matrix_Class_Homework/mat.pdf -------------------------------------------------------------------------------- /Week3-The_Matrix/Matrix_Class_Homework/mat_sparsity.py: -------------------------------------------------------------------------------- 1 | ''' 2 | >>> from mat import Mat 3 | >>> from vec import Vec 4 | >>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Vec(set(range(100000)),{0:2}))[0] 5 | 2 6 | >>> (Vec(set(range(100000)),{0:2})*Mat((set(range(10000)),set(range(100000))),{(0,0):1}).transpose())[0] 7 | 2 8 | >>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Mat((set(range(100000)), set(range(9999))), {(0,0):2}))[0,0] 9 | 2 10 | ''' 11 | -------------------------------------------------------------------------------- /Week3-The_Matrix/The_Matrix_Problems/The_Matrix_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week3-The_Matrix/The_Matrix_Problems/The_Matrix_problems.pdf -------------------------------------------------------------------------------- /Week3-The_Matrix/The_Matrix_Problems/matutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from mat import Mat 4 | 5 | def efficient_rowdict2mat(rowdict): 6 | col_labels = value(rowdict).D 7 | M = Mat((set(keys(rowdict)), col_labels), {}) 8 | for r in rowdict: 9 | for c in rowdict[r].f: 10 | M[r,c] = rowdict[r][c] 11 | return M 12 | 13 | def identity(D, one): 14 | """Given a set D and the field's one, returns the DxD identity matrix 15 | e.g.: 16 | 17 | >>> identity({0,1,2}, 1) 18 | Mat(({0, 1, 2}, {0, 1, 2}), {(0, 0): 1, (1, 1): 1, (2, 2): 1}) 19 | """ 20 | return Mat((D,D), {(d,d):one for d in D}) 21 | 22 | def keys(d): 23 | """Given a dict, returns something that generates the keys; given a list, 24 | returns something that generates the indices. Intended for coldict2mat and rowdict2mat. 25 | """ 26 | return d.keys() if isinstance(d, dict) else range(len(d)) 27 | 28 | def value(d): 29 | """Given either a dict or a list, returns one of the values. 30 | Intended for coldict2mat and rowdict2mat. 31 | """ 32 | return next(iter(d.values())) if isinstance(d, dict) else d[0] 33 | 34 | def mat2rowdict(A): 35 | """Given a matrix, return a dictionary mapping row labels of A to rows of A 36 | e.g.: 37 | 38 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 39 | >>> mat2rowdict(M) 40 | {0: Vec({0, 1},{0: 3, 1: 1}), 1: Vec({0, 1},{0: 4, 1: 0}), 2: Vec({0, 1},{0: 8, 1: -2})} 41 | >>> mat2rowdict(Mat(({0,1},{0,1}),{})) 42 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 43 | """ 44 | return {row:Vec(A.D[1], {col:A[row,col] for col in A.D[1]}) for row in A.D[0]} 45 | 46 | def mat2coldict(A): 47 | """Given a matrix, return a dictionary mapping column labels of A to columns of A 48 | e.g.: 49 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 50 | >>> mat2coldict(M) 51 | {0: Vec({0, 1, 2},{0: 3, 1: 4, 2: 8}), 1: Vec({0, 1, 2},{0: 1, 1: 0, 2: -2})} 52 | >>> mat2coldict(Mat(({0,1},{0,1}),{})) 53 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 54 | """ 55 | return {col:Vec(A.D[0], {row:A[row,col] for row in A.D[0]}) for col in A.D[1]} 56 | 57 | def coldict2mat(coldict): 58 | """ 59 | Given a dictionary or list whose values are Vecs, returns the Mat having these 60 | Vecs as its columns. This is the inverse of mat2coldict. 61 | Assumes all the Vecs have the same label-set. 62 | Assumes coldict is nonempty. 63 | If coldict is a dictionary then its keys will be the column-labels of the Mat. 64 | If coldict is a list then {0...len(coldict)-1} will be the column-labels of the Mat. 65 | e.g.: 66 | 67 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 68 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 69 | >>> mat2coldict(coldict2mat(A)) == A 70 | True 71 | >>> coldict2mat(A) 72 | Mat(({0, 1}, {0, 1}), {(0, 1): 3, (1, 0): 2, (0, 0): 1, (1, 1): 4}) 73 | >>> coldict2mat(A) == coldict2mat(B) 74 | True 75 | """ 76 | row_labels = value(coldict).D 77 | return Mat((row_labels, set(keys(coldict))), {(r,c):coldict[c][r] for c in keys(coldict) for r in row_labels}) 78 | 79 | def rowdict2mat(rowdict): 80 | """ 81 | Given a dictionary or list whose values are Vecs, returns the Mat having these 82 | Vecs as its rows. This is the inverse of mat2rowdict. 83 | Assumes all the Vecs have the same label-set. 84 | Assumes row_dict is nonempty. 85 | If rowdict is a dictionary then its keys will be the row-labels of the Mat. 86 | If rowdict is a list then {0...len(rowdict)-1} will be the row-labels of the Mat. 87 | e.g.: 88 | 89 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 90 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 91 | >>> mat2rowdict(rowdict2mat(A)) == A 92 | True 93 | >>> rowdict2mat(A) 94 | Mat(({0, 1}, {0, 1}), {(0, 1): 2, (1, 0): 3, (0, 0): 1, (1, 1): 4}) 95 | >>> rowdict2mat(A) == rowdict2mat(B) 96 | True 97 | """ 98 | col_labels = value(rowdict).D 99 | return Mat((set(keys(rowdict)), col_labels), {(r,c):rowdict[r][c] for r in keys(rowdict) for c in col_labels}) 100 | 101 | def listlist2mat(L): 102 | """Given a list of lists of field elements, return a matrix whose ith row consists 103 | of the elements of the ith list. The row-labels are {0...len(L)}, and the 104 | column-labels are {0...len(L[0])} 105 | >>> A=listlist2mat([[10,20,30,40],[50,60,70,80]]) 106 | >>> print(A) 107 | 108 | 0 1 2 3 109 | ------------- 110 | 0 | 10 20 30 40 111 | 1 | 50 60 70 80 112 | 113 | """ 114 | m,n = len(L), len(L[0]) 115 | return Mat((set(range(m)),set(range(n))), {(r,c):L[r][c] for r in range(m) for c in range(n)}) 116 | 117 | def submatrix(M, rows, cols): 118 | return Mat((M.D[0]&rows, M.D[1]&cols), {(r,c):val for (r,c),val in M.f.items() if r in rows and c in cols}) 119 | -------------------------------------------------------------------------------- /Week4-The_Basis/Geometry_Lab/geometry_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week4-The_Basis/Geometry_Lab/geometry_lab.pdf -------------------------------------------------------------------------------- /Week4-The_Basis/Geometry_Lab/geometry_lab.py: -------------------------------------------------------------------------------- 1 | # version code 77ed2409f40d+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # version code 05f5a0d767f0+ 6 | # Please fill out this stencil and submit using the provided submission script. 7 | 8 | from mat import Mat 9 | from vec import Vec 10 | import math 11 | from image_mat_util import * 12 | 13 | ## Ungraded task 14 | # A=file2mat('board.png') 15 | # mat2display(A[0],A[1]) 16 | 17 | ## Task 1 18 | def identity(labels = {'x','y','u'}): 19 | ''' 20 | In case you have never seen this notation for a parameter before, 21 | it defines the default value of labels to be {'x','y','u'}. 22 | You should write your procedure as if 23 | it were defined 'def identity(labels):'. However, if you want the labels of 24 | your identity matrix to be {'x','y','u'}, you can just call 25 | identity(). If you want {'r','g','b'}, or another set, to be the 26 | labels of your matrix, you can call identity({'r','g','b'}). 27 | 28 | >>> identity()==Mat(({'x','y','u'},{'x','y','u'}), {('x','x'):1, ('y','y'):1, ('u','u'):1}) 29 | True 30 | >>> identity({'r','g','b'})==Mat(({'r','g','b'},{'r','g','b'}), {('r','r'):1, ('g','g'):1, ('b','b'):1}) 31 | True 32 | ''' 33 | return Mat((labels, labels), {(a,a):1 for a in labels}) 34 | 35 | ## Task 2 36 | def translation(x,y): 37 | ''' 38 | Input: An x and y value by which to translate an image. 39 | Output: Corresponding 3x3 translation matrix. 40 | 41 | >>> translation(9,10)==Mat(({'x','y','u'},{'x','y','u'}), {('x','x'):1, ('y','y'):1, ('u','u'):1, ('y','u'):10, ('x','u'):9}) 42 | True 43 | ''' 44 | return Mat(({'x','y','u'},{'x','y','u'}), {('x','x'):1, ('y','y'):1, ('u','u'):1, ('y','u'):y, ('x','u'):x}) 45 | 46 | ## Task 3 47 | def scale(a, b): 48 | ''' 49 | Input: Scaling parameters for the x and y direction. 50 | Output: Corresponding 3x3 scaling matrix. 51 | 52 | >>> scale(3,4)*Vec({'x','y','u'}, {'x':1,'y':1,'u':1}) == Vec({'x','y','u'}, {'x':3, 'y':4, 'u':1}) 53 | True 54 | >>> scale(0,0)*Vec({'x','y','u'}, {'x':1,'y':1,'u':1}) == Vec({'x','y','u'}, {'u':1}) 55 | True 56 | ''' 57 | return Mat(({'x','y','u'},{'x','y','u'}), {('x','x'):a, ('x','y'):0,('x','u'):0,('y','x'):0,('y','y'):b,('y','u'):0,('u','x'):0,('u','y'):0,('u','u'):1}) 58 | 59 | ## Task 4 60 | def rotation(angle): 61 | ''' 62 | Input: An angle in radians to rotate an image. 63 | Output: Corresponding 3x3 rotation matrix. 64 | Note that the math module is imported. 65 | 66 | >>> def normsq(v): return v*v 67 | >>> normsq(rotation(math.pi) * Vec({'u', 'x', 'y'},{'x':1,'y':2,'u':1}) - Vec({'u', 'x', 'y'},{'u': 1, 'x': -1, 'y': -2})) < 1e-15 68 | True 69 | >>> normsq(rotation(math.pi/2) * Vec({'u', 'x', 'y'},{'x':3,'y':1,'u':1}) - Vec({'u', 'x', 'y'},{'u': 1, 'x': -1, 'y': 3.0})) < 1e-15 70 | True 71 | ''' 72 | return Mat(({'x','y','u'},{'x','y','u'}), {('x','x'):math.cos(angle), ('x','y'):-math.sin(angle),('x','u'):0,('y','x'):math.sin(angle),('y','y'):math.cos(angle),('y','u'):0,('u','x'):0,('u','y'):0,('u','u'):1}) 73 | 74 | ## Task 5 75 | def rotate_about(x,y,angle): 76 | ''' 77 | Input: An x and y coordinate to rotate about, and an angle 78 | in radians to rotate about. 79 | Output: Corresponding 3x3 rotation matrix. 80 | It might be helpful to use procedures you already wrote. 81 | ''' 82 | return translation(x,y)*rotation(angle)*translation(-x,-y) 83 | 84 | 85 | ## Task 6 86 | def reflect_y(): 87 | ''' 88 | Input: None. 89 | Output: 3x3 Y-reflection matrix. 90 | 91 | >>> v = Vec({'x','y','u'}, {'x':1, 'y':1, 'u':1}) 92 | >>> reflect_y()*v == Vec({'x','y','u'}, {'x':-1, 'y':1, 'u':1}) 93 | True 94 | >>> w = Vec({'x','y','u'}, {'u':1}) 95 | >>> reflect_y()*w == Vec({'x','y','u'},{'u':1}) 96 | True 97 | ''' 98 | return scale(-1,1) 99 | ## Task 7 100 | def reflect_x(): 101 | ''' 102 | Inpute: None. 103 | Output: 3x3 X-reflection matrix. 104 | 105 | >>> v = Vec({'x','y','u'}, {'x':1, 'y':1, 'u':1}) 106 | >>> reflect_x()*v == Vec({'x','y','u'}, {'x':1, 'y':-1, 'u':1}) 107 | True 108 | >>> w = Vec({'x','y','u'}, {'u':1}) 109 | >>> reflect_x()*w == Vec({'x','y','u'},{'u':1}) 110 | True 111 | ''' 112 | return scale(1, -1) 113 | 114 | ## Task 8 115 | def scale_color(scale_r,scale_g,scale_b): 116 | ''' 117 | Input: 3 scaling parameters for the colors of the image. 118 | Output: Corresponding 3x3 color scaling matrix. 119 | 120 | >>> scale_color(1,2,3)*Vec({'r','g','b'},{'r':1,'g':2,'b':3}) == Vec({'r','g','b'},{'r':1,'g':4,'b':9}) 121 | True 122 | ''' 123 | return Mat(({'r','g','b'},{'r','g','b'}),{('r','r'):scale_r,('r','g'):0,('r','b'):0,('g','r'):0,('g','g'):scale_g,('g','b'):0,('b''r'):0,('b','g'):0,('b','b'):scale_b}) 124 | 125 | ## Task 9 126 | def grayscale(): 127 | ''' 128 | Input: None 129 | Output: 3x3 greyscale matrix. 130 | ''' 131 | #return scale_color(77/256.0, 151/256.0,28/256.0) 132 | return Mat(({'r','g','b'},{'r','g','b'}),{('r','r'):77/256.0,('r','g'):151/256.0,('r','b'):28/256.0,('g','r'):77/256.0,('g','g'):151/256.0,('g','b'):28/256.0,('b','r'):77/256.0,('b','g'):151/256.0,('b','b'):28/256.0}) 133 | 134 | ## Task 10 135 | def reflect_about(x1, y1, x2, y2): 136 | ''' 137 | Input: 2 points that define a line to reflect about. 138 | Output: Corresponding 3x3 reflect about matrix. 139 | 140 | >>> def normsq(v): return v*v 141 | >>> normsq(reflect_about(0,1,1,1) * Vec({'x','y','u'}, {'u':1}) - Vec({'x', 'u', 'y'},{'x': 0.0, 'u': 1, 'y': 2.0})) < 10e-15 142 | True 143 | >>> normsq(reflect_about(0,0,1,1) * Vec({'x','y','u'}, {'x':1, 'u':1}) - Vec({'x', 'u', 'y'},{'u': 1, 'y': 1})) < 1e-15 144 | True 145 | ''' 146 | theta = math.atan2(y2 - y1, x2 - x1) 147 | return translation(x2,y2)*rotation(theta)*reflect_x()*rotation(-theta)*translation(-x2,-y2) 148 | -------------------------------------------------------------------------------- /Week4-The_Basis/Geometry_Lab/vec.py: -------------------------------------------------------------------------------- 1 | # version code 24ea27739109+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # Copyright 2013 Philip N. Klein 6 | 7 | def getitem(v,k): 8 | """ 9 | Return the value of entry k in v. 10 | Be sure getitem(v,k) returns 0 if k is not represented in v.f. 11 | 12 | >>> v = Vec({'a','b','c', 'd'},{'a':2,'c':1,'d':3}) 13 | >>> v['d'] 14 | 3 15 | >>> v['b'] 16 | 0 17 | """ 18 | return v.f[k] if k in v.f.keys() else 0 19 | def setitem(v,k,val): 20 | """ 21 | Set the element of v with label d to be val. 22 | setitem(v,d,val) should set the value for key d even if d 23 | is not previously represented in v.f. 24 | 25 | >>> v = Vec({'a', 'b', 'c'}, {'b':0}) 26 | >>> v['b'] = 5 27 | >>> v['b'] 28 | 5 29 | >>> v['a'] = 1 30 | >>> v['a'] 31 | 1 32 | >>> v['a'] = 0 33 | >>> v['a'] 34 | 0 35 | """ 36 | v.f[k]=val 37 | 38 | def equal(u,v): 39 | """ 40 | Return true iff u is equal to v. 41 | Because of sparse representation, it is not enough to compare dictionaries 42 | 43 | >>> Vec({'a', 'b', 'c'}, {'a':0}) == Vec({'a', 'b', 'c'}, {'b':0}) 44 | True 45 | 46 | Be sure that equal(u, v) check equalities for all keys from u.f and v.f even if 47 | some keys in u.f do not exist in v.f (or vice versa) 48 | 49 | >>> Vec({'x','y','z'},{'y':1,'x':2}) == Vec({'x','y','z'},{'y':1,'z':0}) 50 | False 51 | >>> Vec({'a','b','c'}, {'a':0,'c':1}) == Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) 52 | False 53 | >>> Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) == Vec({'a','b','c'}, {'a':0,'c':1}) 54 | False 55 | 56 | The keys matter: 57 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'b':1}) 58 | False 59 | 60 | The values matter: 61 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'a':2}) 62 | False 63 | 64 | """ 65 | assert u.D == v.D 66 | for k in u.D: 67 | if getitem(u,k)!=getitem(v,k): 68 | return False 69 | return True 70 | 71 | def add(u,v): 72 | """ 73 | Returns the sum of the two vectors. 74 | Make sure to add together values for all keys from u.f and v.f even if some keys in u.f do not 75 | exist in v.f (or vice versa) 76 | 77 | >>> a = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 78 | >>> b = Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 79 | >>> c = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2,'o':4,'u':7}) 80 | >>> a + b == c 81 | True 82 | >>> a == Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 83 | True 84 | >>> b == Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 85 | True 86 | >>> d = Vec({'x','y','z'}, {'x':2,'y':1}) 87 | >>> e = Vec({'x','y','z'}, {'z':4,'y':-1}) 88 | >>> f = Vec({'x','y','z'}, {'x':2,'y':0,'z':4}) 89 | >>> d + e == f 90 | True 91 | >>> b + Vec({'a','e','i','o','u'}, {}) == b 92 | True 93 | """ 94 | assert u.D == v.D 95 | s=u.copy() 96 | for k in u.D: 97 | setitem(s,k,getitem(u,k)+getitem(v,k)) 98 | return s 99 | def dot(u,v): 100 | """ 101 | Returns the dot product of the two vectors. 102 | 103 | >>> u1 = Vec({'a','b'}, {'a':1, 'b':2}) 104 | >>> u2 = Vec({'a','b'}, {'b':2, 'a':1}) 105 | >>> u1*u2 106 | 5 107 | >>> u1 == Vec({'a','b'}, {'a':1, 'b':2}) 108 | True 109 | >>> u2 == Vec({'a','b'}, {'b':2, 'a':1}) 110 | True 111 | >>> v1 = Vec({'p','q','r','s'}, {'p':2,'s':3,'q':-1,'r':0}) 112 | >>> v2 = Vec({'p','q','r','s'}, {'p':-2,'r':5}) 113 | >>> v1*v2 114 | -4 115 | >>> w1 = Vec({'a','b','c'}, {'a':2,'b':3,'c':4}) 116 | >>> w2 = Vec({'a','b','c'}, {'a':12,'b':8,'c':6}) 117 | >>> w1*w2 118 | 72 119 | 120 | The pairwise products should not be collected in a set before summing 121 | because a set eliminates duplicates 122 | >>> v1 = Vec({1, 2}, {1 : 3, 2 : 6}) 123 | >>> v2 = Vec({1, 2}, {1 : 2, 2 : 1}) 124 | >>> v1 * v2 125 | 12 126 | """ 127 | assert u.D == v.D 128 | s=0 129 | for k in u.D: 130 | s+= getitem(u,k)*getitem(v,k) 131 | return s 132 | 133 | def scalar_mul(v, alpha): 134 | """ 135 | Returns the scalar-vector product alpha times v. 136 | 137 | >>> zero = Vec({'x','y','z','w'}, {}) 138 | >>> u = Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 139 | >>> 0*u == zero 140 | True 141 | >>> 1*u == u 142 | True 143 | >>> 0.5*u == Vec({'x','y','z','w'},{'x':0.5,'y':1,'z':1.5,'w':2}) 144 | True 145 | >>> u == Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 146 | True 147 | """ 148 | u=v.copy() 149 | for k in v.D: 150 | setitem(u,k, alpha*getitem(v,k)) 151 | return u 152 | 153 | def neg(v): 154 | """ 155 | Returns the negation of a vector. 156 | 157 | >>> u = Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 158 | >>> -u 159 | Vec({8, 2, 4, 6},{8: -4, 2: -1, 4: -2, 6: -3}) 160 | >>> u == Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 161 | True 162 | >>> -Vec({'a','b','c'}, {'a':1}) == Vec({'a','b','c'}, {'a':-1}) 163 | True 164 | 165 | """ 166 | u=v.copy() 167 | for k in v.D: 168 | setitem(u,k, -1*getitem(v,k)) 169 | return u 170 | 171 | ############################################################################################################################### 172 | 173 | class Vec: 174 | """ 175 | A vector has two fields: 176 | D - the domain (a set) 177 | f - a dictionary mapping (some) domain elements to field elements 178 | elements of D not appearing in f are implicitly mapped to zero 179 | """ 180 | def __init__(self, labels, function): 181 | self.D = labels 182 | self.f = function 183 | 184 | __getitem__ = getitem 185 | __setitem__ = setitem 186 | __neg__ = neg 187 | __rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar 188 | 189 | def __mul__(self,other): 190 | #If other is a vector, returns the dot product of self and other 191 | if isinstance(other, Vec): 192 | return dot(self,other) 193 | else: 194 | return NotImplemented # Will cause other.__rmul__(self) to be invoked 195 | 196 | def __truediv__(self,other): # Scalar division 197 | return (1/other)*self 198 | 199 | __add__ = add 200 | 201 | def __radd__(self, other): 202 | "Hack to allow sum(...) to work with vectors" 203 | if other == 0: 204 | return self 205 | 206 | def __sub__(a,b): 207 | "Returns a vector which is the difference of a and b." 208 | return a+(-b) 209 | 210 | __eq__ = equal 211 | 212 | def is_almost_zero(self): 213 | s = 0 214 | for x in self.f.values(): 215 | if isinstance(x, int) or isinstance(x, float): 216 | s += x*x 217 | elif isinstance(x, complex): 218 | s += x*x.conjugate() 219 | else: return False 220 | return s < 1e-20 221 | 222 | def __str__(v): 223 | "pretty-printing" 224 | D_list = sorted(v.D, key=repr) 225 | numdec = 3 226 | wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list]) 227 | s1 = ''.join(['{0:>{1}}'.format(str(k),wd[k]) for k in D_list]) 228 | s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list]) 229 | return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2 230 | 231 | def __hash__(self): 232 | "Here we pretend Vecs are immutable so we can form sets of them" 233 | h = hash(frozenset(self.D)) 234 | for k,v in sorted(self.f.items(), key = lambda x:repr(x[0])): 235 | if v != 0: 236 | h = hash((h, hash(v))) 237 | return h 238 | 239 | def __repr__(self): 240 | return "Vec(" + str(self.D) + "," + str(self.f) + ")" 241 | 242 | def copy(self): 243 | "Don't make a new copy of the domain D" 244 | return Vec(self.D, self.f.copy()) 245 | -------------------------------------------------------------------------------- /Week4-The_Basis/The_Basis_Problems/The_Basis_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week4-The_Basis/The_Basis_Problems/The_Basis_problems.pdf -------------------------------------------------------------------------------- /Week4-The_Basis/The_Basis_Problems/matutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from mat import Mat 4 | 5 | def efficient_rowdict2mat(rowdict): 6 | col_labels = value(rowdict).D 7 | M = Mat((set(keys(rowdict)), col_labels), {}) 8 | for r in rowdict: 9 | for c in rowdict[r].f: 10 | M[r,c] = rowdict[r][c] 11 | return M 12 | 13 | def identity(D, one): 14 | """Given a set D and the field's one, returns the DxD identity matrix 15 | e.g.: 16 | 17 | >>> identity({0,1,2}, 1) 18 | Mat(({0, 1, 2}, {0, 1, 2}), {(0, 0): 1, (1, 1): 1, (2, 2): 1}) 19 | """ 20 | return Mat((D,D), {(d,d):one for d in D}) 21 | 22 | def keys(d): 23 | """Given a dict, returns something that generates the keys; given a list, 24 | returns something that generates the indices. Intended for coldict2mat and rowdict2mat. 25 | """ 26 | return d.keys() if isinstance(d, dict) else range(len(d)) 27 | 28 | def value(d): 29 | """Given either a dict or a list, returns one of the values. 30 | Intended for coldict2mat and rowdict2mat. 31 | """ 32 | return next(iter(d.values())) if isinstance(d, dict) else d[0] 33 | 34 | def mat2rowdict(A): 35 | """Given a matrix, return a dictionary mapping row labels of A to rows of A 36 | e.g.: 37 | 38 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 39 | >>> mat2rowdict(M) 40 | {0: Vec({0, 1},{0: 3, 1: 1}), 1: Vec({0, 1},{0: 4, 1: 0}), 2: Vec({0, 1},{0: 8, 1: -2})} 41 | >>> mat2rowdict(Mat(({0,1},{0,1}),{})) 42 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 43 | """ 44 | return {row:Vec(A.D[1], {col:A[row,col] for col in A.D[1]}) for row in A.D[0]} 45 | 46 | def mat2coldict(A): 47 | """Given a matrix, return a dictionary mapping column labels of A to columns of A 48 | e.g.: 49 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 50 | >>> mat2coldict(M) 51 | {0: Vec({0, 1, 2},{0: 3, 1: 4, 2: 8}), 1: Vec({0, 1, 2},{0: 1, 1: 0, 2: -2})} 52 | >>> mat2coldict(Mat(({0,1},{0,1}),{})) 53 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 54 | """ 55 | return {col:Vec(A.D[0], {row:A[row,col] for row in A.D[0]}) for col in A.D[1]} 56 | 57 | def coldict2mat(coldict): 58 | """ 59 | Given a dictionary or list whose values are Vecs, returns the Mat having these 60 | Vecs as its columns. This is the inverse of mat2coldict. 61 | Assumes all the Vecs have the same label-set. 62 | Assumes coldict is nonempty. 63 | If coldict is a dictionary then its keys will be the column-labels of the Mat. 64 | If coldict is a list then {0...len(coldict)-1} will be the column-labels of the Mat. 65 | e.g.: 66 | 67 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 68 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 69 | >>> mat2coldict(coldict2mat(A)) == A 70 | True 71 | >>> coldict2mat(A) 72 | Mat(({0, 1}, {0, 1}), {(0, 1): 3, (1, 0): 2, (0, 0): 1, (1, 1): 4}) 73 | >>> coldict2mat(A) == coldict2mat(B) 74 | True 75 | """ 76 | row_labels = value(coldict).D 77 | return Mat((row_labels, set(keys(coldict))), {(r,c):coldict[c][r] for c in keys(coldict) for r in row_labels}) 78 | 79 | def rowdict2mat(rowdict): 80 | """ 81 | Given a dictionary or list whose values are Vecs, returns the Mat having these 82 | Vecs as its rows. This is the inverse of mat2rowdict. 83 | Assumes all the Vecs have the same label-set. 84 | Assumes row_dict is nonempty. 85 | If rowdict is a dictionary then its keys will be the row-labels of the Mat. 86 | If rowdict is a list then {0...len(rowdict)-1} will be the row-labels of the Mat. 87 | e.g.: 88 | 89 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 90 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 91 | >>> mat2rowdict(rowdict2mat(A)) == A 92 | True 93 | >>> rowdict2mat(A) 94 | Mat(({0, 1}, {0, 1}), {(0, 1): 2, (1, 0): 3, (0, 0): 1, (1, 1): 4}) 95 | >>> rowdict2mat(A) == rowdict2mat(B) 96 | True 97 | """ 98 | col_labels = value(rowdict).D 99 | return Mat((set(keys(rowdict)), col_labels), {(r,c):rowdict[r][c] for r in keys(rowdict) for c in col_labels}) 100 | 101 | def listlist2mat(L): 102 | """Given a list of lists of field elements, return a matrix whose ith row consists 103 | of the elements of the ith list. The row-labels are {0...len(L)}, and the 104 | column-labels are {0...len(L[0])} 105 | >>> A=listlist2mat([[10,20,30,40],[50,60,70,80]]) 106 | >>> print(A) 107 | 108 | 0 1 2 3 109 | ------------- 110 | 0 | 10 20 30 40 111 | 1 | 50 60 70 80 112 | 113 | """ 114 | m,n = len(L), len(L[0]) 115 | return Mat((set(range(m)),set(range(n))), {(r,c):L[r][c] for r in range(m) for c in range(n)}) 116 | 117 | def submatrix(M, rows, cols): 118 | return Mat((M.D[0]&rows, M.D[1]&cols), {(r,c):val for (r,c),val in M.f.items() if r in rows and c in cols}) 119 | -------------------------------------------------------------------------------- /Week4-The_Basis/The_Basis_Problems/vec.py: -------------------------------------------------------------------------------- 1 | # version code 24ea27739109+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # Copyright 2013 Philip N. Klein 6 | 7 | def getitem(v,k): 8 | """ 9 | Return the value of entry k in v. 10 | Be sure getitem(v,k) returns 0 if k is not represented in v.f. 11 | 12 | >>> v = Vec({'a','b','c', 'd'},{'a':2,'c':1,'d':3}) 13 | >>> v['d'] 14 | 3 15 | >>> v['b'] 16 | 0 17 | """ 18 | return v.f[k] if k in v.f.keys() else 0 19 | def setitem(v,k,val): 20 | """ 21 | Set the element of v with label d to be val. 22 | setitem(v,d,val) should set the value for key d even if d 23 | is not previously represented in v.f. 24 | 25 | >>> v = Vec({'a', 'b', 'c'}, {'b':0}) 26 | >>> v['b'] = 5 27 | >>> v['b'] 28 | 5 29 | >>> v['a'] = 1 30 | >>> v['a'] 31 | 1 32 | >>> v['a'] = 0 33 | >>> v['a'] 34 | 0 35 | """ 36 | v.f[k]=val 37 | 38 | def equal(u,v): 39 | """ 40 | Return true iff u is equal to v. 41 | Because of sparse representation, it is not enough to compare dictionaries 42 | 43 | >>> Vec({'a', 'b', 'c'}, {'a':0}) == Vec({'a', 'b', 'c'}, {'b':0}) 44 | True 45 | 46 | Be sure that equal(u, v) check equalities for all keys from u.f and v.f even if 47 | some keys in u.f do not exist in v.f (or vice versa) 48 | 49 | >>> Vec({'x','y','z'},{'y':1,'x':2}) == Vec({'x','y','z'},{'y':1,'z':0}) 50 | False 51 | >>> Vec({'a','b','c'}, {'a':0,'c':1}) == Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) 52 | False 53 | >>> Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) == Vec({'a','b','c'}, {'a':0,'c':1}) 54 | False 55 | 56 | The keys matter: 57 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'b':1}) 58 | False 59 | 60 | The values matter: 61 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'a':2}) 62 | False 63 | 64 | """ 65 | assert u.D == v.D 66 | for k in u.D: 67 | if getitem(u,k)!=getitem(v,k): 68 | return False 69 | return True 70 | 71 | def add(u,v): 72 | """ 73 | Returns the sum of the two vectors. 74 | Make sure to add together values for all keys from u.f and v.f even if some keys in u.f do not 75 | exist in v.f (or vice versa) 76 | 77 | >>> a = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 78 | >>> b = Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 79 | >>> c = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2,'o':4,'u':7}) 80 | >>> a + b == c 81 | True 82 | >>> a == Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 83 | True 84 | >>> b == Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 85 | True 86 | >>> d = Vec({'x','y','z'}, {'x':2,'y':1}) 87 | >>> e = Vec({'x','y','z'}, {'z':4,'y':-1}) 88 | >>> f = Vec({'x','y','z'}, {'x':2,'y':0,'z':4}) 89 | >>> d + e == f 90 | True 91 | >>> b + Vec({'a','e','i','o','u'}, {}) == b 92 | True 93 | """ 94 | assert u.D == v.D 95 | s=u.copy() 96 | for k in u.D: 97 | setitem(s,k,getitem(u,k)+getitem(v,k)) 98 | return s 99 | def dot(u,v): 100 | """ 101 | Returns the dot product of the two vectors. 102 | 103 | >>> u1 = Vec({'a','b'}, {'a':1, 'b':2}) 104 | >>> u2 = Vec({'a','b'}, {'b':2, 'a':1}) 105 | >>> u1*u2 106 | 5 107 | >>> u1 == Vec({'a','b'}, {'a':1, 'b':2}) 108 | True 109 | >>> u2 == Vec({'a','b'}, {'b':2, 'a':1}) 110 | True 111 | >>> v1 = Vec({'p','q','r','s'}, {'p':2,'s':3,'q':-1,'r':0}) 112 | >>> v2 = Vec({'p','q','r','s'}, {'p':-2,'r':5}) 113 | >>> v1*v2 114 | -4 115 | >>> w1 = Vec({'a','b','c'}, {'a':2,'b':3,'c':4}) 116 | >>> w2 = Vec({'a','b','c'}, {'a':12,'b':8,'c':6}) 117 | >>> w1*w2 118 | 72 119 | 120 | The pairwise products should not be collected in a set before summing 121 | because a set eliminates duplicates 122 | >>> v1 = Vec({1, 2}, {1 : 3, 2 : 6}) 123 | >>> v2 = Vec({1, 2}, {1 : 2, 2 : 1}) 124 | >>> v1 * v2 125 | 12 126 | """ 127 | assert u.D == v.D 128 | s=0 129 | for k in u.D: 130 | s+= getitem(u,k)*getitem(v,k) 131 | return s 132 | 133 | def scalar_mul(v, alpha): 134 | """ 135 | Returns the scalar-vector product alpha times v. 136 | 137 | >>> zero = Vec({'x','y','z','w'}, {}) 138 | >>> u = Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 139 | >>> 0*u == zero 140 | True 141 | >>> 1*u == u 142 | True 143 | >>> 0.5*u == Vec({'x','y','z','w'},{'x':0.5,'y':1,'z':1.5,'w':2}) 144 | True 145 | >>> u == Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 146 | True 147 | """ 148 | u=v.copy() 149 | for k in v.D: 150 | setitem(u,k, alpha*getitem(v,k)) 151 | return u 152 | 153 | def neg(v): 154 | """ 155 | Returns the negation of a vector. 156 | 157 | >>> u = Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 158 | >>> -u 159 | Vec({8, 2, 4, 6},{8: -4, 2: -1, 4: -2, 6: -3}) 160 | >>> u == Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 161 | True 162 | >>> -Vec({'a','b','c'}, {'a':1}) == Vec({'a','b','c'}, {'a':-1}) 163 | True 164 | 165 | """ 166 | u=v.copy() 167 | for k in v.D: 168 | setitem(u,k, -1*getitem(v,k)) 169 | return u 170 | 171 | ############################################################################################################################### 172 | 173 | class Vec: 174 | """ 175 | A vector has two fields: 176 | D - the domain (a set) 177 | f - a dictionary mapping (some) domain elements to field elements 178 | elements of D not appearing in f are implicitly mapped to zero 179 | """ 180 | def __init__(self, labels, function): 181 | self.D = labels 182 | self.f = function 183 | 184 | __getitem__ = getitem 185 | __setitem__ = setitem 186 | __neg__ = neg 187 | __rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar 188 | 189 | def __mul__(self,other): 190 | #If other is a vector, returns the dot product of self and other 191 | if isinstance(other, Vec): 192 | return dot(self,other) 193 | else: 194 | return NotImplemented # Will cause other.__rmul__(self) to be invoked 195 | 196 | def __truediv__(self,other): # Scalar division 197 | return (1/other)*self 198 | 199 | __add__ = add 200 | 201 | def __radd__(self, other): 202 | "Hack to allow sum(...) to work with vectors" 203 | if other == 0: 204 | return self 205 | 206 | def __sub__(a,b): 207 | "Returns a vector which is the difference of a and b." 208 | return a+(-b) 209 | 210 | __eq__ = equal 211 | 212 | def is_almost_zero(self): 213 | s = 0 214 | for x in self.f.values(): 215 | if isinstance(x, int) or isinstance(x, float): 216 | s += x*x 217 | elif isinstance(x, complex): 218 | s += x*x.conjugate() 219 | else: return False 220 | return s < 1e-20 221 | 222 | def __str__(v): 223 | "pretty-printing" 224 | D_list = sorted(v.D, key=repr) 225 | numdec = 3 226 | wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list]) 227 | s1 = ''.join(['{0:>{1}}'.format(str(k),wd[k]) for k in D_list]) 228 | s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list]) 229 | return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2 230 | 231 | def __hash__(self): 232 | "Here we pretend Vecs are immutable so we can form sets of them" 233 | h = hash(frozenset(self.D)) 234 | for k,v in sorted(self.f.items(), key = lambda x:repr(x[0])): 235 | if v != 0: 236 | h = hash((h, hash(v))) 237 | return h 238 | 239 | def __repr__(self): 240 | return "Vec(" + str(self.D) + "," + str(self.f) + ")" 241 | 242 | def copy(self): 243 | "Don't make a new copy of the domain D" 244 | return Vec(self.D, self.f.copy()) 245 | -------------------------------------------------------------------------------- /Week5-Dimension/Dimension_Problems/Dimension_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week5-Dimension/Dimension_Problems/Dimension_problems.pdf -------------------------------------------------------------------------------- /Week5-Dimension/Dimension_Problems/triangular.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from vecutil import zero_vec 4 | 5 | def triangular_solve_n(rowlist, b): 6 | ''' 7 | Solves an upper-triangular linear system. 8 | rowlist is a nonempty list of Vecs. Let n = len(rowlist). 9 | The domain D of all these Vecs is {0,1, ..., n-1}. 10 | b is an n-element list or a Vec whose domain is {0,1, ..., n-1}. 11 | The linear equations are: 12 | rowlist[0] * x = b[0] 13 | ... 14 | rowlist[n-1] * x = b[n-1] 15 | The system is triangular. That means rowlist[i][j] is zero 16 | for all i, j in {0,1, ..., n-1} such that i >j. 17 | 18 | This procedure assumes that rowlist[j][j] != 0 for j=0,1, ..., n-1. 19 | 20 | The procedure returns the Vec x that is the unique solution 21 | to the linear system. 22 | ''' 23 | D = rowlist[0].D 24 | n = len(D) 25 | assert D == set(range(n)) 26 | x = zero_vec(D) 27 | for j in reversed(range(n)): 28 | x[j] = (b[j] - rowlist[j] * x)/rowlist[j][j] 29 | return x 30 | 31 | def triangular_solve(rowlist, label_list, b): 32 | ''' 33 | Solves an upper-triangular linear system. 34 | rowlist is a nonempty list of Vecs. Let n = len(rowlist). 35 | b is an n-element list or a Vec over domain {0,1, ..., n-1}. 36 | The linear equations are: 37 | rowlist[0] * x = b[0] 38 | ... 39 | rowlist[n-1] * x = b[n-1] 40 | label_list is a list consisting of all the elements of D, 41 | where D is the domain of each of the vectors in rowlist. 42 | The system is triangular with respect to the ordering given 43 | by label_list. That means rowlist[n-1][d] is zero for 44 | every element d of D except for the last element of label_list, 45 | rowlist[n-2][d] is zero for every element d of D except for 46 | the last two elements of label_list, and so on. 47 | 48 | Thit procedure assumes that rowlist[j][label_list[j]] != 0 49 | for j = 0,1, ..., n-1. 50 | 51 | The procedure returns the Vec x that is the unique solution 52 | to the linear system. 53 | ''' 54 | D = rowlist[0].D 55 | x = zero_vec(D) 56 | for j in reversed(range(len(D))): 57 | c = label_list[j] 58 | row = rowlist[j] 59 | x[c] = (b[j] - x*row)/row[c] 60 | return x 61 | -------------------------------------------------------------------------------- /Week5-Dimension/Dimension_Problems/vec.py: -------------------------------------------------------------------------------- 1 | # version code 24ea27739109+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # Copyright 2013 Philip N. Klein 6 | 7 | def getitem(v,k): 8 | """ 9 | Return the value of entry k in v. 10 | Be sure getitem(v,k) returns 0 if k is not represented in v.f. 11 | 12 | >>> v = Vec({'a','b','c', 'd'},{'a':2,'c':1,'d':3}) 13 | >>> v['d'] 14 | 3 15 | >>> v['b'] 16 | 0 17 | """ 18 | return v.f[k] if k in v.f.keys() else 0 19 | def setitem(v,k,val): 20 | """ 21 | Set the element of v with label d to be val. 22 | setitem(v,d,val) should set the value for key d even if d 23 | is not previously represented in v.f. 24 | 25 | >>> v = Vec({'a', 'b', 'c'}, {'b':0}) 26 | >>> v['b'] = 5 27 | >>> v['b'] 28 | 5 29 | >>> v['a'] = 1 30 | >>> v['a'] 31 | 1 32 | >>> v['a'] = 0 33 | >>> v['a'] 34 | 0 35 | """ 36 | v.f[k]=val 37 | 38 | def equal(u,v): 39 | """ 40 | Return true iff u is equal to v. 41 | Because of sparse representation, it is not enough to compare dictionaries 42 | 43 | >>> Vec({'a', 'b', 'c'}, {'a':0}) == Vec({'a', 'b', 'c'}, {'b':0}) 44 | True 45 | 46 | Be sure that equal(u, v) check equalities for all keys from u.f and v.f even if 47 | some keys in u.f do not exist in v.f (or vice versa) 48 | 49 | >>> Vec({'x','y','z'},{'y':1,'x':2}) == Vec({'x','y','z'},{'y':1,'z':0}) 50 | False 51 | >>> Vec({'a','b','c'}, {'a':0,'c':1}) == Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) 52 | False 53 | >>> Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) == Vec({'a','b','c'}, {'a':0,'c':1}) 54 | False 55 | 56 | The keys matter: 57 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'b':1}) 58 | False 59 | 60 | The values matter: 61 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'a':2}) 62 | False 63 | 64 | """ 65 | assert u.D == v.D 66 | for k in u.D: 67 | if getitem(u,k)!=getitem(v,k): 68 | return False 69 | return True 70 | 71 | def add(u,v): 72 | """ 73 | Returns the sum of the two vectors. 74 | Make sure to add together values for all keys from u.f and v.f even if some keys in u.f do not 75 | exist in v.f (or vice versa) 76 | 77 | >>> a = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 78 | >>> b = Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 79 | >>> c = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2,'o':4,'u':7}) 80 | >>> a + b == c 81 | True 82 | >>> a == Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 83 | True 84 | >>> b == Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 85 | True 86 | >>> d = Vec({'x','y','z'}, {'x':2,'y':1}) 87 | >>> e = Vec({'x','y','z'}, {'z':4,'y':-1}) 88 | >>> f = Vec({'x','y','z'}, {'x':2,'y':0,'z':4}) 89 | >>> d + e == f 90 | True 91 | >>> b + Vec({'a','e','i','o','u'}, {}) == b 92 | True 93 | """ 94 | assert u.D == v.D 95 | s=u.copy() 96 | for k in u.D: 97 | setitem(s,k,getitem(u,k)+getitem(v,k)) 98 | return s 99 | def dot(u,v): 100 | """ 101 | Returns the dot product of the two vectors. 102 | 103 | >>> u1 = Vec({'a','b'}, {'a':1, 'b':2}) 104 | >>> u2 = Vec({'a','b'}, {'b':2, 'a':1}) 105 | >>> u1*u2 106 | 5 107 | >>> u1 == Vec({'a','b'}, {'a':1, 'b':2}) 108 | True 109 | >>> u2 == Vec({'a','b'}, {'b':2, 'a':1}) 110 | True 111 | >>> v1 = Vec({'p','q','r','s'}, {'p':2,'s':3,'q':-1,'r':0}) 112 | >>> v2 = Vec({'p','q','r','s'}, {'p':-2,'r':5}) 113 | >>> v1*v2 114 | -4 115 | >>> w1 = Vec({'a','b','c'}, {'a':2,'b':3,'c':4}) 116 | >>> w2 = Vec({'a','b','c'}, {'a':12,'b':8,'c':6}) 117 | >>> w1*w2 118 | 72 119 | 120 | The pairwise products should not be collected in a set before summing 121 | because a set eliminates duplicates 122 | >>> v1 = Vec({1, 2}, {1 : 3, 2 : 6}) 123 | >>> v2 = Vec({1, 2}, {1 : 2, 2 : 1}) 124 | >>> v1 * v2 125 | 12 126 | """ 127 | assert u.D == v.D 128 | s=0 129 | for k in u.D: 130 | s+= getitem(u,k)*getitem(v,k) 131 | return s 132 | 133 | def scalar_mul(v, alpha): 134 | """ 135 | Returns the scalar-vector product alpha times v. 136 | 137 | >>> zero = Vec({'x','y','z','w'}, {}) 138 | >>> u = Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 139 | >>> 0*u == zero 140 | True 141 | >>> 1*u == u 142 | True 143 | >>> 0.5*u == Vec({'x','y','z','w'},{'x':0.5,'y':1,'z':1.5,'w':2}) 144 | True 145 | >>> u == Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 146 | True 147 | """ 148 | u=v.copy() 149 | for k in v.D: 150 | setitem(u,k, alpha*getitem(v,k)) 151 | return u 152 | 153 | def neg(v): 154 | """ 155 | Returns the negation of a vector. 156 | 157 | >>> u = Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 158 | >>> -u 159 | Vec({8, 2, 4, 6},{8: -4, 2: -1, 4: -2, 6: -3}) 160 | >>> u == Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 161 | True 162 | >>> -Vec({'a','b','c'}, {'a':1}) == Vec({'a','b','c'}, {'a':-1}) 163 | True 164 | 165 | """ 166 | u=v.copy() 167 | for k in v.D: 168 | setitem(u,k, -1*getitem(v,k)) 169 | return u 170 | 171 | ############################################################################################################################### 172 | 173 | class Vec: 174 | """ 175 | A vector has two fields: 176 | D - the domain (a set) 177 | f - a dictionary mapping (some) domain elements to field elements 178 | elements of D not appearing in f are implicitly mapped to zero 179 | """ 180 | def __init__(self, labels, function): 181 | self.D = labels 182 | self.f = function 183 | 184 | __getitem__ = getitem 185 | __setitem__ = setitem 186 | __neg__ = neg 187 | __rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar 188 | 189 | def __mul__(self,other): 190 | #If other is a vector, returns the dot product of self and other 191 | if isinstance(other, Vec): 192 | return dot(self,other) 193 | else: 194 | return NotImplemented # Will cause other.__rmul__(self) to be invoked 195 | 196 | def __truediv__(self,other): # Scalar division 197 | return (1/other)*self 198 | 199 | __add__ = add 200 | 201 | def __radd__(self, other): 202 | "Hack to allow sum(...) to work with vectors" 203 | if other == 0: 204 | return self 205 | 206 | def __sub__(a,b): 207 | "Returns a vector which is the difference of a and b." 208 | return a+(-b) 209 | 210 | __eq__ = equal 211 | 212 | def is_almost_zero(self): 213 | s = 0 214 | for x in self.f.values(): 215 | if isinstance(x, int) or isinstance(x, float): 216 | s += x*x 217 | elif isinstance(x, complex): 218 | s += x*x.conjugate() 219 | else: return False 220 | return s < 1e-20 221 | 222 | def __str__(v): 223 | "pretty-printing" 224 | D_list = sorted(v.D, key=repr) 225 | numdec = 3 226 | wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list]) 227 | s1 = ''.join(['{0:>{1}}'.format(str(k),wd[k]) for k in D_list]) 228 | s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list]) 229 | return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2 230 | 231 | def __hash__(self): 232 | "Here we pretend Vecs are immutable so we can form sets of them" 233 | h = hash(frozenset(self.D)) 234 | for k,v in sorted(self.f.items(), key = lambda x:repr(x[0])): 235 | if v != 0: 236 | h = hash((h, hash(v))) 237 | return h 238 | 239 | def __repr__(self): 240 | return "Vec(" + str(self.D) + "," + str(self.f) + ")" 241 | 242 | def copy(self): 243 | "Don't make a new copy of the domain D" 244 | return Vec(self.D, self.f.copy()) 245 | -------------------------------------------------------------------------------- /Week5-Dimension/Perspective_Lab/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week5-Dimension/Perspective_Lab/board.png -------------------------------------------------------------------------------- /Week5-Dimension/Perspective_Lab/cit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week5-Dimension/Perspective_Lab/cit.png -------------------------------------------------------------------------------- /Week5-Dimension/Perspective_Lab/perspective_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week5-Dimension/Perspective_Lab/perspective_lab.pdf -------------------------------------------------------------------------------- /Week5-Dimension/Perspective_Lab/vec.py: -------------------------------------------------------------------------------- 1 | # version code 24ea27739109+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # Copyright 2013 Philip N. Klein 6 | 7 | def getitem(v,k): 8 | """ 9 | Return the value of entry k in v. 10 | Be sure getitem(v,k) returns 0 if k is not represented in v.f. 11 | 12 | >>> v = Vec({'a','b','c', 'd'},{'a':2,'c':1,'d':3}) 13 | >>> v['d'] 14 | 3 15 | >>> v['b'] 16 | 0 17 | """ 18 | return v.f[k] if k in v.f.keys() else 0 19 | def setitem(v,k,val): 20 | """ 21 | Set the element of v with label d to be val. 22 | setitem(v,d,val) should set the value for key d even if d 23 | is not previously represented in v.f. 24 | 25 | >>> v = Vec({'a', 'b', 'c'}, {'b':0}) 26 | >>> v['b'] = 5 27 | >>> v['b'] 28 | 5 29 | >>> v['a'] = 1 30 | >>> v['a'] 31 | 1 32 | >>> v['a'] = 0 33 | >>> v['a'] 34 | 0 35 | """ 36 | v.f[k]=val 37 | 38 | def equal(u,v): 39 | """ 40 | Return true iff u is equal to v. 41 | Because of sparse representation, it is not enough to compare dictionaries 42 | 43 | >>> Vec({'a', 'b', 'c'}, {'a':0}) == Vec({'a', 'b', 'c'}, {'b':0}) 44 | True 45 | 46 | Be sure that equal(u, v) check equalities for all keys from u.f and v.f even if 47 | some keys in u.f do not exist in v.f (or vice versa) 48 | 49 | >>> Vec({'x','y','z'},{'y':1,'x':2}) == Vec({'x','y','z'},{'y':1,'z':0}) 50 | False 51 | >>> Vec({'a','b','c'}, {'a':0,'c':1}) == Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) 52 | False 53 | >>> Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) == Vec({'a','b','c'}, {'a':0,'c':1}) 54 | False 55 | 56 | The keys matter: 57 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'b':1}) 58 | False 59 | 60 | The values matter: 61 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'a':2}) 62 | False 63 | 64 | """ 65 | assert u.D == v.D 66 | for k in u.D: 67 | if getitem(u,k)!=getitem(v,k): 68 | return False 69 | return True 70 | 71 | def add(u,v): 72 | """ 73 | Returns the sum of the two vectors. 74 | Make sure to add together values for all keys from u.f and v.f even if some keys in u.f do not 75 | exist in v.f (or vice versa) 76 | 77 | >>> a = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 78 | >>> b = Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 79 | >>> c = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2,'o':4,'u':7}) 80 | >>> a + b == c 81 | True 82 | >>> a == Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 83 | True 84 | >>> b == Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 85 | True 86 | >>> d = Vec({'x','y','z'}, {'x':2,'y':1}) 87 | >>> e = Vec({'x','y','z'}, {'z':4,'y':-1}) 88 | >>> f = Vec({'x','y','z'}, {'x':2,'y':0,'z':4}) 89 | >>> d + e == f 90 | True 91 | >>> b + Vec({'a','e','i','o','u'}, {}) == b 92 | True 93 | """ 94 | assert u.D == v.D 95 | s=u.copy() 96 | for k in u.D: 97 | setitem(s,k,getitem(u,k)+getitem(v,k)) 98 | return s 99 | def dot(u,v): 100 | """ 101 | Returns the dot product of the two vectors. 102 | 103 | >>> u1 = Vec({'a','b'}, {'a':1, 'b':2}) 104 | >>> u2 = Vec({'a','b'}, {'b':2, 'a':1}) 105 | >>> u1*u2 106 | 5 107 | >>> u1 == Vec({'a','b'}, {'a':1, 'b':2}) 108 | True 109 | >>> u2 == Vec({'a','b'}, {'b':2, 'a':1}) 110 | True 111 | >>> v1 = Vec({'p','q','r','s'}, {'p':2,'s':3,'q':-1,'r':0}) 112 | >>> v2 = Vec({'p','q','r','s'}, {'p':-2,'r':5}) 113 | >>> v1*v2 114 | -4 115 | >>> w1 = Vec({'a','b','c'}, {'a':2,'b':3,'c':4}) 116 | >>> w2 = Vec({'a','b','c'}, {'a':12,'b':8,'c':6}) 117 | >>> w1*w2 118 | 72 119 | 120 | The pairwise products should not be collected in a set before summing 121 | because a set eliminates duplicates 122 | >>> v1 = Vec({1, 2}, {1 : 3, 2 : 6}) 123 | >>> v2 = Vec({1, 2}, {1 : 2, 2 : 1}) 124 | >>> v1 * v2 125 | 12 126 | """ 127 | assert u.D == v.D 128 | s=0 129 | for k in u.D: 130 | s+= getitem(u,k)*getitem(v,k) 131 | return s 132 | 133 | def scalar_mul(v, alpha): 134 | """ 135 | Returns the scalar-vector product alpha times v. 136 | 137 | >>> zero = Vec({'x','y','z','w'}, {}) 138 | >>> u = Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 139 | >>> 0*u == zero 140 | True 141 | >>> 1*u == u 142 | True 143 | >>> 0.5*u == Vec({'x','y','z','w'},{'x':0.5,'y':1,'z':1.5,'w':2}) 144 | True 145 | >>> u == Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 146 | True 147 | """ 148 | u=v.copy() 149 | for k in v.D: 150 | setitem(u,k, alpha*getitem(v,k)) 151 | return u 152 | 153 | def neg(v): 154 | """ 155 | Returns the negation of a vector. 156 | 157 | >>> u = Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 158 | >>> -u 159 | Vec({8, 2, 4, 6},{8: -4, 2: -1, 4: -2, 6: -3}) 160 | >>> u == Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 161 | True 162 | >>> -Vec({'a','b','c'}, {'a':1}) == Vec({'a','b','c'}, {'a':-1}) 163 | True 164 | 165 | """ 166 | u=v.copy() 167 | for k in v.D: 168 | setitem(u,k, -1*getitem(v,k)) 169 | return u 170 | 171 | ############################################################################################################################### 172 | 173 | class Vec: 174 | """ 175 | A vector has two fields: 176 | D - the domain (a set) 177 | f - a dictionary mapping (some) domain elements to field elements 178 | elements of D not appearing in f are implicitly mapped to zero 179 | """ 180 | def __init__(self, labels, function): 181 | self.D = labels 182 | self.f = function 183 | 184 | __getitem__ = getitem 185 | __setitem__ = setitem 186 | __neg__ = neg 187 | __rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar 188 | 189 | def __mul__(self,other): 190 | #If other is a vector, returns the dot product of self and other 191 | if isinstance(other, Vec): 192 | return dot(self,other) 193 | else: 194 | return NotImplemented # Will cause other.__rmul__(self) to be invoked 195 | 196 | def __truediv__(self,other): # Scalar division 197 | return (1/other)*self 198 | 199 | __add__ = add 200 | 201 | def __radd__(self, other): 202 | "Hack to allow sum(...) to work with vectors" 203 | if other == 0: 204 | return self 205 | 206 | def __sub__(a,b): 207 | "Returns a vector which is the difference of a and b." 208 | return a+(-b) 209 | 210 | __eq__ = equal 211 | 212 | def is_almost_zero(self): 213 | s = 0 214 | for x in self.f.values(): 215 | if isinstance(x, int) or isinstance(x, float): 216 | s += x*x 217 | elif isinstance(x, complex): 218 | s += x*x.conjugate() 219 | else: return False 220 | return s < 1e-20 221 | 222 | def __str__(v): 223 | "pretty-printing" 224 | D_list = sorted(v.D, key=repr) 225 | numdec = 3 226 | wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list]) 227 | s1 = ''.join(['{0:>{1}}'.format(str(k),wd[k]) for k in D_list]) 228 | s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list]) 229 | return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2 230 | 231 | def __hash__(self): 232 | "Here we pretend Vecs are immutable so we can form sets of them" 233 | h = hash(frozenset(self.D)) 234 | for k,v in sorted(self.f.items(), key = lambda x:repr(x[0])): 235 | if v != 0: 236 | h = hash((h, hash(v))) 237 | return h 238 | 239 | def __repr__(self): 240 | return "Vec(" + str(self.D) + "," + str(self.f) + ")" 241 | 242 | def copy(self): 243 | "Don't make a new copy of the domain D" 244 | return Vec(self.D, self.f.copy()) 245 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Gaussian_Elimination_Problems/Gaussian_Elimination_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week6-Gaussian_Elimination_and_the_Inner_Product/Gaussian_Elimination_Problems/Gaussian_Elimination_problems.pdf -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Gaussian_Elimination_Problems/Gaussian_Elimination_problems.py: -------------------------------------------------------------------------------- 1 | # version code 62505f329d9b 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | from matutil import * 6 | from GF2 import one 7 | 8 | 9 | 10 | ## 1: (Problem 1) Recognizing Echelon Form 11 | # Write each matrix as a list of row lists 12 | 13 | echelon_form_1 = [[1,2,0,2,0], 14 | [0,1,0,3,4], 15 | [0,0,2,3,4], 16 | [0,0,0,2,0], 17 | [0,0,0,0,4]] 18 | 19 | echelon_form_2 = [[0,4,3,4,4], 20 | [0,0,4,2,0], 21 | [0,0,0,0,1], 22 | [0,0,0,0,0]] 23 | 24 | echelon_form_3 = [[1,0,0,1], 25 | [0,0,0,1], 26 | [0,0,0,0]] 27 | 28 | echelon_form_4 = [[1,0,0,0], 29 | [0,1,0,0], 30 | [0,0,0,0], 31 | [0,0,0,0]] 32 | 33 | 34 | 35 | ## 2: (Problem 2) Is it echelon? 36 | def is_echelon(A): 37 | ''' 38 | Input: 39 | - A: a list of row lists 40 | Output: 41 | - True if A is in echelon form 42 | - False otherwise 43 | Examples: 44 | >>> is_echelon([[1,1,1],[0,1,1],[0,0,1]]) 45 | True 46 | >>> is_echelon([[0,1,1],[0,1,0],[0,0,1]]) 47 | False 48 | >>> is_echelon([[1,1]]) 49 | True 50 | >>> is_echelon([[1]]) 51 | True 52 | >>> is_echelon([[1],[1]]) 53 | False 54 | >>> is_echelon([[0]]) 55 | True 56 | >>> is_echelon([[0],[1]]) 57 | False 58 | ''' 59 | k=0 # 记录前面有几列0 60 | for j in list(range(len(A[0]))): 61 | m=j 62 | # if the column is all 0 63 | if sum([ A[x][j] for x in range(len(A))])==0: 64 | k=k+1 65 | continue 66 | else: 67 | m=j-k 68 | for i in list(range(m+1,len(A))): 69 | if A[i][j] != 0: 70 | return False 71 | return True 72 | 73 | 74 | ## 3: (Problem 3) Solving with Echelon Form: No Zero Rows 75 | # Give each answer as a list 76 | 77 | echelon_form_vec_a =[309.0/3355, 0, 0, 1.0/671] 78 | echelon_form_vec_b =[-3, 0, -2, 3] 79 | echelon_form_vec_c =[0, 0, -16.0/47, -10.0/47, 2] 80 | 81 | 82 | 83 | ## 4: (Problem 4) Solving with Echelon Form 84 | # If a solution exists, give it as a list vector. 85 | # If no solution exists, provide "None" (without the quotes). 86 | 87 | solving_with_echelon_form_a = None 88 | solving_with_echelon_form_b = None #[21, 0, 2, 0, 0] 89 | 90 | 91 | ## 5: (Problem 5) Echelon Solver 92 | def echelon_solve(row_list, label_list, b): 93 | ''' 94 | Input: 95 | - row_list: a list of Vecs 96 | - label_list: a list of labels establishing an order on the domain of 97 | Vecs in row_list 98 | - b: a vector (represented as a list) 99 | Output: 100 | - Vec x such that row_list * x is b 101 | >>> D = {'A','B','C','D','E'} 102 | >>> U_rows = [Vec(D, {'A':one, 'E':one}), Vec(D, {'B':one, 'E':one}), Vec(D,{'C':one})] 103 | >>> b_list = [one,0,one] 104 | >>> cols = ['A', 'B', 'C', 'D', 'E'] 105 | >>> echelon_solve(U_rows, cols, b_list) == Vec({'B', 'C', 'A', 'D', 'E'},{'B': 0, 'C': one, 'A': one}) 106 | True 107 | ''' 108 | D = rowlist[0].D 109 | x = zero_vec(D) 110 | for j in reversed(range(len(D))): 111 | c = label_list[j] 112 | row = rowlist[j] 113 | x[c] = (b[j] - x*row)/row[c] 114 | return x 115 | 116 | ## 6: (Problem 6) Solving General Matrices via Echelon 117 | row_list = [Vec({'A','B','C','D'},{'A':one,'B':one,'D':one}), Vec({'A','B','C','D'},{'B':one}),Vec({'A','B','C','D'},{'C':one}),Vec({'A','B','C','D'},{'D':one})] # Provide as a list of Vec instances 118 | label_list = ['A', 'B', 'C', 'D'] # Provide as a list 119 | b = [one, one, 0, 0] # Provide as a list of GF(2) values 120 | 121 | 122 | 123 | ## 7: (Problem 7) Nullspace A 124 | null_space_rows_a = {3, 4} # Put the row numbers of M from the PDF 125 | 126 | 127 | 128 | ## 8: (Problem 8) Nullspace B 129 | null_space_rows_b = {4}# Put the row numbers of M from the PDF 130 | 131 | #print(is_echelon([[1,1,1],[0,1,1],[0,0,1]])) 132 | #print(is_echelon([[0,1,1],[0,1,0],[0,0,1]])) 133 | #print(is_echelon([[0]])) 134 | #print(is_echelon([[1,1]])) 135 | #print(is_echelon([[0],[1]])) 136 | ''' 137 | print(is_echelon([[2,1,0],[0,-4,0],[0,0,1]])) 138 | print(is_echelon([[2,1,0],[0,3,0],[1,0,1]])) 139 | print(is_echelon([[2,1,0],[-4,0,0],[0,0,1]])) 140 | print(is_echelon([[1,1,1,1,1],[0,2,0,1,3],[0,0,0,5,3]])) 141 | print(is_echelon([[0,0,0],[0,0,0],[0,0,0]])) 142 | print(is_echelon([[0,1,1],[0,1,0],[0,0,1]])) 143 | ''' 144 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Gaussian_Elimination_Problems/cracking_rand.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 David Eisenstat 2 | """ 3 | Computes the tempering matrix from the MT19937 pseudorandom number generator. 4 | 5 | >>> from cracking_rand import * 6 | >>> import random 7 | >>> prng = random.Random() 8 | >>> n = 624 9 | >>> data = [prng.getrandbits(32) for k in range(n)] 10 | >>> seed = prng.getstate()[1][:n] 11 | >>> T = tempering_mat() 12 | >>> data == [int_from_vec(T * vec_from_int(x)) for x in seed] 13 | True 14 | """ 15 | 16 | 17 | from mat import Mat 18 | from vec import Vec 19 | 20 | #This module should use GF2.one but doesn't yet 21 | 22 | one = 1 23 | 24 | 25 | def format_bit(b): 26 | """ 27 | Converts a bit to a string. 28 | 29 | >>> format_bit(0) 30 | '0' 31 | >>> format_bit(one) 32 | '1' 33 | """ 34 | return '0' if b == 0 else '1' 35 | 36 | 37 | def print_vec(v): 38 | """ 39 | Prints a bit vector compactly. 40 | 41 | >>> print_vec(Vec({0, 1, 2, 3, 4, 5, 6, 7}, {1: one, 3: one, 5: one})) 42 | 01010100 43 | >>> print_vec(Vec({0, 1, 2, 3}, {0: one, 2: one, 3: one})) 44 | 1011 45 | """ 46 | print(''.join(format_bit(v[k]) for k in sorted(v.D))) 47 | 48 | 49 | def print_mat(m): 50 | """ 51 | Prints a bit matrix compactly. 52 | 53 | >>> print_mat(Mat(({0, 1, 2}, {0, 1, 2}), {(0, 1): one, (1, 2): one})) 54 | 010 55 | 001 56 | 000 57 | """ 58 | D0, D1 = map(sorted, m.D) 59 | for i in D0: 60 | print(''.join(format_bit(m[(i, j)]) for j in D1)) 61 | 62 | 63 | def vec_from_int(m, n=32): 64 | """ 65 | Returns the n-bit vector specified by the integer m. 66 | 67 | >>> print_vec(vec_from_int(0b00101010, 8)) 68 | 01010100 69 | >>> print_vec(vec_from_int(0b1101, 4)) 70 | 1011 71 | """ 72 | return Vec(set(range(n)), {k: one for k in range(n) if (2 ** k) & m}) 73 | 74 | 75 | def int_from_vec(v): 76 | """ 77 | Returns the integer specified by the bit vector v. 78 | 79 | >>> int_from_vec(vec_from_int(42, 8)) 80 | 42 81 | >>> int_from_vec(vec_from_int(13, 4)) 82 | 13 83 | """ 84 | # TODO(david): use GF2 85 | return sum(2 ** k for k in v.D if v[k] & 1) 86 | 87 | 88 | def left_shift(k, n=32): 89 | """ 90 | Returns the n*n matrix corresponding to the operation 91 | 92 | lambda v: vec_from_int(int_from_vec(v) << k, n) 93 | 94 | >>> print_mat(left_shift(2, 6)) 95 | 000000 96 | 000000 97 | 100000 98 | 010000 99 | 001000 100 | 000100 101 | >>> int_from_vec(left_shift(2) * vec_from_int(42)) == 42 << 2 102 | True 103 | """ 104 | D = set(range(n)) 105 | return Mat((D, D), {(j + k, j): one for j in range(n - k)}) 106 | 107 | 108 | def right_shift(k, n=32): 109 | """ 110 | Returns the n*n matrix corresponding to the operation 111 | 112 | lambda v: vec_from_int(int_from_vec(v) >> k, n) 113 | 114 | >>> print_mat(right_shift(1, 4)) 115 | 0100 116 | 0010 117 | 0001 118 | 0000 119 | >>> int_from_vec(right_shift(1) * vec_from_int(13)) == 13 >> 1 120 | True 121 | """ 122 | D = set(range(n)) 123 | return Mat((D, D), {(i, i + k): one for i in range(n - k)}) 124 | 125 | 126 | def diag(v): 127 | """ 128 | Returns the diagonal matrix specified by the vector v. 129 | 130 | >>> print_mat(diag(vec_from_int(13, 4))) 131 | 1000 132 | 0000 133 | 0010 134 | 0001 135 | """ 136 | return Mat((v.D, v.D), {(k, k): v[k] for k in v.D}) 137 | 138 | 139 | def bitwise_and(m, n=32): 140 | """ 141 | Returns the matrix for masking an n-bit vector by the integer m. 142 | 143 | >>> print_mat(bitwise_and(13, 4)) 144 | 1000 145 | 0000 146 | 0010 147 | 0001 148 | """ 149 | return diag(vec_from_int(m, n)) 150 | 151 | 152 | def identity_mat(n=32): 153 | """ 154 | Returns the n*n identity matrix. 155 | 156 | >>> print_mat(identity_mat(4)) 157 | 1000 158 | 0100 159 | 0010 160 | 0001 161 | """ 162 | D = set(range(n)) 163 | return Mat((D, D), {(k, k): one for k in range(n)}) 164 | 165 | 166 | def tempering_mat(): 167 | """ 168 | Returns the matrix corresponding to the MT19937 tempering transform. 169 | 170 | >>> print_mat(tempering_mat()) 171 | 10010000000100100010001000000100 172 | 01000000000010000001000100000010 173 | 00100000000001000000100000000001 174 | 00010000000000100000010001000000 175 | 10001001000100010010001000000000 176 | 00000100100000001001000100000000 177 | 00100010010001000100100010001000 178 | 10010001001100100010010001000000 179 | 00000000100100000001001000100010 180 | 00100100010011001000100100010001 181 | 00010000001000100000010000001000 182 | 00000001000100100010001001000100 183 | 00000100000010011000000100100010 184 | 00000000000001001000000010010001 185 | 00000001000000100010000001000000 186 | 00000000000000010000000000100000 187 | 00000000000000001000000000010000 188 | 00100000000001000100000000001000 189 | 00010000000100100010001000000100 190 | 00000000000010000001000100000010 191 | 00000000000000000000100000000001 192 | 00000000000000100000010001000000 193 | 10000001000100000010001000000000 194 | 00000000100000000001000100000000 195 | 00100000010001000100100010001000 196 | 00010000001000100000010001000000 197 | 00000000000100000001001000100010 198 | 00000100000010001000100100010001 199 | 00000000000000000000010000001000 200 | 00000001000000100010000001000100 201 | 00000000000000010000000000100010 202 | 00000000000000001000000010010001 203 | """ 204 | m = identity_mat() 205 | m += right_shift(11) * m 206 | m += bitwise_and(0x9d2c5680) * left_shift(7) * m 207 | m += bitwise_and(0xefc60000) * left_shift(15) * m 208 | m += right_shift(18) * m 209 | return m 210 | 211 | 212 | if __name__ == '__main__': 213 | from doctest import testmod 214 | testmod() 215 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Gaussian_Elimination_Problems/echelon.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from mat import Mat 4 | import GF2 5 | 6 | def row_reduce(rowlist): 7 | """Given a list of vectors, transform the vectors. 8 | Mutates the argument. 9 | Returns a list of the nonzero reduced vectors in echelon form. 10 | """ 11 | col_label_list = sorted(rowlist[0].D, key=repr) 12 | rows_left = set(range(len(rowlist))) 13 | new_rowlist = [] 14 | for c in col_label_list: 15 | #among rows left, list of row-labels whose rows have a nonzero in position c 16 | rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0] 17 | if rows_with_nonzero != []: 18 | pivot = rows_with_nonzero[0] 19 | rows_left.remove(pivot) 20 | new_rowlist.append(rowlist[pivot]) 21 | for r in rows_with_nonzero[1:]: 22 | rowlist[r] -= (rowlist[r][c]/rowlist[pivot][c])*rowlist[pivot] 23 | return new_rowlist 24 | 25 | def transformation_rows(rowlist_input, col_label_list = None): 26 | """Given a matrix A represented by a list of rows 27 | optionally given the unit field element (1 by default), 28 | and optionally given a list of the domain elements of the rows, 29 | return a matrix M represented by a list of rows such that 30 | M A is in echelon form 31 | """ 32 | one = GF2.one # replace this with 1 if working over R or C 33 | rowlist = list(rowlist_input) 34 | if col_label_list == None: col_label_list = sorted(rowlist[0].D, key=repr) 35 | m = len(rowlist) 36 | row_labels = set(range(m)) 37 | M_rowlist = [Vec(row_labels, {i:one}) for i in range(m)] 38 | new_M_rowlist = [] 39 | rows_left = set(range(m)) 40 | for c in col_label_list: 41 | rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0] 42 | if rows_with_nonzero != []: 43 | pivot = rows_with_nonzero[0] 44 | rows_left.remove(pivot) 45 | new_M_rowlist.append(M_rowlist[pivot]) 46 | for r in rows_with_nonzero[1:]: 47 | multiplier = rowlist[r][c]/rowlist[pivot][c] 48 | rowlist[r] -= multiplier*rowlist[pivot] 49 | M_rowlist[r] -= multiplier*M_rowlist[pivot] 50 | for r in rows_left: new_M_rowlist.append(M_rowlist[r]) 51 | return new_M_rowlist 52 | 53 | def transformation(A, col_label_list = None): 54 | """Given a matrix A, and optionally the unit field element (1 by default), 55 | compute matrix M such that M is invertible and 56 | U = M*A is in echelon form. 57 | """ 58 | row_labels, col_labels = A.D 59 | m = len(row_labels) 60 | row_label_list = sorted(row_labels, key=repr) 61 | rowlist = [Vec(col_labels, {c:A[r,c] for c in col_labels}) for r in row_label_list] 62 | M_rows = transformation_rows(rowlist, col_label_list) 63 | M = Mat((set(range(m)), row_labels), {}) 64 | for r in range(m): 65 | for (i,value) in M_rows[r].f.items(): 66 | M[r,row_label_list[i]] = value 67 | return M 68 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Gaussian_Elimination_Problems/gaussian_examples.py: -------------------------------------------------------------------------------- 1 | from mat import Mat 2 | from GF2 import one 3 | 4 | Ad = (set([1,2,3,4]), set(['A','B','C','D'])) 5 | Af = {k:one for k in {(2,'A'),(2,'C'),(2,'D'),(1,'C'),(1,'D'),(3,'A'),(3,'D'),(4,'A'),(4,'B'),(4,'C'),(4,'D')}} 6 | A = Mat(Ad,Af) 7 | 8 | Bd = (set([1,2,3,4]), set(['A','B','C','D'])) 9 | Bf = {k:one for k in {(1,'A'),(1,'B'),(2,'A'),(2,'C'),(3,'B'),(3,'C'),(3,'D'),(4,'A')}} 10 | B=Mat(Bd, Bf) 11 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Integer_Factoring_Lab/factoring_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week6-Gaussian_Elimination_and_the_Inner_Product/Integer_Factoring_Lab/factoring_lab.pdf -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Integer_Factoring_Lab/factoring_lab.py: -------------------------------------------------------------------------------- 1 | # version code 62505f329d9b 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | from vec import Vec, getitem 6 | from GF2 import one 7 | 8 | from factoring_support import dumb_factor 9 | from factoring_support import intsqrt 10 | from factoring_support import gcd 11 | from factoring_support import primes 12 | from factoring_support import prod 13 | 14 | import echelon 15 | 16 | ## Task 1 17 | def int2GF2(i): 18 | ''' 19 | Returns one if i is odd, 0 otherwise. 20 | 21 | Input: 22 | - i: an int 23 | Output: 24 | - one if i is congruent to 1 mod 2 25 | - 0 if i is congruent to 0 mod 2 26 | Examples: 27 | >>> int2GF2(3) 28 | one 29 | >>> int2GF2(100) 30 | 0 31 | ''' 32 | return one if i%2 == 1 else 0 33 | ## Task 2 34 | def make_Vec(primeset, factors): 35 | ''' 36 | Input: 37 | - primeset: a set of primes 38 | - factors: a list of factors [(p_1,a_1), ..., (p_n, a_n)] 39 | with p_i in primeset 40 | Output: 41 | - a vector v over GF(2) with domain primeset 42 | such that v[p_i] = int2GF2(a_i) for all i 43 | Example: 44 | >>> make_Vec({2,3,11}, [(2,3), (3,2)]) == Vec({2,3,11},{2:one}) 45 | True 46 | ''' 47 | return Vec(primeset, {x[0]:int2GF2(x[1]) for x in factors}) 48 | ## Task 3 49 | def find_candidates(N, primeset): 50 | ''' 51 | Input: 52 | - N: an int to factor 53 | - primeset: a set of primes 54 | 55 | Output: 56 | - a tuple (roots, rowlist) 57 | - roots: a list a_0, a_1, ..., a_n where a_i*a_i - N can be factored 58 | over primeset 59 | - rowlist: a list such that rowlist[i] is a 60 | primeset-vector over GF(2) corresponding to a_i 61 | such that len(roots) = len(rowlist) and len(roots) > len(primeset) 62 | Example: 63 | >>> from factoring_support import primes 64 | >>> N = 2419 65 | >>> primeset = primes(32) 66 | >>> roots, rowlist = find_candidates(N, primeset) 67 | >>> set(roots) == set([51, 52, 53, 58, 61, 62, 63, 67, 68, 71, 77, 79]) 68 | True 69 | >>> D = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31} 70 | >>> set(rowlist) == set([Vec(D,{2: one, 13: one, 7: one}),\ 71 | Vec(D,{3: one, 19: one, 5: one}),\ 72 | Vec(D,{2: one, 3: one, 5: one, 13: one}),\ 73 | Vec(D,{3: one, 5: one, 7: one}),\ 74 | Vec(D,{7: one, 2: one, 3: one, 31: one}),\ 75 | Vec(D,{3: one, 19: one}),\ 76 | Vec(D,{2: one, 31: one}),\ 77 | Vec(D,{2: one, 5: one, 23: one}),\ 78 | Vec(D,{5: one}),\ 79 | Vec(D,{3: one, 2: one, 19: one, 23: one}),\ 80 | Vec(D,{2: one, 3: one, 5: one, 13: one}),\ 81 | Vec(D,{2: one, 3: one, 13: one})]) 82 | True 83 | ''' 84 | roots = [] 85 | rowlist = [] 86 | for x in range(2,N): 87 | y = x + intsqrt(N) 88 | tmp = dumb_factor(y*y-N, primeset) 89 | if len(tmp) != 0 : 90 | roots.append(y) 91 | rowlist.append(make_Vec(primeset,tmp)) 92 | if len(roots) >= len(primeset)+1: 93 | break 94 | return (roots, rowlist) 95 | 96 | 97 | 98 | ## Task 4 99 | def find_a_and_b(v, roots, N): 100 | ''' 101 | Input: 102 | - a {0,1,..., n-1}-vector v over GF(2) where n = len(roots) 103 | - a list roots of integers 104 | - an integer N to factor 105 | Output: 106 | a pair (a,b) of integers 107 | such that a*a-b*b is a multiple of N 108 | (if v is correctly chosen) 109 | Example: 110 | >>> roots = [51, 52, 53, 58, 61, 62, 63, 67, 68, 71, 77, 79] 111 | >>> N = 2419 112 | >>> v = Vec({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{1: one, 2: one, 11: one, 5: one}) 113 | >>> find_a_and_b(v, roots, N) 114 | (13498888, 778050) 115 | >>> v = Vec({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{0: 0, 1: 0, 10: one, 2: one}) 116 | >>> find_a_and_b(v, roots, N) 117 | (4081, 1170) 118 | ''' 119 | alist = [ roots[i] for i in v.D if getitem(v,i)==one] 120 | a = prod(alist) 121 | c = prod([x*x-N for x in alist]) 122 | b = intsqrt(c) 123 | assert b*b == c 124 | return (a, b) 125 | 126 | ## Task 5 127 | ''' 128 | N = 2461799993978700679 129 | primelist = primes(10000) 130 | (roots, rowlist) = find_candidates(N, primelist) 131 | M = echelon.transformation_rows(rowlist) 132 | k = -1 133 | while True: 134 | v = M[k] 135 | (a, b) = find_a_and_b(v, roots, N) 136 | k -= 1 137 | print(gcd(a-b, N)) 138 | if gcd(a-b, N)>1: 139 | break 140 | ''' 141 | nontrivial_divisor_of_2461799993978700679 = 1230926561 142 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Integer_Factoring_Lab/factoring_support.py: -------------------------------------------------------------------------------- 1 | from math import sqrt 2 | from functools import reduce 3 | import operator 4 | 5 | def gcd(x,y): return x if y == 0 else gcd(y, x % y) 6 | 7 | def dumb_factor(x, primeset): 8 | """ If x can be factored over the primeset, return the 9 | set of pairs (p_i, a_i) such that x is the product 10 | of p_i to the power of a_i. 11 | If not, return [] 12 | """ 13 | factors = [] 14 | for p in primeset: 15 | exponent = 0 16 | while x % p == 0: 17 | exponent = exponent + 1 18 | x = x//p 19 | if exponent > 0: 20 | factors.append((p,exponent)) 21 | return factors if x == 1 else [] 22 | 23 | def primes(limit): 24 | primeset = set() 25 | a = [True] * limit # Initialize the primality list 26 | a[0] = a[1] = False 27 | for (i, isprime) in enumerate(a): 28 | if isprime: 29 | primeset.add(i) 30 | for n in range(i*i, limit, i): # Mark factors non-prime 31 | a[n] = False 32 | return primeset 33 | 34 | def intsqrt(x): 35 | L = 1 36 | H = x 37 | if H 1: 39 | m = int((L+H)//2) 40 | d = x//m 41 | if d > m: L = m 42 | else: H = m 43 | return L if L*L == x else H 44 | 45 | def prod(factors): 46 | "return product of numbers in given list" 47 | return reduce(operator.mul, factors, 1) 48 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Secret_Sharing_Lab/bitutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | """ 3 | Implements several convenience operations for use with the ECC lab. 4 | 5 | Author: Landon Judkins (ljudkins) 6 | Date: Spring 2009 7 | Updated by Nick Gaya, Spring 2013 8 | 9 | Requires: fields matutil 10 | """ 11 | 12 | from GF2 import zero, one 13 | import mat 14 | import random 15 | 16 | def str2bits(inp): 17 | """ 18 | Convert a string into a list of bits, with each character's bits in order 19 | of increasing significance. 20 | """ 21 | bs = [1<>> from cracking_rand import * 6 | >>> import random 7 | >>> prng = random.Random() 8 | >>> n = 624 9 | >>> data = [prng.getrandbits(32) for k in range(n)] 10 | >>> seed = prng.getstate()[1][:n] 11 | >>> T = tempering_mat() 12 | >>> data == [int_from_vec(T * vec_from_int(x)) for x in seed] 13 | True 14 | """ 15 | 16 | 17 | from mat import Mat 18 | from vec import Vec 19 | 20 | #This module should use GF2.one but doesn't yet 21 | 22 | one = 1 23 | 24 | 25 | def format_bit(b): 26 | """ 27 | Converts a bit to a string. 28 | 29 | >>> format_bit(0) 30 | '0' 31 | >>> format_bit(one) 32 | '1' 33 | """ 34 | return '0' if b == 0 else '1' 35 | 36 | 37 | def print_vec(v): 38 | """ 39 | Prints a bit vector compactly. 40 | 41 | >>> print_vec(Vec({0, 1, 2, 3, 4, 5, 6, 7}, {1: one, 3: one, 5: one})) 42 | 01010100 43 | >>> print_vec(Vec({0, 1, 2, 3}, {0: one, 2: one, 3: one})) 44 | 1011 45 | """ 46 | print(''.join(format_bit(v[k]) for k in sorted(v.D))) 47 | 48 | 49 | def print_mat(m): 50 | """ 51 | Prints a bit matrix compactly. 52 | 53 | >>> print_mat(Mat(({0, 1, 2}, {0, 1, 2}), {(0, 1): one, (1, 2): one})) 54 | 010 55 | 001 56 | 000 57 | """ 58 | D0, D1 = map(sorted, m.D) 59 | for i in D0: 60 | print(''.join(format_bit(m[(i, j)]) for j in D1)) 61 | 62 | 63 | def vec_from_int(m, n=32): 64 | """ 65 | Returns the n-bit vector specified by the integer m. 66 | 67 | >>> print_vec(vec_from_int(0b00101010, 8)) 68 | 01010100 69 | >>> print_vec(vec_from_int(0b1101, 4)) 70 | 1011 71 | """ 72 | return Vec(set(range(n)), {k: one for k in range(n) if (2 ** k) & m}) 73 | 74 | 75 | def int_from_vec(v): 76 | """ 77 | Returns the integer specified by the bit vector v. 78 | 79 | >>> int_from_vec(vec_from_int(42, 8)) 80 | 42 81 | >>> int_from_vec(vec_from_int(13, 4)) 82 | 13 83 | """ 84 | # TODO(david): use GF2 85 | return sum(2 ** k for k in v.D if v[k] & 1) 86 | 87 | 88 | def left_shift(k, n=32): 89 | """ 90 | Returns the n*n matrix corresponding to the operation 91 | 92 | lambda v: vec_from_int(int_from_vec(v) << k, n) 93 | 94 | >>> print_mat(left_shift(2, 6)) 95 | 000000 96 | 000000 97 | 100000 98 | 010000 99 | 001000 100 | 000100 101 | >>> int_from_vec(left_shift(2) * vec_from_int(42)) == 42 << 2 102 | True 103 | """ 104 | D = set(range(n)) 105 | return Mat((D, D), {(j + k, j): one for j in range(n - k)}) 106 | 107 | 108 | def right_shift(k, n=32): 109 | """ 110 | Returns the n*n matrix corresponding to the operation 111 | 112 | lambda v: vec_from_int(int_from_vec(v) >> k, n) 113 | 114 | >>> print_mat(right_shift(1, 4)) 115 | 0100 116 | 0010 117 | 0001 118 | 0000 119 | >>> int_from_vec(right_shift(1) * vec_from_int(13)) == 13 >> 1 120 | True 121 | """ 122 | D = set(range(n)) 123 | return Mat((D, D), {(i, i + k): one for i in range(n - k)}) 124 | 125 | 126 | def diag(v): 127 | """ 128 | Returns the diagonal matrix specified by the vector v. 129 | 130 | >>> print_mat(diag(vec_from_int(13, 4))) 131 | 1000 132 | 0000 133 | 0010 134 | 0001 135 | """ 136 | return Mat((v.D, v.D), {(k, k): v[k] for k in v.D}) 137 | 138 | 139 | def bitwise_and(m, n=32): 140 | """ 141 | Returns the matrix for masking an n-bit vector by the integer m. 142 | 143 | >>> print_mat(bitwise_and(13, 4)) 144 | 1000 145 | 0000 146 | 0010 147 | 0001 148 | """ 149 | return diag(vec_from_int(m, n)) 150 | 151 | 152 | def identity_mat(n=32): 153 | """ 154 | Returns the n*n identity matrix. 155 | 156 | >>> print_mat(identity_mat(4)) 157 | 1000 158 | 0100 159 | 0010 160 | 0001 161 | """ 162 | D = set(range(n)) 163 | return Mat((D, D), {(k, k): one for k in range(n)}) 164 | 165 | 166 | def tempering_mat(): 167 | """ 168 | Returns the matrix corresponding to the MT19937 tempering transform. 169 | 170 | >>> print_mat(tempering_mat()) 171 | 10010000000100100010001000000100 172 | 01000000000010000001000100000010 173 | 00100000000001000000100000000001 174 | 00010000000000100000010001000000 175 | 10001001000100010010001000000000 176 | 00000100100000001001000100000000 177 | 00100010010001000100100010001000 178 | 10010001001100100010010001000000 179 | 00000000100100000001001000100010 180 | 00100100010011001000100100010001 181 | 00010000001000100000010000001000 182 | 00000001000100100010001001000100 183 | 00000100000010011000000100100010 184 | 00000000000001001000000010010001 185 | 00000001000000100010000001000000 186 | 00000000000000010000000000100000 187 | 00000000000000001000000000010000 188 | 00100000000001000100000000001000 189 | 00010000000100100010001000000100 190 | 00000000000010000001000100000010 191 | 00000000000000000000100000000001 192 | 00000000000000100000010001000000 193 | 10000001000100000010001000000000 194 | 00000000100000000001000100000000 195 | 00100000010001000100100010001000 196 | 00010000001000100000010001000000 197 | 00000000000100000001001000100010 198 | 00000100000010001000100100010001 199 | 00000000000000000000010000001000 200 | 00000001000000100010000001000100 201 | 00000000000000010000000000100010 202 | 00000000000000001000000010010001 203 | """ 204 | m = identity_mat() 205 | m += right_shift(11) * m 206 | m += bitwise_and(0x9d2c5680) * left_shift(7) * m 207 | m += bitwise_and(0xefc60000) * left_shift(15) * m 208 | m += right_shift(18) * m 209 | return m 210 | 211 | 212 | if __name__ == '__main__': 213 | from doctest import testmod 214 | testmod() 215 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Secret_Sharing_Lab/echelon.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from mat import Mat 4 | import GF2 5 | 6 | def row_reduce(rowlist): 7 | """Given a list of vectors, transform the vectors. 8 | Mutates the argument. 9 | Returns a list of the nonzero reduced vectors in echelon form. 10 | """ 11 | col_label_list = sorted(rowlist[0].D, key=repr) 12 | rows_left = set(range(len(rowlist))) 13 | new_rowlist = [] 14 | for c in col_label_list: 15 | #among rows left, list of row-labels whose rows have a nonzero in position c 16 | rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0] 17 | if rows_with_nonzero != []: 18 | pivot = rows_with_nonzero[0] 19 | rows_left.remove(pivot) 20 | new_rowlist.append(rowlist[pivot]) 21 | for r in rows_with_nonzero[1:]: 22 | rowlist[r] -= (rowlist[r][c]/rowlist[pivot][c])*rowlist[pivot] 23 | return new_rowlist 24 | 25 | def transformation_rows(rowlist_input, col_label_list = None): 26 | """Given a matrix A represented by a list of rows 27 | optionally given the unit field element (1 by default), 28 | and optionally given a list of the domain elements of the rows, 29 | return a matrix M represented by a list of rows such that 30 | M A is in echelon form 31 | """ 32 | one = GF2.one # replace this with 1 if working over R or C 33 | rowlist = list(rowlist_input) 34 | if col_label_list == None: col_label_list = sorted(rowlist[0].D, key=repr) 35 | m = len(rowlist) 36 | row_labels = set(range(m)) 37 | M_rowlist = [Vec(row_labels, {i:one}) for i in range(m)] 38 | new_M_rowlist = [] 39 | rows_left = set(range(m)) 40 | for c in col_label_list: 41 | rows_with_nonzero = [r for r in rows_left if rowlist[r][c] != 0] 42 | if rows_with_nonzero != []: 43 | pivot = rows_with_nonzero[0] 44 | rows_left.remove(pivot) 45 | new_M_rowlist.append(M_rowlist[pivot]) 46 | for r in rows_with_nonzero[1:]: 47 | multiplier = rowlist[r][c]/rowlist[pivot][c] 48 | rowlist[r] -= multiplier*rowlist[pivot] 49 | M_rowlist[r] -= multiplier*M_rowlist[pivot] 50 | for r in rows_left: new_M_rowlist.append(M_rowlist[r]) 51 | return new_M_rowlist 52 | 53 | def transformation(A, col_label_list = None): 54 | """Given a matrix A, and optionally the unit field element (1 by default), 55 | compute matrix M such that M is invertible and 56 | U = M*A is in echelon form. 57 | """ 58 | row_labels, col_labels = A.D 59 | m = len(row_labels) 60 | row_label_list = sorted(row_labels, key=repr) 61 | rowlist = [Vec(col_labels, {c:A[r,c] for c in col_labels}) for r in row_label_list] 62 | M_rows = transformation_rows(rowlist, col_label_list) 63 | M = Mat((set(range(m)), row_labels), {}) 64 | for r in range(m): 65 | for (i,value) in M_rows[r].f.items(): 66 | M[r,row_label_list[i]] = value 67 | return M 68 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Secret_Sharing_Lab/gaussian_examples.py: -------------------------------------------------------------------------------- 1 | from mat import Mat 2 | from GF2 import one 3 | 4 | Ad = (set([1,2,3,4]), set(['A','B','C','D'])) 5 | Af = {k:one for k in {(2,'A'),(2,'C'),(2,'D'),(1,'C'),(1,'D'),(3,'A'),(3,'D'),(4,'A'),(4,'B'),(4,'C'),(4,'D')}} 6 | A = Mat(Ad,Af) 7 | 8 | Bd = (set([1,2,3,4]), set(['A','B','C','D'])) 9 | Bf = {k:one for k in {(1,'A'),(1,'B'),(2,'A'),(2,'C'),(3,'B'),(3,'C'),(3,'D'),(4,'A')}} 10 | B=Mat(Bd, Bf) 11 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Secret_Sharing_Lab/secret_sharing_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week6-Gaussian_Elimination_and_the_Inner_Product/Secret_Sharing_Lab/secret_sharing_lab.pdf -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/Secret_Sharing_Lab/secret_sharing_lab.py: -------------------------------------------------------------------------------- 1 | # version code 3ebd92e7eece+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | import random 6 | from GF2 import one 7 | from vecutil import list2vec 8 | from independence import is_independent 9 | from vec import Vec 10 | 11 | ## 1: (Task 1) Choosing a Secret Vector 12 | def randGF2(): return random.randint(0,1)*one 13 | 14 | a0 = list2vec([one, one, 0, one, 0, one]) 15 | b0 = list2vec([one, one, 0, 0, 0, one]) 16 | 17 | def choose_secret_vector(s,t): 18 | while True: 19 | u = list2vec([ randGF2() for i in range(6)]) 20 | if a0*u == s and b0*u == t: 21 | return u 22 | 23 | 24 | ## 2: (Task 2) Finding Secret Sharing Vectors 25 | # Give each vector as a Vec instance 26 | #''' 27 | L=[Vec({0, 1, 2, 3, 4, 5},{0: one, 1: 0, 2: one, 3: one, 4: one, 5: 0}), Vec({0, 1, 2, 3, 4, 5},{0: 0, 1: one, 2: 0, 3: one, 4: 0, 5: one}), Vec({0, 1, 2, 3, 4, 5},{0: one, 1: one, 2: one, 3: one, 4: 0, 5: one}), Vec({0, 1, 2, 3, 4, 5},{0: 0, 1: one, 2: one, 3: one, 4: 0, 5: one}), Vec({0, 1, 2, 3, 4, 5},{0: one, 1: 0, 2: one, 3: one, 4: one, 5: one}), Vec({0, 1, 2, 3, 4, 5},{0: one, 1: 0, 2: 0, 3: one, 4: one, 5: one}), Vec({0, 1, 2, 3, 4, 5},{0: one, 1: one, 2: 0, 3: 0, 4: one, 5: one}), Vec({0, 1, 2, 3, 4, 5},{0: one, 1: one, 2: one, 3: 0, 4: one, 5: 0})] 28 | 29 | secret_a0 =list2vec([one, one, 0, one, 0, one]) 30 | secret_b0 =list2vec([one, one, 0, 0, 0, one]) 31 | secret_a1 =L[0] 32 | secret_b1 =L[1] 33 | secret_a2 =L[2] 34 | secret_b2 =L[3] 35 | secret_a3 =L[4] 36 | secret_b3 =L[5] 37 | secret_a4 =L[6] 38 | secret_b4 =L[7] 39 | 40 | #print(choose_secret_vector(s,t)) 41 | #u = list2vec([ randGF2() for i in range(6)]) 42 | #print(u) 43 | 44 | # Program for task 2 45 | ''' 46 | L=list(range(0,8)) 47 | for n in range(100): 48 | u = [list2vec([ randGF2() for i in range(6)]) for j in range(8)] 49 | for k in range(28): 50 | S=list() 51 | random.shuffle(L) 52 | for i in range(3): 53 | S.append(u[L[i]]) 54 | print("len S") 55 | print(k, len(u),len(S)) 56 | if is_independent(S)==False: 57 | break 58 | if is_independent(S)==True: 59 | print(u) 60 | ''' 61 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/The_Inner_Product_Problems/The_Inner_Product_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week6-Gaussian_Elimination_and_the_Inner_Product/The_Inner_Product_Problems/The_Inner_Product_problems.pdf -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/The_Inner_Product_Problems/The_Inner_Product_problems.py: -------------------------------------------------------------------------------- 1 | # version code 3ebd92e7eece+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | 6 | 7 | 8 | 9 | ## 1: (Problem 1) Norm 10 | norm1 = 3 11 | norm2 = 4 12 | norm3 = 3 13 | 14 | 15 | 16 | ## 2: (Problem 2) Closest Vector 17 | # Write each vector as a list 18 | closest_vector_1 = [1.6,3.2] 19 | closest_vector_2 = [0,1,0] 20 | closest_vector_3 = [3,2,1,-4] 21 | 22 | 23 | 24 | ## 3: (Problem 3) Projection Orthogonal to and onto Vectors 25 | # Write each vector as a list 26 | # round up to 6 decimal points if necessary 27 | project_onto_1 = [2,0] 28 | projection_orthogonal_1 = [0,1] 29 | 30 | project_onto_2 = [-1/6.0,-1/3.0,1/6.0] 31 | projection_orthogonal_2 = [1+1/6.0,1+1/3.0,4-1/6.0] 32 | 33 | project_onto_3 = [1,1,4] 34 | projection_orthogonal_3 = [0,0,0] 35 | 36 | -------------------------------------------------------------------------------- /Week6-Gaussian_Elimination_and_the_Inner_Product/The_Inner_Product_Problems/orthogonalization.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | 4 | def project_along(b, v, eps = 1E-20): 5 | ''' 6 | Project b along v. 7 | 8 | Input: 9 | - b: a Vec 10 | - v: a Vec 11 | - eps (default: 1E-20): threshold below which squared norms are considered zero 12 | 13 | Output: 14 | - a Vec representing the projection of b onto v 15 | ''' 16 | sigma = ((b*v)/(v*v)) if v*v > eps else 0 17 | return sigma * v 18 | 19 | def project_orthogonal(b, vlist): 20 | ''' 21 | Project b orthogonal to vlist. 22 | 23 | Input: 24 | - b: a Vec 25 | - vlist: a list of Vecs 26 | 27 | Output: the projection of b orthogonal to the Vecs in vlist 28 | ''' 29 | for v in vlist: 30 | b = b - project_along(b, v) 31 | return b 32 | 33 | def aug_project_orthogonal(b, vlist, eps = 1E-20): 34 | alphadict = {len(vlist):1} 35 | for i,v in enumerate(vlist): 36 | sigma = (b*v)/(v*v) if v*v > eps else 0 37 | alphadict[i] = sigma 38 | b = b - sigma*v 39 | return (b, alphadict) 40 | 41 | def orthogonalize(vlist): 42 | ''' 43 | Orthogonalizes vlist preserving order. 44 | The ith vector in the output list is the projection of vlist[i] orthogonal to 45 | the space spanned by all the previous vectors in the output list. 46 | 47 | Input: a list of Vecs 48 | 49 | Output: a list of mutually orthogonal Vecs spanning the same space as the input Vecs 50 | ''' 51 | assert isinstance(vlist, list) 52 | vstarlist = [] 53 | for v in vlist: 54 | vstarlist.append(project_orthogonal(v, vstarlist)) 55 | return vstarlist 56 | 57 | def aug_orthogonalize(vlist): 58 | ''' 59 | Input: a list of Vecs 60 | Output: a list of orthonormal Vecs spanning the same space as the input Vecs 61 | ''' 62 | assert isinstance(vlist, list) 63 | vstarlist = [] 64 | sigma_vecs = [] 65 | D = set(range(len(vlist))) 66 | for v in vlist: 67 | (vstar, sigmadict) = aug_project_orthogonal(v, vstarlist) 68 | vstarlist.append(vstar) 69 | sigma_vecs.append(Vec(D, sigmadict)) 70 | return vstarlist, sigma_vecs 71 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Machine_Learning_Lab/cancer_data.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from matutil import rowdict2mat 4 | 5 | def read_training_data(fname, D=None): 6 | """Given a file in appropriate format, and given a set D of features, 7 | returns the pair (A, b) consisting of 8 | a P-by-D matrix A and a P-vector b, 9 | where P is a set of patient identification integers (IDs). 10 | 11 | For each patient ID p, 12 | - row p of A is the D-vector describing patient p's tissue sample, 13 | - entry p of b is +1 if patient p's tissue is malignant, and -1 if it is benign. 14 | 15 | The set D of features must be a subset of the features in the data (see text). 16 | """ 17 | file = open(fname) 18 | params = ["radius", "texture", "perimeter","area","smoothness","compactness","concavity","concave points","symmetry","fractal dimension"]; 19 | stats = ["(mean)", "(stderr)", "(worst)"] 20 | feature_labels = set([y+x for x in stats for y in params]) 21 | feature_map = {params[i]+stats[j]:j*len(params)+i for i in range(len(params)) for j in range(len(stats))} 22 | if D is None: D = feature_labels 23 | feature_vectors = {} 24 | patient_diagnoses = {} 25 | for line in file: 26 | row = line.split(",") 27 | patient_ID = int(row[0]) 28 | patient_diagnoses[patient_ID] = -1 if row[1]=='B' else +1 29 | feature_vectors[patient_ID] = Vec(D, {f:float(row[feature_map[f]+2]) for f in D}) 30 | return rowdict2mat(feature_vectors), Vec(set(patient_diagnoses.keys()), patient_diagnoses) 31 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Machine_Learning_Lab/machine_learning_lab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week7-Orthogonalization/Machine_Learning_Lab/machine_learning_lab.pdf -------------------------------------------------------------------------------- /Week7-Orthogonalization/Machine_Learning_Lab/machine_learning_lab.py: -------------------------------------------------------------------------------- 1 | # version code 0672c0a36066+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | from mat import * 6 | from vec import * 7 | from cancer_data import * 8 | 9 | ## Ungraded task 10 | #(A, b) = read_training_data('train.data') 11 | 12 | ## Task 1 ## 13 | def signum(u): 14 | ''' 15 | Input: 16 | - u: Vec 17 | Output: 18 | - v: Vec such that: 19 | if u[d] >= 0, then v[d] = 1 20 | if u[d] < 0, then v[d] = -1 21 | Example: 22 | >>> signum(Vec({1,2,3},{1:2, 2:-1})) == Vec({1,2,3},{1:1,2:-1,3:1}) 23 | True 24 | ''' 25 | #return Vec{u.D, {k:x for k in u.D }) 26 | f = {} 27 | for k in u.D: 28 | f[k] = 1 if getitem(u, k) >= 0 else -1 29 | v = Vec(u.D, f) 30 | return v 31 | 32 | ## Task 2 ## 33 | def fraction_wrong(A, b, w): 34 | ''' 35 | Input: 36 | - A: a Mat with rows as feature vectors 37 | - b: a Vec of actual diagnoses 38 | - w: hypothesis Vec 39 | Output: 40 | - Fraction (as a decimal in [0,1]) of vectors incorrectly 41 | classified by w 42 | Example: 43 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 44 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 45 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 46 | >>> fraction_wrong(A, b, w) 47 | 0.3333333333333333 48 | ''' 49 | Aw = signum(matrix_vector_mul(A, w)) 50 | tmp = Aw - b 51 | return sum([1 if getitem(tmp, k) != 0 else 0 for k in tmp.D]) / len(b.D) 52 | 53 | ## Task 3 ## 54 | def loss(A, b, w): 55 | ''' 56 | Input: 57 | - A: feature Mat 58 | - b: diagnoses Vec 59 | - w: hypothesis Vec 60 | Output: 61 | - Value of loss function at w for training data 62 | Example: 63 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 64 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 65 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 66 | >>> loss(A, b, w) 67 | 317 68 | ''' 69 | return dot(matrix_vector_mul(A, w)-b, matrix_vector_mul(A, w)-b) 70 | 71 | 72 | ## Task 4 ## 73 | def find_grad(A, b, w): 74 | ''' 75 | Input: 76 | - A: feature Mat 77 | - b: diagnoses Vec 78 | - w: hypothesis Vec 79 | Output: 80 | - Value of the gradient function at w 81 | Example: 82 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 83 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 84 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 85 | >>> find_grad(A, b, w) == Vec({'B', 'A'},{'B': -290, 'A': 60}) 86 | True 87 | ''' 88 | return 2*(A*w-b)*A 89 | 90 | ## Task 5 ## 91 | def gradient_descent_step(A, b, w, sigma): 92 | ''' 93 | Input: 94 | - A: feature Mat 95 | - b: diagnoses Vec 96 | - w: hypothesis Vec 97 | - sigma: step size 98 | Output: 99 | - The vector w' resulting from 1 iteration of gradient descent 100 | starting from w and moving sigma. 101 | Example: 102 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 103 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 104 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 105 | >>> sigma = .1 106 | >>> gradient_descent_step(A, b, w, sigma) == Vec({'B', 'A'},{'B': 27.0, 'A': -5.0}) 107 | True 108 | ''' 109 | return w - sigma * find_grad(A, b, w) 110 | 111 | ## Ungraded task ## 112 | def gradient_descent(A, b, w, sigma, T): 113 | ''' 114 | Input: 115 | - A: feature Mat 116 | - b: diagnoses Vec 117 | - w: hypothesis Vec 118 | - sigma: step size 119 | - T: number of iterations to run 120 | Output: hypothesis vector obtained after T iterations of gradient descent. 121 | ''' 122 | pass 123 | 124 | 125 | 126 | 127 | ''' 128 | print(signum(Vec({1,2,3},{1:2, 2:-1}))) 129 | A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 130 | b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 131 | w = Vec({'A','B'}, {'A':1, 'B':-2}) 132 | print(fraction_wrong(A, b, w)) 133 | A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 134 | b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 135 | w = Vec({'A','B'}, {'A':1, 'B':-2}) 136 | print(loss(A, b, w)) 137 | ''' 138 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Machine_Learning_Lab/orthogonalization.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | 4 | def project_along(b, v, eps = 1E-20): 5 | ''' 6 | Project b along v. 7 | 8 | Input: 9 | - b: a Vec 10 | - v: a Vec 11 | - eps (default: 1E-20): threshold below which squared norms are considered zero 12 | 13 | Output: 14 | - a Vec representing the projection of b onto v 15 | ''' 16 | sigma = ((b*v)/(v*v)) if v*v > eps else 0 17 | return sigma * v 18 | 19 | def project_orthogonal(b, vlist): 20 | ''' 21 | Project b orthogonal to vlist. 22 | 23 | Input: 24 | - b: a Vec 25 | - vlist: a list of Vecs 26 | 27 | Output: the projection of b orthogonal to the Vecs in vlist 28 | ''' 29 | for v in vlist: 30 | b = b - project_along(b, v) 31 | return b 32 | 33 | def aug_project_orthogonal(b, vlist, eps = 1E-20): 34 | alphadict = {len(vlist):1} 35 | for i,v in enumerate(vlist): 36 | sigma = (b*v)/(v*v) if v*v > eps else 0 37 | alphadict[i] = sigma 38 | b = b - sigma*v 39 | return (b, alphadict) 40 | 41 | def orthogonalize(vlist): 42 | ''' 43 | Orthogonalizes vlist preserving order. 44 | The ith vector in the output list is the projection of vlist[i] orthogonal to 45 | the space spanned by all the previous vectors in the output list. 46 | 47 | Input: a list of Vecs 48 | 49 | Output: a list of mutually orthogonal Vecs spanning the same space as the input Vecs 50 | ''' 51 | assert isinstance(vlist, list) 52 | vstarlist = [] 53 | for v in vlist: 54 | vstarlist.append(project_orthogonal(v, vstarlist)) 55 | return vstarlist 56 | 57 | def aug_orthogonalize(vlist): 58 | ''' 59 | Input: a list of Vecs 60 | Output: a list of orthonormal Vecs spanning the same space as the input Vecs 61 | ''' 62 | assert isinstance(vlist, list) 63 | vstarlist = [] 64 | sigma_vecs = [] 65 | D = set(range(len(vlist))) 66 | for v in vlist: 67 | (vstar, sigmadict) = aug_project_orthogonal(v, vstarlist) 68 | vstarlist.append(vstar) 69 | sigma_vecs.append(Vec(D, sigmadict)) 70 | return vstarlist, sigma_vecs 71 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/GF2.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from numbers import Number 3 | 4 | class One: 5 | def __add__(self, other): return self if other == 0 else 0 6 | __sub__ = __add__ 7 | def __mul__(self, other): 8 | if isinstance(other, Number): 9 | return 0 if other == 0 else self 10 | return other 11 | def __div__(self, other): 12 | if other == 0: raise ZeroDivisionError 13 | return self 14 | __truediv__ = __div__ 15 | def __rdiv__(self,other): return other 16 | __rtruediv__ = __rdiv__ 17 | __radd__ = __add__ 18 | __rsub__ = __add__ 19 | __rmul__ = __mul__ 20 | #hack to ensure not (one < 1e-16) by ensuring not (one < x) for every x 21 | def __lt__(self,other): return False 22 | 23 | def __str__(self): return 'one' 24 | __repr__ = __str__ 25 | def __neg__(self): return self 26 | def __bool__(self): return True 27 | def __format__(self, format_spec): return format(str(self),format_spec) 28 | 29 | one = One() 30 | zero = 0 31 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/Orthogonalization_problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codewatson/Coding-the-Matrix/4c855dc14d3df842336f796092c3664097a6bc03/Week7-Orthogonalization/Orthogonalization_Problems/Orthogonalization_problems.pdf -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/Orthogonalization_problems.py: -------------------------------------------------------------------------------- 1 | # version code 7f08c507c12c+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | from mat import Mat 6 | from vec import Vec 7 | from vecutil import list2vec 8 | from matutil import listlist2mat 9 | from orthogonalization import * 10 | from math import sqrt 11 | from triangular import triangular_solve 12 | 13 | ## 1: (Problem 1) Generators for orthogonal complement 14 | U_vecs_1 = [list2vec([0,0,3,2])] 15 | W_vecs_1 = [list2vec(v) for v in [[1,2,-3,-1],[1,2,0,1],[3,1,0,-1],[-1,-2,3,1]]] 16 | # Give a list of Vecs 17 | 18 | #print(orthogonalize(W_vecs_1)) 19 | ortho_compl_generators_1 =[project_orthogonal(b, U_vecs_1) for b in W_vecs_1 ] 20 | 21 | U_vecs_2 = [list2vec([3,0,1])] 22 | W_vecs_2 = [list2vec(v) for v in [[1,0,0],[1,0,1]]] 23 | 24 | # Give a list of Vecs 25 | ortho_compl_generators_2 = [project_orthogonal(b, U_vecs_2) for b in W_vecs_2 ] 26 | 27 | U_vecs_3 = [list2vec(v) for v in [[-4,3,1,-2],[-2,2,3,-1]]] 28 | W_vecs_3 = [list2vec(v) for v in [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]] 29 | 30 | # Give a list of Vecs 31 | ortho_compl_generators_3 = [project_orthogonal(b, U_vecs_3) for b in W_vecs_3 ] 32 | 33 | 34 | ## 2: (Problem 2) Basis for null space 35 | # Your solution should be a list of Vecs 36 | 37 | null_space_basis =[ project_orthogonal(b, [list2vec(v) for v in [[-4,-1,-3,-1],[0,4,0,-1]]]) for b in [list2vec(i) for i in [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]] ] 38 | #print([list2vec(v) for v in [[-4,-1,-3,-1],[0,4,0,-1]]]) 39 | #print(null_space_basis) 40 | 41 | ## 3: (Problem 3) Orthonormalize(L) 42 | def orthonormalize(L): 43 | ''' 44 | Input: a list L of linearly independent Vecs 45 | Output: A list Lstar of len(L) orthonormal Vecs such that, for all i in range(len(L)), 46 | Span L[:i+1] == Span Lstar[:i+1] 47 | 48 | >>> from vec import Vec 49 | >>> D = {'a','b','c','d'} 50 | >>> 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})] 51 | >>> for v in orthonormalize(L): print(v) 52 | ... 53 | 54 | a b c d 55 | ----------------------- 56 | 0.73 0.548 0.183 0.365 57 | 58 | a b c d 59 | -------------------------- 60 | 0.187 0.403 -0.566 -0.695 61 | 62 | a b c d 63 | -------------------------- 64 | 0.528 -0.653 -0.512 0.181 65 | ''' 66 | V=orthogonalize(L) 67 | return [1/sqrt(sum([v[i]**2 for i in range(len(v.D))]))*v for v in V] 68 | 69 | 70 | 71 | ## 4: (Problem 4) aug_orthonormalize(L) 72 | def aug_orthonormalize(L): 73 | ''' 74 | Input: 75 | - L: a list of Vecs 76 | Output: 77 | - A pair Qlist, Rlist such that: 78 | * coldict2mat(L) == coldict2mat(Qlist) * coldict2mat(Rlist) 79 | * Qlist = orthonormalize(L) 80 | >>> from vec import Vec 81 | >>> D={'a','b','c','d'} 82 | >>> 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})] 83 | >>> Qlist, Rlist = aug_orthonormalize(L) 84 | ''' 85 | #Qlist, Rlist = aug_orthonormalize(L) 86 | #Rl=[1/sqrt(sum([v[i]**2 for i in range(len(v.D))]))*v for v in orthogonalize( Rlist)] 87 | #Ql=[1/sqrt(sum([v[i]**2 for i in range(len(v.D))]))*v for v in orthogonalize(Qlist)] 88 | #return (Ql,Rl) 89 | Ql, Rl = aug_orthogonalize(L) 90 | Qlist = orthonormalize(Ql) 91 | mults = [(v*v)**(1/2) for v in Ql] 92 | for vector in Rl: 93 | for i in range(len(vector.D)): 94 | vector[i] = vector[i] * mults[i] 95 | return Qlist, Rl 96 | 97 | ## 5: (Problem 5) QR factorization of small matrices 98 | #Compute the QR factorization 99 | 100 | #Please represent your solution as a list of rows, such as [[1,0,0],[0,1,0],[0,0,1]] 101 | A=[list2vec(v) for v in [[6,6], [2,0],[3,3]]] 102 | #print(A) 103 | part_1_Q = ... #aug_orthonormalize(A)[0] 104 | part_1_R = ... #aug_orthonormalize(A)[1] 105 | #print(list[orthonormalize(A)]) 106 | A=[list2vec(v) for v in [[2,3], [2,1],[1,1]]] 107 | #print(A) 108 | part_2_Q = ... #aug_orthonormalize(A)[0] 109 | part_2_R = ... #aug_orthonormalize(A)[1] 110 | #print(list(orthonormalize(A))) 111 | 112 | 113 | 114 | ## 6: (Problem 6) QR Solve 115 | from matutil import mat2coldict, coldict2mat 116 | from python_lab import dict2list, list2dict 117 | 118 | def QR_factor(A): 119 | col_labels = sorted(A.D[1], key=repr) 120 | Acols = dict2list(mat2coldict(A),col_labels) 121 | Qlist, Rlist = aug_orthonormalize(Acols) 122 | #Now make Mats 123 | Q = coldict2mat(Qlist) 124 | R = coldict2mat(list2dict(Rlist, col_labels)) 125 | return Q,R 126 | 127 | def QR_solve(A, b): 128 | ''' 129 | Input: 130 | - A: a Mat with linearly independent columns 131 | - b: a Vec whose domain equals the set of row-labels of A 132 | Output: 133 | - vector x that minimizes norm(b - A*x) 134 | Note: This procedure uses the procedure QR_factor, which in turn uses dict2list and list2dict. 135 | You wrote these procedures long back in python_lab. Make sure the completed python_lab.py 136 | is in your matrix directory. 137 | Example: 138 | >>> domain = ({'a','b','c'},{'A','B'}) 139 | >>> A = Mat(domain,{('a','A'):-1, ('a','B'):2,('b','A'):5, ('b','B'):3,('c','A'):1,('c','B'):-2}) 140 | >>> Q, R = QR_factor(A) 141 | >>> b = Vec(domain[0], {'a': 1, 'b': -1}) 142 | >>> x = QR_solve(A, b) 143 | >>> result = A.transpose()*(b-A*x) 144 | >>> result.is_almost_zero() 145 | True 146 | ''' 147 | Q, R = QR_factor(A) 148 | return triangular_solve(mat2rowdict(R), sorted(A.D[1],key=repr), Q.transpose()*b) 149 | 150 | 151 | 152 | ## 7: (Problem 7) Least Squares Problem 153 | # Please give each solution as a Vec 154 | 155 | least_squares_A1 = listlist2mat([[8, 1], [6, 2], [0, 6]]) 156 | least_squares_Q1 = listlist2mat([[.8,-0.099],[.6, 0.132],[0,0.986]]) 157 | least_squares_R1 = listlist2mat([[10,2],[0,6.08]]) 158 | least_squares_b1 = list2vec([10, 8, 6]) 159 | from solver import solve 160 | x_hat_1 = solve(least_squares_R1, least_squares_Q1.transpose()*least_squares_b1) 161 | 162 | 163 | least_squares_A2 = listlist2mat([[3, 1], [4, 1], [5, 1]]) 164 | least_squares_Q2 = listlist2mat([[.424, .808],[.566, .115],[.707, -.577]]) 165 | least_squares_R2 = listlist2mat([[7.07, 1.7],[0,.346]]) 166 | least_squares_b2 = list2vec([10,13,15]) 167 | 168 | x_hat_2 = solve(least_squares_R2, least_squares_Q2.transpose()*least_squares_b2) 169 | 170 | 171 | 172 | ## 8: (Problem 8) Small examples of least squares 173 | #Find the vector minimizing (Ax-b)^2 174 | 175 | #Please represent your solution as a list 176 | 177 | your_answer_1 = ... 178 | your_answer_2 = ... 179 | 180 | 181 | 182 | ## 9: (Problem 9) Linear regression example 183 | #Find a and b for the y=ax+b line of best fit 184 | 185 | a = ... 186 | b = ... 187 | 188 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/Orthogonalization_problems.py.bak: -------------------------------------------------------------------------------- 1 | # version code 7f08c507c12c+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | from mat import Mat 6 | from vec import Vec 7 | from vecutil import list2vec 8 | from matutil import listlist2mat 9 | #from orthogonalization import orthogonalize, project_orthogonal 10 | #from GF2 import one 11 | 12 | 13 | ## 1: (Problem 1) Generators for orthogonal complement 14 | U_vecs_1 = [list2vec([0,0,3,2])] 15 | W_vecs_1 = [list2vec(v) for v in [[1,2,-3,-1],[1,2,0,1],[3,1,0,-1],[-1,-2,3,1]]] 16 | # Give a list of Vecs 17 | #print(orthogonalize(W_vecs_1)) 18 | ortho_compl_generators_1 = ...# [Vec({0, 1, 2, 3},{0: -1.2460684954515273e-16, 1: -2.1893488932780114e-16, 2: 2.1713452766624683e-16, 3: 7.365115888176723e-18})]#[ project_orthogonal(U_vecs_1[0], orthogonalize(W_vecs_1)) ] 19 | #print(ortho_compl_generators_1) 20 | 21 | U_vecs_2 = [list2vec([3,0,1])] 22 | W_vecs_2 = [list2vec(v) for v in [[1,0,0],[1,0,1]]] 23 | 24 | # Give a list of Vecs 25 | ortho_compl_generators_2 =...# [list2vec([0,0,0])] 26 | #ortho_compl_generators_2 =[ project_orthogonal(U_vecs_2[0], orthogonalize(W_vecs_2))] 27 | #print(orthogonalize(W_vecs_2)) 28 | #print(ortho_compl_generators_2) 29 | 30 | U_vecs_3 = [list2vec(v) for v in [[-4,3,1,-2],[-2,2,3,-1]]] 31 | W_vecs_3 = [list2vec(v) for v in [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]] 32 | 33 | # Give a list of Vecs 34 | ortho_compl_generators_3 =...# [list2vec([0,0,0,0]),list2vec([0,0,0,0])]#[project_orthogonal(U_vecs_3[i], orthogonalize(W_vecs_3)) for i in range(2)] 35 | #print(ortho_compl_generators_3) 36 | 37 | 38 | ## 2: (Problem 2) Basis for null space 39 | # Your solution should be a list of Vecs 40 | null_space_basis = ... 41 | 42 | 43 | 44 | ## 3: (Problem 3) Orthonormalize(L) 45 | def orthonormalize(L): 46 | ''' 47 | Input: a list L of linearly independent Vecs 48 | Output: A list Lstar of len(L) orthonormal Vecs such that, for all i in range(len(L)), 49 | Span L[:i+1] == Span Lstar[:i+1] 50 | 51 | >>> from vec import Vec 52 | >>> D = {'a','b','c','d'} 53 | >>> 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})] 54 | >>> for v in orthonormalize(L): print(v) 55 | ... 56 | 57 | a b c d 58 | ----------------------- 59 | 0.73 0.548 0.183 0.365 60 | 61 | a b c d 62 | -------------------------- 63 | 0.187 0.403 -0.566 -0.695 64 | 65 | a b c d 66 | -------------------------- 67 | 0.528 -0.653 -0.512 0.181 68 | ''' 69 | pass 70 | 71 | 72 | 73 | ## 4: (Problem 4) aug_orthonormalize(L) 74 | def aug_orthonormalize(L): 75 | ''' 76 | Input: 77 | - L: a list of Vecs 78 | Output: 79 | - A pair Qlist, Rlist such that: 80 | * coldict2mat(L) == coldict2mat(Qlist) * coldict2mat(Rlist) 81 | * Qlist = orthonormalize(L) 82 | >>> from vec import Vec 83 | >>> D={'a','b','c','d'} 84 | >>> 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})] 85 | >>> Qlist, Rlist = aug_orthonormalize(L) 86 | >>> from matutil import coldict2mat 87 | >>> print(coldict2mat(Qlist)) 88 | 89 | 0 1 2 90 | --------------------- 91 | a | 0.73 0.187 0.528 92 | b | 0.548 0.403 -0.653 93 | c | 0.183 -0.566 -0.512 94 | d | 0.365 -0.695 0.181 95 | 96 | >>> print(coldict2mat(Rlist)) 97 | 98 | 0 1 2 99 | ------------------ 100 | 0 | 5.48 8.03 9.49 101 | 1 | 0 11.4 -0.636 102 | 2 | 0 0 6.04 103 | 104 | >>> print(coldict2mat(Qlist)*coldict2mat(Rlist)) 105 | 106 | 0 1 2 107 | --------- 108 | a | 4 8 10 109 | b | 3 9 1 110 | c | 1 -5 -1 111 | d | 2 -5 5 112 | 113 | ''' 114 | pass 115 | 116 | 117 | 118 | ## 5: (Problem 5) QR factorization of small matrices 119 | #Compute the QR factorization 120 | 121 | #Please represent your solution as a list of rows, such as [[1,0,0],[0,1,0],[0,0,1]] 122 | 123 | part_1_Q = ... 124 | part_1_R = ... 125 | 126 | part_2_Q = ... 127 | part_2_R = ... 128 | 129 | 130 | 131 | ## 6: (Problem 6) QR Solve 132 | from matutil import mat2coldict, coldict2mat 133 | from python_lab import dict2list, list2dict 134 | 135 | def QR_factor(A): 136 | col_labels = sorted(A.D[1], key=repr) 137 | Acols = dict2list(mat2coldict(A),col_labels) 138 | Qlist, Rlist = aug_orthonormalize(Acols) 139 | #Now make Mats 140 | Q = coldict2mat(Qlist) 141 | R = coldict2mat(list2dict(Rlist, col_labels)) 142 | return Q,R 143 | 144 | 145 | def QR_solve(A, b): 146 | ''' 147 | Input: 148 | - A: a Mat with linearly independent columns 149 | - b: a Vec whose domain equals the set of row-labels of A 150 | Output: 151 | - vector x that minimizes norm(b - A*x) 152 | Note: This procedure uses the procedure QR_factor, which in turn uses dict2list and list2dict. 153 | You wrote these procedures long back in python_lab. Make sure the completed python_lab.py 154 | is in your matrix directory. 155 | Example: 156 | >>> domain = ({'a','b','c'},{'A','B'}) 157 | >>> A = Mat(domain,{('a','A'):-1, ('a','B'):2,('b','A'):5, ('b','B'):3,('c','A'):1,('c','B'):-2}) 158 | >>> Q, R = QR_factor(A) 159 | >>> b = Vec(domain[0], {'a': 1, 'b': -1}) 160 | >>> x = QR_solve(A, b) 161 | >>> result = A.transpose()*(b-A*x) 162 | >>> result.is_almost_zero() 163 | True 164 | ''' 165 | pass 166 | 167 | 168 | 169 | ## 7: (Problem 7) Least Squares Problem 170 | # Please give each solution as a Vec 171 | 172 | least_squares_A1 = listlist2mat([[8, 1], [6, 2], [0, 6]]) 173 | least_squares_Q1 = listlist2mat([[.8,-0.099],[.6, 0.132],[0,0.986]]) 174 | least_squares_R1 = listlist2mat([[10,2],[0,6.08]]) 175 | least_squares_b1 = list2vec([10, 8, 6]) 176 | 177 | x_hat_1 = ... 178 | 179 | 180 | least_squares_A2 = listlist2mat([[3, 1], [4, 1], [5, 1]]) 181 | least_squares_Q2 = listlist2mat([[.424, .808],[.566, .115],[.707, -.577]]) 182 | least_squares_R2 = listlist2mat([[7.07, 1.7],[0,.346]]) 183 | least_squares_b2 = list2vec([10,13,15]) 184 | 185 | x_hat_2 = ... 186 | 187 | 188 | 189 | ## 8: (Problem 8) Small examples of least squares 190 | #Find the vector minimizing (Ax-b)^2 191 | 192 | #Please represent your solution as a list 193 | 194 | your_answer_1 = ... 195 | your_answer_2 = ... 196 | 197 | 198 | 199 | ## 9: (Problem 9) Linear regression example 200 | #Find a and b for the y=ax+b line of best fit 201 | 202 | a = ... 203 | b = ... 204 | 205 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/QR.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from orthonormalization import * 3 | from dictutil import dict2list, list2dict 4 | from matutil import mat2coldict, coldict2mat 5 | 6 | def factor(A): 7 | col_labels = sorted(A.D[1], key=repr) 8 | Acols = dict2list(mat2coldict(A),col_labels) 9 | Qlist, Rlist = aug_orthonormalize(Acols) 10 | #Now make Mats 11 | Q = coldict2mat(Qlist) 12 | R = coldict2mat(list2dict(Rlist, col_labels)) 13 | return Q,R 14 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/age-height.txt: -------------------------------------------------------------------------------- 1 | age height 2 | 18 76.1 3 | 19 77 4 | 20 78.1 5 | 21 78.2 6 | 22 78.8 7 | 23 79.7 8 | 24 79.9 9 | 25 81.1 10 | 26 81.2 11 | 27 81.8 12 | 28 82.8 13 | 29 83.5 14 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/bitutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | """ 3 | Implements several convenience operations for use with the ECC lab. 4 | 5 | Author: Landon Judkins (ljudkins) 6 | Date: Spring 2009 7 | Updated by Nick Gaya, Spring 2013 8 | 9 | Requires: fields matutil 10 | """ 11 | 12 | from GF2 import zero, one 13 | import mat 14 | import random 15 | 16 | def str2bits(inp): 17 | """ 18 | Convert a string into a list of bits, with each character's bits in order 19 | of increasing significance. 20 | """ 21 | bs = [1<= 0, then v[d] = 1 17 | if u[d] < 0, then v[d] = -1 18 | Example: 19 | >>> signum(Vec({1,2,3},{1:2, 2:-1})) == Vec({1,2,3},{1:1,2:-1,3:1}) 20 | True 21 | ''' 22 | r={} 23 | for d in u.D: 24 | r[d]=1 if u[d]>=0 else -1 25 | return Vec(u.D,r) 26 | ## Task 2 ## 27 | def fraction_wrong(A, b, w): 28 | ''' 29 | Input: 30 | - A: a Mat with rows as feature vectors 31 | - b: a Vec of actual diagnoses 32 | - w: hypothesis Vec 33 | Output: 34 | - Fraction (as a decimal in [0,1]) of vectors incorrectly 35 | classified by w 36 | Example: 37 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 38 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 39 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 40 | >>> fraction_wrong(A, b, w) 41 | 0.3333333333333333 42 | ''' 43 | aw=signum(matrix_vector_mul(A,w))-b 44 | return sum([1 if aw[k] !=0 else 0 for k in aw.D])/len(b.D) 45 | ## Task 3 ## 46 | def loss(A, b, w): 47 | ''' 48 | Input: 49 | - A: feature Mat 50 | - b: diagnoses Vec 51 | - w: hypothesis Vec 52 | Output: 53 | - Value of loss function at w for training data 54 | Example: 55 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 56 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 57 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 58 | >>> loss(A, b, w) 59 | 317 60 | ''' 61 | aw=matrix_vector_mul(A,w)-b 62 | return dot(aw,aw) 63 | ## Task 4 ## 64 | def find_grad(A, b, w): 65 | ''' 66 | Input: 67 | - A: feature Mat 68 | - b: diagnoses Vec 69 | - w: hypothesis Vec 70 | Output: 71 | - Value of the gradient function at w 72 | Example: 73 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 74 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 75 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 76 | >>> find_grad(A, b, w) == Vec({'B', 'A'},{'B': -290, 'A': 60}) 77 | True 78 | ''' 79 | return 2*(A*w-b)*A 80 | 81 | 82 | ## Task 5 ## 83 | def gradient_descent_step(A, b, w, sigma): 84 | ''' 85 | Input: 86 | - A: feature Mat 87 | - b: diagnoses Vec 88 | - w: hypothesis Vec 89 | - sigma: step size 90 | Output: 91 | - The vector w' resulting from 1 iteration of gradient descent 92 | starting from w and moving sigma. 93 | Example: 94 | >>> A = Mat(({'a','b','c'},{'A','B'}), {('a','A'):-4, ('a','B'):3, ('b','A'):1, ('b','B'):8, ('c','A'):5, ('c','B'):2}) 95 | >>> b = Vec({'a','b','c'}, {'a':1, 'b':-1,'c':1}) 96 | >>> w = Vec({'A','B'}, {'A':1, 'B':-2}) 97 | >>> sigma = .1 98 | >>> gradient_descent_step(A, b, w, sigma) == Vec({'B', 'A'},{'B': 27.0, 'A': -5.0}) 99 | True 100 | ''' 101 | return w-sigma*find_grad(A,b,w) 102 | 103 | ## Ungraded task ## 104 | def gradient_descent(A, b, w, sigma, T): 105 | ''' 106 | Input: 107 | - A: feature Mat 108 | - b: diagnoses Vec 109 | - w: hypothesis Vec 110 | - sigma: step size 111 | - T: number of iterations to run 112 | Output: hypothesis vector obtained after T iterations of gradient descent. 113 | ''' 114 | pass 115 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/matutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from mat import Mat 4 | 5 | def efficient_rowdict2mat(rowdict): 6 | col_labels = value(rowdict).D 7 | M = Mat((set(keys(rowdict)), col_labels), {}) 8 | for r in rowdict: 9 | for c in rowdict[r].f: 10 | M[r,c] = rowdict[r][c] 11 | return M 12 | 13 | def identity(D, one): 14 | """Given a set D and the field's one, returns the DxD identity matrix 15 | e.g.: 16 | 17 | >>> identity({0,1,2}, 1) 18 | Mat(({0, 1, 2}, {0, 1, 2}), {(0, 0): 1, (1, 1): 1, (2, 2): 1}) 19 | """ 20 | return Mat((D,D), {(d,d):one for d in D}) 21 | 22 | def keys(d): 23 | """Given a dict, returns something that generates the keys; given a list, 24 | returns something that generates the indices. Intended for coldict2mat and rowdict2mat. 25 | """ 26 | return d.keys() if isinstance(d, dict) else range(len(d)) 27 | 28 | def value(d): 29 | """Given either a dict or a list, returns one of the values. 30 | Intended for coldict2mat and rowdict2mat. 31 | """ 32 | return next(iter(d.values())) if isinstance(d, dict) else d[0] 33 | 34 | def mat2rowdict(A): 35 | """Given a matrix, return a dictionary mapping row labels of A to rows of A 36 | e.g.: 37 | 38 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 39 | >>> mat2rowdict(M) 40 | {0: Vec({0, 1},{0: 3, 1: 1}), 1: Vec({0, 1},{0: 4, 1: 0}), 2: Vec({0, 1},{0: 8, 1: -2})} 41 | >>> mat2rowdict(Mat(({0,1},{0,1}),{})) 42 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 43 | """ 44 | return {row:Vec(A.D[1], {col:A[row,col] for col in A.D[1]}) for row in A.D[0]} 45 | 46 | def mat2coldict(A): 47 | """Given a matrix, return a dictionary mapping column labels of A to columns of A 48 | e.g.: 49 | >>> M = Mat(({0, 1, 2}, {0, 1}), {(0, 1): 1, (2, 0): 8, (1, 0): 4, (0, 0): 3, (2, 1): -2}) 50 | >>> mat2coldict(M) 51 | {0: Vec({0, 1, 2},{0: 3, 1: 4, 2: 8}), 1: Vec({0, 1, 2},{0: 1, 1: 0, 2: -2})} 52 | >>> mat2coldict(Mat(({0,1},{0,1}),{})) 53 | {0: Vec({0, 1},{0: 0, 1: 0}), 1: Vec({0, 1},{0: 0, 1: 0})} 54 | """ 55 | return {col:Vec(A.D[0], {row:A[row,col] for row in A.D[0]}) for col in A.D[1]} 56 | 57 | def coldict2mat(coldict): 58 | """ 59 | Given a dictionary or list whose values are Vecs, returns the Mat having these 60 | Vecs as its columns. This is the inverse of mat2coldict. 61 | Assumes all the Vecs have the same label-set. 62 | Assumes coldict is nonempty. 63 | If coldict is a dictionary then its keys will be the column-labels of the Mat. 64 | If coldict is a list then {0...len(coldict)-1} will be the column-labels of the Mat. 65 | e.g.: 66 | 67 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 68 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 69 | >>> mat2coldict(coldict2mat(A)) == A 70 | True 71 | >>> coldict2mat(A) 72 | Mat(({0, 1}, {0, 1}), {(0, 1): 3, (1, 0): 2, (0, 0): 1, (1, 1): 4}) 73 | >>> coldict2mat(A) == coldict2mat(B) 74 | True 75 | """ 76 | row_labels = value(coldict).D 77 | return Mat((row_labels, set(keys(coldict))), {(r,c):coldict[c][r] for c in keys(coldict) for r in row_labels}) 78 | 79 | def rowdict2mat(rowdict): 80 | """ 81 | Given a dictionary or list whose values are Vecs, returns the Mat having these 82 | Vecs as its rows. This is the inverse of mat2rowdict. 83 | Assumes all the Vecs have the same label-set. 84 | Assumes row_dict is nonempty. 85 | If rowdict is a dictionary then its keys will be the row-labels of the Mat. 86 | If rowdict is a list then {0...len(rowdict)-1} will be the row-labels of the Mat. 87 | e.g.: 88 | 89 | >>> A = {0:Vec({0,1},{0:1,1:2}),1:Vec({0,1},{0:3,1:4})} 90 | >>> B = [Vec({0,1},{0:1,1:2}),Vec({0,1},{0:3,1:4})] 91 | >>> mat2rowdict(rowdict2mat(A)) == A 92 | True 93 | >>> rowdict2mat(A) 94 | Mat(({0, 1}, {0, 1}), {(0, 1): 2, (1, 0): 3, (0, 0): 1, (1, 1): 4}) 95 | >>> rowdict2mat(A) == rowdict2mat(B) 96 | True 97 | """ 98 | col_labels = value(rowdict).D 99 | return Mat((set(keys(rowdict)), col_labels), {(r,c):rowdict[r][c] for r in keys(rowdict) for c in col_labels}) 100 | 101 | def listlist2mat(L): 102 | """Given a list of lists of field elements, return a matrix whose ith row consists 103 | of the elements of the ith list. The row-labels are {0...len(L)}, and the 104 | column-labels are {0...len(L[0])} 105 | >>> A=listlist2mat([[10,20,30,40],[50,60,70,80]]) 106 | >>> print(A) 107 | 108 | 0 1 2 3 109 | ------------- 110 | 0 | 10 20 30 40 111 | 1 | 50 60 70 80 112 | 113 | """ 114 | m,n = len(L), len(L[0]) 115 | return Mat((set(range(m)),set(range(n))), {(r,c):L[r][c] for r in range(m) for c in range(n)}) 116 | 117 | def submatrix(M, rows, cols): 118 | return Mat((M.D[0]&rows, M.D[1]&cols), {(r,c):val for (r,c),val in M.f.items() if r in rows and c in cols}) 119 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/orthogonalization.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | 4 | def project_along(b, v, eps = 1E-20): 5 | ''' 6 | Project b along v. 7 | 8 | Input: 9 | - b: a Vec 10 | - v: a Vec 11 | - eps (default: 1E-20): threshold below which squared norms are considered zero 12 | 13 | Output: 14 | - a Vec representing the projection of b onto v 15 | ''' 16 | sigma = ((b*v)/(v*v)) if v*v > eps else 0 17 | return sigma * v 18 | 19 | def project_orthogonal(b, vlist): 20 | ''' 21 | Project b orthogonal to vlist. 22 | 23 | Input: 24 | - b: a Vec 25 | - vlist: a list of Vecs 26 | 27 | Output: the projection of b orthogonal to the Vecs in vlist 28 | ''' 29 | for v in vlist: 30 | b = b - project_along(b, v) 31 | return b 32 | 33 | def aug_project_orthogonal(b, vlist, eps = 1E-20): 34 | alphadict = {len(vlist):1} 35 | for i,v in enumerate(vlist): 36 | sigma = (b*v)/(v*v) if v*v > eps else 0 37 | alphadict[i] = sigma 38 | b = b - sigma*v 39 | return (b, alphadict) 40 | 41 | def orthogonalize(vlist): 42 | ''' 43 | Orthogonalizes vlist preserving order. 44 | The ith vector in the output list is the projection of vlist[i] orthogonal to 45 | the space spanned by all the previous vectors in the output list. 46 | 47 | Input: a list of Vecs 48 | 49 | Output: a list of mutually orthogonal Vecs spanning the same space as the input Vecs 50 | ''' 51 | assert isinstance(vlist, list) 52 | vstarlist = [] 53 | for v in vlist: 54 | vstarlist.append(project_orthogonal(v, vstarlist)) 55 | return vstarlist 56 | 57 | def aug_orthogonalize(vlist): 58 | ''' 59 | Input: a list of Vecs 60 | Output: a list of orthonormal Vecs spanning the same space as the input Vecs 61 | ''' 62 | assert isinstance(vlist, list) 63 | vstarlist = [] 64 | sigma_vecs = [] 65 | D = set(range(len(vlist))) 66 | for v in vlist: 67 | (vstar, sigmadict) = aug_project_orthogonal(v, vstarlist) 68 | vstarlist.append(vstar) 69 | sigma_vecs.append(Vec(D, sigmadict)) 70 | 71 | def aug_orthonormalize(L): 72 | 73 | ''' 74 | Input: 75 | - L: a list of Vecs 76 | Output: 77 | - A pair Qlist, Rlist such that: 78 | * coldict2mat(L) == coldict2mat(Qlist) * coldict2mat(Rlist) 79 | * Qlist = orthonormalize(L) 80 | >>> from vec import Vec 81 | >>> D={'a','b','c','d'} 82 | >>> 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})] 83 | >>> Qlist, Rlist = aug_orthonormalize(L) 84 | ''' 85 | Ql, Rl = aug_orthogonalize(L) 86 | Qlist = orthonormalize(Ql) 87 | mults = [(v*v)**(1/2) for v in Ql] 88 | for vector in Rl: 89 | for i in range(len(vector.D)): 90 | vector[i] = vector[i] * mults[i] 91 | return vstarlist, sigma_vecs 92 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/python_lab.py: -------------------------------------------------------------------------------- 1 | # version code ef5291f09f60+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | 6 | 7 | 8 | 9 | ## 1: (Task 1) Minutes in a Week 10 | minutes_in_week = 60 * 24 * 7 11 | 12 | 13 | 14 | ## 2: (Task 2) Remainder 15 | #For this task, your expression must use // 16 | remainder_without_mod = 2304811 - 47 * (2304811 // 47) 17 | 18 | 19 | 20 | ## 3: (Task 3) Divisibility 21 | divisible_by_3 = (673 + 909) % 3 == 0 22 | 23 | 24 | 25 | ## 4: (Task 4) Conditional Expression 26 | x = -9 27 | y = 1/2 28 | expression_val = 2 ** (y+1/2) if x+10<0 else 2**(y-1/2) 29 | 30 | 31 | 32 | ## 5: (Task 5) Squares Set Comprehension 33 | first_five_squares = {x ** 2 for x in {1,2,3,4,5} } 34 | 35 | 36 | 37 | ## 6: (Task 6) Powers-of-2 Set Comprehension 38 | first_five_pows_two = { 2** x for x in {0,1,2,3,4} } 39 | 40 | 41 | 42 | ## 7: (Task 7) Double comprehension evaluating to nine-element set 43 | # Assign three-element sets to X1 and Y1 so that 44 | # {x*y for x in X1 for y in Y1} evaluates to a nine-element set. 45 | 46 | X1 = { 1,3, 2 } 47 | Y1 = { 11, 13, 17 } 48 | 49 | 50 | 51 | ## 8: (Task 8) Double comprehension evaluating to five-element set 52 | # Assign disjoint three-element sets to X1 and Y1 so that 53 | # {x*y for x in X1 for y in Y1} evaluates to a five-element set. 54 | 55 | X2 = { 16,0,8 } 56 | Y2 = { 1,2,4} 57 | 58 | 59 | 60 | ## 9: (Task 9) Set intersection as a comprehension 61 | S = {1, 2, 3, 4} 62 | T = {3, 4, 5, 6} 63 | # Replace { ... } with a one-line set comprehension that evaluates to the intersection of S and T 64 | S_intersect_T = { x for x in S for y in T if x == y} 65 | 66 | 67 | 68 | ## 10: (Task 10) Average 69 | list_of_numbers = [20, 10, 15, 75] 70 | # Replace ... with a one-line expression that evaluates to the average of list_of_numbers. 71 | # Your expression should refer to the variable list_of_numbers, and should work 72 | # for a list of any length greater than zero. 73 | list_average =sum(list_of_numbers)/len(list_of_numbers) 74 | 75 | 76 | 77 | ## 11: (Task 11) Cartesian-product comprehension 78 | # Replace ... with a double list comprehension over ['A','B','C'] and [1,2,3] 79 | cartesian_product =[ [x] +[ y] for x in ['A','B','C'] for y in [1, 2,3]] 80 | 81 | 82 | 83 | ## 12: (Task 12) Sum of numbers in list of list of numbers 84 | LofL = [[.25, .75, .1], [-1, 0], [4, 4, 4, 4]] 85 | # Replace ... with a one-line expression of the form sum([sum(...) ... ]) that 86 | # includes a comprehension and evaluates to the sum of all numbers in all the lists. 87 | LofL_sum =sum([sum(x) for x in LofL ]) 88 | 89 | 90 | 91 | ## 13: (Task 13) Three-element tuples summing to zero 92 | S = {-4, -2, 1, 2, 5, 0} 93 | # Replace [ ... ] with a one-line list comprehension in which S appears 94 | zero_sum_list = [(x,y,z) for x in S for y in S for z in S if x+y+z == 0 ] 95 | 96 | 97 | 98 | ## 14: (Task 14) Nontrivial three-element tuples summing to zero 99 | S = {-4, -2, 1, 2, 5, 0} 100 | # Replace [ ... with a one-line list comprehension in which S appears 101 | exclude_zero_list = [(x,y,z) for x in S for y in S for z in S if x|y|z if x+y+z == 0 ] 102 | 103 | 104 | 105 | ## 15: (Task 15) One nontrivial three-element tuple summing to zero 106 | S = {-4, -2, 1, 2, 5, 0} 107 | # Replace ... with a one-line expression that uses a list comprehension in which S appears 108 | first_of_tuples_list =[ (x,y,z) for x in S for y in S for z in S if x or y or z if x+y+z == 0 ][0] 109 | 110 | 111 | ## 16: (Task 16) List and set differ 112 | # Assign to example_L a list such that len(example_L) != len(list(set(example_L))) 113 | example_L = [1 ,2, 1, 4, 1] 114 | 115 | 116 | 117 | ## 17: (Task 17) Odd numbers 118 | # Replace {...} with a one-line set comprehension over a range of the form range(n) 119 | odd_num_list_range = {i for i in range(100) if i%2} 120 | 121 | 122 | 123 | ## 18: (Task 18) Using range and zip 124 | # In the line below, replace ... with an expression that does not include a comprehension. 125 | # Instead, it should use zip and range. 126 | # Note: zip() does not return a list. It returns an 'iterator of tuples' 127 | range_and_zip = list(zip(range(5),['A','B','C','D','E'])) 128 | 129 | 130 | 131 | ## 19: (Task 19) Using zip to find elementwise sums 132 | A = [10, 25, 40] 133 | B = [1, 15, 20] 134 | # Replace [...] with a one-line comprehension that uses zip together with the variables A and B. 135 | # The comprehension should evaluate to a list whose ith element is the ith element of 136 | # A plus the ith element of B. 137 | list_sum_zip = [sum(x) for x in zip(A,B)] 138 | 139 | 140 | 141 | ## 20: (Task 20) Extracting the value corresponding to key k from each dictionary in a list 142 | dlist = [{'James':'Sean', 'director':'Terence'}, {'James':'Roger', 'director':'Lewis'}, {'James':'Pierce', 'director':'Roger'}] 143 | k = 'James' 144 | # Replace [...] with a one-line comprehension that uses dlist and k 145 | # and that evaluates to ['Sean','Roger','Pierce'] 146 | value_list = [x[k] for x in dlist] 147 | 148 | 149 | ## 21: (Task 21) Extracting the value corresponding to k when it exists 150 | dlist = [{'Bilbo':'Ian','Frodo':'Elijah'},{'Bilbo':'Martin','Thorin':'Richard'}] 151 | k = 'Bilbo' 152 | #Replace [...] with a one-line comprehension 153 | value_list_modified_1 = [x[k] if k in x else 'NOT PRESENT' for x in dlist ] # <-- Use the same expression here 154 | k = 'Frodo' 155 | value_list_modified_2 = [x.get(k, 'NOT PRESENT') for x in dlist ] # <-- as you do here 156 | 157 | 158 | 159 | ## 22: (Task 22) A dictionary mapping integers to their squares 160 | # Replace {...} with a one-line dictionary comprehension 161 | square_dict = {k:k*k for k in range(100) } 162 | 163 | 164 | 165 | ## 23: (Task 23) Making the identity function 166 | D = {'red','white','blue'} 167 | # Replace {...} with a one-line dictionary comprehension 168 | identity_dict = { x:x for x in D } 169 | 170 | 171 | 172 | ## 24: (Task 24) Mapping integers to their representation over a given base 173 | base = 10 174 | digits = set(range(base)) 175 | # Replace { ... } with a one-line dictionary comprehension 176 | # Your comprehension should use the variables 'base' and 'digits' so it will work correctly if these 177 | # are assigned different values (e.g. base = 2 and digits = {0,1}) 178 | representation_dict = { x:(x//base//base,x//base%base,x%base) for x in range(base ** 3) } 179 | 180 | 181 | 182 | ## 25: (Task 25) A dictionary mapping names to salaries 183 | id2salary = {0:1000.0, 1:1200.50, 2:990} 184 | names = ['Larry', 'Curly', 'Moe'] 185 | # Replace { ... } with a one-line dictionary comprehension that uses id2salary and names. 186 | listdict2dict ={names[k]:v for (k,v) in id2salary.items()} 187 | 188 | 189 | 190 | ## 26: (Task 26) Procedure nextInts 191 | # Complete the procedure definition by replacing [ ... ] with a one-line list comprehension 192 | def nextInts(L): return [ i+1 for i in L ] 193 | 194 | 195 | 196 | ## 27: (Task 27) Procedure cubes 197 | # Complete the procedure definition by replacing [ ... ] with a one-line list comprehension 198 | def cubes(L): return [ i**3 for i in L ] 199 | 200 | 201 | 202 | ## 28: (Task 28) Procedure dict2list 203 | # Input: a dictionary dct and a list keylist consisting of the keys of dct 204 | # Output: the list L such that L[i] is the value associated in dct with keylist[i] 205 | # Example: dict2list({'a':'A', 'b':'B', 'c':'C'},['b','c','a']) should equal ['B','C','A'] 206 | # Complete the procedure definition by replacing [ ... ] with a one-line list comprehension 207 | def dict2list(dct, keylist): return [dct[i] for i in keylist] 208 | 209 | 210 | 211 | ## 29: (Task 29) Procedure list2dict 212 | # Input: a list L and a list keylist of the same length 213 | # Output: the dictionary that maps keylist[i] to L[i] for i=0,1,...len(L)-1 214 | # Example: list2dict(['A','B','C'],['a','b','c']) should equal {'a':'A', 'b':'B', 'c':'C'} 215 | # Complete the procedure definition by replacing { ... } with a one-line dictionary comprehension 216 | def list2dict(L, keylist): return { keylist[i]:L[i] for i in range(len(L)) } 217 | 218 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/read_data.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from mat import Mat 4 | 5 | def read_vectors(filename): 6 | """File should have the following format: 7 | First line should consist of labels, separated by tabs or spaces. 8 | Remaining lines should consist of numeric data. 9 | Procedure returns a list of Vecs, one for each line of numeric data. 10 | The labels for the Vecs are the strings given in the first line. 11 | """ 12 | with open(filename) as file: 13 | labels = file.readline().split() 14 | vlist = [Vec(set(labels), dict(zip(labels, map(float, line.split())))) for line in file] 15 | return vlist 16 | 17 | def read_matrix(filename): 18 | """File should have the following format: 19 | First line should consist of column labels, separated by tabs or spaces. 20 | Each subsequent line should consist of a row label followed by numeric data. 21 | Procedure returns a matrix with the given row and column labels and numeric data 22 | """ 23 | with open(filename) as file: 24 | col_labels = file.readline().split() 25 | row_labels = set() 26 | f = {} 27 | for line in file: 28 | entries = line.split() 29 | row_label = entries[0] 30 | row_labels.add(row_label) 31 | for col, entry in zip(col_labels, entries[1:]): 32 | f[row_label, col] = entry 33 | return Mat((row_labels, set(col_labels)), f) 34 | 35 | def read_vector(filename): 36 | """File should have the following format: 37 | Each line consists of a label followed by a single numeric value, separated by whitespace 38 | Procedure returns a vector with one entry per line of the file 39 | """ 40 | with open(filename) as file: 41 | func = {k: float(v) for k,v in (line.split() for line in file)} 42 | domain = set(func.keys()) 43 | return Vec(domain, func) 44 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/triangular.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | from vecutil import zero_vec 4 | 5 | def triangular_solve_n(rowlist, b): 6 | ''' 7 | Solves an upper-triangular linear system. 8 | rowlist is a nonempty list of Vecs. Let n = len(rowlist). 9 | The domain D of all these Vecs is {0,1, ..., n-1}. 10 | b is an n-element list or a Vec whose domain is {0,1, ..., n-1}. 11 | The linear equations are: 12 | rowlist[0] * x = b[0] 13 | ... 14 | rowlist[n-1] * x = b[n-1] 15 | The system is triangular. That means rowlist[i][j] is zero 16 | for all i, j in {0,1, ..., n-1} such that i >j. 17 | 18 | This procedure assumes that rowlist[j][j] != 0 for j=0,1, ..., n-1. 19 | 20 | The procedure returns the Vec x that is the unique solution 21 | to the linear system. 22 | ''' 23 | D = rowlist[0].D 24 | n = len(D) 25 | assert D == set(range(n)) 26 | x = zero_vec(D) 27 | for j in reversed(range(n)): 28 | x[j] = (b[j] - rowlist[j] * x)/rowlist[j][j] 29 | return x 30 | 31 | def triangular_solve(rowlist, label_list, b): 32 | ''' 33 | Solves an upper-triangular linear system. 34 | rowlist is a nonempty list of Vecs. Let n = len(rowlist). 35 | b is an n-element list or a Vec over domain {0,1, ..., n-1}. 36 | The linear equations are: 37 | rowlist[0] * x = b[0] 38 | ... 39 | rowlist[n-1] * x = b[n-1] 40 | label_list is a list consisting of all the elements of D, 41 | where D is the domain of each of the vectors in rowlist. 42 | The system is triangular with respect to the ordering given 43 | by label_list. That means rowlist[n-1][d] is zero for 44 | every element d of D except for the last element of label_list, 45 | rowlist[n-2][d] is zero for every element d of D except for 46 | the last two elements of label_list, and so on. 47 | 48 | This procedure assumes that rowlist[j][label_list[j]] != 0 49 | for j = 0,1, ..., n-1. 50 | 51 | The procedure returns the Vec x that is the unique solution 52 | to the linear system. 53 | ''' 54 | D = rowlist[0].D 55 | x = zero_vec(D) 56 | for j in reversed(range(len(D))): 57 | c = label_list[j] 58 | row = rowlist[j] 59 | x[c] = (b[j] - x*row)/row[c] 60 | return x 61 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/vec.py: -------------------------------------------------------------------------------- 1 | # version code 24ea27739109+ 2 | coursera = 1 3 | # Please fill out this stencil and submit using the provided submission script. 4 | 5 | # Copyright 2013 Philip N. Klein 6 | 7 | def getitem(v,k): 8 | """ 9 | Return the value of entry k in v. 10 | Be sure getitem(v,k) returns 0 if k is not represented in v.f. 11 | 12 | >>> v = Vec({'a','b','c', 'd'},{'a':2,'c':1,'d':3}) 13 | >>> v['d'] 14 | 3 15 | >>> v['b'] 16 | 0 17 | """ 18 | return v.f[k] if k in v.f.keys() else 0 19 | def setitem(v,k,val): 20 | """ 21 | Set the element of v with label d to be val. 22 | setitem(v,d,val) should set the value for key d even if d 23 | is not previously represented in v.f. 24 | 25 | >>> v = Vec({'a', 'b', 'c'}, {'b':0}) 26 | >>> v['b'] = 5 27 | >>> v['b'] 28 | 5 29 | >>> v['a'] = 1 30 | >>> v['a'] 31 | 1 32 | >>> v['a'] = 0 33 | >>> v['a'] 34 | 0 35 | """ 36 | v.f[k] = val 37 | 38 | 39 | 40 | 41 | def equal(u,v): 42 | """ 43 | Return true iff u is equal to v. 44 | Because of sparse representation, it is not enough to compare dictionaries 45 | 46 | >>> Vec({'a', 'b', 'c'}, {'a':0}) == Vec({'a', 'b', 'c'}, {'b':0}) 47 | True 48 | 49 | Be sure that equal(u, v) check equalities for all keys from u.f and v.f even if 50 | some keys in u.f do not exist in v.f (or vice versa) 51 | 52 | >>> Vec({'x','y','z'},{'y':1,'x':2}) == Vec({'x','y','z'},{'y':1,'z':0}) 53 | False 54 | >>> Vec({'a','b','c'}, {'a':0,'c':1}) == Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) 55 | False 56 | >>> Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) == Vec({'a','b','c'}, {'a':0,'c':1}) 57 | False 58 | 59 | The keys matter: 60 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'b':1}) 61 | False 62 | 63 | The values matter: 64 | >>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'a':2}) 65 | False 66 | 67 | """ 68 | assert u.D == v.D 69 | return True if sum([ 1 for x in u.D if getitem(u,x) == getitem(v,x)]) == len(u.D) else False 70 | 71 | 72 | 73 | def add(u,v): 74 | """ 75 | Returns the sum of the two vectors. 76 | Make sure to add together values for all keys from u.f and v.f even if some keys in u.f do not 77 | exist in v.f (or vice versa) 78 | 79 | >>> a = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 80 | >>> b = Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 81 | >>> c = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2,'o':4,'u':7}) 82 | >>> a + b == c 83 | True 84 | >>> a == Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2}) 85 | True 86 | >>> b == Vec({'a','e','i','o','u'}, {'o':4,'u':7}) 87 | True 88 | >>> d = Vec({'x','y','z'}, {'x':2,'y':1}) 89 | >>> e = Vec({'x','y','z'}, {'z':4,'y':-1}) 90 | >>> f = Vec({'x','y','z'}, {'x':2,'y':0,'z':4}) 91 | >>> d + e == f 92 | True 93 | >>> b + Vec({'a','e','i','o','u'}, {}) == b 94 | True 95 | """ 96 | assert u.D == v.D 97 | return Vec(u.D, {x:getitem(u,x) + getitem(v,x) for x in u.D } ) 98 | 99 | 100 | 101 | def dot(u,v): 102 | """ 103 | Returns the dot product of the two vectors. 104 | 105 | >>> u1 = Vec({'a','b'}, {'a':1, 'b':2}) 106 | >>> u2 = Vec({'a','b'}, {'b':2, 'a':1}) 107 | >>> u1*u2 108 | 5 109 | >>> u1 == Vec({'a','b'}, {'a':1, 'b':2}) 110 | True 111 | >>> u2 == Vec({'a','b'}, {'b':2, 'a':1}) 112 | True 113 | >>> v1 = Vec({'p','q','r','s'}, {'p':2,'s':3,'q':-1,'r':0}) 114 | >>> v2 = Vec({'p','q','r','s'}, {'p':-2,'r':5}) 115 | >>> v1*v2 116 | -4 117 | >>> w1 = Vec({'a','b','c'}, {'a':2,'b':3,'c':4}) 118 | >>> w2 = Vec({'a','b','c'}, {'a':12,'b':8,'c':6}) 119 | >>> w1*w2 120 | 72 121 | 122 | The pairwise products should not be collected in a set before summing 123 | because a set eliminates duplicates 124 | >>> v1 = Vec({1, 2}, {1 : 3, 2 : 6}) 125 | >>> v2 = Vec({1, 2}, {1 : 2, 2 : 1}) 126 | >>> v1 * v2 127 | 12 128 | """ 129 | assert u.D == v.D 130 | return sum([getitem(u,x) * getitem(v,x) for x in u.D]) 131 | 132 | 133 | def scalar_mul(v, alpha): 134 | """ 135 | Returns the scalar-vector product alpha times v. 136 | 137 | >>> zero = Vec({'x','y','z','w'}, {}) 138 | >>> u = Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 139 | >>> 0*u == zero 140 | True 141 | >>> 1*u == u 142 | True 143 | >>> 0.5*u == Vec({'x','y','z','w'},{'x':0.5,'y':1,'z':1.5,'w':2}) 144 | True 145 | >>> u == Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4}) 146 | True 147 | """ 148 | return Vec(v.D, { x: alpha * getitem(v,x) for x in v.D}) 149 | 150 | 151 | 152 | def neg(v): 153 | """ 154 | Returns the negation of a vector. 155 | 156 | >>> u = Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 157 | >>> -u 158 | Vec({8, 2, 4, 6},{8: -4, 2: -1, 4: -2, 6: -3}) 159 | >>> u == Vec({2,4,6,8},{2:1,4:2,6:3,8:4}) 160 | True 161 | >>> -Vec({'a','b','c'}, {'a':1}) == Vec({'a','b','c'}, {'a':-1}) 162 | True 163 | 164 | """ 165 | 166 | return Vec(v.D, { x: -1 * getitem(v,x) for x in v.D}) 167 | ############################################################################################################################### 168 | 169 | class Vec: 170 | """ 171 | A vector has two fields: 172 | D - the domain (a set) 173 | f - a dictionary mapping (some) domain elements to field elements 174 | elements of D not appearing in f are implicitly mapped to zero 175 | """ 176 | def __init__(self, labels, function): 177 | self.D = labels 178 | self.f = function 179 | 180 | __getitem__ = getitem 181 | __setitem__ = setitem 182 | __neg__ = neg 183 | __rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar 184 | 185 | def __mul__(self,other): 186 | #If other is a vector, returns the dot product of self and other 187 | if isinstance(other, Vec): 188 | return dot(self,other) 189 | else: 190 | return NotImplemented # Will cause other.__rmul__(self) to be invoked 191 | 192 | def __truediv__(self,other): # Scalar division 193 | return (1/other)*self 194 | 195 | __add__ = add 196 | 197 | def __radd__(self, other): 198 | "Hack to allow sum(...) to work with vectors" 199 | if other == 0: 200 | return self 201 | 202 | def __sub__(a,b): 203 | "Returns a vector which is the difference of a and b." 204 | return a+(-b) 205 | 206 | __eq__ = equal 207 | 208 | def is_almost_zero(self): 209 | s = 0 210 | for x in self.f.values(): 211 | if isinstance(x, int) or isinstance(x, float): 212 | s += x*x 213 | elif isinstance(x, complex): 214 | s += x*x.conjugate() 215 | else: return False 216 | return s < 1e-20 217 | 218 | def __str__(v): 219 | "pretty-printing" 220 | D_list = sorted(v.D, key=repr) 221 | numdec = 3 222 | wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list]) 223 | s1 = ''.join(['{0:>{1}}'.format(str(k),wd[k]) for k in D_list]) 224 | s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list]) 225 | return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2 226 | 227 | def __hash__(self): 228 | "Here we pretend Vecs are immutable so we can form sets of them" 229 | h = hash(frozenset(self.D)) 230 | for k,v in sorted(self.f.items(), key = lambda x:repr(x[0])): 231 | if v != 0: 232 | h = hash((h, hash(v))) 233 | return h 234 | 235 | def __repr__(self): 236 | return "Vec(" + str(self.D) + "," + str(self.f) + ")" 237 | 238 | def copy(self): 239 | "Don't make a new copy of the domain D" 240 | return Vec(self.D, self.f.copy()) 241 | -------------------------------------------------------------------------------- /Week7-Orthogonalization/Orthogonalization_Problems/vecutil.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Philip N. Klein 2 | from vec import Vec 3 | 4 | def list2vec(L): 5 | """Given a list L of field elements, return a Vec with domain {0...len(L)-1} 6 | whose entry i is L[i] 7 | 8 | >>> list2vec([10, 20, 30]) 9 | Vec({0, 1, 2},{0: 10, 1: 20, 2: 30}) 10 | """ 11 | return Vec(set(range(len(L))), {k:L[k] for k in range(len(L))}) 12 | 13 | def zero_vec(D): 14 | """Returns a zero vector with the given domain 15 | """ 16 | return Vec(D, {}) 17 | --------------------------------------------------------------------------------