P02: Image Compression Using SVD

P02: Image Compression Using SVD

Build a tool that compresses images by decomposing them with Singular Value Decomposition, letting you visually see how much information each โ€œrankโ€ captures.


Overview

Attribute Value
Difficulty Intermediate
Time Estimate 1-2 weeks
Language Python (recommended) or C
Prerequisites Basic matrix operations, understanding of P01
Primary Book โ€œMath for Programmersโ€ by Paul Orland

Learning Objectives

By completing this project, you will:

  1. See matrices as data - Understand that any grid of numbers (images, spreadsheets) is a matrix
  2. Master matrix decomposition - Break matrices into simpler, meaningful components
  3. Understand eigenvalues intuitively - The โ€œimportance weightsโ€ of a matrixโ€™s structure
  4. Grasp low-rank approximation - How a few numbers can capture most information
  5. Connect SVD to applications - Compression, recommendation systems, dimensionality reduction
  6. Build numerical intuition - Understand floating-point precision and numerical stability

Theoretical Foundation

Part 1: Images as Matrices

The Digital Image

A grayscale image is nothing more than a matrix of numbers:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    GRAYSCALE IMAGE AS MATRIX                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                โ”‚
โ”‚    Image (visual)              Matrix (numerical)              โ”‚
โ”‚                                                                โ”‚
โ”‚    โ–‘โ–‘โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘             [0   0   0   0   128 128 128 ... โ”‚
โ”‚    โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘              0   0   128 128 255 255 255 ... โ”‚
โ”‚    โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘              0   0   128 128 255 255 255 ... โ”‚
โ”‚    โ–‘โ–‘โ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘              0   0   128 0   0   0   128 ... โ”‚
โ”‚    โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘              0   0   0   0   0   0   0   ... โ”‚
โ”‚                                        ...                     โ”‚
โ”‚                                                                โ”‚
โ”‚    Each pixel = one matrix entry                               โ”‚
โ”‚    Value 0-255 represents darkness to brightness               โ”‚
โ”‚                                                                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Grayscale Image as Matrix

For an mร—n image, we have an mร—n matrix A where:

  • A[i][j] = brightness of pixel at row i, column j
  • Typically 0 = black, 255 = white (for 8-bit images)

For color images, we have three matrices: one each for Red, Green, Blue channels.

Matrix Properties

A 512ร—512 grayscale image:
- 512 ร— 512 = 262,144 pixels
- Each pixel = 1 byte (8 bits, values 0-255)
- Total: 262,144 bytes โ‰ˆ 256 KB

Can we store this with fewer numbers?

Part 2: The Rank of a Matrix

What is Rank?

The rank of a matrix is the number of โ€œtruly independentโ€ pieces of information it contains.

Full rank matrix (rank 3):      Low rank matrix (rank 1):

[1  0  0]                       [1  2  3]
[0  1  0]   rank = 3            [2  4  6]   rank = 1
[0  0  1]                       [3  6  9]

Every row/column adds new       All rows are multiples of [1,2,3]
information                     Only ONE piece of information!

Key insight: A rank-1 matrix can be written as the outer product of two vectors:

[1  2  3]     [1]
[2  4  6]  =  [2] ร— [1  2  3]  =  u ร— vแต€
[3  6  9]     [3]

Instead of storing 9 numbers, store 6 numbers (two vectors)!

Rank and Information

  • A rank-k matrix can be written as the sum of k rank-1 matrices
  • Real images rarely have exact low rank, but are โ€œapproximatelyโ€ low rank
  • The important patterns are captured by the first few rank-1 pieces
  • The remaining pieces are often noise or fine detail
Full Image โ‰ˆ Major patterns + Minor patterns + Finer details + Noise
             (rank 1)         (rank 2-10)     (rank 11-50)    (rest)

Part 3: Eigenvalues and Eigenvectors

The Core Concept

An eigenvector of matrix A is a special direction that only gets stretched (not rotated) by A:

A ร— v = ฮป ร— v

Where:
- v is the eigenvector (a direction in space)
- ฮป (lambda) is the eigenvalue (the stretch factor)

Visually:

                    A transforms...

Regular vector:     โ†’  gets rotated AND stretched
Eigenvector:        โ†’  gets ONLY stretched (by factor ฮป)

If ฮป = 2:  eigenvector doubles in length
If ฮป = 0.5: eigenvector halves
If ฮป = -1: eigenvector flips direction
If ฮป = 0:  eigenvector collapses to zero

Why Eigenvectors Matter

Eigenvectors reveal the natural axes of a transformation:

Consider stretching an image 2ร— horizontally, 0.5ร— vertically:

          [2   0]
Stretch = [0  0.5]

Eigenvectors: [1, 0] with ฮป=2    (horizontal direction)
              [0, 1] with ฮป=0.5  (vertical direction)

These are the "natural" directions of the transformation!

For symmetric matrices (like Aแต€A), eigenvectors are orthogonalโ€”they form a new coordinate system aligned with the matrixโ€™s โ€œpreferredโ€ directions.

Eigenvalue Magnitude

The magnitude of an eigenvalue indicates importance:

  • Large ฮป : This direction is strongly affected by the transformation
  • Small ฮป : This direction is weakly affected
  • ฮป = 0: This direction is completely nullified (in the null space)

Part 4: Singular Value Decomposition (SVD)

The Grand Decomposition

SVD says: Every matrix can be written as a sequence of three simple operations.

A = U ร— ฮฃ ร— Vแต€

Where:
- U: mร—m orthogonal matrix (rotation in output space)
- ฮฃ: mร—n diagonal matrix (scaling)
- Vแต€: nร—n orthogonal matrix (rotation in input space)

For an mร—n matrix A.

Geometrically:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      SVD GEOMETRIC INTERPRETATION                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                         โ”‚
โ”‚    Any matrix transformation can be decomposed into:                    โ”‚
โ”‚                                                                         โ”‚
โ”‚    Vแต€           ฮฃ              U                                        โ”‚
โ”‚    โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ†’  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ†’   โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                   โ”‚
โ”‚    Rotate      Scale along    Rotate again                              โ”‚
โ”‚    input       new axes       in output space                           โ”‚
โ”‚                                                                         โ”‚
โ”‚    โ—‹             โฌญ              โฌญ                                       โ”‚
โ”‚   โ•ฑโ”‚โ•ฒ    โ†’     โ•ฑ   โ•ฒ     โ†’    โ•ฑ    โ•ฒ                                    โ”‚
โ”‚    โ”‚             โ”‚               โ•ฒ                                      โ”‚
โ”‚    โ†‘             โ†‘                โ†–                                     โ”‚
โ”‚                                                                         โ”‚
โ”‚    Original   Stretched/       Final                                    โ”‚
โ”‚    circle     squished         ellipse                                  โ”‚
โ”‚               along axes                                                โ”‚
โ”‚                                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

SVD Geometric Interpretation

The Components

ฮฃ (Sigma) - The Singular Values:

        [ฯƒโ‚  0   0  ...]
    ฮฃ = [0   ฯƒโ‚‚  0  ...]
        [0   0   ฯƒโ‚ƒ ...]
        [... ... ... ]

- ฯƒโ‚ โ‰ฅ ฯƒโ‚‚ โ‰ฅ ฯƒโ‚ƒ โ‰ฅ ... โ‰ฅ 0 (ordered by magnitude)
- These are the square roots of eigenvalues of Aแต€A
- They measure the "importance" of each component

U - Left Singular Vectors:

  • Columns of U are orthonormal vectors in the output space
  • They form the new coordinate axes after transformation
  • uโ‚ is the most โ€œstretchedโ€ direction

V - Right Singular Vectors:

  • Columns of V are orthonormal vectors in the input space
  • They are the input directions that become the U directions
  • Avโ‚ points in the uโ‚ direction (scaled by ฯƒโ‚)

SVD as Sum of Rank-1 Matrices

The magical property:

A = ฯƒโ‚(uโ‚ ร— vโ‚แต€) + ฯƒโ‚‚(uโ‚‚ ร— vโ‚‚แต€) + ฯƒโ‚ƒ(uโ‚ƒ ร— vโ‚ƒแต€) + ...

Each term (uแตข ร— vแตขแต€) is a rank-1 matrix!
Each ฯƒแตข is the "weight" or importance of that term.

For images:

Image = ฯƒโ‚(patternโ‚) + ฯƒโ‚‚(patternโ‚‚) + ฯƒโ‚ƒ(patternโ‚ƒ) + ...

Where ฯƒโ‚ > ฯƒโ‚‚ > ฯƒโ‚ƒ > ...

The first few patterns capture most of the image!

Part 5: Low-Rank Approximation

The Eckart-Young-Mirsky Theorem

This is the key result that makes SVD useful for compression:

The best rank-k approximation to A is obtained by keeping only the top k singular values.

A_k = ฯƒโ‚(uโ‚ ร— vโ‚แต€) + ฯƒโ‚‚(uโ‚‚ ร— vโ‚‚แต€) + ... + ฯƒโ‚–(uโ‚– ร— vโ‚–แต€)

This is the closest rank-k matrix to A (in terms of Frobenius norm).
No other rank-k matrix is closer!

Compression Achieved

For an mร—n image with rank-k approximation:

Original storage: m ร— n values

SVD storage (rank k):
- k columns of U: m ร— k values
- k singular values: k values
- k columns of V: n ร— k values
Total: k ร— (m + n + 1) values

Compression ratio: (m ร— n) / (k ร— (m + n + 1))

Example with 512ร—512 image:

Original: 262,144 values

Rank 10:  10 ร— (512 + 512 + 1) = 10,250 values
Compression: 25.6ร— smaller!

Rank 50:  50 ร— 1,025 = 51,250 values
Compression: 5.1ร— smaller!

Choosing k

How many singular values to keep?

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    SINGULAR VALUE DECAY                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                โ”‚
โ”‚  ฯƒ                                                             โ”‚
โ”‚  โ”‚                                                             โ”‚
โ”‚  โ”‚โ–ˆ                                                            โ”‚
โ”‚  โ”‚โ–ˆ                                                            โ”‚
โ”‚  โ”‚โ–ˆโ–ˆ                                                           โ”‚
โ”‚  โ”‚โ–ˆโ–ˆโ–ˆ                                                          โ”‚
โ”‚  โ”‚โ–ˆโ–ˆโ–ˆโ–ˆ                                                         โ”‚
โ”‚  โ”‚โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ                                                       โ”‚
โ”‚  โ”‚โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ                                                    โ”‚
โ”‚  โ”‚โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ k       โ”‚
โ”‚     โ†‘           โ†‘                    โ†‘                         โ”‚
โ”‚     keep these  cutoff               discard these             โ”‚
โ”‚     (signal)    here                 (noise/detail)            โ”‚
โ”‚                                                                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Singular Value Decay

Common criteria:

  1. Keep k values that capture X% of total โ€œenergyโ€:
    (ฯƒโ‚ยฒ + ฯƒโ‚‚ยฒ + ... + ฯƒโ‚–ยฒ) / (ฯƒโ‚ยฒ + ฯƒโ‚‚ยฒ + ... + ฯƒโ‚™ยฒ) โ‰ฅ X%
    
  2. Keep values above a threshold
  3. Fixed k based on desired file size

Part 6: Computing SVD

Method 1: Via Eigendecomposition

For matrix A, compute:

  1. Aแต€A (symmetric positive semi-definite)
  2. Find eigenvalues ฮปแตข and eigenvectors vแตข of Aแต€A
  3. Singular values: ฯƒแตข = โˆšฮปแตข
  4. V = [vโ‚, vโ‚‚, โ€ฆ, vโ‚™]
  5. U columns: uแตข = Avแตข / ฯƒแตข

This works but has numerical issues for large matrices.

Method 2: Power Iteration (for largest singular value)

def largest_singular_value(A, iterations=100):
    v = random_unit_vector(n)
    for _ in range(iterations):
        u = A @ v           # Apply A
        u = u / norm(u)     # Normalize
        v = A.T @ u         # Apply Aแต€
        v = v / norm(v)     # Normalize
    sigma = norm(A @ v)
    return sigma, u, v

This finds ฯƒโ‚, uโ‚, vโ‚. For subsequent singular values, deflate: Aโ‚‚ = A - ฯƒโ‚uโ‚vโ‚แต€

Method 3: Use a Library

In practice, use optimized implementations:

import numpy as np
U, S, Vt = np.linalg.svd(A, full_matrices=False)

Part 7: Image-Specific Considerations

Color Images

For RGB images, apply SVD to each channel separately:

Original: R, G, B channels (each mร—n)

For each channel:
  U_c, ฮฃ_c, V_c = SVD(channel)
  compressed_c = U_c[:, :k] @ ฮฃ_c[:k, :k] @ V_c[:k, :]

Reconstruct: Combine compressed R, G, B

Or convert to YCbCr and compress more aggressively on chrominance channels (human eyes are less sensitive to color detail).

Block-Based Compression

Like JPEG, process image in blocks:

For each 8ร—8 or 16ร—16 block:
  Apply SVD
  Keep top k singular values
  Store U, ฮฃ, V for block

This allows local adaptation and parallelization.

Comparison with Other Methods

Method Approach SVD Similarity
JPEG DCT + quantization Both find basis; DCT uses fixed basis
PCA Find principal components PCA of rows = SVD (related)
Wavelets Multi-resolution decomposition Different basis functions

Project Specification

What Youโ€™re Building

A command-line tool that:

  1. Loads a grayscale or color image
  2. Computes SVD of the image matrix
  3. Reconstructs the image using top k singular values
  4. Displays/saves the compressed image
  5. Reports compression ratio and quality metrics

Minimum Requirements

  • Load image as matrix (grayscale first)
  • Compute SVD (use library or implement)
  • Reconstruct image with top k singular values
  • Display original vs compressed side-by-side
  • Calculate and display compression ratio
  • Allow user to specify k
  • Show singular value decay plot

Stretch Goals

  • Support color images (per-channel SVD)
  • Implement SVD from scratch (power iteration)
  • Interactive slider to adjust k in real-time
  • Calculate PSNR/SSIM quality metrics
  • Compare with JPEG at similar file sizes
  • Save compressed representation to file

Solution Architecture

Data Structures

class SVDCompressor:
    """Handles SVD-based image compression."""

    def __init__(self, image: np.ndarray):
        self.original = image
        self.U = None
        self.S = None  # Singular values
        self.Vt = None

    def compress(self, k: int) -> np.ndarray:
        """Return rank-k approximation."""
        pass

    def compression_ratio(self, k: int) -> float:
        """Calculate storage ratio."""
        pass

    def energy_captured(self, k: int) -> float:
        """Percentage of total variance captured."""
        pass

Module Structure

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           main.py                               โ”‚
โ”‚  - CLI argument parsing                                         โ”‚
โ”‚  - Load image                                                   โ”‚
โ”‚  - Display results                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                               โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ–ผ                      โ–ผ                      โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   image.py   โ”‚      โ”‚    svd.py    โ”‚      โ”‚  metrics.py  โ”‚
โ”‚              โ”‚      โ”‚              โ”‚      โ”‚              โ”‚
โ”‚ load_image   โ”‚      โ”‚ compute_svd  โ”‚      โ”‚ psnr         โ”‚
โ”‚ save_image   โ”‚      โ”‚ reconstruct  โ”‚      โ”‚ ssim         โ”‚
โ”‚ display      โ”‚      โ”‚ truncate     โ”‚      โ”‚ compression_ratio โ”‚
โ”‚ to_grayscale โ”‚      โ”‚              โ”‚      โ”‚ energy_ratio โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                               โ”‚
                               โ–ผ
                      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                      โ”‚  visualize.pyโ”‚
                      โ”‚              โ”‚
                      โ”‚ plot_singular_values โ”‚
                      โ”‚ side_by_side โ”‚
                      โ”‚ difference_image โ”‚
                      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Processing Pipeline

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        SVD COMPRESSION PIPELINE                         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                        โ”‚
โ”‚  โ”‚ Input Image โ”‚  512ร—512 grayscale                                     โ”‚
โ”‚  โ”‚ (m ร— n)     โ”‚  262,144 values                                        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                        โ”‚
โ”‚         โ”‚                                                               โ”‚
โ”‚         โ–ผ  Compute SVD                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚  โ”‚ A = U ร— ฮฃ ร— Vแต€                                   โ”‚                   โ”‚
โ”‚  โ”‚                                                  โ”‚                   โ”‚
โ”‚  โ”‚ U: 512ร—512    ฮฃ: 512ร—512 diagonal    Vแต€: 512ร—512โ”‚                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚         โ”‚              โ”‚                   โ”‚                            โ”‚
โ”‚         โ–ผ              โ–ผ                   โ–ผ                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                       โ”‚
โ”‚  โ”‚ Keep top โ”‚   โ”‚ Keep top   โ”‚      โ”‚ Keep top โ”‚                       โ”‚
โ”‚  โ”‚ k columnsโ”‚   โ”‚ k values   โ”‚      โ”‚ k rows   โ”‚                       โ”‚
โ”‚  โ”‚ of U     โ”‚   โ”‚ of ฮฃ       โ”‚      โ”‚ of Vแต€    โ”‚                       โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                       โ”‚
โ”‚         โ”‚              โ”‚                   โ”‚                            โ”‚
โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                            โ”‚
โ”‚                        โ–ผ                                                โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚              โ”‚ Reconstruct     โ”‚                                        โ”‚
โ”‚              โ”‚ A_k = U_k ฮฃ_k V_k^T โ”‚                                   โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚                       โ”‚                                                 โ”‚
โ”‚                       โ–ผ                                                 โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚              โ”‚ Compressed Imageโ”‚  k = 50: 51,250 values                 โ”‚
โ”‚              โ”‚ (rank k approx) โ”‚  5ร— compression                        โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚                                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

SVD Compression Pipeline


Phased Implementation Guide

Phase 1: Image Loading and Display (Days 1-2)

Goal: Load and display images as matrices

Tasks:

  1. Set up Python environment with numpy, PIL/OpenCV, matplotlib
  2. Load grayscale image as numpy array
  3. Display image using matplotlib
  4. Print matrix dimensions and value range
  5. Visualize raw matrix values (maybe a small crop)

Verification:

# Image should load as 2D array
assert len(image.shape) == 2  # grayscale
assert image.min() >= 0 and image.max() <= 255

# Display should show correct image
plt.imshow(image, cmap='gray')

Phase 2: SVD Computation (Days 3-4)

Goal: Compute and understand SVD components

Tasks:

  1. Compute SVD using np.linalg.svd()
  2. Verify: reconstruct original from U, S, Vt
  3. Plot singular values (should decay)
  4. Calculate energy captured by top k values

Verification:

U, S, Vt = np.linalg.svd(image, full_matrices=False)

# Reconstruct should equal original
reconstructed = U @ np.diag(S) @ Vt
assert np.allclose(image, reconstructed)

# Singular values should be non-negative and ordered
assert all(s >= 0 for s in S)
assert all(S[i] >= S[i+1] for i in range(len(S)-1))

Phase 3: Low-Rank Approximation (Days 5-6)

Goal: Reconstruct images with reduced rank

Tasks:

  1. Implement truncation to rank k
  2. Reconstruct and display for various k values
  3. Create side-by-side comparisons
  4. Calculate compression ratios

Implementation:

def compress(U, S, Vt, k):
    """Reconstruct using only top k singular values."""
    U_k = U[:, :k]
    S_k = S[:k]
    Vt_k = Vt[:k, :]
    return U_k @ np.diag(S_k) @ Vt_k

Verification:

  • k=1: Very blurry, single dominant pattern
  • k=10: Major features visible
  • k=50: Good quality for most images
  • k=full: Equals original

Phase 4: Visualization (Days 7-8)

Goal: Create informative visualizations

Tasks:

  1. Plot singular value decay (log scale useful)
  2. Show cumulative energy curve
  3. Display rank-1, rank-10, rank-50, original side by side
  4. Create difference image (original - compressed)
  5. Implement interactive slider for k

Visualizations:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   VISUALIZATION DASHBOARD                      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚  โ”‚ Singular Value Decay    โ”‚  โ”‚ Cumulative Energy       โ”‚     โ”‚
โ”‚  โ”‚                         โ”‚  โ”‚                         โ”‚     โ”‚
โ”‚  โ”‚  ฯƒ                      โ”‚  โ”‚  %                 100% โ”‚     โ”‚
โ”‚  โ”‚  โ”‚\                     โ”‚  โ”‚  โ”‚            ____โ”€โ”€    โ”‚     โ”‚
โ”‚  โ”‚  โ”‚ \                    โ”‚  โ”‚  โ”‚        ___/          โ”‚     โ”‚
โ”‚  โ”‚  โ”‚  \_____              โ”‚  โ”‚  โ”‚    ___/              โ”‚     โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ k        โ”‚  โ”‚  โ””โ”€โ”€โ”€/โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ k    โ”‚     โ”‚
โ”‚  โ”‚                         โ”‚  โ”‚                         โ”‚     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚                                                                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
โ”‚  โ”‚  k = 1    โ”‚ โ”‚  k = 10   โ”‚ โ”‚  k = 50   โ”‚ โ”‚ Original  โ”‚      โ”‚
โ”‚  โ”‚           โ”‚ โ”‚           โ”‚ โ”‚           โ”‚ โ”‚           โ”‚      โ”‚
โ”‚  โ”‚   โ–’โ–’โ–’โ–’    โ”‚ โ”‚   โ–“โ–“โ–’โ–’    โ”‚ โ”‚   โ–ˆโ–ˆโ–ˆโ–ˆ    โ”‚ โ”‚   โ–ˆโ–ˆโ–ˆโ–ˆ    โ”‚      โ”‚
โ”‚  โ”‚   โ–’โ–’โ–’โ–’    โ”‚ โ”‚   โ–“โ–“โ–’โ–’    โ”‚ โ”‚   โ–ˆโ–ˆโ–ˆโ–ˆ    โ”‚ โ”‚   โ–ˆโ–ˆโ–ˆโ–ˆ    โ”‚      โ”‚
โ”‚  โ”‚           โ”‚ โ”‚           โ”‚ โ”‚           โ”‚ โ”‚           โ”‚      โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
โ”‚                                                                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

SVD Visualization Dashboard

Phase 5: Metrics and Analysis (Days 9-10)

Goal: Quantify compression quality

Tasks:

  1. Implement PSNR (Peak Signal-to-Noise Ratio)
  2. Implement MSE (Mean Squared Error)
  3. Calculate compression ratios for various k
  4. Create quality vs. compression tradeoff plot
  5. Compare with JPEG at similar sizes

Metrics:

def mse(original, compressed):
    return np.mean((original - compressed) ** 2)

def psnr(original, compressed, max_val=255):
    return 10 * np.log10(max_val**2 / mse(original, compressed))

# PSNR > 30 dB: Good quality
# PSNR > 40 dB: Excellent quality

Phase 6: Color Images (Days 11-12)

Goal: Extend to RGB images

Tasks:

  1. Load color image and split into R, G, B channels
  2. Apply SVD to each channel
  3. Reconstruct each channel
  4. Combine channels and display
  5. Compare different k for each channel

Implementation:

def compress_color(image, k):
    channels = [image[:,:,i] for i in range(3)]
    compressed = []
    for channel in channels:
        U, S, Vt = np.linalg.svd(channel, full_matrices=False)
        compressed.append(compress(U, S, Vt, k))
    return np.stack(compressed, axis=2)

Phase 7: Optional - Implement SVD from Scratch (Days 13-14)

Goal: Understand the algorithm deeply

Tasks:

  1. Implement power iteration for largest singular value
  2. Implement matrix deflation
  3. Compute multiple singular values iteratively
  4. Compare results with numpy

Implementation:

def power_iteration(A, num_iters=100):
    """Find largest singular value and vectors."""
    m, n = A.shape
    v = np.random.randn(n)
    v = v / np.linalg.norm(v)

    for _ in range(num_iters):
        u = A @ v
        u = u / np.linalg.norm(u)
        v = A.T @ u
        v = v / np.linalg.norm(v)

    sigma = np.linalg.norm(A @ v)
    return sigma, u, v

def svd_manual(A, k):
    """Compute top k singular values via power iteration."""
    singular_values = []
    U_cols, V_cols = [], []
    A_remaining = A.copy()

    for _ in range(k):
        sigma, u, v = power_iteration(A_remaining)
        singular_values.append(sigma)
        U_cols.append(u)
        V_cols.append(v)
        A_remaining = A_remaining - sigma * np.outer(u, v)

    return np.array(U_cols).T, np.array(singular_values), np.array(V_cols)

Testing Strategy

Unit Tests

  1. SVD reconstruction:
    • Full reconstruction should equal original (within floating point tolerance)
  2. Singular value properties:
    • All singular values โ‰ฅ 0
    • Sorted in descending order
    • Count โ‰ค min(m, n)
  3. Orthogonality:
    • U columns should be orthonormal: Uแต€U = I
    • V columns should be orthonormal: Vแต€V = I
  4. Rank-k approximation:
    • rank(A_k) โ‰ค k
    • A_k converges to A as k increases

Visual Tests

  1. Quality progression: k=1 โ†’ k=full should show smooth improvement
  2. No artifacts: Compressed image shouldnโ€™t have obvious visual errors
  3. Difference image: Should show high-frequency detail removed

Numerical Tests

  1. Compression ratio: Should match theoretical formula
  2. Energy capture: Sum of top k ฯƒยฒ / total ฯƒยฒ should increase with k
  3. PSNR: Should increase with k

Common Pitfalls and Debugging

Numerical Precision

Symptom: Small differences between original and full reconstruction

Cause: Floating-point arithmetic has limited precision

Fix: Use np.allclose() with appropriate tolerance, not exact equality

Image Data Type

Symptom: Image looks wrong or values are clipped

Cause: Image loaded as uint8 (0-255) but SVD produces floats

Fix: Convert to float before SVD, clip to [0, 255] after reconstruction

Memory for Large Images

Symptom: Out of memory for large images

Cause: Full SVD computes all singular values

Fix: Use svd(A, full_matrices=False) for economy SVD, or use randomized SVD

Color Channel Issues

Symptom: Color images have wrong colors after reconstruction

Cause: Channels mixed up or not properly recombined

Fix: Carefully track channel order, ensure floatโ†’uint8 conversion is correct

Visualization Scale

Symptom: Compressed image looks too dark or too bright

Cause: Value range not normalized for display

Fix: Clip to valid range, or normalize: (image - min) / (max - min)


Extensions and Challenges

Beginner Extensions

  • Save/load compressed representation
  • Process multiple images in batch
  • Add command-line interface with argparse

Intermediate Extensions

  • Implement randomized SVD for large images
  • Adaptive k selection based on quality threshold
  • Block-based SVD (like JPEG blocks)
  • Video compression (SVD on frame differences)

Advanced Extensions

  • Implement truncated SVD with Lanczos algorithm
  • Compare with DCT-based compression
  • Explore tensor decomposition for color images
  • GPU acceleration with CuPy or PyTorch

Real-World Connections

Data Compression

SVD is the mathematical foundation for:

  • Netflixโ€™s video encoding (partial)
  • Image thumbnails and progressive loading
  • Scientific data compression

Recommendation Systems

Netflix Prize (2006-2009) used matrix factorization:

Ratings Matrix โ‰ˆ U ร— ฮฃ ร— Vแต€

U rows: user latent factors (taste preferences)
V rows: item latent factors (movie characteristics)
ฮฃ: importance weights

Your image compression is training you for this!

Dimensionality Reduction

PCA (Principal Component Analysis) is closely related:

Centered data matrix X
PCA directions = right singular vectors of X
PCA scores = left singular vectors ร— singular values

Natural Language Processing

Latent Semantic Analysis (LSA):

Term-Document Matrix โ†’ SVD โ†’ Topics

U: term-topic relationships
V: document-topic relationships
ฮฃ: topic importance

Noise Reduction

Small singular values often correspond to noise:

Signal โ‰ˆ large singular values
Noise โ‰ˆ small singular values

Removing small ฯƒแตข denoises the data!

Self-Assessment Checklist

Conceptual Understanding

  • I can explain what a matrix rank means geometrically
  • I understand why singular values are ordered
  • I can explain the Eckart-Young theorem in simple terms
  • I know why low-rank approximation works for compression
  • I understand the relationship between SVD and eigendecomposition

Practical Skills

  • I can compute SVD and reconstruct the original matrix
  • I can choose an appropriate k for a given compression target
  • I can measure and interpret compression quality metrics
  • I can visualize singular value decay and energy capture
  • I can apply SVD compression to color images

Teaching Test

Can you explain to someone else:

  • Why can a rank-1 matrix be stored with fewer numbers?
  • What do the columns of U and V represent?
  • Why are the first singular values larger?
  • How does SVD relate to JPEG compression?

Resources

Primary

  • โ€œMath for Programmersโ€ by Paul Orland - Practical approach
  • 3Blue1Brown: Essence of Linear Algebra - Especially the SVD intuition
  • Grokking Algorithms - Appendix on linear algebra

Reference

  • โ€œNumerical Linear Algebraโ€ by Trefethen & Bau - Rigorous treatment
  • โ€œMining of Massive Datasetsโ€ - SVD for recommendation
  • โ€œThe Elements of Statistical Learningโ€ - SVD/PCA connection

Online

  • NumPy SVD documentation - Implementation details
  • Interactive SVD visualizations - Various web apps
  • JPEG compression tutorials - For comparison

When you complete this project, youโ€™ll understand that matrices contain hidden structureโ€”and that structure can be extracted, prioritized, and reconstructed. This is the foundation for machine learning, signal processing, and data science.