1"""
2Vector and Matrix Operations for AI/ML
3
4Demonstrates fundamental linear algebra concepts:
5- Vector spaces: basis, span, linear independence
6- Matrix operations: multiplication, transpose, inverse
7- Rank computation
8- ML applications: feature vectors, weight matrices
9
10Dependencies: numpy, matplotlib
11"""
12
13import numpy as np
14import matplotlib.pyplot as plt
15
16
17def vector_space_basics():
18 """Demonstrate vector space concepts: basis, span, linear independence"""
19 print("=" * 60)
20 print("VECTOR SPACE BASICS")
21 print("=" * 60)
22
23 # Standard basis in R^3
24 e1 = np.array([1, 0, 0])
25 e2 = np.array([0, 1, 0])
26 e3 = np.array([0, 0, 1])
27
28 print("\nStandard basis vectors in R^3:")
29 print(f"e1 = {e1}")
30 print(f"e2 = {e2}")
31 print(f"e3 = {e3}")
32
33 # Any vector can be expressed as linear combination of basis
34 v = np.array([3, -2, 5])
35 print(f"\nVector v = {v}")
36 print(f"v = 3*e1 + (-2)*e2 + 5*e3")
37 reconstructed = 3*e1 + (-2)*e2 + 5*e3
38 print(f"Reconstructed: {reconstructed}")
39 print(f"Match: {np.allclose(v, reconstructed)}")
40
41 # Linear independence check
42 print("\n--- Linear Independence ---")
43 v1 = np.array([1, 2, 3])
44 v2 = np.array([4, 5, 6])
45 v3 = np.array([7, 8, 9]) # v3 is in span of v1, v2
46
47 # Stack vectors as columns and check rank
48 A = np.column_stack([v1, v2, v3])
49 rank = np.linalg.matrix_rank(A)
50 print(f"\nVectors: {v1}, {v2}, {v3}")
51 print(f"Matrix A (vectors as columns):\n{A}")
52 print(f"Rank(A) = {rank}")
53 print(f"Linearly independent: {rank == 3} (expect False)")
54
55 # Linearly independent set
56 w1 = np.array([1, 0, 0])
57 w2 = np.array([0, 1, 0])
58 w3 = np.array([1, 1, 1])
59 B = np.column_stack([w1, w2, w3])
60 rank_B = np.linalg.matrix_rank(B)
61 print(f"\nVectors: {w1}, {w2}, {w3}")
62 print(f"Matrix B:\n{B}")
63 print(f"Rank(B) = {rank_B}")
64 print(f"Linearly independent: {rank_B == 3}")
65
66
67def matrix_operations():
68 """Demonstrate matrix multiplication, transpose, inverse"""
69 print("\n" + "=" * 60)
70 print("MATRIX OPERATIONS")
71 print("=" * 60)
72
73 # Matrix multiplication
74 A = np.array([[1, 2, 3],
75 [4, 5, 6]])
76 B = np.array([[7, 8],
77 [9, 10],
78 [11, 12]])
79
80 print("\nMatrix A (2x3):")
81 print(A)
82 print("\nMatrix B (3x2):")
83 print(B)
84
85 C = A @ B # Matrix multiplication
86 print("\nC = A @ B (2x2):")
87 print(C)
88 print(f"Shape: {C.shape}")
89
90 # Transpose
91 print("\n--- Transpose ---")
92 print(f"A^T (3x2):\n{A.T}")
93 print(f"(A^T)^T == A: {np.allclose((A.T).T, A)}")
94
95 # Inverse (square matrix)
96 print("\n--- Matrix Inverse ---")
97 D = np.array([[4, 7],
98 [2, 6]])
99 print(f"Matrix D:\n{D}")
100
101 D_inv = np.linalg.inv(D)
102 print(f"\nD_inv:\n{D_inv}")
103
104 # Verify D @ D_inv = I
105 identity = D @ D_inv
106 print(f"\nD @ D_inv:\n{identity}")
107 print(f"Is identity: {np.allclose(identity, np.eye(2))}")
108
109 # Determinant (must be non-zero for invertible)
110 det_D = np.linalg.det(D)
111 print(f"\ndet(D) = {det_D:.4f}")
112 print(f"Invertible: {not np.isclose(det_D, 0)}")
113
114
115def rank_computation():
116 """Demonstrate rank computation and its significance"""
117 print("\n" + "=" * 60)
118 print("MATRIX RANK")
119 print("=" * 60)
120
121 # Full rank matrix
122 print("\n--- Full Rank Matrix ---")
123 A = np.array([[1, 2, 3],
124 [0, 1, 4],
125 [5, 6, 0]])
126 rank_A = np.linalg.matrix_rank(A)
127 print(f"Matrix A (3x3):\n{A}")
128 print(f"Rank(A) = {rank_A}")
129 print(f"Full rank: {rank_A == min(A.shape)}")
130
131 # Rank deficient matrix (linearly dependent rows)
132 print("\n--- Rank Deficient Matrix ---")
133 B = np.array([[1, 2, 3],
134 [2, 4, 6], # 2 * row1
135 [4, 5, 6]])
136 rank_B = np.linalg.matrix_rank(B)
137 print(f"Matrix B (3x3):\n{B}")
138 print(f"Rank(B) = {rank_B}")
139 print(f"Full rank: {rank_B == min(B.shape)}")
140 print("Row 2 = 2 * Row 1, hence rank deficient")
141
142 # Rectangular matrix
143 print("\n--- Rectangular Matrix ---")
144 C = np.array([[1, 2, 3, 4],
145 [5, 6, 7, 8],
146 [9, 10, 11, 12]])
147 rank_C = np.linalg.matrix_rank(C)
148 print(f"Matrix C (3x4):\n{C}")
149 print(f"Rank(C) = {rank_C}")
150 print(f"Max possible rank = min(3, 4) = {min(C.shape)}")
151
152
153def ml_application_example():
154 """ML application: feature matrix and weight matrix multiplication"""
155 print("\n" + "=" * 60)
156 print("ML APPLICATION: LINEAR MODEL")
157 print("=" * 60)
158
159 # Feature matrix X: each row is a sample, each column is a feature
160 # 5 samples, 3 features
161 X = np.array([[1.0, 2.0, 3.0],
162 [1.5, 2.5, 3.5],
163 [2.0, 3.0, 4.0],
164 [2.5, 3.5, 4.5],
165 [3.0, 4.0, 5.0]])
166
167 # Weight matrix W: (3 features, 2 outputs)
168 W = np.array([[0.5, -0.3],
169 [0.2, 0.8],
170 [-0.1, 0.4]])
171
172 # Bias vector b: (2 outputs)
173 b = np.array([1.0, -0.5])
174
175 print(f"Feature matrix X (5 samples, 3 features):\n{X}")
176 print(f"\nWeight matrix W (3 features, 2 outputs):\n{W}")
177 print(f"\nBias vector b (2 outputs): {b}")
178
179 # Linear transformation: Y = X @ W + b
180 Y = X @ W + b
181 print(f"\nOutput Y = X @ W + b (5 samples, 2 outputs):\n{Y}")
182
183 print("\nInterpretation:")
184 print("- Each row of X is a feature vector for one sample")
185 print("- W maps 3D feature space to 2D output space")
186 print("- Each row of Y is the model output for one sample")
187
188 # Compute rank of feature matrix
189 rank_X = np.linalg.matrix_rank(X)
190 print(f"\nRank(X) = {rank_X}")
191 print(f"Max rank = min(5, 3) = {min(X.shape)}")
192
193 if rank_X < min(X.shape):
194 print("Warning: Feature matrix is rank deficient!")
195 print("Some features may be linearly dependent (redundant)")
196 else:
197 print("Feature matrix has full rank (good!)")
198
199
200def visualize_vector_operations():
201 """Visualize 2D vector operations"""
202 print("\n" + "=" * 60)
203 print("VISUALIZING VECTOR OPERATIONS")
204 print("=" * 60)
205
206 # Create figure
207 fig, axes = plt.subplots(1, 2, figsize=(12, 5))
208
209 # Plot 1: Vector addition
210 ax1 = axes[0]
211 v1 = np.array([2, 1])
212 v2 = np.array([1, 3])
213 v_sum = v1 + v2
214
215 origin = np.array([0, 0])
216 ax1.quiver(*origin, *v1, angles='xy', scale_units='xy', scale=1,
217 color='r', width=0.006, label='v1')
218 ax1.quiver(*origin, *v2, angles='xy', scale_units='xy', scale=1,
219 color='b', width=0.006, label='v2')
220 ax1.quiver(*origin, *v_sum, angles='xy', scale_units='xy', scale=1,
221 color='g', width=0.006, label='v1+v2')
222
223 # Parallelogram
224 ax1.plot([v1[0], v_sum[0]], [v1[1], v_sum[1]], 'k--', alpha=0.3)
225 ax1.plot([v2[0], v_sum[0]], [v2[1], v_sum[1]], 'k--', alpha=0.3)
226
227 ax1.set_xlim(-0.5, 4)
228 ax1.set_ylim(-0.5, 5)
229 ax1.set_aspect('equal')
230 ax1.grid(True, alpha=0.3)
231 ax1.legend()
232 ax1.set_title('Vector Addition')
233 ax1.set_xlabel('x')
234 ax1.set_ylabel('y')
235
236 # Plot 2: Linear transformation (matrix multiplication)
237 ax2 = axes[1]
238
239 # Transformation matrix (rotation + scaling)
240 theta = np.pi / 4 # 45 degrees
241 A = np.array([[np.cos(theta), -np.sin(theta)],
242 [np.sin(theta), np.cos(theta)]]) * 1.5
243
244 # Original vectors
245 vectors = np.array([[1, 0], [0, 1], [1, 1]])
246
247 for i, v in enumerate(vectors):
248 v_transformed = A @ v
249
250 # Original vector
251 ax2.quiver(*origin, *v, angles='xy', scale_units='xy', scale=1,
252 color='blue', width=0.005, alpha=0.5)
253
254 # Transformed vector
255 ax2.quiver(*origin, *v_transformed, angles='xy', scale_units='xy', scale=1,
256 color='red', width=0.005, label='Transformed' if i == 0 else '')
257
258 ax2.set_xlim(-2, 2)
259 ax2.set_ylim(-2, 2)
260 ax2.set_aspect('equal')
261 ax2.grid(True, alpha=0.3)
262 ax2.legend(['Original (blue)', 'Transformed (red)'])
263 ax2.set_title('Linear Transformation (Rotation + Scale)')
264 ax2.set_xlabel('x')
265 ax2.set_ylabel('y')
266
267 plt.tight_layout()
268 plt.savefig('/opt/projects/01_Personal/03_Study/examples/Math_for_AI/vector_ops.png', dpi=150)
269 print("Visualization saved to vector_ops.png")
270 plt.close()
271
272
273if __name__ == "__main__":
274 # Run all demonstrations
275 vector_space_basics()
276 matrix_operations()
277 rank_computation()
278 ml_application_example()
279 visualize_vector_operations()
280
281 print("\n" + "=" * 60)
282 print("All demonstrations completed!")
283 print("=" * 60)