🔢 Linear Algebra Operations
NumPy's linear algebra module (numpy.linalg) provides powerful tools for matrix operations, solving linear systems, and advanced mathematical computations. Essential for machine learning, engineering, and scientific computing!
import numpy as np
# Linear algebra overview
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(f"Matrix A: \n{A}")
print(f"Matrix B: \n{B}")
# Matrix operations
print(f"A × B: \n{A @ B}")
print(f"Determinant of A: {np.linalg.det(A):.2f}")
🧮 Matrix Operations
Fundamental operations for working with matrices.
Matrix Multiplication
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
vector = np.array([1, 2])
# Different multiplication types
print(f"Matrix × Matrix: \n{A @ B}")
print(f"Matrix × Vector: {A @ vector}")
# Element-wise multiplication (different!)
print(f"Element-wise A * B: \n{A * B}")
Matrix Properties
import numpy as np
matrix = np.array([[2, 1], [1, 3]])
# Important properties
det = np.linalg.det(matrix)
trace = np.trace(matrix) # Sum of diagonal
rank = np.linalg.matrix_rank(matrix)
print(f"Matrix: \n{matrix}")
print(f"Determinant: {det:.2f}")
print(f"Trace: {trace}")
print(f"Rank: {rank}")
if det != 0:
print("Matrix is invertible!")
Matrix Transpose
import numpy as np
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(f"Original: \n{matrix}")
print(f"Transpose: \n{matrix.T}")
# For square matrices
square = np.array([[1, 2], [3, 4]])
product = square @ square.T
print(f"A @ A.T: \n{product}")
🔍 Matrix Decompositions
Break matrices into simpler components for analysis.
Eigenvalues and Eigenvectors
import numpy as np
# Symmetric matrix
matrix = np.array([[4, -2], [-2, 1]])
# Eigenvalue decomposition
eigenvals, eigenvecs = np.linalg.eig(matrix)
print(f"Matrix: \n{matrix}")
print(f"Eigenvalues: {eigenvals.round(3)}")
print(f"Eigenvectors: \n{eigenvecs.round(3)}")
# Verify: A × v = λ × v
for i in range(len(eigenvals)):
Av = matrix @ eigenvecs[:, i]
λv = eigenvals[i] * eigenvecs[:, i]
print(f"Verification {i+1}: {np.allclose(Av, λv)}")
Singular Value Decomposition
import numpy as np
matrix = np.array([[1, 2, 3], [4, 5, 6]])
# SVD decomposition
U, s, Vt = np.linalg.svd(matrix)
print(f"Original: \n{matrix}")
print(f"U shape: {U.shape}")
print(f"Singular values: {s.round(3)}")
print(f"Vt shape: {Vt.shape}")
# Reconstruct matrix
reconstructed = U @ np.diag(s) @ Vt
print(f"Reconstructed: \n{reconstructed.round(3)}")
QR Decomposition
import numpy as np
matrix = np.array([[1, 2], [3, 4], [5, 6]])
# QR decomposition
Q, R = np.linalg.qr(matrix)
print(f"Original: \n{matrix}")
print(f"Q (orthogonal): \n{Q.round(3)}")
print(f"R (upper triangular): \n{R.round(3)}")
# Verify: A = Q × R
print(f"Q × R: \n{(Q @ R).round(3)}")
⚖️ Solving Linear Systems
Solve systems of linear equations efficiently.
Basic System Solving
import numpy as np
# Solve: 2x + 3y = 7, x - y = 1
A = np.array([[2, 3], [1, -1]])
b = np.array([7, 1])
# Solve Ax = b
x = np.linalg.solve(A, b)
print(f"System Ax = b:")
print(f"A: \n{A}")
print(f"b: {b}")
print(f"Solution x: {x}")
# Verify
verification = A @ x
print(f"A × x: {verification}")
print(f"Matches b: {np.allclose(verification, b)}")
Least Squares Solution
import numpy as np
# Find best fit line: y = mx + c
x_data = np.array([1, 2, 3, 4, 5])
y_data = np.array([2.1, 3.9, 6.1, 8.2, 9.8])
# Set up system: [x, 1] × [m, c] = y
A = np.column_stack([x_data, np.ones(len(x_data))])
# Least squares solution
solution = np.linalg.lstsq(A, y_data, rcond=None)[0]
slope, intercept = solution
print(f"Best fit: y = {slope:.2f}x + {intercept:.2f}")
# Predictions
y_pred = slope * x_data + intercept
print(f"Actual: {y_data}")
print(f"Predicted: {y_pred.round(2)}")
🔄 Matrix Inverse
Find matrix inverses for solving systems.
Matrix Inverse
import numpy as np
matrix = np.array([[4, 7], [2, 6]])
try:
# Calculate inverse
inverse = np.linalg.inv(matrix)
print(f"Matrix: \n{matrix}")
print(f"Inverse: \n{inverse.round(3)}")
# Verify: A × A⁻¹ = I
identity = matrix @ inverse
print(f"A × A⁻¹: \n{identity.round(3)}")
except np.linalg.LinAlgError:
print("Matrix is not invertible!")
Pseudoinverse
import numpy as np
# Non-square matrix
matrix = np.array([[1, 2], [3, 4], [5, 6]])
# Moore-Penrose pseudoinverse
pinv = np.linalg.pinv(matrix)
print(f"Original: \n{matrix}")
print(f"Pseudoinverse: \n{pinv.round(3)}")
# Property: A × A⁺ × A = A
result = matrix @ pinv @ matrix
print(f"A × A⁺ × A: \n{result.round(3)}")
📐 Vector Operations
Essential operations for vectors.
Vector Norms
import numpy as np
vector = np.array([3, 4, 5])
# Different norms
l1_norm = np.linalg.norm(vector, ord=1) # Sum of absolutes
l2_norm = np.linalg.norm(vector, ord=2) # Euclidean
inf_norm = np.linalg.norm(vector, ord=np.inf) # Max absolute
print(f"Vector: {vector}")
print(f"L1 norm: {l1_norm}")
print(f"L2 norm: {l2_norm:.3f}")
print(f"Infinity norm: {inf_norm}")
# Unit vector
unit_vector = vector / l2_norm
print(f"Unit vector: {unit_vector.round(3)}")
Dot and Cross Products
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# Products
dot_product = np.dot(a, b)
cross_product = np.cross(a, b)
print(f"Vector a: {a}")
print(f"Vector b: {b}")
print(f"Dot product: {dot_product}")
print(f"Cross product: {cross_product}")
# Angle between vectors
cos_angle = dot_product / (np.linalg.norm(a) * np.linalg.norm(b))
angle_deg = np.degrees(np.arccos(cos_angle))
print(f"Angle: {angle_deg:.1f}°")
🧠 Real-World Applications
Principal Component Analysis
import numpy as np
# Sample data: height and weight
data = np.array([[170, 65], [175, 70], [165, 60], [180, 80], [160, 55]])
# Center data
centered = data - np.mean(data, axis=0)
# Covariance matrix
cov_matrix = np.cov(centered.T)
# PCA via eigenvalue decomposition
eigenvals, eigenvecs = np.linalg.eig(cov_matrix)
# Sort by eigenvalue
idx = eigenvals.argsort()[::-1]
eigenvals = eigenvals[idx]
eigenvecs = eigenvecs[:, idx]
print(f"Principal components: \n{eigenvecs.round(3)}")
print(f"Explained variance: {eigenvals.round(3)}")
print(f"Variance ratios: {(eigenvals/eigenvals.sum()).round(3)}")
Image Compression
import numpy as np
# Simulate image matrix
np.random.seed(42)
image = np.random.randint(0, 256, (20, 20))
# SVD compression
U, s, Vt = np.linalg.svd(image)
# Keep only top k components
k = 5
compressed = U[:, :k] @ np.diag(s[:k]) @ Vt[:k, :]
print(f"Original shape: {image.shape}")
print(f"Kept {k}/{len(s)} components")
print(f"Compression ratio: {k/len(s):.1%}")
# Reconstruction error
error = np.linalg.norm(image - compressed)
print(f"Reconstruction error: {error:.1f}")
🎯 Key Takeaways
🚀 What's Next?
You've mastered mathematical functions! Next, explore array aggregation operations.
Continue to: Array Aggregation
Was this helpful?
Track Your Learning Progress
Sign in to bookmark tutorials and keep track of your learning journey.
Your progress is saved automatically as you read.