The decomposition of any matrix into the product of an orthogonal matrix, a diagonal matrix with nonzero diagonal elements ranked from highest to lowest, and another orthogonal matrix.

Theorem

Let

Let

  • : matrix
  • : matrix
  • : matrix

If

  • orthogonally diagonalizes
  • Nonzero diagonal entries of are , , , where are nonzero eigenvalues of corresponding to the column vectors of
  • Column vectors of are ordered so that
  • is an orthonormal basis for 1
  • is an extension of to an orthonormal basis for

Then

Procedure

To compute the SVD of an matrix with rank :

  1. Compute (an symmetric matrix)

  2. Find eigenvalues and eigenvectors of

    • Find all eigenvalues of
    • Find corresponding eigenvectors for each eigenvalue
  3. Normalize the eigenvectors

  4. Order eigenvalues and eigenvectors

    • Order eigenvalues from largest to smallest:
    • Order the corresponding unit eigenvectors accordingly to form
  5. Construct (an matrix)

    • Compute singular values: for
    • Place on the diagonal
    • Fill remaining entries with zeros
  6. Construct (an matrix)

    • For : compute
    • If , extend with solution space of
    • Form
  7. (Optional) Verify:

In short,

  1. Descending sort normalized eigenvalues () & eigenvectors () of
  2. . If ,
  3. Column stack with if

Tip

Based on Tranpose product rank theorem

Based on Number of Nonzero Eigenvalues Theorem

Example

Let

Step 1: Compute

Step 2: Find eigenvalues and eigenvectors of

Finding eigenvalues:

Thus,

Finding eigenvectors:

For :

For :

For :

Suppose for , for and . The unnormalized eigenvectors are:

Step 3: Normalize the eigenvectors to unit length

For

For

For

Step 4: Order eigenvalues and eigenvectors

Step 5: Construct

Step 6: Construct

For : compute

For

For

Notice that . Thus we extend with :

Find in :

So , . Suppose

Unnormalized vector:

Therefore

Step 7: Verify

Eigenvalues of and

Let be an matrix.

The nonzero eigenvalues of and are identical.

Note

This explains why we can compute SVD using either or - they share the same nonzero eigenvalues, which determine the singular values.

Existence of SVD

Let be an matrix with .

Then can be written as:

where:

  • and are orthogonal matrices
  • is a diagonal matrix containing the nonzero eigenvalues of or , ordered from largest to smallest

Note

This is equivalent to the standard SVD form , where , , and .

Rank and Nonzero Eigenvalues

For any matrix :

Equivalently, the column rank and row rank equal the number of nonzero singular values.

Note

This connects Rank to eigenvalues through SVD, providing a computational method for determining rank.

Rank of Kronecker Product

Let be an matrix and be a matrix.

Then:

where denotes the Kronecker product.

Non-negative Definite Characterization

Let be an symmetric matrix.

Then is positive semidefinite if and only if:

for all positive semidefinite matrices .

where denotes the trace of a matrix.

Rayleigh Quotient Bounds

Let be an Positive Semidefinite Matrix with nonzero eigenvalues ordered as .

For any nonzero vector :

Case 1: If (full rank):

Case 2: If (rank deficient):

Note

The quantity is called the Rayleigh quotient. This theorem shows that:

  • The largest eigenvalue is the maximum value of the Rayleigh quotient
  • The smallest nonzero eigenvalue is the minimum value (when is full rank)
  • When is rank deficient, the Rayleigh quotient can reach 0

Code implementation

import numpy as np
from scipy.linalg import null_space
 
np.set_printoptions(precision=2, suppress=True)
 
 
A = np.array([
    [2, 3],
    [4, 5],
    [6, 7]
])
 
print(f"{A=}")
#|| <jIh\n\n{k=}laa2rII|bCEGstAtvo>
 
k = int(np.linalg.matrix_rank(A))
m, n = A.shape
 
ATA = A.T @ A
 
eigval, eigvec = np.linalg.eig(ATA)
 
# Descending sort
idx = np.argsort(eigval)[::-1]
eigval_sorted = eigval[idx]
V = eigvec[:, idx]
sigma = np.sqrt(eigval_sorted[:k])
 
Sigma = np.zeros((m, n))
Sigma[:k, :k] = np.diag(sigma)
 
U_k = np.column_stack([A @ V[:, i] / sigma[i] for i in range(k)])
if k < m:
    U = np.column_stack([U_k, null_space(A.T)])
else:
    U = U_k
 
 
#|| <bCEGstAtvo|gnwb7rDeUd>
 
print(U @ Sigma @ V.T)
print(A)
print(np.allclose(A, U @ Sigma @ V.T))

Footnotes

  1. Column Space