├── Cohen_ES_alglin_cap6.PDF ├── Cohen_linalg_ch6.PDF ├── ES_TOC_cap1.pdf ├── README.md ├── TOC_ch1.pdf ├── matlab ├── LAbookX_chapter02.m ├── LAbookX_chapter03.m ├── LAbookX_chapter05.m ├── LAbookX_chapter06.m ├── LAbookX_chapter07.m ├── LAbookX_chapter08.m ├── LAbookX_chapter09.m ├── LAbookX_chapter10.m ├── LAbookX_chapter11.m ├── LAbookX_chapter12.m ├── LAbookX_chapter13.m ├── LAbookX_chapter14.m ├── LAbookX_chapter15.m ├── LAbookX_chapter16.m ├── LAbookX_chapter17.m ├── LAbookX_chapter18.m ├── LAbookX_chapter19.m └── widget_data.txt └── python ├── LAbookX_chapter02.ipynb ├── LAbookX_chapter03.ipynb ├── LAbookX_chapter05.ipynb ├── LAbookX_chapter06.ipynb ├── LAbookX_chapter07.ipynb ├── LAbookX_chapter08.ipynb ├── LAbookX_chapter09.ipynb ├── LAbookX_chapter10.ipynb ├── LAbookX_chapter11.ipynb ├── LAbookX_chapter12.ipynb ├── LAbookX_chapter13.ipynb ├── LAbookX_chapter14.ipynb ├── LAbookX_chapter15.ipynb ├── LAbookX_chapter16.ipynb ├── LAbookX_chapter17.ipynb ├── LAbookX_chapter18.ipynb ├── LAbookX_chapter19.ipynb └── widget_data.txt /Cohen_ES_alglin_cap6.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikexcohen/LinAlgBook/ce8077d7002db3ba0c206ebaee9bc610ca081709/Cohen_ES_alglin_cap6.PDF -------------------------------------------------------------------------------- /Cohen_linalg_ch6.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikexcohen/LinAlgBook/ce8077d7002db3ba0c206ebaee9bc610ca081709/Cohen_linalg_ch6.PDF -------------------------------------------------------------------------------- /ES_TOC_cap1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikexcohen/LinAlgBook/ce8077d7002db3ba0c206ebaee9bc610ca081709/ES_TOC_cap1.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linear algebra book 2 | 3 | This is all the code that accompanies the book "Linear Algebra: Theory, Intuition, Code" 4 | 5 | https://www.amazon.com/Linear-Algebra-Theory-Intuition-Code/dp/9083136604 6 | 7 | You can inspect the Table of Contents (TOC) and read chapter 1. 8 | 9 | Check out the free sample chapter on matrix multiplications! 10 | 11 | 12 | 13 | Note: For an independent translation of the book code into R, see the following link: 14 | https://alexander-pastukhov.github.io/cohen-linear-algebra/ 15 | 16 | And for an indepenedent translation into C++, see: 17 | https://github.com/thehoglet/LinAlgBook 18 | 19 | # SPANISH TRANSLATION 20 | 21 | The book has been expertly translated into Spanish by [Diana Llorente](https://spanishtechnicaltranslations.com/). 22 | 23 | 24 | You can inspect the Table of Contents (TOC) and read chapter 1. 25 | 26 | Check out the free sample chapter on matrix multiplications! 27 | 28 | You can find it here: 29 | [https://www.amazon.es/dp/B0DC6QY81S/](https://www.amazon.es/dp/B0DC6QY81S/) 30 | 31 | -------------------------------------------------------------------------------- /TOC_ch1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikexcohen/LinAlgBook/ce8077d7002db3ba0c206ebaee9bc610ca081709/TOC_ch1.pdf -------------------------------------------------------------------------------- /matlab/LAbookX_chapter02.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Vectors (chapter 2) 7 | % 8 | %% 9 | 10 | %% Section 2.1, code block 2.2 11 | 12 | % creating scalars (numeric variables) 13 | aScalar = 4; 14 | 15 | 16 | %% Section 2.2, code block 2.4 17 | 18 | 19 | % create a vector 20 | v = [ 2 -1]; 21 | 22 | 23 | % plot it 24 | figure(1), clf 25 | plot([0 v(1)],[0 v(2)],'k') 26 | axis([-3,3,-3,3]) 27 | grid on 28 | 29 | %% Section 2.2, code block 2.6 30 | 31 | % row vector 32 | v1 = [ 2 5 4 7 ]; 33 | 34 | 35 | % column vector 36 | v2 = [ 2; 5; 4; 7 ]; 37 | 38 | %% Section 2.3, code block 2.8 39 | 40 | % start with a row vector 41 | v1 = [ 2 5 4 7 ]; 42 | 43 | % transpose to a column vector 44 | v2 = v1'; 45 | 46 | 47 | %% Section 2.5, code block 2.10 48 | 49 | % two vectors 50 | v1 = [ 2 5 4 7 ]; 51 | v2 = [ 4 1 0 2 ]; 52 | 53 | % scalar-multiply and add 54 | v3 = 4*v1 - 2*v2; 55 | 56 | %% Section 2.9, code block 2.12 57 | 58 | % the "base" vector 59 | v = [ 1 2 ]; 60 | 61 | figure(2), clf, hold on 62 | plot([0 v(1)],[0 v(2)],'linew',2) 63 | 64 | for i=1:10 65 | 66 | % random scalar 67 | s = randn; 68 | sv = s*v; 69 | 70 | % plot that one on top 71 | plot([0 sv(1)],[0 sv(2)],'linew',2) 72 | end 73 | 74 | grid on 75 | axis([-1 1 -1 1]*4) 76 | axis square 77 | 78 | %% done. 79 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter03.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Vector Multiplications (chapter 3) 7 | % 8 | %% 9 | 10 | %% Section 3.1, code block 3.2 11 | 12 | % create two vectors 13 | v1 = [ 2 5 4 7 ]; 14 | v2 = [ 4 1 0 2 ]; 15 | 16 | % dot product between them 17 | dp = dot (v1,v2); 18 | 19 | %% Section 3.5, code block 3.4 20 | 21 | % some scalars 22 | l1 = 1; 23 | l2 = 2; 24 | l3 = -3; 25 | 26 | % some vectors 27 | v1 = [ 4 5 1 ]'; 28 | v2 = [-4 0 -4 ]'; 29 | v3 = [ 1 3 2 ]'; 30 | 31 | % a linear weighted combination 32 | l1*v1 + l2*v2 + l3*v3 33 | 34 | %% Section 3.6, code block 3.6 35 | 36 | % two column vectors 37 | v1 = [ 2, 5, 4, 7 ]'; 38 | v2 = [ 4 1 0 2 ]'; 39 | 40 | % outer product 41 | op = v1 * v2'; 42 | 43 | 44 | %% Section 3.7, code block 3.8 45 | 46 | % two vectors 47 | v1 = [ 2, 5, 4, 7 ]; 48 | v2 = [ 4, 1, 0, 2 ]; 49 | 50 | % Hadamard multiplication 51 | v3 = v1 .* v2; 52 | 53 | %% Section 3.9, code block 3.10 54 | 55 | % a vector 56 | v = [2 5 4 7]; 57 | 58 | % its norm 59 | vMag = norm(v); 60 | 61 | % the unit vector 62 | v_unit = v / vMag; 63 | 64 | 65 | 66 | %% Section 3.13, code block 3.12 67 | 68 | % three vectors 69 | v1 = [ 1, 2, 3, 4, 5 ]; 70 | v2 = [ 2, 3, 4, 5, 6 ]; 71 | v3 = [ 3, 4, 5, 6, 7 ]; 72 | 73 | % linear weighted combo 74 | w = [ -1 3 -2 ]; 75 | result = v1*w(1) + v2*w(2) + v3*w(3) 76 | 77 | %% Section 3.13, code block 3.14 78 | 79 | v = [ 7 4 -5 8 3 ]'; 80 | o = ones ( size(v) ) ; 81 | 82 | % average via dot product 83 | ave = dot(v,o) / length(v) 84 | 85 | %% Section 3.13, code block 3.16 86 | 87 | % vector 88 | v = [ 7, 4, -5, 8, 3 ]; 89 | 90 | % random weighting vector 91 | w = rand( size(v) ); 92 | 93 | % weighted dp 94 | wAve = dot(v,w/sum(w)); 95 | 96 | %% done. 97 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter05.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Matrices (chapter 5) 7 | % 8 | %% 9 | 10 | %% Section 5.4, code block 5.2 11 | 12 | % create a matrix of random numbers 13 | A = randn(2,5); 14 | 15 | % two ways to transpose 16 | At1 = A'; 17 | At2 = transpose(A); 18 | 19 | 20 | %% Section 5.5, code block 5.4 21 | 22 | % identity matrix 23 | I = eye(4); 24 | 25 | % ones matrix 26 | O = ones(4); 27 | 28 | % zeros matrix 29 | Z = zeros(4); 30 | 31 | 32 | %% Section 5.5, code block 5.6 33 | 34 | % diagonal matrix from a vecot 35 | D = diag([ 1, 2, 3, 5]); 36 | 37 | % diagonal of a full matrix 38 | R = randn(3,4); 39 | d = diag(R); 40 | 41 | 42 | %% Section 5.5, code block 5.8 43 | 44 | % random numbers matrix 45 | A = randn(3,5); 46 | 47 | % another random matrix 48 | B = randn(3,4); 49 | 50 | % augmented matrix 51 | AB = [A B]; 52 | 53 | 54 | %% Section 5.5, code block 5.10 55 | 56 | % Create a matrix 57 | A = randn(5); 58 | 59 | % extract the lower triangle 60 | L = tril(A); 61 | 62 | % extract the upper triangle 63 | U = triu(A); 64 | 65 | %% Section 5.5, code block 5.12 66 | 67 | % start from this vector 68 | t = 1:4; 69 | 70 | % toeplitz 71 | T = toeplitz(t); 72 | 73 | % hankel 74 | H = hankel(t,t([end 1:end-1])); 75 | 76 | %% Section 5.8, code block 5.14 77 | 78 | % scalar to shift by 79 | l = .01; 80 | 81 | % identity matrix 82 | I = eye(4); 83 | 84 | % just some matrix 85 | A = randn(4); 86 | 87 | % shifted version 88 | As = A + l*I; 89 | 90 | %% Section 5.9, code block 5.16 91 | 92 | % a matrix 93 | A = randn(4); 94 | 95 | % its trace 96 | tr = trace(A); 97 | 98 | %% Section 5.13, code block 5.18 99 | 100 | % create two matrices 101 | A = randn(4,2); 102 | B = randn(4,2); 103 | 104 | % initialize the result 105 | C = zeros(2); 106 | 107 | % the multiplications 108 | for coli=1:2 % columns in A 109 | for colj=1:2 % columns in B 110 | C(coli,colj) = dot(A(:,coli),B(:,colj)); 111 | end 112 | end 113 | 114 | %% Section 5.13, code block 5.20 115 | 116 | % a full matrix 117 | A = randn(4); 118 | 119 | % get the upper-triangle 120 | Al = tril(A); 121 | 122 | % sum it with its transpose 123 | S = Al + Al'; 124 | 125 | %% Section 5.13, code block 5.22 126 | 127 | % empty rectangular matrix 128 | D = zeros(4,8); 129 | 130 | % populate its diagonals 131 | for d=1:min(size(D)) 132 | D(d,d) = d; 133 | end 134 | 135 | %% done. 136 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter06.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Matrix multiplications (chapter 6) 7 | % 8 | %% 9 | 10 | %% Section 6.1, code block 6.2 11 | 12 | % two matrices 13 | M1 = randn(4,3); 14 | M2 = randn(3,5); 15 | 16 | % and their product 17 | C = M1 * M2; 18 | 19 | %% Section 6.2, code block 6.4 20 | 21 | A = randn(2,2); 22 | B = randn(2,2); 23 | 24 | % notice that C1 != C2 25 | C1 = A*B; 26 | C2 = B*A; 27 | 28 | %% Section 6.8, code block 6.6 29 | 30 | % a pair of matrices 31 | M1 = randn(4,3); 32 | M2 = randn(4,3); 33 | 34 | % their Hadamard multiplication 35 | C = M1 .* M2 36 | 37 | %% Section 6.9, code block 6.8 38 | 39 | % a small matrix 40 | A = [ 1, 2, 3; 4, 5, 6 ]; 41 | 42 | % vectorized 43 | A(:) 44 | 45 | %% Section 6.9, code block 6.10 46 | 47 | A = randn(4,3); 48 | B = randn(4,3); 49 | 50 | % the transpose-trace trick for the frobenius dot product 51 | f = trace(A'*B); 52 | 53 | %% Section 6.10, code block 6.12 54 | 55 | A = randn(4,3); 56 | norm(A,'fro') 57 | 58 | %% Section 6.15, code block 6.14 59 | 60 | % the matrices 61 | A = randn(2,4); 62 | B = randn(4,3); 63 | 64 | % initialize 65 | C1 = zeros(2,3); 66 | 67 | % loop over (N) columns in A 68 | for i=1:size(A,2) 69 | C1 = C1 + A(:,i)*B(i,:); 70 | end 71 | 72 | % show equality by subtraction (expect zeros) 73 | C1 - A*B 74 | 75 | 76 | %% Section 6.15, code block 6.16 77 | 78 | % create the matrices 79 | D = diag(1:4); 80 | A = randn(4); 81 | 82 | % two kinds of multiplication 83 | C1 = D.*A; 84 | C2 = D*A; 85 | 86 | % they're the same 87 | [diag(C1) diag(C2)] 88 | 89 | 90 | %% Section 6.15, code block 6.18 91 | 92 | % the matrix 93 | A = diag(rand(3,1)); 94 | 95 | % the two symmetric matrices 96 | C1 = (A'+A)/2; 97 | C2 = A'*A; 98 | 99 | % their equivalence 100 | C1-sqrt(C2) 101 | 102 | %% Section 6.15, code block 6.20 103 | 104 | % matrix and vector 105 | m = 5; 106 | A = randn(m); 107 | v = randn(m,1); 108 | 109 | % the two sides of the equation 110 | LHS = norm(A*v); 111 | RHS = norm(A,'fro')*norm(v); 112 | 113 | % their difference 114 | RHS-LHS % should always be positive 115 | 116 | %% done. 117 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter07.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Rank (chapter 7) 7 | % 8 | %% 9 | 10 | %% Section 7.3, code block 7.2 11 | 12 | % a matrix 13 | A = randn(3,6); 14 | 15 | % and its rank 16 | r = rank(A) 17 | 18 | %% Section 7.4, code block 7.4 19 | 20 | % scalar 21 | s = randn; 22 | 23 | % matrix 24 | M = randn(3,5); 25 | 26 | % their ranks 27 | r1 = rank(M); 28 | r2 = rank(s*M); 29 | 30 | % are the same 31 | disp ([ r1 r2 ]) 32 | 33 | 34 | %% Section 7.10, code block 7.6 35 | 36 | % inspect the source code for rank 37 | edit rank 38 | 39 | 40 | %% Section 7.15, code block 7.8 41 | 42 | % two random matrices 43 | A = randn(9,2); 44 | B = randn(2,16); 45 | 46 | % the rank of their product (assume max possible) 47 | C = A*B; 48 | 49 | 50 | %% Section 7.15, code block 7.10 51 | 52 | % zeros matrix 53 | Z = zeros(5); 54 | 55 | % tiny noise matrix 56 | N = randn(5) * eps*1e-307; 57 | 58 | % add them together 59 | ZN = Z + N; 60 | 61 | % check their ranks 62 | rank(Z) % r=0 63 | rank(ZN) % r=5 64 | 65 | % and the matrix norm 66 | norm(ZN,'fro') 67 | 68 | %% done. 69 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter08.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Matrix spaces (chapter 8) 7 | % 8 | %% 9 | 10 | %% Section 8.7, code block 8.2 11 | 12 | A = randn(3,4); 13 | null(A) 14 | 15 | 16 | %% Section 8.15, code block 8.4 17 | 18 | % create reduced-rank matrices 19 | A = randn(4,3) * randn(3,4); 20 | B = randn(4,3) * randn(3,4); 21 | 22 | % find a vector in A's nullspace 23 | n = null(A); 24 | 25 | % zeros vector 26 | B*A*n 27 | 28 | % not zeros vector 29 | A*B*n 30 | 31 | %% Section 8.15, code block 8.6 32 | 33 | % create a rank-9 matrix 34 | A = randn(16,9) * randn(9,11); 35 | 36 | % "right" null space 37 | rn = null(A); 38 | 39 | % left-null space 40 | ln = null(A'); 41 | 42 | % rank of the matrix 43 | r = rank(A); 44 | 45 | % check the dimensionalities! 46 | size(rn,2) + r 47 | size(ln,2) + r 48 | 49 | %% done. 50 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter09.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Complex numbers (chapter 9) 7 | % 8 | %% 9 | 10 | %% Section 9.2, code block 9.2 11 | 12 | % one way to create a complex number 13 | z = complex(3,4); 14 | 15 | % initialize zeros 16 | Z = zeros(2,1); 17 | 18 | % can simply replace one element with a complex number 19 | Z(1) = 3+4i; 20 | 21 | %% Section 9.3, code block 9.4 22 | 23 | % some random real and imaginary parts 24 | r = randi([-3,3],1,3); 25 | i = randi([-3,3],1,3); 26 | 27 | % combine into a matrix 28 | Z = r + i*1j; 29 | 30 | % its conjugate 31 | conj(Z) 32 | 33 | %% Section 9.5, code block 9.6 34 | 35 | % a complex vector 36 | v = [ 0 1i ]; 37 | 38 | % Hermitian dot product 39 | dot(v,v) 40 | 41 | %% Section 9.10, code block 9.8 42 | 43 | U = .5 * [ 1 + 1i 1-1i; 1-1i 1+1i ]; 44 | 45 | % Hermitian 46 | U'*U 47 | 48 | % not Hermitian 49 | transpose(U)*U 50 | 51 | %% Section 9.10, code block 9.10 52 | 53 | % create a complex matrix 54 | A = complex(randn(3,3) , randn(3,3)); 55 | 56 | % new matrices by adding and multiplying 57 | A1 = A+A'; 58 | A2 = A*A'; 59 | 60 | 61 | ishermitian(A1) % issymmetric(A1) is false! 62 | ishermitian(A2) 63 | 64 | %% done. 65 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter10.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Systems of equations (chapter 10) 7 | % 8 | %% 9 | 10 | %% Section 10.3, code block 10.2 11 | 12 | % create a matrix 13 | A = randn(4,3); 14 | 15 | % take its LU decomposition 16 | [L,U,P] = lu(A); 17 | 18 | %% Section 10.5, code block 10.4 19 | 20 | A = randn(2,4); 21 | 22 | % its RREF 23 | rref(A) 24 | 25 | %% Section 10.12, code block 10.6 26 | 27 | % the matrix 28 | A = [ 2 0 -3; 3 1 4 ; 1 0 -1]; 29 | 30 | % note: column vector! 31 | x = [ 2 3 4 ]'; 32 | 33 | % the constants vector 34 | b = A*x; 35 | 36 | 37 | %% Section 10.12, code block 10.8 38 | 39 | % one example 40 | rref(randn(3,6)) 41 | 42 | %% done. 43 | 44 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter11.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Determinant (chapter 11) 7 | % 8 | %% 9 | 10 | %% Section 11.6, code block 11.2 11 | 12 | A = randn(3,3); 13 | det(A) 14 | 15 | 16 | %% Section 11.6, code block 11.4 17 | 18 | % random matrix and vector 19 | A = randi([0 10],4); 20 | b = randi([-10 -1],1); 21 | 22 | % show equivalence 23 | [ det(b*A) b^4*det(A) ] 24 | 25 | 26 | %% Section 11.6, code block 11.6 27 | 28 | % matrix sizes 29 | ns = 3:30; 30 | 31 | % iterations 32 | iters = 100; 33 | 34 | % initialize results matrix 35 | dets = zeros(length(ns),iters); 36 | 37 | % loop over matrix sizes 38 | for ni=1:length(ns) 39 | for i=1:iters 40 | 41 | % step 1 42 | A = randn(ns(ni)); 43 | 44 | % step 2 45 | A(:,1) = A(:,2); 46 | 47 | % step 3 48 | dets(ni,i) = abs(det(A)); 49 | end 50 | end 51 | 52 | % show in a plot 53 | figure(1), clf 54 | plot(ns,log(mean(dets,2)),'s-') 55 | xlabel('Matrix size') 56 | ylabel('Log determinant') 57 | 58 | %% done. 59 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter12.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Matrix inverse (chapter 12) 7 | % 8 | %% 9 | 10 | %% Section 12.4, code block 12.2 11 | 12 | % a square matrix (full-rank!) 13 | A = randn(3,3); 14 | 15 | % inverse 16 | Ai = inv(A); 17 | 18 | % should equal identity 19 | A*Ai 20 | 21 | %% Section 12.5, code block 12.4 22 | 23 | % invertible matrix 24 | A = randn(3); 25 | 26 | % RREF with identity 27 | Ar = rref([A eye(3)]); % RREF 28 | 29 | % extract the inverse part 30 | Ar = Ar(:,4:end); 31 | 32 | % inverse via inv function 33 | Ai = inv(A); 34 | 35 | % check for equality 36 | Ar-Ai 37 | 38 | 39 | %% Section 12.7, code block 12.6 40 | 41 | % tall matrix 42 | A = randn(5,3); 43 | 44 | % left inverse 45 | Al = inv(A'*A)*A'; 46 | 47 | % check for I 48 | Al*A 49 | 50 | 51 | %% Section 12.8, code block 12.8 52 | 53 | % make a reduced-rank matrix 54 | A = randn(3,3); 55 | A(2,:) = A(1,:); 56 | 57 | % MP pseudoinverse 58 | Api = pinv(A); 59 | 60 | Api*A 61 | 62 | %% Section 12.12, code block 12.10 63 | 64 | % create matrix 65 | m = 4; 66 | A = randn(m); 67 | [M,G] = deal( zeros(m) ); 68 | 69 | % compute matrices 70 | for i=1:m 71 | for j=1:m 72 | 73 | %% select rows/cols 74 | rows = true(1,m); 75 | rows(i) = false; 76 | 77 | cols = true(1,m); 78 | cols(j) = false; 79 | 80 | % compute M 81 | M(i,j) = det( A(rows,cols) ); 82 | 83 | % compute G 84 | G(i,j) = (-1)^(i+j); 85 | end 86 | end 87 | 88 | % compute C 89 | C = M .* G; 90 | 91 | % compute A 92 | Ainv = C'/det(A); 93 | AinvI = inv(A); 94 | AinvI-Ainv % compare against inv() 95 | 96 | %% Section 12.12, code block 12.12 97 | 98 | % square matrix 99 | A = randn(5); 100 | Ai = inv(A); 101 | Api = pinv(A); 102 | Ai - Api % test equivalence 103 | 104 | % tall matrix 105 | T = randn(5,3); 106 | Tl = inv(T'*T)*T'; % left inv 107 | Tpi = pinv(T); % pinv 108 | Tl - Tpi % test equivalance 109 | 110 | %% done. 111 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter13.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Projections and orthogonalization (chapter 13) 7 | % 8 | %% 9 | 10 | %% Section 13.2, code block 13.2 11 | 12 | % matrix and vector 13 | A = [1 2; 3 1; 1 1 ] ; 14 | b = [ 5.5 -3.5 1.5 ]'; 15 | 16 | % short-cut for least-squares solver 17 | A\b 18 | 19 | 20 | %% Section 13.6, code block 13.4 21 | 22 | % the matrix 23 | A = randn(4,3); 24 | 25 | % its QR decomposition 26 | [Q,R] = qr(A); % add ,"econ" to get economy decomposition 27 | 28 | 29 | %% Section 13.11, code block 13.6 30 | 31 | % sizes 32 | m = 4; 33 | n = 4; 34 | 35 | % matrix 36 | A = randn(m,n); 37 | 38 | % initialize 39 | Q = zeros(m,n); 40 | 41 | for i=1:n % loop through columns (n) 42 | 43 | Q(:,i) = A(:,i); 44 | 45 | % orthogonalize 46 | if i>1 47 | a = A(:,i); % convenience 48 | for j=1:i-1 % only to earlier columns 49 | q = Q(:,j); % convenience 50 | Q(:,i) = Q(:,i) - (a'*q/(q'*q)) * q; 51 | end 52 | end 53 | 54 | % normalize 55 | Q(:,i) = Q(:,i) / norm(Q(:,i)); 56 | end 57 | 58 | % test against "real" Q matrix 59 | [Q2,R] = qr(A); 60 | 61 | % note the possible sign differences. 62 | % seemingly non-zero columns will be 0 when adding 63 | Q - Q2 64 | 65 | %% done. 66 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter14.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Least squares (chapter 14) 7 | % 8 | %% 9 | 10 | %% Section 14.10, code block 14.2 11 | 12 | % load the data 13 | data = load('widget_data.txt'); 14 | 15 | % design matrix 16 | X = [ones(1000,1) data(:,1:2)]; 17 | 18 | % outcome variable 19 | y = data(:,3); 20 | 21 | % beta coefficients 22 | beta = X\y; 23 | 24 | % scaled coefficients (intercept not scaled) 25 | betaScaled = beta'./std(X); 26 | 27 | 28 | %% Section 14.10, code block 14.4 29 | 30 | figure(1), clf 31 | subplot(121) 32 | plot(X(:,2),y,'o','markerfacecolor','k') 33 | axis square, title('Time variable') 34 | xlabel('Time of day') 35 | ylabel('Widgets purchased') 36 | 37 | 38 | subplot(122) 39 | plot(X(:,3),y,'o','markerfacecolor','k') 40 | axis square, title('Age variable') 41 | xlabel('Age'), ylabel('Widgets purchased') 42 | 43 | 44 | %% Section 14.10, code block 14.6 45 | 46 | % predicted data values 47 | yHat = X*beta; 48 | 49 | % R-squared 50 | r2 = 1 - sum((yHat-y).^2) / sum((y-mean(y)).^2); 51 | 52 | %% done. 53 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter15.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Eigendecomposition (chapter 15) 7 | % 8 | %% 9 | 10 | %% Section 15.4, code block 15.2 11 | 12 | % friendly little matrix 13 | A = [ 2 3; 3 2 ]; 14 | 15 | % vector of eigenvalues 16 | L = eig(A); 17 | 18 | % diagonalization 19 | [V,L] = eig(A); 20 | 21 | %% Section 15.12, code block 15.4 22 | 23 | % create two matrices 24 | n = 3; 25 | A = randn(n); 26 | B = randn(n); 27 | 28 | % note the order of inputs 29 | [evecs,evals] = eig(A,B); 30 | 31 | %% Section 15.16, code block 15.6 32 | 33 | % largest matrix size 34 | maxN = 100; 35 | 36 | % initialize 37 | avediffs = zeros(maxN,1); 38 | 39 | for n=1:maxN 40 | 41 | % create matrices 42 | A = randn(n); 43 | B = randn(n); 44 | 45 | % GED two ways 46 | l1 = eig(A,B); 47 | l2 = eig(inv(B)*A); 48 | 49 | % sort the eigenvalues 50 | l1 = sort(l1); 51 | l2 = sort(l2); 52 | 53 | % store the differences 54 | avediffs(n) = mean(abs(l1-l2)); 55 | end 56 | 57 | figure(1), clf 58 | plot(avediffs,'s-') 59 | xlabel('Matrix size') 60 | ylabel('\Delta\lambda') 61 | 62 | %% Section 15.16, code block 15.8 63 | 64 | % create a diagonal matrix 65 | D = diag(1:5); 66 | 67 | % check out its eigendecomposition 68 | [V,L] = eig(D) 69 | 70 | %% Section 15.16, code block 15.10 71 | 72 | % create the Hankel matrix 73 | N = 50; 74 | T = toeplitz(1:N); 75 | H = hankel(1:N,[N 1:N-1]); 76 | 77 | % diagonalize 78 | [V,D] = eig(H); 79 | [~,sidx] = sort(diag(D),'descend'); 80 | V = V(:,sidx); 81 | 82 | 83 | % visualize 84 | figure(2), clf 85 | 86 | % the matrix 87 | subplot(221) 88 | imagesc(H) 89 | axis square 90 | 91 | % all eigenvectors 92 | subplot(222) 93 | imagesc(V) 94 | axis square 95 | 96 | % a few evecs 97 | subplot(212) 98 | plot(V(:,1:4),'o-') 99 | 100 | %% done. 101 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter16.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Singular value decomposition (chapter 16) 7 | % 8 | %% 9 | 10 | %% Section 16.3, code block 16.2 11 | 12 | % a fun matrix 13 | A = [1 1 0; 0 1 1 ] ; 14 | 15 | % and its glorious SVD 16 | [U,S,V] = svd(A); 17 | 18 | %% Section 16.10, code block 16.4 19 | 20 | % matrix 21 | A = randn(5,5); 22 | 23 | % "my" condition number 24 | s = svd(A); 25 | condnum = max(s) / min(s); 26 | 27 | % MATLAB's condition number 28 | condnumM = cond(A); 29 | 30 | % comparison 31 | disp([ condnum,condnumM ]) 32 | 33 | %% Section 16.14, code block 16.6 34 | 35 | % the matrix 36 | m = 6; 37 | n = 3; 38 | A = randn(m,n); 39 | 40 | % the SVD's 41 | [Uf,Sf,Vf] = svd(A); % f for full 42 | [Ue,Se,Ve] = svd(A,'econ'); % e for econ 43 | 44 | % check out their sizes 45 | whos A U* S* V* 46 | 47 | %% Section 16.14, code block 16.8 48 | 49 | % matrix 50 | A = randn(4,5); 51 | 52 | % get V 53 | [V,L2] = eig(A'*A); 54 | 55 | % sort by descending eigenvalues 56 | [L2,idx] = sort(diag(L2),'d'); 57 | V = V(:,idx); 58 | 59 | % same for U 60 | [U,L2] = eig(A*A'); 61 | [L2,idx] = sort(diag(L2),'d'); 62 | U = U(:,idx); % sort by descending L 63 | 64 | 65 | % create Sigma 66 | S = zeros(size(A)); 67 | for i=1:length(L2) 68 | S(i,i) = sqrt(L2(i)); 69 | end 70 | 71 | % check against MATLAB's SVD function 72 | [U2,S2,V2] = svd(A); 73 | 74 | %% Section 16.14, code block 16.10 75 | 76 | % the matrix and its decomp 77 | A = randn(5,3); 78 | [U,S,V] = svd(A); 79 | 80 | % loop over layers 81 | figure(1), clf 82 | for i=1:3 83 | subplot(2,4,i) 84 | 85 | % create a layer 86 | onelayer = U(:,i)*S(i,i)*V(:,i)'; 87 | imagesc(onelayer) 88 | title(sprintf('Layer %g',i)) 89 | 90 | % low-rank approx up to this layer 91 | subplot(2,4,i+4) 92 | lowrank = U(:,1:i)*S(1:i,1:i)*V(:,1:i)'; 93 | imagesc(lowrank) 94 | title(sprintf('Layers 1:%g',i)) 95 | end 96 | 97 | % the original (full-rank) image 98 | subplot(248) 99 | imagesc(A),title('Original A') 100 | 101 | %% Section 16.14, code block 16.12 102 | 103 | % matrix sizes 104 | m = 6; 105 | n = 16; 106 | 107 | % desired condition number 108 | condnum = 42; 109 | 110 | % create U and V from random numbers, orthogonalized 111 | [U,r] = qr( randn(m) ); 112 | [V,r] = qr( randn(n) ); 113 | 114 | % create singular values vector 115 | s = linspace(condnum,1,min(m,n)); 116 | S = zeros(m,n); 117 | for i=1:min(m,n) 118 | S(i,i) = s(i); 119 | end 120 | 121 | % construct matrix 122 | A = U*S*V'; 123 | 124 | % confirm! 125 | cond(A) 126 | 127 | %% Section 16.14, code block 16.14 128 | 129 | % get pic and convert to double 130 | pic = imread('https://upload.wikimedia.org/wikipedia/en/8/86/Einstein_tongue.jpg'); 131 | pic = double(pic); 132 | 133 | % SVD 134 | [U,S,V] = svd( pic ); 135 | 136 | % components to keep 137 | comps = 1:20; 138 | 139 | % low-rank approximation 140 | lowrank = U(:,comps) * S(comps,comps)*V(:,comps)'; 141 | 142 | 143 | % show the original and low-rank 144 | figure(2), clf 145 | subplot(121) 146 | imagesc(pic), axis image 147 | title('Original') 148 | 149 | subplot(122) 150 | imagesc(lowrank), axis image 151 | title(sprintf('Comps. %g-%g',comps(1),comps(end))) 152 | colormap gray 153 | 154 | %% Section 16.14, code block 16.16 155 | 156 | % convert to percent explained 157 | s = 100*diag(S)./sum(S(:)); 158 | 159 | figure(3), clf 160 | plot(s,'s-'), xlim([0 100]) 161 | xlabel('Component number') 162 | ylabel('Pct variance explains') 163 | 164 | 165 | % threshold in percent 166 | thresh = 4; 167 | 168 | % comps greater than X% 169 | comps = s>thresh; 170 | lowrank = U(:,comps) * S(comps,comps)*V(:,comps)'; 171 | 172 | % show the original and low-rank 173 | figure(4) 174 | subplot(121) 175 | imagesc(pic), axis image 176 | title('Original') 177 | 178 | subplot(122) 179 | imagesc(lowrank), axis image 180 | title(sprintf('%g comps with > %g%%',sum(comps),thresh)) 181 | colormap gray 182 | 183 | %% Section 16.14, code block 16.18 184 | 185 | % initialize 186 | RMS = zeros(length(s),1); 187 | 188 | 189 | for si=1:length(s) 190 | % compute low-rank approx 191 | lowrank=U(:,1:si)*S(1:si,1:si)*V(:,1:si)'; 192 | 193 | % difference image 194 | diffimg = lowrank - pic; 195 | 196 | % RMS 197 | RMS(si) = sqrt(mean(diffimg(:).^2)); 198 | end 199 | 200 | figure(5), clf 201 | plot(RMS,'s-') 202 | xlabel('Rank approximation') 203 | ylabel('Error (a.u.)') 204 | 205 | %% Section 16.14, code block 16.20 206 | 207 | % some tall matrix 208 | X = randi([1 6],[4 2]); 209 | 210 | % eq. 29 211 | [U,S,V] = svd(X); 212 | 213 | % eq. 30 214 | longV1 = inv((U*S*V')'*U*S*V')*(U*S*V')'; 215 | 216 | % eq. 31 217 | longV2 = inv(V*S'*U'*U*S*V')*(U*S*V')'; 218 | 219 | % eq. 32 220 | longV3 = inv(V*S'*S*V') * (U*S*V')'; 221 | 222 | % eq. 33 223 | longV4 = V*(S'*S)^(-1)*V'*V*S'*U'; 224 | 225 | % eq. 34 226 | MPpinv = pinv(X); 227 | 228 | 229 | % compare any of them to the pinv, e.g., 230 | MPpinv - longV3 231 | 232 | %% Section 16.14, code block 16.22 233 | 234 | k = 5; 235 | n = 13; 236 | a = pinv(ones(n,1)*k); 237 | a - 1/(k*n) % check for zeros 238 | 239 | %% Section 16.14, code block 16.24 240 | 241 | % parameters 242 | M = 10; % matrix size 243 | nIters = 100; % number of iterations 244 | condnums = linspace(10,1e10,30); 245 | 246 | % initialize the average eigval differences 247 | avediffs = zeros(nIters,length(condnums)); 248 | 249 | 250 | % loop over experiment iterations 251 | for iteri=1:nIters 252 | 253 | % condition numbers 254 | for condi=1:length(condnums) 255 | 256 | % create A 257 | [U,~] = qr( randn(M) ); 258 | [V,~] = qr( randn(M) ); 259 | S = diag( linspace(condnums(condi),1,M) ); 260 | A = U*S*V'; % construct matrix 261 | 262 | 263 | % create B 264 | [U,~] = qr( randn(M) ); 265 | [V,~] = qr( randn(M) ); 266 | S = diag( linspace(condnums(condi),1,M) ); 267 | B = U*S*V'; % construct matrix 268 | 269 | 270 | % eigenvalues 271 | l1 = eig(A,B); 272 | l2 = eig(inv(B)*A); 273 | 274 | % and sort 275 | l1 = sort(l1); 276 | l2 = sort(l2); 277 | 278 | % store the differences 279 | avediffs(iteri,condi) = mean(abs(l1-l2)); 280 | end 281 | end 282 | 283 | % plot 284 | figure(6), clf 285 | plot(condnums,nanmean(avediffs),'s-') 286 | xlabel('Condition number') 287 | ylabel('\Delta\lambda') 288 | 289 | %% done. 290 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter17.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Quadratic form and definiteness (chapter 17) 7 | % 8 | %% 9 | 10 | %% Section 17.1, code block 17.2 11 | 12 | % create matrix and vector 13 | m = 4; 14 | A = randn(m); 15 | v = randn(1,m); 16 | 17 | % the quadratic form 18 | v*A*v' 19 | 20 | 21 | %% Section 17.9, code block 17.4 22 | 23 | A = [1 2; 2 3]; % matrix 24 | vi = -2:.1:2; % vector elements 25 | quadform = zeros(length(vi)); 26 | 27 | for i=1:length(vi) 28 | for j=1:length(vi) 29 | v = [vi(i) vi(j)]'; % vector 30 | quadform(i,j) = v'*A*v/(v'*v); 31 | end 32 | end 33 | 34 | figure(1), clf 35 | surf(vi,vi,quadform') 36 | xlabel('v_1'), ylabel('v_2') 37 | zlabel('$\zeta$','Interpreter','latex') 38 | 39 | %% Section 17.9, code block 17.6 40 | 41 | n = 4; 42 | nIterations = 500; 43 | defcat = zeros(nIterations,1); 44 | 45 | for iteri=1:nIterations 46 | 47 | % create the matrix 48 | A = randi([-10 10],n); 49 | ev = eig(A); % ev = EigenValues 50 | while ~isreal(ev) 51 | A = randi([-10 10],n); 52 | ev = eig(A); 53 | end 54 | 55 | % "zero" threshold (from rank) 56 | t = n * eps(max(svd(A))); 57 | 58 | % test definiteness 59 | if all(sign(ev)==1) 60 | defcat(iteri) = 1; % pos. def 61 | elseif all(sign(ev)>-1) && sum(abs(ev)0 62 | defcat(iteri) = 2; % pos. semidef 63 | elseif all(sign(ev)<1) && sum(abs(ev)0 64 | defcat(iteri) = 4; % neg. semidef 65 | elseif all(sign(ev)==-1) 66 | defcat(iteri) = 5; % neg. def 67 | else 68 | defcat(iteri) = 3; % indefinite 69 | end 70 | end 71 | 72 | % print out summary 73 | for i=1:5 74 | fprintf('cat %g: %g\n',i,sum(defcat==i)) 75 | end 76 | 77 | 78 | %% done. 79 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter18.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Covariance matrices (chapter 18) 7 | % 8 | %% 9 | 10 | %% Section 18.8, code block 18.2 11 | 12 | % create the "data" 13 | n = 200; 14 | X = randn(n,4); 15 | 16 | % mean-center 17 | X = X-mean(X,1); 18 | 19 | % covariance 20 | covM = X'*X / (n-1); 21 | 22 | % stdevs 23 | stdM = inv( diag(std(X)) ); 24 | 25 | % correlation matrix 26 | corM = stdM* X'*X *stdM / (n-1); 27 | 28 | % compare covariances 29 | disp(covM-cov(X)) 30 | 31 | % compare corrs 32 | disp(corM-corrcoef(X)) 33 | 34 | %% done. 35 | -------------------------------------------------------------------------------- /matlab/LAbookX_chapter19.m: -------------------------------------------------------------------------------- 1 | %% 2 | % BOOK: Linear Algebra: Theory, Intuition, Code 3 | % AUTHOR: Mike X Cohen 4 | % WEBSITE: sincxpress.com 5 | % 6 | % CHAPTER: Principal components analysis (chapter 19) 7 | % 8 | %% 9 | 10 | %% Section 19.7, code block 19.2 11 | 12 | % create data 13 | N = 1000; 14 | h = linspace(150,190,N) + randn(1,N)*5; 15 | w = h*.7 - 50 + randn(1,N)*10; 16 | 17 | % covariance 18 | X = [h' w']; 19 | X = X-mean(X,1); 20 | C = X'*X / (length(h)-1); 21 | 22 | % PCA and sort results 23 | [V,D] = eig(C); 24 | [eigvals,i] = sort(diag(D),'descend'); 25 | V = V(:,i); 26 | eigvals = 100*eigvals/sum(eigvals); 27 | scores = X*V; % not used but useful code 28 | 29 | % plot data with PCs 30 | figure(1), clf, hold on 31 | plot(X(:,1),X(:,2),'ro') 32 | plot([0 V(1,1)]*45,[0 V(2,1)]*45,'k','linew',2) 33 | plot([0 V(1,2)]*25,[0 V(2,2)]*25,'k','linew',2) 34 | xlabel('Height (cm)'), ylabel('Weight (kg)') 35 | axis([-1 1 -1 1]*50), axis square 36 | 37 | %% Section 19.7, code block 19.4 38 | 39 | % mean-center 40 | X = X-mean(X,1); 41 | 42 | % SVD 43 | [U,S,Vv] = svd(X); % Vv == V 44 | 45 | % scores 46 | scores = X*Vv; 47 | 48 | % normalized svals 49 | s = diag(S).^2 / (length(X)-1); 50 | s = 100*s/sum(s); % s == eigvals 51 | 52 | %% done. 53 | -------------------------------------------------------------------------------- /matlab/widget_data.txt: -------------------------------------------------------------------------------- 1 | 10,32.614,10 2 | 15,34.89,14 3 | 17,34.652,20 4 | 15,27.755,17 5 | 13,40.604,14 6 | 10,43.29,10 7 | 15,35.673,17 8 | 13,37.358,11 9 | 13,30.958,18 10 | 13,32.542,13 11 | 12,34.376,19 12 | 14,37.618,17 13 | 14,32.704,14 14 | 14,33.209,13 15 | 12,31.672,11 16 | 20,25.297,23 17 | 12,37.014,16 18 | 17,31.698,17 19 | 14,31.792,10 20 | 18,25.8,22 21 | 15,30.976,13 22 | 10,45.895,10 23 | 15,27.105,17 24 | 15,44.487,11 25 | 14,35.699,13 26 | 13,27.158,16 27 | 13,43.88,10 28 | 14,34.248,14 29 | 19,28.787,24 30 | 11,37.937,8 31 | 15,31.133,14 32 | 15,25.287,19 33 | 10,35.529,9 34 | 13,30.551,11 35 | 12,42.503,14 36 | 17,24.957,19 37 | 15,30.916,21 38 | 13,31.413,9 39 | 10,42.537,11 40 | 19,35.357,22 41 | 19,26.688,23 42 | 13,38.877,9 43 | 14,34.836,14 44 | 13,35.518,13 45 | 11,34.2,14 46 | 8,40.129,10 47 | 17,35.312,25 48 | 15,33.218,9 49 | 12,32.44,12 50 | 16,32.258,18 51 | 16,41.34,22 52 | 14,31.535,19 53 | 16,30.875,18 54 | 13,48.637,12 55 | 14,37.19,20 56 | 20,30.738,19 57 | 13,42.287,13 58 | 12,35.133,20 59 | 11,39.433,11 60 | 13,37.594,8 61 | 16,39.072,15 62 | 18,28.002,23 63 | 15,35.003,14 64 | 12,39.771,16 65 | 14,36.925,19 66 | 16,41.279,11 67 | 15,29.914,20 68 | 13,39.509,9 69 | 16,34.7,16 70 | 11,37.914,13 71 | 16,34.304,14 72 | 11,44.052,9 73 | 18,30.577,27 74 | 10,33.671,14 75 | 16,30.829,18 76 | 14,34.663,20 77 | 16,33.093,19 78 | 11,35.881,17 79 | 17,38.191,21 80 | 18,33.245,19 81 | 10,44.542,9 82 | 16,29.269,19 83 | 16,40.853,18 84 | 12,31.954,16 85 | 12,35.033,16 86 | 14,36.373,18 87 | 16,39.378,18 88 | 13,41.223,15 89 | 15,31.206,21 90 | 14,32.686,14 91 | 19,38.516,19 92 | 12,32.72,12 93 | 19,26.076,17 94 | 13,36.93,14 95 | 14,30.251,22 96 | 17,26.012,18 97 | 15,38.591,17 98 | 17,33.137,22 99 | 11,41.7,16 100 | 12,33.59,7 101 | 14,38.047,8 102 | 14,36.328,15 103 | 14,33.259,16 104 | 11,34.218,17 105 | 16,29.622,22 106 | 10,37.306,14 107 | 17,35.907,19 108 | 15,31.25,16 109 | 11,39.165,9 110 | 14,35.775,13 111 | 16,19.226,23 112 | 14,30.529,13 113 | 14,32.485,14 114 | 15,33.604,10 115 | 16,39.014,16 116 | 13,38.707,15 117 | 16,31.988,17 118 | 13,35.472,12 119 | 14,40.554,15 120 | 12,37.003,12 121 | 21,33.324,23 122 | 14,38.382,13 123 | 12,35.82,14 124 | 9,35.989,10 125 | 17,33.907,18 126 | 12,45.984,10 127 | 15,29.047,19 128 | 17,21.527,22 129 | 14,34.929,15 130 | 11,31.871,20 131 | 11,31.535,12 132 | 15,35.766,17 133 | 17,32.918,20 134 | 10,38.58,14 135 | 16,23.347,18 136 | 16,39.872,22 137 | 14,30.098,17 138 | 12,33.978,13 139 | 16,28.972,18 140 | 15,27.777,17 141 | 15,38.492,20 142 | 17,34.852,25 143 | 13,28.923,12 144 | 14,34.332,20 145 | 15,42.117,14 146 | 11,33.136,12 147 | 13,28.239,9 148 | 12,40.578,14 149 | 15,32.283,16 150 | 12,36.686,19 151 | 11,36.533,14 152 | 18,34.495,18 153 | 12,39.123,9 154 | 14,30.148,14 155 | 16,32.225,17 156 | 13,42.907,18 157 | 14,32.239,17 158 | 13,30.98,13 159 | 17,32.393,25 160 | 14,29.035,19 161 | 13,32.871,15 162 | 16,30.091,18 163 | 14,38.929,18 164 | 11,36.232,18 165 | 14,42.772,19 166 | 15,36.305,25 167 | 11,31.195,13 168 | 12,29.139,14 169 | 18,37.345,20 170 | 15,30.345,12 171 | 18,28.317,16 172 | 14,33.719,15 173 | 18,32.81,20 174 | 15,27.173,18 175 | 16,38.68,12 176 | 15,37.195,18 177 | 15,35.954,17 178 | 13,31.428,17 179 | 13,37.881,16 180 | 11,43.972,8 181 | 14,35.139,14 182 | 16,35.54,25 183 | 16,42.278,12 184 | 16,30.453,19 185 | 10,39.972,7 186 | 13,40.549,10 187 | 13,32.584,18 188 | 15,36.211,18 189 | 14,35.401,11 190 | 9,32.978,14 191 | 14,27.06,18 192 | 14,37.044,11 193 | 17,33.539,17 194 | 15,38.509,18 195 | 16,32.743,21 196 | 11,39.714,8 197 | 16,29.098,21 198 | 13,33.911,15 199 | 13,35.509,22 200 | 9,33.791,7 201 | 13,38.544,10 202 | 13,32.626,17 203 | 15,37.028,19 204 | 11,40.773,9 205 | 16,31.125,15 206 | 16,37.108,15 207 | 15,37.649,17 208 | 14,36.202,13 209 | 16,26.759,19 210 | 11,46.02,12 211 | 10,33.508,22 212 | 12,32.21,13 213 | 13,38.052,17 214 | 15,34.808,18 215 | 15,35.66,20 216 | 14,34.058,18 217 | 12,33.406,12 218 | 14,34.496,15 219 | 14,44.099,17 220 | 10,36.011,13 221 | 14,34.692,18 222 | 17,30.07,18 223 | 12,32.567,13 224 | 14,29.945,18 225 | 12,36.308,19 226 | 10,39.851,11 227 | 17,35.886,14 228 | 12,36.851,11 229 | 13,31.18,14 230 | 11,44.411,8 231 | 10,32.478,8 232 | 14,33.589,16 233 | 16,34.817,15 234 | 15,35.832,13 235 | 12,37.285,13 236 | 12,36.097,18 237 | 14,41.558,15 238 | 13,29.273,11 239 | 13,36.635,16 240 | 8,34.379,10 241 | 12,36.193,13 242 | 14,38.392,14 243 | 16,41.915,14 244 | 15,30.497,19 245 | 14,40.797,11 246 | 15,40.616,21 247 | 13,40.205,14 248 | 17,38.673,14 249 | 11,37.146,11 250 | 16,28.44,21 251 | 11,40.02,15 252 | 12,34.419,13 253 | 14,37.351,13 254 | 15,28.81,15 255 | 16,33.302,17 256 | 14,37.188,23 257 | 16,32.005,20 258 | 16,41.715,16 259 | 15,29.732,16 260 | 10,37.746,16 261 | 16,36.274,20 262 | 17,29.231,14 263 | 11,25.041,14 264 | 13,28.947,14 265 | 17,32.014,17 266 | 17,29.255,15 267 | 16,32.276,15 268 | 15,40.543,16 269 | 15,31.56,18 270 | 15,37.3,12 271 | 16,30.654,20 272 | 15,31.397,16 273 | 13,31.868,13 274 | 18,26.486,23 275 | 14,43.102,17 276 | 13,41.671,13 277 | 14,36.033,19 278 | 7,47.328,3 279 | 16,32.166,21 280 | 14,33.483,20 281 | 17,28.952,16 282 | 13,41.24,15 283 | 14,30.397,12 284 | 17,31.399,23 285 | 15,39.291,14 286 | 14,40.117,20 287 | 12,39.64,10 288 | 16,36.479,18 289 | 9,40.454,14 290 | 11,39.125,10 291 | 16,31.864,13 292 | 12,42.244,13 293 | 13,33.554,12 294 | 14,38.342,21 295 | 12,32.913,12 296 | 14,32.717,13 297 | 10,44.005,11 298 | 14,20.855,22 299 | 12,35.666,13 300 | 12,35.501,15 301 | 15,30.073,19 302 | 15,39.068,17 303 | 12,35.658,16 304 | 14,33.751,11 305 | 17,31.077,14 306 | 11,37.786,11 307 | 12,34.233,10 308 | 13,40.43,7 309 | 11,37.07,15 310 | 16,32.678,22 311 | 12,40.378,17 312 | 19,29.148,25 313 | 13,32.138,15 314 | 12,35.695,11 315 | 14,36.257,21 316 | 14,30.204,19 317 | 14,34.086,10 318 | 15,29.447,18 319 | 14,31.944,14 320 | 12,36.724,16 321 | 14,29.013,17 322 | 13,41.946,10 323 | 14,25.741,12 324 | 12,38.733,12 325 | 8,37.4,7 326 | 16,45.843,10 327 | 14,32.674,19 328 | 14,29.35,22 329 | 17,30.381,19 330 | 17,35.847,17 331 | 12,38.482,14 332 | 14,31.19,17 333 | 13,39.08,18 334 | 11,41.545,8 335 | 10,41.799,14 336 | 16,36.746,16 337 | 17,36.597,21 338 | 16,33.453,19 339 | 15,38.728,19 340 | 10,33.93,15 341 | 12,38.953,11 342 | 11,34.686,12 343 | 13,45.435,12 344 | 14,26.74,20 345 | 13,35.367,18 346 | 12,39.068,15 347 | 16,29.395,17 348 | 13,26.796,17 349 | 17,31.254,17 350 | 16,34.722,15 351 | 9,43.034,16 352 | 19,37.948,24 353 | 14,32.698,18 354 | 11,40.941,13 355 | 11,38.734,9 356 | 18,32.006,24 357 | 16,31.022,16 358 | 15,23.565,17 359 | 12,39.669,15 360 | 13,35.348,17 361 | 13,37.852,8 362 | 14,37.129,19 363 | 12,38.141,18 364 | 16,32.709,18 365 | 10,33.106,10 366 | 14,37.545,20 367 | 14,34.963,24 368 | 16,32.016,20 369 | 10,39.235,18 370 | 13,35.482,11 371 | 14,34.12,14 372 | 15,35.301,18 373 | 19,29.845,23 374 | 16,31.282,16 375 | 13,36.663,14 376 | 13,35.583,17 377 | 16,42.912,18 378 | 11,33.138,14 379 | 15,31.29,23 380 | 14,36.472,12 381 | 10,38.42,5 382 | 17,42.656,16 383 | 15,34.758,19 384 | 13,35.849,11 385 | 12,39.157,17 386 | 17,35.64,19 387 | 17,32.395,18 388 | 12,39.721,14 389 | 11,34.384,11 390 | 13,34.354,19 391 | 13,40.568,17 392 | 13,37.581,17 393 | 17,35.994,18 394 | 12,41.366,14 395 | 11,33.123,15 396 | 12,40.856,12 397 | 12,38.19,20 398 | 12,40.882,16 399 | 18,32.101,14 400 | 18,29.193,21 401 | 17,28.144,14 402 | 10,37.813,13 403 | 15,32.748,19 404 | 14,40.337,16 405 | 12,38.149,16 406 | 15,30.002,15 407 | 13,31.197,18 408 | 17,27.601,17 409 | 15,32.723,20 410 | 13,34.046,15 411 | 16,31.915,14 412 | 14,28.454,24 413 | 18,32.233,23 414 | 14,36.616,18 415 | 16,33.913,14 416 | 16,32.508,14 417 | 10,43.938,14 418 | 12,33.534,22 419 | 11,34.728,17 420 | 13,35.944,17 421 | 12,28.402,12 422 | 14,37.438,21 423 | 11,30.319,5 424 | 15,35.225,22 425 | 9,37.656,7 426 | 11,33.8,13 427 | 17,27.801,20 428 | 13,36.039,16 429 | 10,37.967,7 430 | 15,39.653,17 431 | 17,32.321,19 432 | 14,34.644,10 433 | 11,34.795,8 434 | 10,33.263,13 435 | 18,23.175,20 436 | 12,36.078,12 437 | 14,45.229,13 438 | 15,30.725,20 439 | 17,26.127,24 440 | 12,33.41,13 441 | 15,29.064,18 442 | 15,35.08,15 443 | 16,43.117,19 444 | 9,45.473,11 445 | 16,31.954,18 446 | 14,24.659,24 447 | 13,39.382,19 448 | 10,45.948,8 449 | 15,41.663,13 450 | 14,47.091,12 451 | 12,42.585,13 452 | 14,31.647,14 453 | 15,33.501,17 454 | 14,23.808,19 455 | 15,34.034,15 456 | 14,42.493,12 457 | 15,42.94,10 458 | 14,34.284,17 459 | 14,39.048,19 460 | 10,25.928,17 461 | 13,31.645,17 462 | 16,30.897,16 463 | 18,36.648,17 464 | 13,38.786,18 465 | 17,33.184,18 466 | 14,34.326,14 467 | 11,44.476,8 468 | 9,35.814,7 469 | 10,45.816,8 470 | 12,40.835,15 471 | 13,42.48,10 472 | 14,38.73,16 473 | 20,32.222,21 474 | 14,44.165,15 475 | 13,35.693,15 476 | 15,37.836,14 477 | 14,30.474,18 478 | 16,32.985,16 479 | 10,37.023,14 480 | 13,31.653,17 481 | 16,37.091,25 482 | 8,35.593,8 483 | 15,38.727,21 484 | 12,41.143,17 485 | 14,31.838,14 486 | 14,41.738,12 487 | 11,39.206,12 488 | 14,24.419,17 489 | 12,30.924,17 490 | 16,36.228,17 491 | 13,40.285,16 492 | 18,35.541,22 493 | 14,30.633,16 494 | 16,24.297,20 495 | 14,32.321,26 496 | 15,29.611,20 497 | 15,32.705,17 498 | 15,33.939,16 499 | 17,31.87,17 500 | 12,29.025,13 501 | 13,31.584,13 502 | 10,33.117,13 503 | 13,35.818,18 504 | 10,27.113,22 505 | 14,27.676,19 506 | 13,41.98,15 507 | 9,40.385,8 508 | 13,34.637,11 509 | 13,32.246,14 510 | 15,32.979,18 511 | 16,32.484,15 512 | 18,28.994,22 513 | 15,35.482,19 514 | 14,43.034,16 515 | 14,32.155,22 516 | 14,44.299,18 517 | 12,39.622,19 518 | 19,35.344,22 519 | 15,35.447,17 520 | 12,31.499,18 521 | 13,41.429,13 522 | 13,33.938,13 523 | 13,36.854,16 524 | 12,40.046,13 525 | 14,33.779,22 526 | 12,39.745,13 527 | 13,38.186,10 528 | 11,36.475,16 529 | 16,28.578,14 530 | 19,33.73,22 531 | 17,37.52,16 532 | 12,30.557,11 533 | 15,24.452,23 534 | 15,33.663,20 535 | 13,38.955,11 536 | 16,33.059,18 537 | 13,35.82,11 538 | 14,26.735,17 539 | 16,25.429,17 540 | 13,42.192,16 541 | 13,36.721,18 542 | 16,32.912,20 543 | 13,35.887,15 544 | 15,32.735,16 545 | 11,27.634,23 546 | 14,38.158,15 547 | 13,36.338,17 548 | 12,45.87,13 549 | 15,28.964,15 550 | 14,31.292,20 551 | 12,39.212,15 552 | 14,39.463,16 553 | 15,33.524,18 554 | 17,37.206,17 555 | 17,38.931,20 556 | 15,37.992,11 557 | 11,33.487,13 558 | 13,36.174,10 559 | 13,42.809,16 560 | 18,25.836,19 561 | 11,40.889,6 562 | 15,37.909,21 563 | 15,30.887,17 564 | 15,33.002,16 565 | 14,32.1,17 566 | 15,38.509,20 567 | 15,31.31,15 568 | 16,32.465,20 569 | 17,40.866,13 570 | 12,43.661,14 571 | 10,38.237,13 572 | 14,33.04,13 573 | 13,42.823,14 574 | 12,48.123,15 575 | 17,31.695,19 576 | 18,27.586,19 577 | 13,26.993,21 578 | 16,33.663,20 579 | 13,42.785,13 580 | 13,46.442,6 581 | 15,35.315,16 582 | 16,35.426,15 583 | 17,24.487,21 584 | 12,45.607,14 585 | 17,27.114,16 586 | 14,41.224,14 587 | 9,39.841,14 588 | 11,43.737,9 589 | 13,36.841,18 590 | 19,34.456,27 591 | 12,36.788,13 592 | 15,33.326,11 593 | 14,41.672,15 594 | 14,32.711,21 595 | 13,41.765,13 596 | 15,34.845,24 597 | 13,34.702,19 598 | 9,40.931,16 599 | 14,27.308,16 600 | 12,34.174,19 601 | 15,32.119,22 602 | 10,39.221,12 603 | 12,36.264,14 604 | 15,35.246,17 605 | 16,26.017,21 606 | 11,39.035,18 607 | 14,33.512,19 608 | 12,41.992,11 609 | 8,22.369,12 610 | 14,31.504,14 611 | 13,43.294,16 612 | 14,36.325,15 613 | 11,43.86,15 614 | 16,40.824,20 615 | 14,36.239,16 616 | 11,35.085,9 617 | 13,31.988,17 618 | 15,27.276,13 619 | 12,31.738,10 620 | 15,35.04,18 621 | 15,30.755,24 622 | 17,28.203,22 623 | 14,31.196,22 624 | 12,34.39,13 625 | 13,43.032,14 626 | 14,35.592,11 627 | 15,44.29,17 628 | 20,22.957,17 629 | 10,43.002,10 630 | 13,36.26,17 631 | 13,38.576,14 632 | 14,30.417,15 633 | 15,25.387,21 634 | 12,29.998,15 635 | 16,37.83,21 636 | 9,39.551,9 637 | 12,37.79,10 638 | 20,31.258,24 639 | 16,35.378,17 640 | 15,27.353,18 641 | 15,30.93,23 642 | 18,24.247,22 643 | 14,35.061,11 644 | 15,32.265,18 645 | 18,34.05,11 646 | 15,33.358,18 647 | 11,32.219,10 648 | 15,33.251,11 649 | 17,34.728,15 650 | 13,37.345,11 651 | 16,34.018,24 652 | 15,29.032,23 653 | 10,34.242,16 654 | 13,36.703,13 655 | 12,29.322,21 656 | 12,27.408,15 657 | 12,37.047,9 658 | 8,36.607,8 659 | 13,32.728,20 660 | 12,39.521,11 661 | 13,36.991,14 662 | 16,29.896,14 663 | 13,40.536,8 664 | 16,28.86,21 665 | 13,35.137,14 666 | 13,37.885,15 667 | 17,33.819,20 668 | 17,33.923,19 669 | 13,39.091,11 670 | 14,34.551,19 671 | 10,45.033,9 672 | 12,35.147,15 673 | 14,30.917,16 674 | 11,31.057,17 675 | 13,40.201,12 676 | 13,31.352,18 677 | 13,32.757,16 678 | 13,40.592,17 679 | 13,32.248,15 680 | 11,36.939,15 681 | 14,37.631,13 682 | 15,35.521,16 683 | 15,34.614,15 684 | 12,37.315,12 685 | 14,37.418,13 686 | 12,36.735,12 687 | 14,45.234,17 688 | 14,29.639,19 689 | 12,27.652,20 690 | 16,37.296,16 691 | 14,46.263,9 692 | 17,32.095,15 693 | 16,28.982,21 694 | 14,30.895,18 695 | 14,34.802,21 696 | 13,36.777,15 697 | 14,31.581,22 698 | 15,25.971,20 699 | 11,43.472,16 700 | 11,33.505,17 701 | 15,33.669,13 702 | 12,44.392,13 703 | 15,40.306,23 704 | 16,31.113,16 705 | 12,28.198,12 706 | 9,43.609,12 707 | 12,36.229,14 708 | 14,29.828,16 709 | 14,39.436,17 710 | 11,30.319,18 711 | 13,46.915,16 712 | 13,41.175,21 713 | 17,31.977,21 714 | 12,38.415,12 715 | 16,32.272,16 716 | 11,39.426,13 717 | 14,31.726,18 718 | 14,33.507,17 719 | 16,38.062,13 720 | 17,36.348,20 721 | 15,40.043,12 722 | 14,35.533,12 723 | 13,37.582,14 724 | 17,22.571,22 725 | 15,26.386,19 726 | 15,34.583,20 727 | 12,35.467,8 728 | 11,31.172,17 729 | 19,32.471,15 730 | 14,34.559,19 731 | 12,38.955,13 732 | 15,37.323,14 733 | 15,38.194,20 734 | 11,35.237,11 735 | 12,29.726,15 736 | 15,35.535,13 737 | 10,45.53,8 738 | 13,34.568,17 739 | 15,25.246,21 740 | 13,43.109,14 741 | 15,32.851,15 742 | 16,34.037,15 743 | 11,33.991,14 744 | 14,37.182,12 745 | 17,28.268,18 746 | 11,36.233,15 747 | 9,39.884,11 748 | 13,34.909,16 749 | 17,38.199,15 750 | 13,32.254,9 751 | 15,33.102,15 752 | 10,22.401,15 753 | 14,32.184,15 754 | 16,35.133,16 755 | 16,30.109,21 756 | 14,37.242,18 757 | 12,31.984,16 758 | 13,44.962,17 759 | 13,36.282,17 760 | 14,29.523,16 761 | 17,30.663,21 762 | 16,36.81,21 763 | 15,27.265,20 764 | 12,31.269,12 765 | 13,37.261,16 766 | 15,41.283,14 767 | 15,33.62,21 768 | 11,33.339,13 769 | 13,34.679,14 770 | 11,44.79,13 771 | 17,30.947,19 772 | 13,42.982,9 773 | 14,29.397,22 774 | 13,24.552,17 775 | 12,34.867,14 776 | 11,38.705,12 777 | 16,35.771,18 778 | 16,38.591,12 779 | 19,29.961,26 780 | 13,34.258,18 781 | 10,41.734,9 782 | 14,33.626,17 783 | 17,32.872,18 784 | 15,33.118,16 785 | 17,31.193,21 786 | 17,31.537,18 787 | 12,40.591,13 788 | 13,36.559,14 789 | 13,31.53,19 790 | 15,29.285,15 791 | 16,32.305,22 792 | 18,29.603,20 793 | 15,42.758,17 794 | 15,37.068,19 795 | 14,27.375,18 796 | 16,28.291,19 797 | 12,32.552,15 798 | 12,32.229,12 799 | 14,36.176,16 800 | 10,34.8,12 801 | 22,27.091,30 802 | 10,40.37,9 803 | 17,31.161,15 804 | 14,32.821,15 805 | 14,31.416,19 806 | 17,36.024,19 807 | 13,31.518,18 808 | 18,32.064,23 809 | 12,34.023,15 810 | 11,33.287,10 811 | 12,37.972,16 812 | 13,34.344,17 813 | 15,34.834,19 814 | 10,34.678,15 815 | 9,39.235,11 816 | 14,33.299,16 817 | 11,35.3,14 818 | 15,27.363,23 819 | 17,27.412,26 820 | 13,32.814,19 821 | 13,32.201,12 822 | 9,35.904,15 823 | 11,46.426,13 824 | 12,39.932,10 825 | 13,36.322,10 826 | 15,37.269,13 827 | 16,36.229,14 828 | 11,36.292,14 829 | 15,36.725,17 830 | 14,23.735,15 831 | 15,31.964,18 832 | 15,42.541,14 833 | 15,35.504,19 834 | 15,31.342,19 835 | 15,30.561,19 836 | 14,41.377,9 837 | 17,38.05,19 838 | 9,34.712,14 839 | 11,39.118,17 840 | 14,38.016,15 841 | 13,38.395,16 842 | 12,30.54,18 843 | 12,36.219,7 844 | 13,39.698,6 845 | 15,39.867,18 846 | 14,33.527,14 847 | 13,36.014,13 848 | 13,33.131,13 849 | 14,29.452,16 850 | 14,31.062,19 851 | 13,43.491,18 852 | 20,28.541,20 853 | 11,36.837,17 854 | 14,29.34,22 855 | 12,38.489,17 856 | 13,43.547,14 857 | 13,33.566,15 858 | 13,33.951,9 859 | 12,42.205,13 860 | 12,41.816,12 861 | 15,34.329,11 862 | 14,36.305,15 863 | 12,40.69,18 864 | 11,32.557,18 865 | 16,37.92,21 866 | 15,34.234,11 867 | 14,37.532,13 868 | 14,33.927,14 869 | 14,36.693,16 870 | 19,27.083,21 871 | 16,40.759,21 872 | 14,38.777,14 873 | 11,33.28,13 874 | 13,38.24,17 875 | 12,33.412,16 876 | 18,25.868,18 877 | 11,33.773,16 878 | 13,33.55,21 879 | 11,40.016,12 880 | 15,36.15,18 881 | 13,46.021,13 882 | 12,31.382,19 883 | 15,35.991,15 884 | 14,36.445,13 885 | 13,40.274,16 886 | 15,22.513,17 887 | 16,36.048,15 888 | 16,27.741,18 889 | 15,40.342,19 890 | 15,41.902,13 891 | 16,37.221,19 892 | 12,40.066,12 893 | 13,28.916,12 894 | 12,39.357,12 895 | 13,31.065,11 896 | 15,31.639,17 897 | 15,31.312,18 898 | 14,30.579,20 899 | 15,40.629,20 900 | 17,26.819,20 901 | 15,28.156,15 902 | 15,33.472,12 903 | 15,31.72,14 904 | 17,33.263,26 905 | 13,33.673,25 906 | 13,32.834,20 907 | 11,44.923,17 908 | 11,30.008,17 909 | 12,38.902,13 910 | 12,29.831,13 911 | 14,22.646,22 912 | 14,31.458,12 913 | 17,31.215,17 914 | 9,37.26,11 915 | 10,34.205,17 916 | 12,34.675,15 917 | 13,35.153,15 918 | 16,30.122,16 919 | 15,36.057,16 920 | 17,33.232,19 921 | 16,33.237,16 922 | 14,33.256,15 923 | 13,36.008,16 924 | 14,41.26,17 925 | 12,36.685,11 926 | 12,38.724,11 927 | 15,32.304,20 928 | 13,33.048,14 929 | 13,39.621,15 930 | 6,48.604,16 931 | 14,39.359,18 932 | 17,29.992,18 933 | 15,34.38,17 934 | 13,30.63,19 935 | 13,33.85,16 936 | 15,32.256,22 937 | 14,29.603,17 938 | 14,36.998,14 939 | 16,26.652,22 940 | 16,33.102,18 941 | 16,25.595,20 942 | 12,37.103,17 943 | 13,40.862,14 944 | 15,39.432,15 945 | 8,44.297,7 946 | 10,37.98,13 947 | 15,29.259,23 948 | 17,41.304,20 949 | 10,43.361,18 950 | 14,36.74,14 951 | 14,32.101,24 952 | 12,31.793,9 953 | 11,41.282,12 954 | 15,24.954,15 955 | 14,29.994,20 956 | 14,26.264,18 957 | 10,37.582,8 958 | 21,27.545,18 959 | 18,31.677,22 960 | 14,36.464,13 961 | 12,45.472,8 962 | 13,35.617,13 963 | 14,38.562,10 964 | 13,40.047,13 965 | 16,31.892,12 966 | 12,39.726,11 967 | 17,31.82,19 968 | 19,27.103,26 969 | 15,34.635,15 970 | 17,35.662,20 971 | 15,24.268,17 972 | 11,46.949,14 973 | 12,33.926,18 974 | 16,34.36,16 975 | 13,34.763,18 976 | 14,30.588,15 977 | 16,35.483,15 978 | 15,33.622,20 979 | 14,34.433,21 980 | 12,33.689,18 981 | 13,41.028,14 982 | 12,32.584,13 983 | 13,33.291,14 984 | 13,35.857,17 985 | 13,35.648,13 986 | 11,32.798,20 987 | 10,29.26,10 988 | 16,30.299,22 989 | 16,23.047,18 990 | 10,45.962,14 991 | 13,27.477,8 992 | 14,33.15,15 993 | 16,35.937,15 994 | 15,30.695,15 995 | 16,41.187,10 996 | 14,37.124,16 997 | 14,25.962,19 998 | 17,33.047,25 999 | 9,39.386,12 1000 | 13,34.73,16 1001 | -------------------------------------------------------------------------------- /python/LAbookX_chapter02.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Vectors (chapter 2)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "import matplotlib.pyplot as plt" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "### Section 2.1, code block 2.1" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "# creating scalars (numeric variables)\n", 39 | "aScalar = 4" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "### Section 2.2, code block 2.3" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# make the vector\n", 56 | "v = np.array([2,-1])\n", 57 | "\n", 58 | "# plot it\n", 59 | "plt.plot([0,v[0]],[0,v[1]])\n", 60 | "plt.axis('square')\n", 61 | "plt.axis([-3,3,-3,3])\n", 62 | "plt.grid('on')\n", 63 | "plt.show()" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "### Section 2.2, code block 2.5" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "# list\n", 80 | "v1 = [2,5,4,7] \n", 81 | "\n", 82 | "# array, no orientation\n", 83 | "v2 = np.array([2,5,4,7])\n", 84 | "\n", 85 | "# col. vector\n", 86 | "v3 = np.array([ [2],[5],[4],[7] ])\n", 87 | "\n", 88 | "# row vector\n", 89 | "v4 = np.array([ [2,5,4,7] ]) " 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": {}, 95 | "source": [ 96 | "### Section 2.3, code block 2.7" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "metadata": {}, 103 | "outputs": [], 104 | "source": [ 105 | "# row vector\n", 106 | "v1 = np.array([ [2,5,4,7] ]) \n", 107 | "\n", 108 | "# column vector\n", 109 | "v2 = v1.T " 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "### Section 2.5, code block 2.9" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "# two vectors\n", 126 | "v1 = np.array([2,5,4,7])\n", 127 | "v2 = np.array([4,1,0,2])\n", 128 | "\n", 129 | "# scalar-multiply and add\n", 130 | "v3 = 4*v1 - 2*v2" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "### Section 2.9, code block 2.11" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "# vector\n", 147 | "v = np.array([1,2])\n", 148 | "\n", 149 | "# plot it\n", 150 | "plt.plot([0,v[0]],[0,v[1]])\n", 151 | "\n", 152 | "# and then plot scaled versions on top\n", 153 | "for i in range(10):\n", 154 | " # random scalar\n", 155 | " s = np.random.randn()\n", 156 | " # scaled vector\n", 157 | " sv = s*v\n", 158 | " plt.plot([0,sv[0]],[0,sv[1]])\n", 159 | " \n", 160 | " \n", 161 | "plt.grid('on')\n", 162 | "plt.axis('square')\n", 163 | "plt.axis([-4,4,-4,4])\n", 164 | "plt.show()" 165 | ] 166 | } 167 | ], 168 | "metadata": { 169 | "kernelspec": { 170 | "display_name": "Python 3", 171 | "language": "python", 172 | "name": "python3" 173 | }, 174 | "language_info": { 175 | "codemirror_mode": { 176 | "name": "ipython", 177 | "version": 3 178 | }, 179 | "file_extension": ".py", 180 | "mimetype": "text/x-python", 181 | "name": "python", 182 | "nbconvert_exporter": "python", 183 | "pygments_lexer": "ipython3", 184 | "version": "3.7.4" 185 | } 186 | }, 187 | "nbformat": 4, 188 | "nbformat_minor": 2 189 | } 190 | -------------------------------------------------------------------------------- /python/LAbookX_chapter03.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Vector multiplications (chapter 3)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "### Section 3.1, code block 3.1" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "# two vectors\n", 38 | "v1 = np.array([2,5,4,7])\n", 39 | "v2 = np.array([4,1,0,2])\n", 40 | "\n", 41 | "# dot product between them\n", 42 | "dp = np.dot(v1,v2)" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "### Section 3.5, code block 3.3" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "# scalars\n", 59 | "l1 = 1\n", 60 | "l2 = 2\n", 61 | "l3 = -3\n", 62 | "\n", 63 | "# vectors\n", 64 | "v1 = np.array([4,5,1])\n", 65 | "v2 = np.array([-4,0,-4])\n", 66 | "v3 = np.array([1,3,2])\n", 67 | "\n", 68 | "# linear weighted combinations\n", 69 | "l1*v1 + l2*v2 + l3*v3" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "### Section 3.6, code block 3.5" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "# two vectors\n", 86 | "v1 = np.array([2,5,4,7])\n", 87 | "v2 = np.array([4,1,0,2])\n", 88 | "\n", 89 | "# outer product\n", 90 | "op = np.outer(v1,v2)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "### Section 3.7, code block 3.7" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": null, 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "# two vectors\n", 107 | "v1 = np.array([2,5,4,7])\n", 108 | "v2 = np.array([4,1,0,2])\n", 109 | "\n", 110 | "# Hadamard\n", 111 | "v3 = v1 * v2" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "### Section 3.9, code block 3.9" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": {}, 125 | "outputs": [], 126 | "source": [ 127 | "# a friendly vector\n", 128 | "v = np.array([2,5,4,7])\n", 129 | "\n", 130 | "# its norm\n", 131 | "vMag = np.linalg.norm(v)\n", 132 | "\n", 133 | "# the unit vector\n", 134 | "v_unit = v / vMag" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "### Section 3.13, code block 3.11" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "# some vectors\n", 151 | "v1 = np.array([1,2,3,4,5])\n", 152 | "v2 = np.array([2,3,4,5,6])\n", 153 | "v3 = np.array([3,4,5,6,7])\n", 154 | "\n", 155 | "# the weightings\n", 156 | "w = [-1,3,-2]\n", 157 | "\n", 158 | "# their weighted combo\n", 159 | "result = v1*w[0] + v2*w[1] + v3*w[2]" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "### Section 3.13, code block 3.13" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "# a vector (technically, type list)\n", 176 | "v = [ 7, 4, -5, 8, 3 ]\n", 177 | "\n", 178 | "# the ones vector\n", 179 | "o = np.ones(len(v))\n", 180 | "\n", 181 | "# average via dot product\n", 182 | "ave = np.dot(v,o) / len(v)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": {}, 188 | "source": [ 189 | "### Section 3.13, code block 3.15" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": null, 195 | "metadata": {}, 196 | "outputs": [], 197 | "source": [ 198 | "# list\n", 199 | "v = [ 7, 4, -5, 8, 3 ]\n", 200 | "\n", 201 | "# random weightings\n", 202 | "w = np.random.rand(len(v))\n", 203 | "\n", 204 | "# weighted dot product\n", 205 | "wAve = np.dot(v, w/sum(w))" 206 | ] 207 | } 208 | ], 209 | "metadata": { 210 | "kernelspec": { 211 | "display_name": "Python 3", 212 | "language": "python", 213 | "name": "python3" 214 | }, 215 | "language_info": { 216 | "codemirror_mode": { 217 | "name": "ipython", 218 | "version": 3 219 | }, 220 | "file_extension": ".py", 221 | "mimetype": "text/x-python", 222 | "name": "python", 223 | "nbconvert_exporter": "python", 224 | "pygments_lexer": "ipython3", 225 | "version": "3.7.4" 226 | } 227 | }, 228 | "nbformat": 4, 229 | "nbformat_minor": 2 230 | } 231 | -------------------------------------------------------------------------------- /python/LAbookX_chapter05.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Matrices (chapter 5)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "from scipy.linalg import hankel,toeplitz" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "### Section 5.4, code block 5.1" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "# a matrix\n", 39 | "A = np.random.randn(2,5)\n", 40 | "\n", 41 | "# two ways to transpose\n", 42 | "At1 = A.T\n", 43 | "At2 = np.transpose(A)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "### Section 5.5, code block 5.3" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "# identity matrix\n", 60 | "I = np.eye(4)\n", 61 | "\n", 62 | "# ones matrix\n", 63 | "O = np.ones(4)\n", 64 | "\n", 65 | "# zeros matrix (note the tuple input)\n", 66 | "Z = np.zeros((4,4))" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "### Section 5.5, code block 5.5" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "# diagonal matrix\n", 83 | "D = np.diag([1,2,3,5]) \n", 84 | "\n", 85 | "# diagonal elements\n", 86 | "R = np.random.randn(3,4)\n", 87 | "d = np.diag(R) " 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "### Section 5.5, code block 5.7" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "# two matrices\n", 104 | "A = np.random.randn(3,5)\n", 105 | "B = np.random.randn(3,4)\n", 106 | "\n", 107 | "# augmenting\n", 108 | "AB = np.concatenate((A,B),axis=1)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "### Section 5.5, code block 5.9" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": {}, 122 | "outputs": [], 123 | "source": [ 124 | "# matrix\n", 125 | "A = np.random.randn(5,5)\n", 126 | "\n", 127 | "# extract the lower triangle\n", 128 | "L = np.tril(A)\n", 129 | "\n", 130 | "# extract the upper triangle\n", 131 | "U = np.triu(A)" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "### Section 5.5, code block 5.11" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "# the vector\n", 148 | "t = [1,2,3,4]\n", 149 | "\n", 150 | "# the matrices (functions imported from scipy at top of script)\n", 151 | "T = toeplitz(t)\n", 152 | "H = hankel(t,r=[2,3,4,1])" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "### Section 5.8, code block 5.13" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [ 168 | "# lambda\n", 169 | "l = .01\n", 170 | "\n", 171 | "# I\n", 172 | "I = np.eye(4)\n", 173 | "\n", 174 | "# the shifted matrix\n", 175 | "A = np.random.randn(4,4)\n", 176 | "As = A + l*I" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "### Section 5.9, code block 5.15" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": {}, 190 | "outputs": [], 191 | "source": [ 192 | "A = np.random.randn(4,4)\n", 193 | "tr = np.trace(A)" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "### Section 5.13, code block 5.17" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": null, 206 | "metadata": {}, 207 | "outputs": [], 208 | "source": [ 209 | "# two matrices\n", 210 | "A = np.random.randn(4,2)\n", 211 | "B = np.random.randn(4,2)\n", 212 | "\n", 213 | "# initialize the output\n", 214 | "C = np.zeros((2,2))\n", 215 | "\n", 216 | "# loop over columns and compute dot products\n", 217 | "for coli in range(2):\n", 218 | " for colj in range(2):\n", 219 | " C[coli,colj] = np.dot(A[:,coli],B[:,colj])" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": {}, 225 | "source": [ 226 | "### Section 5.13, code block 5.19" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": null, 232 | "metadata": {}, 233 | "outputs": [], 234 | "source": [ 235 | "# a full matrix\n", 236 | "A = np.random.randn(4,4)\n", 237 | "\n", 238 | "# get its lower triangle\n", 239 | "Al = np.tril(A)\n", 240 | "\n", 241 | "# add it to its transpose\n", 242 | "S = Al + Al.T" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "### Section 5.13, code block 5.21" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": null, 255 | "metadata": {}, 256 | "outputs": [], 257 | "source": [ 258 | "# initialize\n", 259 | "D = np.zeros((4,8))\n", 260 | "\n", 261 | "# loop over smaller dimension\n", 262 | "for d in range(min(D.shape)):\n", 263 | " D[d,d] = d+1" 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": null, 269 | "metadata": {}, 270 | "outputs": [], 271 | "source": [] 272 | } 273 | ], 274 | "metadata": { 275 | "kernelspec": { 276 | "display_name": "Python 3", 277 | "language": "python", 278 | "name": "python3" 279 | }, 280 | "language_info": { 281 | "codemirror_mode": { 282 | "name": "ipython", 283 | "version": 3 284 | }, 285 | "file_extension": ".py", 286 | "mimetype": "text/x-python", 287 | "name": "python", 288 | "nbconvert_exporter": "python", 289 | "pygments_lexer": "ipython3", 290 | "version": "3.7.4" 291 | } 292 | }, 293 | "nbformat": 4, 294 | "nbformat_minor": 2 295 | } 296 | -------------------------------------------------------------------------------- /python/LAbookX_chapter06.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Matrix multiplications (chapter 6)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "### Section 6.1, code block 6.1" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "# two matrices\n", 38 | "M1 = np.random.randn(4,3)\n", 39 | "M2 = np.random.randn(3,5)\n", 40 | "\n", 41 | "# and their product\n", 42 | "C = M1 @ M2" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "### Section 6.2, code block 6.3" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "A = np.random.randn(2,2)\n", 59 | "B = np.random.randn(2,2)\n", 60 | "\n", 61 | "# notice that C1 != C2\n", 62 | "C1 = A@B\n", 63 | "C2 = B@A" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "### Section 6.8, code block 6.5" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "M1 = np.random.randn(4,3)\n", 80 | "M2 = np.random.randn(4,3)\n", 81 | "C = M1 * M2 # note the * instead of @" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "### Section 6.9, code block 6.7" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "A = np.array([ [1,2,3],[4,5,6] ])\n", 98 | "A.flatten(order='F')" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "### Section 6.9, code block 6.9" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "A = np.random.randn(4,3)\n", 115 | "B = np.random.randn(4,3)\n", 116 | "\n", 117 | "# the transpose-trace trick for the frobenius dot product\n", 118 | "f = np.trace(A.T@B)" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "### Section 6.10, code block 6.11" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "A = np.random.randn(4,3)\n", 135 | "np.linalg.norm(A,'fro')" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "### Section 6.15, code block 6.13" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [ 151 | "# two matrices\n", 152 | "A = np.random.randn(2,4)\n", 153 | "B = np.random.randn(4,3)\n", 154 | "\n", 155 | "# initialize product\n", 156 | "C1 = np.zeros((2,3))\n", 157 | "\n", 158 | "# sum over columns\n", 159 | "for i in range(4):\n", 160 | " C1 += np.outer(A[:,i],B[i,:])\n", 161 | "\n", 162 | "# show equality\n", 163 | "C1 - A@B " 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "### Section 6.15, code block 6.15" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": null, 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "# a diagonal matrix and a full one\n", 180 | "D = np.diag(np.arange(1,5))\n", 181 | "A = np.random.randn(4,4)\n", 182 | "\n", 183 | "# two kinds of products\n", 184 | "C1 = D*A\n", 185 | "C2 = D@A\n", 186 | "\n", 187 | "# are they the same?\n", 188 | "print(np.diag(C1))\n", 189 | "print(np.diag(C2))" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "### Section 6.15, code block 6.17" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": null, 202 | "metadata": {}, 203 | "outputs": [], 204 | "source": [ 205 | "# diagonal matrix\n", 206 | "A = np.diag(np.random.rand(3))\n", 207 | "\n", 208 | "# two symmetric matrices\n", 209 | "C1 = (A.T+A)/2\n", 210 | "C2 = A.T@A\n", 211 | "\n", 212 | "# are they the same?\n", 213 | "C1-np.sqrt(C2)" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "### Section 6.15, code block 6.19" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": null, 226 | "metadata": {}, 227 | "outputs": [], 228 | "source": [ 229 | "# a matrix and a vector (walk into a bar...)\n", 230 | "m = 5\n", 231 | "A = np.random.randn(m,m)\n", 232 | "v = np.random.randn(m)\n", 233 | "\n", 234 | "# the two sides of the equation\n", 235 | "LHS = np.linalg.norm(A@v)\n", 236 | "RHS = np.linalg.norm(A,ord='fro') * np.linalg.norm(v)\n", 237 | "\n", 238 | "# should always be positive\n", 239 | "RHS-LHS " 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": null, 245 | "metadata": {}, 246 | "outputs": [], 247 | "source": [] 248 | } 249 | ], 250 | "metadata": { 251 | "kernelspec": { 252 | "display_name": "Python 3", 253 | "language": "python", 254 | "name": "python3" 255 | }, 256 | "language_info": { 257 | "codemirror_mode": { 258 | "name": "ipython", 259 | "version": 3 260 | }, 261 | "file_extension": ".py", 262 | "mimetype": "text/x-python", 263 | "name": "python", 264 | "nbconvert_exporter": "python", 265 | "pygments_lexer": "ipython3", 266 | "version": "3.7.4" 267 | } 268 | }, 269 | "nbformat": 4, 270 | "nbformat_minor": 2 271 | } 272 | -------------------------------------------------------------------------------- /python/LAbookX_chapter07.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Rank (chapter 7)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "### Section 7.3, code block 7.1" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "A = np.random.randn(3,6)\n", 38 | "r = np.linalg.matrix_rank(A)" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "### Section 7.4, code block 7.3" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "# scalar and matrix\n", 55 | "s = np.random.randn()\n", 56 | "M = np.random.randn(3,5)\n", 57 | "\n", 58 | "# their ranks\n", 59 | "r1 = np.linalg.matrix_rank(M)\n", 60 | "r2 = np.linalg.matrix_rank(s*M)\n", 61 | "\n", 62 | "# same or different?\n", 63 | "print(r1,r2)" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "### Section 7.10, code block 7.5" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "# inspect the code for rank\n", 80 | "??np.linalg.matrix_rank" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "### Section 7.15, code block 7.7" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "# two random matrices\n", 97 | "A = np.random.randn(9,2)\n", 98 | "B = np.random.randn(2,16)\n", 99 | "\n", 100 | "# their product (assume max possible rank)\n", 101 | "C = A@B" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "### Section 7.15, code block 7.9" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "metadata": {}, 115 | "outputs": [], 116 | "source": [ 117 | "# zeros matrix\n", 118 | "Z = np.zeros((5,5))\n", 119 | "\n", 120 | "# tiny noise matrix\n", 121 | "N = np.random.randn(5,5)\n", 122 | "\n", 123 | "# add them\n", 124 | "ZN = Z + N*np.finfo(float).eps*1e-307\n", 125 | "\n", 126 | "# print the results\n", 127 | "print(np.linalg.matrix_rank(Z))\n", 128 | "print(np.linalg.matrix_rank(ZN))\n", 129 | "print(np.linalg.norm(ZN,'fro'))" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": null, 135 | "metadata": {}, 136 | "outputs": [], 137 | "source": [] 138 | } 139 | ], 140 | "metadata": { 141 | "kernelspec": { 142 | "display_name": "Python 3", 143 | "language": "python", 144 | "name": "python3" 145 | }, 146 | "language_info": { 147 | "codemirror_mode": { 148 | "name": "ipython", 149 | "version": 3 150 | }, 151 | "file_extension": ".py", 152 | "mimetype": "text/x-python", 153 | "name": "python", 154 | "nbconvert_exporter": "python", 155 | "pygments_lexer": "ipython3", 156 | "version": "3.7.4" 157 | } 158 | }, 159 | "nbformat": 4, 160 | "nbformat_minor": 2 161 | } 162 | -------------------------------------------------------------------------------- /python/LAbookX_chapter08.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Matrix spaces (chapter 8)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "from scipy.linalg import null_space" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "### Section 8.7, code block 8.1" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "A = np.random.randn(3,4)\n", 39 | "\n", 40 | "# the null space\n", 41 | "null_space(A)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "### Section 8.15, code block 8.3" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "# reduced-rank matrices\n", 58 | "A = np.random.randn(4,3)@np.random.randn(3,4)\n", 59 | "B = np.random.randn(4,3)@np.random.randn(3,4)\n", 60 | "\n", 61 | "# null space of A\n", 62 | "n = null_space(A)\n", 63 | "\n", 64 | "# zeros vector\n", 65 | "print(B@A@n) \n", 66 | "\n", 67 | "# not zeros vector\n", 68 | "print(A@B@n) " 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "### Section 8.15, code block 8.5" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "# a reduced-rank matrix\n", 85 | "A = np.random.randn(16,9) @ np.random.randn(9,11)\n", 86 | "\n", 87 | "# null spaces\n", 88 | "rn = null_space(A)\n", 89 | "ln = null_space(A.T)\n", 90 | "r = np.linalg.matrix_rank(A)\n", 91 | "\n", 92 | "# dimensionalities\n", 93 | "print(rn.shape[1]+r)\n", 94 | "print(ln.shape[1]+r)" 95 | ] 96 | } 97 | ], 98 | "metadata": { 99 | "kernelspec": { 100 | "display_name": "Python 3", 101 | "language": "python", 102 | "name": "python3" 103 | }, 104 | "language_info": { 105 | "codemirror_mode": { 106 | "name": "ipython", 107 | "version": 3 108 | }, 109 | "file_extension": ".py", 110 | "mimetype": "text/x-python", 111 | "name": "python", 112 | "nbconvert_exporter": "python", 113 | "pygments_lexer": "ipython3", 114 | "version": "3.7.4" 115 | } 116 | }, 117 | "nbformat": 4, 118 | "nbformat_minor": 2 119 | } 120 | -------------------------------------------------------------------------------- /python/LAbookX_chapter09.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Complex numbers (chapter 9)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "### Section 9.2, code block 9.1" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "# one way to create a complex number\n", 38 | "z = np.complex(3,4)\n", 39 | "\n", 40 | "# note the datatype input\n", 41 | "Z = np.zeros(2,dtype=complex)\n", 42 | "Z[0] = 3+4j" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "### Section 9.3, code block 9.3" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "# real numbers for the matrix\n", 59 | "r = np.random.randint(-3,4,size=3) # real part\n", 60 | "i = np.random.randint(-3,4,size=3) # imag part\n", 61 | "\n", 62 | "# create a complex matrix\n", 63 | "Z = r + i*1j\n", 64 | "\n", 65 | "# print the matrix and its transpose\n", 66 | "print(Z)\n", 67 | "print(Z.conj())" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "### Section 9.5, code block 9.5" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "v = [0,1j]\n", 84 | "\n", 85 | "# \"normal\" and hermitian dot product\n", 86 | "print(np.dot(v,v))\n", 87 | "print(np.vdot(v,v))" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "### Section 9.10, code block 9.7" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "U = .5*np.array([ [1+1j,1-1j],[1-1j,1+1j] ])\n", 104 | "\n", 105 | "# Hermitian\n", 106 | "print(U@np.matrix(U).H) \n", 107 | "\n", 108 | "# not Hermitian\n", 109 | "U@U.T" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "### Section 9.10, code block 9.9" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "# create a complex matrix\n", 126 | "r = np.random.randn(3,3)\n", 127 | "i = np.random.randn(3,3)\n", 128 | "A = np.matrix( r + i*1j )\n", 129 | "\n", 130 | "# new matrices by adding and multiplying\n", 131 | "A1 = A+A.H\n", 132 | "A2 = A@A.H\n", 133 | "\n", 134 | "# test for Hermitian\n", 135 | "print(A1-A1.H)\n", 136 | "print(A2-A2.H)" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [] 145 | } 146 | ], 147 | "metadata": { 148 | "kernelspec": { 149 | "display_name": "Python 3", 150 | "language": "python", 151 | "name": "python3" 152 | }, 153 | "language_info": { 154 | "codemirror_mode": { 155 | "name": "ipython", 156 | "version": 3 157 | }, 158 | "file_extension": ".py", 159 | "mimetype": "text/x-python", 160 | "name": "python", 161 | "nbconvert_exporter": "python", 162 | "pygments_lexer": "ipython3", 163 | "version": "3.7.4" 164 | } 165 | }, 166 | "nbformat": 4, 167 | "nbformat_minor": 2 168 | } 169 | -------------------------------------------------------------------------------- /python/LAbookX_chapter10.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Systems of equations (chapter 10)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "from scipy.linalg import lu\n", 23 | "import sympy as sym" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Section 10.3, code block 10.1" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "# create a matrix\n", 40 | "A = np.random.randn(4,3)\n", 41 | "\n", 42 | "# take its LU decomposition\n", 43 | "P,L,U = lu(A)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "### Section 10.5, code block 10.3" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "A = np.random.randn(2,4)\n", 60 | "\n", 61 | "# transform to sympy matrix for RREF\n", 62 | "sym.Matrix(A).rref()" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "### Section 10.12, code block 10.5" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "# matrix\n", 79 | "A = np.array([[2,0,-3],[3,1,4],[1,0,-1]])\n", 80 | "\n", 81 | "# constants\n", 82 | "x = [2,3,4]\n", 83 | "\n", 84 | "# solution\n", 85 | "b = A@x" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "### Section 10.12, code block 10.7" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "# one example...\n", 102 | "A = np.random.randn(3,6)\n", 103 | "sym.Matrix(A).rref()[0]" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [] 112 | } 113 | ], 114 | "metadata": { 115 | "kernelspec": { 116 | "display_name": "Python 3", 117 | "language": "python", 118 | "name": "python3" 119 | }, 120 | "language_info": { 121 | "codemirror_mode": { 122 | "name": "ipython", 123 | "version": 3 124 | }, 125 | "file_extension": ".py", 126 | "mimetype": "text/x-python", 127 | "name": "python", 128 | "nbconvert_exporter": "python", 129 | "pygments_lexer": "ipython3", 130 | "version": "3.7.4" 131 | } 132 | }, 133 | "nbformat": 4, 134 | "nbformat_minor": 2 135 | } 136 | -------------------------------------------------------------------------------- /python/LAbookX_chapter11.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Determinant (chapter 11)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "import matplotlib.pyplot as plt" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "### Section 11.6, code block 11.1" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "A = np.random.randn(3,3)\n", 39 | "np.linalg.det(A)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "### Section 11.6, code block 11.3" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# random matrix and vector\n", 56 | "A = np.random.randint(0,11,(4,4))\n", 57 | "b = np.random.randint(-10,1)\n", 58 | "\n", 59 | "# show their equivalence\n", 60 | "print(np.linalg.det(b*A),b**4*np.linalg.det(A))" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "### Section 11.6, code block 11.5" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "# matrix sizes\n", 77 | "ns = np.arange(3,31)\n", 78 | "\n", 79 | "# iteration\n", 80 | "iters = 100\n", 81 | "\n", 82 | "# initialize\n", 83 | "dets = np.zeros((len(ns),iters))\n", 84 | "\n", 85 | "# loop over matrix sizes\n", 86 | "for ni in range(len(ns)):\n", 87 | " for i in range(iters):\n", 88 | " \n", 89 | " # step 1\n", 90 | " A = np.random.randn(ns[ni],ns[ni])\n", 91 | " \n", 92 | " # step 2\n", 93 | " A[:,0] = A[:,1]\n", 94 | " \n", 95 | " # step 3\n", 96 | " dets[ni,i]=np.abs(np.linalg.det(A))\n", 97 | " \n", 98 | "\n", 99 | "# plotting\n", 100 | "plt.plot(ns,np.log(np.mean(dets,axis=1)))\n", 101 | "plt.xlabel('Matrix size')\n", 102 | "plt.ylabel('Log determinant')\n", 103 | "plt.show()" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [] 112 | } 113 | ], 114 | "metadata": { 115 | "kernelspec": { 116 | "display_name": "Python 3", 117 | "language": "python", 118 | "name": "python3" 119 | }, 120 | "language_info": { 121 | "codemirror_mode": { 122 | "name": "ipython", 123 | "version": 3 124 | }, 125 | "file_extension": ".py", 126 | "mimetype": "text/x-python", 127 | "name": "python", 128 | "nbconvert_exporter": "python", 129 | "pygments_lexer": "ipython3", 130 | "version": "3.7.4" 131 | } 132 | }, 133 | "nbformat": 4, 134 | "nbformat_minor": 2 135 | } 136 | -------------------------------------------------------------------------------- /python/LAbookX_chapter12.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Matrix inverse (chapter 12)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "import sympy as sym\n", 23 | "import matplotlib.pyplot as plt" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Section 12.4, code block 12.1" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "# random invertible matrix\n", 40 | "A = np.random.randn(3,3)\n", 41 | "\n", 42 | "# its inverse\n", 43 | "Ai = np.linalg.inv(A)\n", 44 | "\n", 45 | "# should be identity\n", 46 | "A@Ai" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### Section 12.5, code block 12.3" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "# matrix\n", 63 | "A = np.random.randn(3,3)\n", 64 | "\n", 65 | "# concatenated by identity\n", 66 | "Acat = np.concatenate((A,np.eye(3,3)),axis=1)\n", 67 | "\n", 68 | "# RREF (via sympy)\n", 69 | "Ar = sym.Matrix(Acat).rref()[0] # RREF\n", 70 | "\n", 71 | "# keep inverse\n", 72 | "Ar = Ar[:,3:]\n", 73 | "\n", 74 | "# numpy's inv\n", 75 | "Ai = np.linalg.inv(A)\n", 76 | "\n", 77 | "# compare\n", 78 | "Ar-Ai\n" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "### Section 12.7, code block 12.5" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "# tall matrix\n", 95 | "A = np.random.randn(5,3)\n", 96 | "\n", 97 | "# left inverse\n", 98 | "Al = np.linalg.inv(A.T@A)@A.T\n", 99 | "\n", 100 | "# check for I\n", 101 | "Al@A" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "### Section 12.8, code block 12.7" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "metadata": {}, 115 | "outputs": [], 116 | "source": [ 117 | "# reduced-rank matrix\n", 118 | "A = np.random.randn(3,3)\n", 119 | "A[1,:] = A[0,:]\n", 120 | "\n", 121 | "# pseudoinverse\n", 122 | "Api = np.linalg.pinv(A)\n", 123 | "\n", 124 | "# identity matrix?\n", 125 | "Api@A" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "### Section 12.12, code block 12.9" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "\n", 142 | "# create matrix\n", 143 | "m = 4\n", 144 | "A = np.random.randn(m,m)\n", 145 | "\n", 146 | "# initialize\n", 147 | "M = np.zeros((m,m))\n", 148 | "G = np.zeros((m,m))\n", 149 | "\n", 150 | "# compute minors matrix\n", 151 | "for i in range(m):\n", 152 | " for j in range(m):\n", 153 | " \n", 154 | " # select rows and cols\n", 155 | " rows = [True]*m\n", 156 | " rows[i] = False\n", 157 | " \n", 158 | " cols = [True]*m\n", 159 | " cols[j] = False\n", 160 | " \n", 161 | " M[i,j]=np.linalg.det(A[rows,:][:,cols])\n", 162 | " \n", 163 | " # compute G\n", 164 | " G[i,j] = (-1)**(i+j)\n", 165 | "\n", 166 | " \n", 167 | "# compute C\n", 168 | "C = M * G\n", 169 | "\n", 170 | "# compute A\n", 171 | "Ainv = C.T / np.linalg.det(A)\n", 172 | "\n", 173 | "# 'regular' inverse function\n", 174 | "AinvI = np.linalg.inv(A)\n", 175 | "\n", 176 | "# compare against inv()\n", 177 | "AinvI-Ainv " 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "### Section 12.12, code block 12.11" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [ 193 | "# square matrix\n", 194 | "A = np.random.randn(5,5)\n", 195 | "Ai = np.linalg.inv(A)\n", 196 | "Api = np.linalg.pinv(A)\n", 197 | "# test equivalence\n", 198 | "print(Ai - Api) \n", 199 | "\n", 200 | "\n", 201 | "\n", 202 | "# tall matrix\n", 203 | "T = np.random.randn(5,3)\n", 204 | "Tl = np.linalg.inv(T.T@T)@T.T # left inv\n", 205 | "Tpi = np.linalg.pinv(T) # pinv\n", 206 | "# test equivalence\n", 207 | "print(Tl - Tpi)" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": null, 213 | "metadata": {}, 214 | "outputs": [], 215 | "source": [] 216 | } 217 | ], 218 | "metadata": { 219 | "kernelspec": { 220 | "display_name": "Python 3", 221 | "language": "python", 222 | "name": "python3" 223 | }, 224 | "language_info": { 225 | "codemirror_mode": { 226 | "name": "ipython", 227 | "version": 3 228 | }, 229 | "file_extension": ".py", 230 | "mimetype": "text/x-python", 231 | "name": "python", 232 | "nbconvert_exporter": "python", 233 | "pygments_lexer": "ipython3", 234 | "version": "3.7.4" 235 | } 236 | }, 237 | "nbformat": 4, 238 | "nbformat_minor": 2 239 | } 240 | -------------------------------------------------------------------------------- /python/LAbookX_chapter13.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Projections and orthogonalization (chapter 13)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "### Section 13.2, code block 13.1" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "# matrix and vector\n", 38 | "A = [[1,2],[3,1],[1,1]]\n", 39 | "b = [5.5,-3.5,1.5]\n", 40 | "\n", 41 | "# least-squares solver\n", 42 | "np.linalg.lstsq(A,b)[0]\n" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "### Section 13.6, code block 13.3" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "A = np.random.randn(4,3)\n", 59 | "Q,R = np.linalg.qr(A) # add ,mode='complete' for full decomp." 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "### Section 13.11, code block 13.5" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "# create the matrix \n", 76 | "m = 4\n", 77 | "n = 4\n", 78 | "A = np.random.randn(m,n)\n", 79 | "\n", 80 | "# initialize\n", 81 | "Q = np.zeros((m,n))\n", 82 | "\n", 83 | "\n", 84 | "# the GS algo\n", 85 | "for i in range(n):\n", 86 | " \n", 87 | " # initialize\n", 88 | " Q[:,i] = A[:,i]\n", 89 | " \n", 90 | " # orthogonalize\n", 91 | " a = A[:,i] # convenience\n", 92 | " for j in range(i): # only to earlier cols\n", 93 | " q = Q[:,j] # convenience\n", 94 | " Q[:,i]=Q[:,i]-np.dot(a,q)/np.dot(q,q)*q\n", 95 | " \n", 96 | " # normalize\n", 97 | " Q[:,i] = Q[:,i] / np.linalg.norm(Q[:,i])\n", 98 | "\n", 99 | " \n", 100 | "# \"real\" QR decomposition for comparison\n", 101 | "Q2,R = np.linalg.qr(A)\n", 102 | "\n", 103 | "\n", 104 | "# note the possible sign differences.\n", 105 | "# seemingly non-zero columns will be 0 when adding\n", 106 | "Q-Q2" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [] 115 | } 116 | ], 117 | "metadata": { 118 | "kernelspec": { 119 | "display_name": "Python 3", 120 | "language": "python", 121 | "name": "python3" 122 | }, 123 | "language_info": { 124 | "codemirror_mode": { 125 | "name": "ipython", 126 | "version": 3 127 | }, 128 | "file_extension": ".py", 129 | "mimetype": "text/x-python", 130 | "name": "python", 131 | "nbconvert_exporter": "python", 132 | "pygments_lexer": "ipython3", 133 | "version": "3.7.4" 134 | } 135 | }, 136 | "nbformat": 4, 137 | "nbformat_minor": 2 138 | } 139 | -------------------------------------------------------------------------------- /python/LAbookX_chapter14.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Least squares (chapter 14)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "import matplotlib.pyplot as plt" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "### Section 14.10, code block 14.1" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "# load the data\n", 39 | "data = np.loadtxt(fname='widget_data.txt',delimiter=',')\n", 40 | "\n", 41 | "# design matrix\n", 42 | "X = np.concatenate((np.ones((1000,1)),data[:,:2]),axis=1)\n", 43 | "\n", 44 | "# outcome variable\n", 45 | "y = data[:,2]\n", 46 | "\n", 47 | "# beta coefficients\n", 48 | "beta = np.linalg.lstsq(X,y)[0]\n", 49 | "\n", 50 | "# scaled coefficients (intercept not scaled)\n", 51 | "betaScaled = beta/np.std(X,axis=0,ddof=1)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "### Section 14.10, code block 14.3" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "# setup the figure\n", 68 | "fig,ax = plt.subplots(1,2,figsize=(8,4))\n", 69 | "\n", 70 | "# plot widgets by time\n", 71 | "ax[0].plot(X[:,1],y,'o',markerfacecolor='k')\n", 72 | "ax[0].set_title('Time variable')\n", 73 | "ax[0].set_xlabel('Time of day')\n", 74 | "ax[0].set_ylabel('Widgets purchased')\n", 75 | "\n", 76 | "# plot widgets by age\n", 77 | "ax[1].plot(X[:,2],y,'o',markerfacecolor='k')\n", 78 | "ax[1].set_title('Age variable')\n", 79 | "ax[1].set_xlabel('Age')\n", 80 | "ax[1].set_ylabel('Widgets purchased')\n", 81 | "plt.show()" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "### Section 14.10, code block 14.5" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "# predicted data\n", 98 | "yHat = X@beta\n", 99 | "\n", 100 | "# r-squared\n", 101 | "r2 = 1 - np.sum((yHat-y)**2) / np.sum((y-np.mean(y))**2)\n", 102 | "r2" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [] 111 | } 112 | ], 113 | "metadata": { 114 | "kernelspec": { 115 | "display_name": "Python 3", 116 | "language": "python", 117 | "name": "python3" 118 | }, 119 | "language_info": { 120 | "codemirror_mode": { 121 | "name": "ipython", 122 | "version": 3 123 | }, 124 | "file_extension": ".py", 125 | "mimetype": "text/x-python", 126 | "name": "python", 127 | "nbconvert_exporter": "python", 128 | "pygments_lexer": "ipython3", 129 | "version": "3.7.4" 130 | } 131 | }, 132 | "nbformat": 4, 133 | "nbformat_minor": 2 134 | } 135 | -------------------------------------------------------------------------------- /python/LAbookX_chapter15.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Eigendecomposition (chapter 15)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "from scipy.linalg import eig,hankel\n", 23 | "import matplotlib.pyplot as plt" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Section 15.4, code block 15.1" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "# matrix\n", 40 | "A = np.array([[2,3],[3,2]])\n", 41 | "\n", 42 | "# eigendecomposition\n", 43 | "L,V = np.linalg.eig(A)\n", 44 | "\n", 45 | "# transform eigenvalues into diagonal matrix\n", 46 | "L = np.diag(L)" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### Section 15.12, code block 15.4" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "# create two random matrices\n", 63 | "n = 3\n", 64 | "A = np.random.randn(n,n)\n", 65 | "B = np.random.randn(n,n)\n", 66 | "\n", 67 | "# note that this is scipy's eig, not numpy's\n", 68 | "evals,evecs = eig(A,B)" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "### Section 15.16, code block 15.5" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "# initialize results vector\n", 85 | "avediffs = np.zeros(100)\n", 86 | "\n", 87 | "# loop over matrix sizes\n", 88 | "for n in range(1,101):\n", 89 | " \n", 90 | " # create matrices\n", 91 | " A = np.random.randn(n,n)\n", 92 | " B = np.random.randn(n,n)\n", 93 | " \n", 94 | " # GED\n", 95 | " l1 = eig(A,B)[0]\n", 96 | " l2 = eig(np.linalg.inv(B)@A)[0]\n", 97 | "\n", 98 | " # important to sort eigvals\n", 99 | " l1.sort()\n", 100 | " l2.sort()\n", 101 | " \n", 102 | " # their differences\n", 103 | " avediffs[n-1] = np.mean(np.abs(l1-l2))\n", 104 | " \n", 105 | " \n", 106 | "# visualize\n", 107 | "plt.plot(avediffs)\n", 108 | "plt.show()" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "### Section 15.16, code block 15.7" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": {}, 122 | "outputs": [], 123 | "source": [ 124 | "# diagonal matrix\n", 125 | "D = np.diag(range(1,6))\n", 126 | "\n", 127 | "# eigenstuff\n", 128 | "L,V = np.linalg.eig(D)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "### Section 15.16, code block 15.9" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [ 144 | "\n", 145 | "# create the hankel matrix\n", 146 | "t = np.arange(1,51)\n", 147 | "lstrow = np.append(t[-1],np.arange(1,t[-1]))\n", 148 | "H = hankel(t,r=lstrow)\n", 149 | "\n", 150 | "# eigendecomposition\n", 151 | "d,V = np.linalg.eig(H)\n", 152 | "V = V[:,np.argsort(d)[::-1]]\n", 153 | "\n", 154 | "\n", 155 | "# the matrix\n", 156 | "plt.subplot(221) \n", 157 | "plt.imshow(H)\n", 158 | "\n", 159 | "# the eigenvectors\n", 160 | "plt.subplot(222) \n", 161 | "plt.imshow(V)\n", 162 | "\n", 163 | "# some evecs\n", 164 | "plt.subplot(212) \n", 165 | "plt.plot(V[:,:4])\n", 166 | "\n", 167 | "plt.show()" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": null, 173 | "metadata": {}, 174 | "outputs": [], 175 | "source": [] 176 | } 177 | ], 178 | "metadata": { 179 | "kernelspec": { 180 | "display_name": "Python 3", 181 | "language": "python", 182 | "name": "python3" 183 | }, 184 | "language_info": { 185 | "codemirror_mode": { 186 | "name": "ipython", 187 | "version": 3 188 | }, 189 | "file_extension": ".py", 190 | "mimetype": "text/x-python", 191 | "name": "python", 192 | "nbconvert_exporter": "python", 193 | "pygments_lexer": "ipython3", 194 | "version": "3.7.4" 195 | } 196 | }, 197 | "nbformat": 4, 198 | "nbformat_minor": 2 199 | } 200 | -------------------------------------------------------------------------------- /python/LAbookX_chapter16.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Singular value decomposition (chapter 16)\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "import matplotlib.pyplot as plt\n", 23 | "from imageio import imread\n", 24 | "from scipy.linalg import eig" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "### Section 16.3, code block 16.1" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "# A matrix\n", 41 | "A = [[1,1,0],[0,1,1]]\n", 42 | "\n", 43 | "# its SVD\n", 44 | "U,s,V = np.linalg.svd(A)" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "### Section 16.10, code block 16.3" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "# a matrix\n", 61 | "A = np.random.randn(5,5)\n", 62 | "\n", 63 | "# its singular values\n", 64 | "s = np.linalg.svd(A)[1]\n", 65 | "\n", 66 | "# \"manual\" condition number\n", 67 | "condnum = np.max(s)/np.min(s)\n", 68 | "\n", 69 | "# compare above with numpy's cond()\n", 70 | "print(condnum,np.linalg.cond(A))" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "### Section 16.14, code block 16.5" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "# the matrix\n", 87 | "m = 6\n", 88 | "n = 3\n", 89 | "A = np.random.randn(m,n)\n", 90 | "\n", 91 | "# the two SVDs\n", 92 | "Uf,sf,Vf = np.linalg.svd(A)\n", 93 | "Ue,se,Ve = np.linalg.svd(A,full_matrices=False)\n", 94 | "\n", 95 | "# examine sizes of matrices from full SVD\n", 96 | "print(Uf.shape, sf.shape, Vf.shape)\n", 97 | "\n", 98 | "# and from economy\n", 99 | "print(Ue.shape, se.shape, Ve.shape)" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": {}, 105 | "source": [ 106 | "### Section 16.14, code block 16.7" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [ 115 | "# matrix\n", 116 | "A = np.random.randn(4,5)\n", 117 | "\n", 118 | "# get V\n", 119 | "L2,V = np.linalg.eig(A.T@A) \n", 120 | "# sort by descending eigenvalues\n", 121 | "V = V[:,np.argsort(L2)[::-1]]\n", 122 | "\n", 123 | "# get U\n", 124 | "L2,U = np.linalg.eig(A@A.T) \n", 125 | "# sort by descending eigenvalues\n", 126 | "U = U[:,np.argsort(L2)[::-1]]\n", 127 | "\n", 128 | "# create Sigma\n", 129 | "S = np.zeros(A.shape)\n", 130 | "for i,s in enumerate(np.sort(L2)[::-1]):\n", 131 | " S[i,i] = np.sqrt(s)\n", 132 | "\n", 133 | "# now get the SVD \n", 134 | "U2,S2,V2 = np.linalg.svd(A)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "### Section 16.14, code block 16.9" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "# setup the figure\n", 151 | "fig,ax = plt.subplots(2,4)\n", 152 | "\n", 153 | "# create the matrix and get its SVD\n", 154 | "A = np.random.randn(5,3)\n", 155 | "U,s,V = np.linalg.svd(A)\n", 156 | "S = np.diag(s) # need Sigma as matrix\n", 157 | "\n", 158 | "# loop over layers\n", 159 | "for i in range(3):\n", 160 | " \n", 161 | " # compute and show one layer\n", 162 | " onelayer = np.outer(U[:,i],V[i,:])*s[i]\n", 163 | " ax[0,i].imshow(onelayer)\n", 164 | " ax[0,i].set_title('Layer %g'%i)\n", 165 | " ax[0,i].axis('off')\n", 166 | " \n", 167 | " # compute the low-rank approximation up to this layer\n", 168 | " lowrank = U[:,:i+1]@S[:i+1,:i+1]@V[:i+1,:]\n", 169 | " ax[1,i].imshow(lowrank)\n", 170 | " ax[1,i].set_title('Layers 0:%g'%i)\n", 171 | " ax[1,i].axis('off')\n", 172 | " \n", 173 | "\n", 174 | "# finally, show the original matrix\n", 175 | "ax[1,3].imshow(A)\n", 176 | "ax[1,3].set_title('Orig. A')\n", 177 | "ax[1,3].axis('off')\n", 178 | "ax[0,3].axis('off')\n", 179 | "plt.show()" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "### Section 16.14, code block 16.11" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": null, 192 | "metadata": {}, 193 | "outputs": [], 194 | "source": [ 195 | "# matrix sizes\n", 196 | "m = 6\n", 197 | "n = 16\n", 198 | "\n", 199 | "# desired condition number\n", 200 | "condnum = 42\n", 201 | "\n", 202 | "# create U and V from random numbers\n", 203 | "U,r = np.linalg.qr( np.random.randn(m,m) )\n", 204 | "V,r = np.linalg.qr( np.random.randn(n,n) )\n", 205 | "\n", 206 | "# create singular values vector\n", 207 | "s = np.linspace(condnum,1,np.min((m,n)))\n", 208 | "S = np.zeros((m,n))\n", 209 | "for i in range(min((m,n))):\n", 210 | " S[i,i] = s[i]\n", 211 | "\n", 212 | "# construct matrix\n", 213 | "A = U@S@V.T \n", 214 | "\n", 215 | "# confirm!\n", 216 | "np.linalg.cond(A) " 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "### Section 16.14, code block 16.13" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": null, 229 | "metadata": {}, 230 | "outputs": [], 231 | "source": [ 232 | "# download picture and convert to float\n", 233 | "pic = imread('https://upload.wikimedia.org/wikipedia/en/8/86/Einstein_tongue.jpg')\n", 234 | "np.array(pic,dtype=float)\n", 235 | "\n", 236 | "# SVD and create sigma matrix\n", 237 | "U,s,V = np.linalg.svd( pic )\n", 238 | "S = np.zeros(pic.shape)\n", 239 | "for i in range(len(s)):\n", 240 | " S[i,i] = s[i]\n", 241 | "\n", 242 | "# number of components to use\n", 243 | "comps = slice(0,21) \n", 244 | "\n", 245 | "# create the low-rank approx.\n", 246 | "lowrank = U[:,comps]@S[comps,comps]@V[comps,:]\n", 247 | "\n", 248 | "\n", 249 | "# show the original and low-rank\n", 250 | "plt.subplot(1,2,1)\n", 251 | "plt.imshow(pic,cmap='gray')\n", 252 | "plt.title('Original')\n", 253 | "plt.subplot(1,2,2)\n", 254 | "plt.imshow(lowrank,cmap='gray')\n", 255 | "plt.title('Comps. %g-%g'%(comps.start,comps.stop-1));" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "### Section 16.14, code block 16.15" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": null, 268 | "metadata": {}, 269 | "outputs": [], 270 | "source": [ 271 | "# convert to percent explained\n", 272 | "s = 100*s/np.sum(s)\n", 273 | "\n", 274 | "# visualize\n", 275 | "plt.plot(s,'s-')\n", 276 | "plt.xlim([0,100])\n", 277 | "plt.xlabel('Component number')\n", 278 | "plt.ylabel('Pct variance explains')\n", 279 | "plt.show()\n", 280 | "\n", 281 | "\n", 282 | "# threshold in percent\n", 283 | "thresh = 4 \n", 284 | "I,J=np.ix_(s>thresh,s>thresh) # comps > X%\n", 285 | "lowrank = np.squeeze(U[:,J]@S[I,J]@V[J,:])\n", 286 | "\n", 287 | "\n", 288 | "# show the original and low-rank\n", 289 | "plt.subplot(1,2,1)\n", 290 | "plt.imshow(pic,cmap='gray')\n", 291 | "plt.title('Original')\n", 292 | "plt.subplot(1,2,2)\n", 293 | "plt.imshow(lowrank,cmap='gray')\n", 294 | "plt.title('%g comps. at %g%%'%(len(I),thresh));" 295 | ] 296 | }, 297 | { 298 | "cell_type": "markdown", 299 | "metadata": {}, 300 | "source": [ 301 | "### Section 16.14, code block 16.17" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "metadata": {}, 308 | "outputs": [], 309 | "source": [ 310 | "# initialize RMS vector\n", 311 | "RMS = np.zeros(len(s))\n", 312 | "\n", 313 | "# loop through singular values (SVD layers)\n", 314 | "for si in range(len(s)):\n", 315 | " \n", 316 | " # create the low-rank img\n", 317 | " i = si+1 # mind the indexing!\n", 318 | " lowrank = U[:,:i]@S[:i,:i]@V[:i,:]\n", 319 | " \n", 320 | " # get the difference\n", 321 | " diffimg = lowrank - pic\n", 322 | " \n", 323 | " # compute RMS for this rank\n", 324 | " RMS[si] = np.sqrt(np.mean(diffimg.flatten()**2))\n", 325 | "\n", 326 | " \n", 327 | "# how's it look?!?\n", 328 | "plt.plot(RMS,'s-')\n", 329 | "plt.xlabel('Rank approximation')\n", 330 | "plt.ylabel('Error (a.u.)')\n", 331 | "plt.show()" 332 | ] 333 | }, 334 | { 335 | "cell_type": "markdown", 336 | "metadata": {}, 337 | "source": [ 338 | "### Section 16.14, code block 16.19" 339 | ] 340 | }, 341 | { 342 | "cell_type": "code", 343 | "execution_count": null, 344 | "metadata": {}, 345 | "outputs": [], 346 | "source": [ 347 | "# some random tall matrix\n", 348 | "X = np.random.randint(low=1,high=7,size=(4,2))\n", 349 | "\n", 350 | "# eq. 29\n", 351 | "U,s,V = np.linalg.svd(X) \n", 352 | "S = np.zeros(X.shape)\n", 353 | "for i,ss in enumerate(s):\n", 354 | " S[i,i] = ss\n", 355 | "\n", 356 | "# eq. 30\n", 357 | "longV1 = np.linalg.inv( (U@S@V).T@U@S@V ) @ (U@S@V).T\n", 358 | "\n", 359 | "# eq. 31\n", 360 | "longV2 = np.linalg.inv( V.T@S.T@U.T@U@S@V ) @ (U@S@V).T\n", 361 | "\n", 362 | "# eq. 32\n", 363 | "longV3 = np.linalg.inv(V.T@S.T@S@V) @ (U@S@V).T\n", 364 | "\n", 365 | "# eq. 33\n", 366 | "longV4 = V@np.linalg.matrix_power(S.T@S,-1) @ V@V.T@S.T@U.T\n", 367 | "\n", 368 | "# eq. 34\n", 369 | "MPpinv = np.linalg.pinv(X)\n", 370 | "\n", 371 | "# now compare any to pinv, e.g.,\n", 372 | "longV3 - MPpinv" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [ 379 | "### Section 16.14, code block 16.21" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": null, 385 | "metadata": {}, 386 | "outputs": [], 387 | "source": [ 388 | "k = 5\n", 389 | "n = 13\n", 390 | "a = np.linalg.pinv(np.ones((n,1))*k)\n", 391 | "\n", 392 | "# check for zeros\n", 393 | "a - 1/(k*n)" 394 | ] 395 | }, 396 | { 397 | "cell_type": "markdown", 398 | "metadata": {}, 399 | "source": [ 400 | "### Section 16.14, code block 16.23" 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "execution_count": null, 406 | "metadata": {}, 407 | "outputs": [], 408 | "source": [ 409 | "# matrix size\n", 410 | "M = 10 \n", 411 | "\n", 412 | "# condition numbers\n", 413 | "cns = np.linspace(10,1e10,30)\n", 414 | "\n", 415 | "# results vector\n", 416 | "avediffs = np.zeros(len(cns))\n", 417 | "\n", 418 | "# loop over condition numbers\n", 419 | "for condi in range(len(cns)):\n", 420 | " \n", 421 | " # create A\n", 422 | " U,r = np.linalg.qr( np.random.randn(M,M) )\n", 423 | " V,r = np.linalg.qr( np.random.randn(M,M) )\n", 424 | " S = np.diag(np.linspace(cns[condi],1,M))\n", 425 | " A = U@S@V.T # construct matrix \n", 426 | " \n", 427 | " # create B\n", 428 | " U,r = np.linalg.qr( np.random.randn(M,M) )\n", 429 | " V,r = np.linalg.qr( np.random.randn(M,M) )\n", 430 | " S = np.diag(np.linspace(cns[condi],1,M))\n", 431 | " B = U@S@V.T # construct matrix\n", 432 | " \n", 433 | " # GEDs and sort\n", 434 | " l1 = eig(A,B)[0]\n", 435 | " l2 = eig(np.linalg.inv(B)@A)[0]\n", 436 | " l1.sort()\n", 437 | " l2.sort()\n", 438 | " \n", 439 | " # get differences\n", 440 | " avediffs[condi] = np.mean(np.abs(l1-l2))\n", 441 | "\n", 442 | "# plot them!\n", 443 | "plt.plot(cns,avediffs)\n", 444 | "plt.show()" 445 | ] 446 | } 447 | ], 448 | "metadata": { 449 | "kernelspec": { 450 | "display_name": "Python 3", 451 | "language": "python", 452 | "name": "python3" 453 | }, 454 | "language_info": { 455 | "codemirror_mode": { 456 | "name": "ipython", 457 | "version": 3 458 | }, 459 | "file_extension": ".py", 460 | "mimetype": "text/x-python", 461 | "name": "python", 462 | "nbconvert_exporter": "python", 463 | "pygments_lexer": "ipython3", 464 | "version": "3.7.4" 465 | } 466 | }, 467 | "nbformat": 4, 468 | "nbformat_minor": 2 469 | } 470 | -------------------------------------------------------------------------------- /python/LAbookX_chapter17.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Quadratic form and definiteness (chapter 17)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "import matplotlib.pyplot as plt\n", 23 | "from mpl_toolkits.mplot3d import Axes3D" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Section 17.1, code block 17.1" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "# matrix size\n", 40 | "m = 4\n", 41 | "\n", 42 | "# a matrix and a row vector\n", 43 | "A = np.random.randn(m,m)\n", 44 | "v = np.random.randn(1,m)\n", 45 | "\n", 46 | "# quadratic form for this vector-matrix pair\n", 47 | "v@A@v.T\n" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "### Section 17.9, code block 17.3" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "# matrix\n", 64 | "A = np.array([[-2,3],[2,8]])\n", 65 | "\n", 66 | "# range of vector elements\n", 67 | "vi = np.linspace(-2,2,30) \n", 68 | "\n", 69 | "# initialize\n", 70 | "qf = np.zeros((len(vi),len(vi)))\n", 71 | "\n", 72 | "# for the visualization\n", 73 | "X,Y = np.meshgrid(vi,vi)\n", 74 | "\n", 75 | "for i in range(len(vi)):\n", 76 | " for j in range(len(vi)):\n", 77 | " \n", 78 | " # this vector\n", 79 | " v = np.array([ vi[i],vi[j] ])\n", 80 | " \n", 81 | " # QF (note the normalization term)\n", 82 | " qf[i,j] = v.T@A@v / (v.T@v)\n", 83 | "\n", 84 | "\n", 85 | "# setup the figure\n", 86 | "ax = plt.axes(projection='3d')\n", 87 | "\n", 88 | "# plot a surface\n", 89 | "ax.plot_surface(X, Y, qf.T)\n", 90 | "ax.set_xlabel('v_1'), ax.set_ylabel('v_2')\n", 91 | "ax.set_zlabel('$\\zeta$')\n", 92 | "plt.show()" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "### Section 17.9, code block 17.5" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "# initializations\n", 109 | "n = 4 # matrix size\n", 110 | "nIterations = 500 # number of matrices\n", 111 | "defcat = np.zeros(nIterations) # results\n", 112 | "\n", 113 | "\n", 114 | "# loop over matrices\n", 115 | "for iteri in range(nIterations):\n", 116 | " \n", 117 | " # keep creating a matrix until it has real-valued evals\n", 118 | " A = np.random.randint(-10,11,size=(n,n))\n", 119 | " e = np.linalg.eig(A)[0]\n", 120 | " while ~np.all(np.isreal(e)):\n", 121 | " A = np.random.randint(-10,11,size=(n,n))\n", 122 | " e = np.linalg.eig(A)[0]\n", 123 | " \n", 124 | " # \"zero\" threshold (from rank)\n", 125 | " t = n*np.spacing(np.max(np.linalg.svd(A)[1]))\n", 126 | " \n", 127 | " \n", 128 | " # test definiteness\n", 129 | " if np.all(np.sign(e)==1):\n", 130 | " defcat[iteri] = 1 # pos. def\n", 131 | " elif np.all(np.sign(e)>-1)&sum(abs(e)0:\n", 132 | " defcat[iteri] = 2 # pos. semidef\n", 133 | " elif np.all(np.sign(e)<1)&sum(abs(e)0:\n", 134 | " defcat[iteri] = 4 # neg. semidef\n", 135 | " elif np.all(np.sign(e)==-1):\n", 136 | " defcat[iteri] = 5 # neg. def\n", 137 | " else:\n", 138 | " defcat[iteri] = 3 # indefinite\n", 139 | "\n", 140 | " \n", 141 | " \n", 142 | "# print out summary\n", 143 | "for i in range(1,6):\n", 144 | " print('cat %g: %g'%(i,sum(defcat==i)))" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [] 153 | } 154 | ], 155 | "metadata": { 156 | "kernelspec": { 157 | "display_name": "Python 3", 158 | "language": "python", 159 | "name": "python3" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 3 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython3", 171 | "version": "3.7.4" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 2 176 | } 177 | -------------------------------------------------------------------------------- /python/LAbookX_chapter18.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Covariance matrices (chapter 18)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "### Section 18.8, code block 18.2" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "# create data\n", 38 | "n = 200\n", 39 | "X = np.random.randn(n,4)\n", 40 | "\n", 41 | "# mean-center\n", 42 | "X = X-np.mean(X,axis=0) \n", 43 | "\n", 44 | "# covariance\n", 45 | "covM = X.T@X / (n-1) \n", 46 | "\n", 47 | "# standard deviations matrix\n", 48 | "stdM = np.linalg.inv( np.diag(np.std(X,axis=0,ddof=1)) )\n", 49 | "\n", 50 | "# \"manual\" correlation matrix\n", 51 | "corM = stdM@ X.T@X @stdM / (n-1) \n", 52 | "\n", 53 | "# compare ours against numpy's\n", 54 | "print(np.round(covM-np.cov(X.T),3)), print(' ')\n", 55 | "print(np.round(corM-np.corrcoef(X.T),3))" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [] 64 | } 65 | ], 66 | "metadata": { 67 | "kernelspec": { 68 | "display_name": "Python 3", 69 | "language": "python", 70 | "name": "python3" 71 | }, 72 | "language_info": { 73 | "codemirror_mode": { 74 | "name": "ipython", 75 | "version": 3 76 | }, 77 | "file_extension": ".py", 78 | "mimetype": "text/x-python", 79 | "name": "python", 80 | "nbconvert_exporter": "python", 81 | "pygments_lexer": "ipython3", 82 | "version": "3.7.4" 83 | } 84 | }, 85 | "nbformat": 4, 86 | "nbformat_minor": 2 87 | } 88 | -------------------------------------------------------------------------------- /python/LAbookX_chapter19.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# BOOK: Linear Algebra: Theory, Intuition, Code\n", 8 | "#### AUTHOR: Mike X Cohen\n", 9 | "#### WEBSITE: sincxpress.com\n", 10 | "\n", 11 | "## CHAPTER: Principal components analysis (chapter 19)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "## import libraries for the entire chapter\n", 21 | "import numpy as np\n", 22 | "import matplotlib.pyplot as plt" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "### Section 19.7, code block 19.1" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "\n", 39 | "# create data\n", 40 | "N = 1000\n", 41 | "h = np.linspace(150,190,N) + np.random.randn(N)*5\n", 42 | "w = h*.7 - 50 + np.random.randn(N)*10\n", 43 | "\n", 44 | "# covariance\n", 45 | "X = np.vstack((h,w)).T\n", 46 | "X = X-np.mean(X,axis=0)\n", 47 | "C = X.T@X / (len(h)-1)\n", 48 | "\n", 49 | "# PCA\n", 50 | "eigvals,V = np.linalg.eig(C)\n", 51 | "i = np.argsort(eigvals)[::-1]\n", 52 | "V = V[:,i]\n", 53 | "eigvals = eigvals[i]\n", 54 | "eigvals = 100*eigvals/np.sum(eigvals)\n", 55 | "scores = X@V # not used, but useful code\n", 56 | "\n", 57 | "# plot data with PCs\n", 58 | "fig = plt.figure(figsize=(5,5))\n", 59 | "plt.plot(X[:,0],X[:,1],'ko')\n", 60 | "plt.plot([0,V[0,0]*45],[0,V[1,0]*45],'r')\n", 61 | "plt.plot([0,V[0,1]*25],[0,V[1,1]*25],'r')\n", 62 | "plt.xlabel('Height'), plt.ylabel('Weight')\n", 63 | "plt.axis([-50,50,-50,50])\n", 64 | "plt.show()" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "### Section 19.7, code block 19.3" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "# re-mean-center\n", 81 | "X = X-np.mean(X,axis=0)\n", 82 | "\n", 83 | "# SVD\n", 84 | "U,s,Vv = np.linalg.svd(X) # Vv == V\n", 85 | "scores = X@Vv.T\n", 86 | "\n", 87 | "# convert to percent variance\n", 88 | "s = s**2 / (len(X)-1)\n", 89 | "s = 100*s/sum(s) # s == eigvals" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [] 98 | } 99 | ], 100 | "metadata": { 101 | "kernelspec": { 102 | "display_name": "Python 3", 103 | "language": "python", 104 | "name": "python3" 105 | }, 106 | "language_info": { 107 | "codemirror_mode": { 108 | "name": "ipython", 109 | "version": 3 110 | }, 111 | "file_extension": ".py", 112 | "mimetype": "text/x-python", 113 | "name": "python", 114 | "nbconvert_exporter": "python", 115 | "pygments_lexer": "ipython3", 116 | "version": "3.7.4" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 2 121 | } 122 | -------------------------------------------------------------------------------- /python/widget_data.txt: -------------------------------------------------------------------------------- 1 | 10,32.614,10 2 | 15,34.89,14 3 | 17,34.652,20 4 | 15,27.755,17 5 | 13,40.604,14 6 | 10,43.29,10 7 | 15,35.673,17 8 | 13,37.358,11 9 | 13,30.958,18 10 | 13,32.542,13 11 | 12,34.376,19 12 | 14,37.618,17 13 | 14,32.704,14 14 | 14,33.209,13 15 | 12,31.672,11 16 | 20,25.297,23 17 | 12,37.014,16 18 | 17,31.698,17 19 | 14,31.792,10 20 | 18,25.8,22 21 | 15,30.976,13 22 | 10,45.895,10 23 | 15,27.105,17 24 | 15,44.487,11 25 | 14,35.699,13 26 | 13,27.158,16 27 | 13,43.88,10 28 | 14,34.248,14 29 | 19,28.787,24 30 | 11,37.937,8 31 | 15,31.133,14 32 | 15,25.287,19 33 | 10,35.529,9 34 | 13,30.551,11 35 | 12,42.503,14 36 | 17,24.957,19 37 | 15,30.916,21 38 | 13,31.413,9 39 | 10,42.537,11 40 | 19,35.357,22 41 | 19,26.688,23 42 | 13,38.877,9 43 | 14,34.836,14 44 | 13,35.518,13 45 | 11,34.2,14 46 | 8,40.129,10 47 | 17,35.312,25 48 | 15,33.218,9 49 | 12,32.44,12 50 | 16,32.258,18 51 | 16,41.34,22 52 | 14,31.535,19 53 | 16,30.875,18 54 | 13,48.637,12 55 | 14,37.19,20 56 | 20,30.738,19 57 | 13,42.287,13 58 | 12,35.133,20 59 | 11,39.433,11 60 | 13,37.594,8 61 | 16,39.072,15 62 | 18,28.002,23 63 | 15,35.003,14 64 | 12,39.771,16 65 | 14,36.925,19 66 | 16,41.279,11 67 | 15,29.914,20 68 | 13,39.509,9 69 | 16,34.7,16 70 | 11,37.914,13 71 | 16,34.304,14 72 | 11,44.052,9 73 | 18,30.577,27 74 | 10,33.671,14 75 | 16,30.829,18 76 | 14,34.663,20 77 | 16,33.093,19 78 | 11,35.881,17 79 | 17,38.191,21 80 | 18,33.245,19 81 | 10,44.542,9 82 | 16,29.269,19 83 | 16,40.853,18 84 | 12,31.954,16 85 | 12,35.033,16 86 | 14,36.373,18 87 | 16,39.378,18 88 | 13,41.223,15 89 | 15,31.206,21 90 | 14,32.686,14 91 | 19,38.516,19 92 | 12,32.72,12 93 | 19,26.076,17 94 | 13,36.93,14 95 | 14,30.251,22 96 | 17,26.012,18 97 | 15,38.591,17 98 | 17,33.137,22 99 | 11,41.7,16 100 | 12,33.59,7 101 | 14,38.047,8 102 | 14,36.328,15 103 | 14,33.259,16 104 | 11,34.218,17 105 | 16,29.622,22 106 | 10,37.306,14 107 | 17,35.907,19 108 | 15,31.25,16 109 | 11,39.165,9 110 | 14,35.775,13 111 | 16,19.226,23 112 | 14,30.529,13 113 | 14,32.485,14 114 | 15,33.604,10 115 | 16,39.014,16 116 | 13,38.707,15 117 | 16,31.988,17 118 | 13,35.472,12 119 | 14,40.554,15 120 | 12,37.003,12 121 | 21,33.324,23 122 | 14,38.382,13 123 | 12,35.82,14 124 | 9,35.989,10 125 | 17,33.907,18 126 | 12,45.984,10 127 | 15,29.047,19 128 | 17,21.527,22 129 | 14,34.929,15 130 | 11,31.871,20 131 | 11,31.535,12 132 | 15,35.766,17 133 | 17,32.918,20 134 | 10,38.58,14 135 | 16,23.347,18 136 | 16,39.872,22 137 | 14,30.098,17 138 | 12,33.978,13 139 | 16,28.972,18 140 | 15,27.777,17 141 | 15,38.492,20 142 | 17,34.852,25 143 | 13,28.923,12 144 | 14,34.332,20 145 | 15,42.117,14 146 | 11,33.136,12 147 | 13,28.239,9 148 | 12,40.578,14 149 | 15,32.283,16 150 | 12,36.686,19 151 | 11,36.533,14 152 | 18,34.495,18 153 | 12,39.123,9 154 | 14,30.148,14 155 | 16,32.225,17 156 | 13,42.907,18 157 | 14,32.239,17 158 | 13,30.98,13 159 | 17,32.393,25 160 | 14,29.035,19 161 | 13,32.871,15 162 | 16,30.091,18 163 | 14,38.929,18 164 | 11,36.232,18 165 | 14,42.772,19 166 | 15,36.305,25 167 | 11,31.195,13 168 | 12,29.139,14 169 | 18,37.345,20 170 | 15,30.345,12 171 | 18,28.317,16 172 | 14,33.719,15 173 | 18,32.81,20 174 | 15,27.173,18 175 | 16,38.68,12 176 | 15,37.195,18 177 | 15,35.954,17 178 | 13,31.428,17 179 | 13,37.881,16 180 | 11,43.972,8 181 | 14,35.139,14 182 | 16,35.54,25 183 | 16,42.278,12 184 | 16,30.453,19 185 | 10,39.972,7 186 | 13,40.549,10 187 | 13,32.584,18 188 | 15,36.211,18 189 | 14,35.401,11 190 | 9,32.978,14 191 | 14,27.06,18 192 | 14,37.044,11 193 | 17,33.539,17 194 | 15,38.509,18 195 | 16,32.743,21 196 | 11,39.714,8 197 | 16,29.098,21 198 | 13,33.911,15 199 | 13,35.509,22 200 | 9,33.791,7 201 | 13,38.544,10 202 | 13,32.626,17 203 | 15,37.028,19 204 | 11,40.773,9 205 | 16,31.125,15 206 | 16,37.108,15 207 | 15,37.649,17 208 | 14,36.202,13 209 | 16,26.759,19 210 | 11,46.02,12 211 | 10,33.508,22 212 | 12,32.21,13 213 | 13,38.052,17 214 | 15,34.808,18 215 | 15,35.66,20 216 | 14,34.058,18 217 | 12,33.406,12 218 | 14,34.496,15 219 | 14,44.099,17 220 | 10,36.011,13 221 | 14,34.692,18 222 | 17,30.07,18 223 | 12,32.567,13 224 | 14,29.945,18 225 | 12,36.308,19 226 | 10,39.851,11 227 | 17,35.886,14 228 | 12,36.851,11 229 | 13,31.18,14 230 | 11,44.411,8 231 | 10,32.478,8 232 | 14,33.589,16 233 | 16,34.817,15 234 | 15,35.832,13 235 | 12,37.285,13 236 | 12,36.097,18 237 | 14,41.558,15 238 | 13,29.273,11 239 | 13,36.635,16 240 | 8,34.379,10 241 | 12,36.193,13 242 | 14,38.392,14 243 | 16,41.915,14 244 | 15,30.497,19 245 | 14,40.797,11 246 | 15,40.616,21 247 | 13,40.205,14 248 | 17,38.673,14 249 | 11,37.146,11 250 | 16,28.44,21 251 | 11,40.02,15 252 | 12,34.419,13 253 | 14,37.351,13 254 | 15,28.81,15 255 | 16,33.302,17 256 | 14,37.188,23 257 | 16,32.005,20 258 | 16,41.715,16 259 | 15,29.732,16 260 | 10,37.746,16 261 | 16,36.274,20 262 | 17,29.231,14 263 | 11,25.041,14 264 | 13,28.947,14 265 | 17,32.014,17 266 | 17,29.255,15 267 | 16,32.276,15 268 | 15,40.543,16 269 | 15,31.56,18 270 | 15,37.3,12 271 | 16,30.654,20 272 | 15,31.397,16 273 | 13,31.868,13 274 | 18,26.486,23 275 | 14,43.102,17 276 | 13,41.671,13 277 | 14,36.033,19 278 | 7,47.328,3 279 | 16,32.166,21 280 | 14,33.483,20 281 | 17,28.952,16 282 | 13,41.24,15 283 | 14,30.397,12 284 | 17,31.399,23 285 | 15,39.291,14 286 | 14,40.117,20 287 | 12,39.64,10 288 | 16,36.479,18 289 | 9,40.454,14 290 | 11,39.125,10 291 | 16,31.864,13 292 | 12,42.244,13 293 | 13,33.554,12 294 | 14,38.342,21 295 | 12,32.913,12 296 | 14,32.717,13 297 | 10,44.005,11 298 | 14,20.855,22 299 | 12,35.666,13 300 | 12,35.501,15 301 | 15,30.073,19 302 | 15,39.068,17 303 | 12,35.658,16 304 | 14,33.751,11 305 | 17,31.077,14 306 | 11,37.786,11 307 | 12,34.233,10 308 | 13,40.43,7 309 | 11,37.07,15 310 | 16,32.678,22 311 | 12,40.378,17 312 | 19,29.148,25 313 | 13,32.138,15 314 | 12,35.695,11 315 | 14,36.257,21 316 | 14,30.204,19 317 | 14,34.086,10 318 | 15,29.447,18 319 | 14,31.944,14 320 | 12,36.724,16 321 | 14,29.013,17 322 | 13,41.946,10 323 | 14,25.741,12 324 | 12,38.733,12 325 | 8,37.4,7 326 | 16,45.843,10 327 | 14,32.674,19 328 | 14,29.35,22 329 | 17,30.381,19 330 | 17,35.847,17 331 | 12,38.482,14 332 | 14,31.19,17 333 | 13,39.08,18 334 | 11,41.545,8 335 | 10,41.799,14 336 | 16,36.746,16 337 | 17,36.597,21 338 | 16,33.453,19 339 | 15,38.728,19 340 | 10,33.93,15 341 | 12,38.953,11 342 | 11,34.686,12 343 | 13,45.435,12 344 | 14,26.74,20 345 | 13,35.367,18 346 | 12,39.068,15 347 | 16,29.395,17 348 | 13,26.796,17 349 | 17,31.254,17 350 | 16,34.722,15 351 | 9,43.034,16 352 | 19,37.948,24 353 | 14,32.698,18 354 | 11,40.941,13 355 | 11,38.734,9 356 | 18,32.006,24 357 | 16,31.022,16 358 | 15,23.565,17 359 | 12,39.669,15 360 | 13,35.348,17 361 | 13,37.852,8 362 | 14,37.129,19 363 | 12,38.141,18 364 | 16,32.709,18 365 | 10,33.106,10 366 | 14,37.545,20 367 | 14,34.963,24 368 | 16,32.016,20 369 | 10,39.235,18 370 | 13,35.482,11 371 | 14,34.12,14 372 | 15,35.301,18 373 | 19,29.845,23 374 | 16,31.282,16 375 | 13,36.663,14 376 | 13,35.583,17 377 | 16,42.912,18 378 | 11,33.138,14 379 | 15,31.29,23 380 | 14,36.472,12 381 | 10,38.42,5 382 | 17,42.656,16 383 | 15,34.758,19 384 | 13,35.849,11 385 | 12,39.157,17 386 | 17,35.64,19 387 | 17,32.395,18 388 | 12,39.721,14 389 | 11,34.384,11 390 | 13,34.354,19 391 | 13,40.568,17 392 | 13,37.581,17 393 | 17,35.994,18 394 | 12,41.366,14 395 | 11,33.123,15 396 | 12,40.856,12 397 | 12,38.19,20 398 | 12,40.882,16 399 | 18,32.101,14 400 | 18,29.193,21 401 | 17,28.144,14 402 | 10,37.813,13 403 | 15,32.748,19 404 | 14,40.337,16 405 | 12,38.149,16 406 | 15,30.002,15 407 | 13,31.197,18 408 | 17,27.601,17 409 | 15,32.723,20 410 | 13,34.046,15 411 | 16,31.915,14 412 | 14,28.454,24 413 | 18,32.233,23 414 | 14,36.616,18 415 | 16,33.913,14 416 | 16,32.508,14 417 | 10,43.938,14 418 | 12,33.534,22 419 | 11,34.728,17 420 | 13,35.944,17 421 | 12,28.402,12 422 | 14,37.438,21 423 | 11,30.319,5 424 | 15,35.225,22 425 | 9,37.656,7 426 | 11,33.8,13 427 | 17,27.801,20 428 | 13,36.039,16 429 | 10,37.967,7 430 | 15,39.653,17 431 | 17,32.321,19 432 | 14,34.644,10 433 | 11,34.795,8 434 | 10,33.263,13 435 | 18,23.175,20 436 | 12,36.078,12 437 | 14,45.229,13 438 | 15,30.725,20 439 | 17,26.127,24 440 | 12,33.41,13 441 | 15,29.064,18 442 | 15,35.08,15 443 | 16,43.117,19 444 | 9,45.473,11 445 | 16,31.954,18 446 | 14,24.659,24 447 | 13,39.382,19 448 | 10,45.948,8 449 | 15,41.663,13 450 | 14,47.091,12 451 | 12,42.585,13 452 | 14,31.647,14 453 | 15,33.501,17 454 | 14,23.808,19 455 | 15,34.034,15 456 | 14,42.493,12 457 | 15,42.94,10 458 | 14,34.284,17 459 | 14,39.048,19 460 | 10,25.928,17 461 | 13,31.645,17 462 | 16,30.897,16 463 | 18,36.648,17 464 | 13,38.786,18 465 | 17,33.184,18 466 | 14,34.326,14 467 | 11,44.476,8 468 | 9,35.814,7 469 | 10,45.816,8 470 | 12,40.835,15 471 | 13,42.48,10 472 | 14,38.73,16 473 | 20,32.222,21 474 | 14,44.165,15 475 | 13,35.693,15 476 | 15,37.836,14 477 | 14,30.474,18 478 | 16,32.985,16 479 | 10,37.023,14 480 | 13,31.653,17 481 | 16,37.091,25 482 | 8,35.593,8 483 | 15,38.727,21 484 | 12,41.143,17 485 | 14,31.838,14 486 | 14,41.738,12 487 | 11,39.206,12 488 | 14,24.419,17 489 | 12,30.924,17 490 | 16,36.228,17 491 | 13,40.285,16 492 | 18,35.541,22 493 | 14,30.633,16 494 | 16,24.297,20 495 | 14,32.321,26 496 | 15,29.611,20 497 | 15,32.705,17 498 | 15,33.939,16 499 | 17,31.87,17 500 | 12,29.025,13 501 | 13,31.584,13 502 | 10,33.117,13 503 | 13,35.818,18 504 | 10,27.113,22 505 | 14,27.676,19 506 | 13,41.98,15 507 | 9,40.385,8 508 | 13,34.637,11 509 | 13,32.246,14 510 | 15,32.979,18 511 | 16,32.484,15 512 | 18,28.994,22 513 | 15,35.482,19 514 | 14,43.034,16 515 | 14,32.155,22 516 | 14,44.299,18 517 | 12,39.622,19 518 | 19,35.344,22 519 | 15,35.447,17 520 | 12,31.499,18 521 | 13,41.429,13 522 | 13,33.938,13 523 | 13,36.854,16 524 | 12,40.046,13 525 | 14,33.779,22 526 | 12,39.745,13 527 | 13,38.186,10 528 | 11,36.475,16 529 | 16,28.578,14 530 | 19,33.73,22 531 | 17,37.52,16 532 | 12,30.557,11 533 | 15,24.452,23 534 | 15,33.663,20 535 | 13,38.955,11 536 | 16,33.059,18 537 | 13,35.82,11 538 | 14,26.735,17 539 | 16,25.429,17 540 | 13,42.192,16 541 | 13,36.721,18 542 | 16,32.912,20 543 | 13,35.887,15 544 | 15,32.735,16 545 | 11,27.634,23 546 | 14,38.158,15 547 | 13,36.338,17 548 | 12,45.87,13 549 | 15,28.964,15 550 | 14,31.292,20 551 | 12,39.212,15 552 | 14,39.463,16 553 | 15,33.524,18 554 | 17,37.206,17 555 | 17,38.931,20 556 | 15,37.992,11 557 | 11,33.487,13 558 | 13,36.174,10 559 | 13,42.809,16 560 | 18,25.836,19 561 | 11,40.889,6 562 | 15,37.909,21 563 | 15,30.887,17 564 | 15,33.002,16 565 | 14,32.1,17 566 | 15,38.509,20 567 | 15,31.31,15 568 | 16,32.465,20 569 | 17,40.866,13 570 | 12,43.661,14 571 | 10,38.237,13 572 | 14,33.04,13 573 | 13,42.823,14 574 | 12,48.123,15 575 | 17,31.695,19 576 | 18,27.586,19 577 | 13,26.993,21 578 | 16,33.663,20 579 | 13,42.785,13 580 | 13,46.442,6 581 | 15,35.315,16 582 | 16,35.426,15 583 | 17,24.487,21 584 | 12,45.607,14 585 | 17,27.114,16 586 | 14,41.224,14 587 | 9,39.841,14 588 | 11,43.737,9 589 | 13,36.841,18 590 | 19,34.456,27 591 | 12,36.788,13 592 | 15,33.326,11 593 | 14,41.672,15 594 | 14,32.711,21 595 | 13,41.765,13 596 | 15,34.845,24 597 | 13,34.702,19 598 | 9,40.931,16 599 | 14,27.308,16 600 | 12,34.174,19 601 | 15,32.119,22 602 | 10,39.221,12 603 | 12,36.264,14 604 | 15,35.246,17 605 | 16,26.017,21 606 | 11,39.035,18 607 | 14,33.512,19 608 | 12,41.992,11 609 | 8,22.369,12 610 | 14,31.504,14 611 | 13,43.294,16 612 | 14,36.325,15 613 | 11,43.86,15 614 | 16,40.824,20 615 | 14,36.239,16 616 | 11,35.085,9 617 | 13,31.988,17 618 | 15,27.276,13 619 | 12,31.738,10 620 | 15,35.04,18 621 | 15,30.755,24 622 | 17,28.203,22 623 | 14,31.196,22 624 | 12,34.39,13 625 | 13,43.032,14 626 | 14,35.592,11 627 | 15,44.29,17 628 | 20,22.957,17 629 | 10,43.002,10 630 | 13,36.26,17 631 | 13,38.576,14 632 | 14,30.417,15 633 | 15,25.387,21 634 | 12,29.998,15 635 | 16,37.83,21 636 | 9,39.551,9 637 | 12,37.79,10 638 | 20,31.258,24 639 | 16,35.378,17 640 | 15,27.353,18 641 | 15,30.93,23 642 | 18,24.247,22 643 | 14,35.061,11 644 | 15,32.265,18 645 | 18,34.05,11 646 | 15,33.358,18 647 | 11,32.219,10 648 | 15,33.251,11 649 | 17,34.728,15 650 | 13,37.345,11 651 | 16,34.018,24 652 | 15,29.032,23 653 | 10,34.242,16 654 | 13,36.703,13 655 | 12,29.322,21 656 | 12,27.408,15 657 | 12,37.047,9 658 | 8,36.607,8 659 | 13,32.728,20 660 | 12,39.521,11 661 | 13,36.991,14 662 | 16,29.896,14 663 | 13,40.536,8 664 | 16,28.86,21 665 | 13,35.137,14 666 | 13,37.885,15 667 | 17,33.819,20 668 | 17,33.923,19 669 | 13,39.091,11 670 | 14,34.551,19 671 | 10,45.033,9 672 | 12,35.147,15 673 | 14,30.917,16 674 | 11,31.057,17 675 | 13,40.201,12 676 | 13,31.352,18 677 | 13,32.757,16 678 | 13,40.592,17 679 | 13,32.248,15 680 | 11,36.939,15 681 | 14,37.631,13 682 | 15,35.521,16 683 | 15,34.614,15 684 | 12,37.315,12 685 | 14,37.418,13 686 | 12,36.735,12 687 | 14,45.234,17 688 | 14,29.639,19 689 | 12,27.652,20 690 | 16,37.296,16 691 | 14,46.263,9 692 | 17,32.095,15 693 | 16,28.982,21 694 | 14,30.895,18 695 | 14,34.802,21 696 | 13,36.777,15 697 | 14,31.581,22 698 | 15,25.971,20 699 | 11,43.472,16 700 | 11,33.505,17 701 | 15,33.669,13 702 | 12,44.392,13 703 | 15,40.306,23 704 | 16,31.113,16 705 | 12,28.198,12 706 | 9,43.609,12 707 | 12,36.229,14 708 | 14,29.828,16 709 | 14,39.436,17 710 | 11,30.319,18 711 | 13,46.915,16 712 | 13,41.175,21 713 | 17,31.977,21 714 | 12,38.415,12 715 | 16,32.272,16 716 | 11,39.426,13 717 | 14,31.726,18 718 | 14,33.507,17 719 | 16,38.062,13 720 | 17,36.348,20 721 | 15,40.043,12 722 | 14,35.533,12 723 | 13,37.582,14 724 | 17,22.571,22 725 | 15,26.386,19 726 | 15,34.583,20 727 | 12,35.467,8 728 | 11,31.172,17 729 | 19,32.471,15 730 | 14,34.559,19 731 | 12,38.955,13 732 | 15,37.323,14 733 | 15,38.194,20 734 | 11,35.237,11 735 | 12,29.726,15 736 | 15,35.535,13 737 | 10,45.53,8 738 | 13,34.568,17 739 | 15,25.246,21 740 | 13,43.109,14 741 | 15,32.851,15 742 | 16,34.037,15 743 | 11,33.991,14 744 | 14,37.182,12 745 | 17,28.268,18 746 | 11,36.233,15 747 | 9,39.884,11 748 | 13,34.909,16 749 | 17,38.199,15 750 | 13,32.254,9 751 | 15,33.102,15 752 | 10,22.401,15 753 | 14,32.184,15 754 | 16,35.133,16 755 | 16,30.109,21 756 | 14,37.242,18 757 | 12,31.984,16 758 | 13,44.962,17 759 | 13,36.282,17 760 | 14,29.523,16 761 | 17,30.663,21 762 | 16,36.81,21 763 | 15,27.265,20 764 | 12,31.269,12 765 | 13,37.261,16 766 | 15,41.283,14 767 | 15,33.62,21 768 | 11,33.339,13 769 | 13,34.679,14 770 | 11,44.79,13 771 | 17,30.947,19 772 | 13,42.982,9 773 | 14,29.397,22 774 | 13,24.552,17 775 | 12,34.867,14 776 | 11,38.705,12 777 | 16,35.771,18 778 | 16,38.591,12 779 | 19,29.961,26 780 | 13,34.258,18 781 | 10,41.734,9 782 | 14,33.626,17 783 | 17,32.872,18 784 | 15,33.118,16 785 | 17,31.193,21 786 | 17,31.537,18 787 | 12,40.591,13 788 | 13,36.559,14 789 | 13,31.53,19 790 | 15,29.285,15 791 | 16,32.305,22 792 | 18,29.603,20 793 | 15,42.758,17 794 | 15,37.068,19 795 | 14,27.375,18 796 | 16,28.291,19 797 | 12,32.552,15 798 | 12,32.229,12 799 | 14,36.176,16 800 | 10,34.8,12 801 | 22,27.091,30 802 | 10,40.37,9 803 | 17,31.161,15 804 | 14,32.821,15 805 | 14,31.416,19 806 | 17,36.024,19 807 | 13,31.518,18 808 | 18,32.064,23 809 | 12,34.023,15 810 | 11,33.287,10 811 | 12,37.972,16 812 | 13,34.344,17 813 | 15,34.834,19 814 | 10,34.678,15 815 | 9,39.235,11 816 | 14,33.299,16 817 | 11,35.3,14 818 | 15,27.363,23 819 | 17,27.412,26 820 | 13,32.814,19 821 | 13,32.201,12 822 | 9,35.904,15 823 | 11,46.426,13 824 | 12,39.932,10 825 | 13,36.322,10 826 | 15,37.269,13 827 | 16,36.229,14 828 | 11,36.292,14 829 | 15,36.725,17 830 | 14,23.735,15 831 | 15,31.964,18 832 | 15,42.541,14 833 | 15,35.504,19 834 | 15,31.342,19 835 | 15,30.561,19 836 | 14,41.377,9 837 | 17,38.05,19 838 | 9,34.712,14 839 | 11,39.118,17 840 | 14,38.016,15 841 | 13,38.395,16 842 | 12,30.54,18 843 | 12,36.219,7 844 | 13,39.698,6 845 | 15,39.867,18 846 | 14,33.527,14 847 | 13,36.014,13 848 | 13,33.131,13 849 | 14,29.452,16 850 | 14,31.062,19 851 | 13,43.491,18 852 | 20,28.541,20 853 | 11,36.837,17 854 | 14,29.34,22 855 | 12,38.489,17 856 | 13,43.547,14 857 | 13,33.566,15 858 | 13,33.951,9 859 | 12,42.205,13 860 | 12,41.816,12 861 | 15,34.329,11 862 | 14,36.305,15 863 | 12,40.69,18 864 | 11,32.557,18 865 | 16,37.92,21 866 | 15,34.234,11 867 | 14,37.532,13 868 | 14,33.927,14 869 | 14,36.693,16 870 | 19,27.083,21 871 | 16,40.759,21 872 | 14,38.777,14 873 | 11,33.28,13 874 | 13,38.24,17 875 | 12,33.412,16 876 | 18,25.868,18 877 | 11,33.773,16 878 | 13,33.55,21 879 | 11,40.016,12 880 | 15,36.15,18 881 | 13,46.021,13 882 | 12,31.382,19 883 | 15,35.991,15 884 | 14,36.445,13 885 | 13,40.274,16 886 | 15,22.513,17 887 | 16,36.048,15 888 | 16,27.741,18 889 | 15,40.342,19 890 | 15,41.902,13 891 | 16,37.221,19 892 | 12,40.066,12 893 | 13,28.916,12 894 | 12,39.357,12 895 | 13,31.065,11 896 | 15,31.639,17 897 | 15,31.312,18 898 | 14,30.579,20 899 | 15,40.629,20 900 | 17,26.819,20 901 | 15,28.156,15 902 | 15,33.472,12 903 | 15,31.72,14 904 | 17,33.263,26 905 | 13,33.673,25 906 | 13,32.834,20 907 | 11,44.923,17 908 | 11,30.008,17 909 | 12,38.902,13 910 | 12,29.831,13 911 | 14,22.646,22 912 | 14,31.458,12 913 | 17,31.215,17 914 | 9,37.26,11 915 | 10,34.205,17 916 | 12,34.675,15 917 | 13,35.153,15 918 | 16,30.122,16 919 | 15,36.057,16 920 | 17,33.232,19 921 | 16,33.237,16 922 | 14,33.256,15 923 | 13,36.008,16 924 | 14,41.26,17 925 | 12,36.685,11 926 | 12,38.724,11 927 | 15,32.304,20 928 | 13,33.048,14 929 | 13,39.621,15 930 | 6,48.604,16 931 | 14,39.359,18 932 | 17,29.992,18 933 | 15,34.38,17 934 | 13,30.63,19 935 | 13,33.85,16 936 | 15,32.256,22 937 | 14,29.603,17 938 | 14,36.998,14 939 | 16,26.652,22 940 | 16,33.102,18 941 | 16,25.595,20 942 | 12,37.103,17 943 | 13,40.862,14 944 | 15,39.432,15 945 | 8,44.297,7 946 | 10,37.98,13 947 | 15,29.259,23 948 | 17,41.304,20 949 | 10,43.361,18 950 | 14,36.74,14 951 | 14,32.101,24 952 | 12,31.793,9 953 | 11,41.282,12 954 | 15,24.954,15 955 | 14,29.994,20 956 | 14,26.264,18 957 | 10,37.582,8 958 | 21,27.545,18 959 | 18,31.677,22 960 | 14,36.464,13 961 | 12,45.472,8 962 | 13,35.617,13 963 | 14,38.562,10 964 | 13,40.047,13 965 | 16,31.892,12 966 | 12,39.726,11 967 | 17,31.82,19 968 | 19,27.103,26 969 | 15,34.635,15 970 | 17,35.662,20 971 | 15,24.268,17 972 | 11,46.949,14 973 | 12,33.926,18 974 | 16,34.36,16 975 | 13,34.763,18 976 | 14,30.588,15 977 | 16,35.483,15 978 | 15,33.622,20 979 | 14,34.433,21 980 | 12,33.689,18 981 | 13,41.028,14 982 | 12,32.584,13 983 | 13,33.291,14 984 | 13,35.857,17 985 | 13,35.648,13 986 | 11,32.798,20 987 | 10,29.26,10 988 | 16,30.299,22 989 | 16,23.047,18 990 | 10,45.962,14 991 | 13,27.477,8 992 | 14,33.15,15 993 | 16,35.937,15 994 | 15,30.695,15 995 | 16,41.187,10 996 | 14,37.124,16 997 | 14,25.962,19 998 | 17,33.047,25 999 | 9,39.386,12 1000 | 13,34.73,16 1001 | --------------------------------------------------------------------------------