Implement Proper Orthogonal Decomposition (POD) in the src/svdrom/pod.py module.
The POD should use the SVD class/function (see #2)
POD calculation using NumPy:
import numpy as np
n_snapshots = 200 # number of temporal snapshots
n_points = 10_000 # number of grid points
X = np.random.rand(n_snapshots, n_points) # data matrix with dimensions (n_snapshots x n_points)
X_mean = np.mean(X, axis=0) # time average
X_fluc = X - X_mean # fluctuations about the time average
u, s, v = np.linalg.svd(X_fluc/np.sqrt(n_snapshots), full_matrices=False)
phi = v.T # these are the POD modes (i.e. spatial modes)
coeffs = u @ np.diag(s) # these are the temporal coefficients, should be equivalent to `X_fluc/np.sqrt(n_snapshots) @ phi`
energy = s**2 # energy associated with each POD mode
# Note the following:
C = X_fluc.T @ X_fluc / n_snapshots # covariance matrix (a.k.a. Reynolds Stress Tensor)
total_energy = np.trace(C) # should be equivalent to `np.sum(coeffs**2)` and to `np.sum(energy)`
References:
Implement Proper Orthogonal Decomposition (POD) in the
src/svdrom/pod.pymodule.The POD should use the SVD class/function (see #2)
POD calculation using NumPy:
References: