🔢 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.