The discrete cosine transform(DCT) is a popular choice for spectral analysis in audio, video, image compression algorithms. This is primarily due its efficient "spectral compaction" property in comparison with Fast Fourier Transform(FFT). Is there a way to measure approximate "spectral compaction-gain" (if its appropriate to term) - say "X" times - achieved by using DCT on data instead of FFT?


2 Answers 2


In Discrete-Time Signal Processing by Oppenheim, chapter 8.5, there is a quantification of mean squared error by setting coefficients to 0 for both DCT and DFT:

enter image description here

From this, you can of course calculate the percentages as you see fit. This particular analysis was done for signal:

$$x[n] = a^n\cos(\omega_0n + \phi)$$

with following transforms:

enter image description here

If you wish to play with this example here's the code. It gives both the MSE and the amount of energy preserved after reconstruction.

enter image description here enter image description here

%% Signal to analyse
N = 32; % Must be even!
a = 0.9;
w0 = 0.1*pi;

n = 1:N;
x = a.^n.*cos(w0*n);

plot(n, x)

%% Calculate transforms
Xdft = fft(x);
Xdct = dct(x);

%% Plot

stem(0:N/2, real(Xdft(1:N/2+1)))
title("Real part of DFT")

stem(0:N/2, imag(Xdft(1:N/2+1)))
title("Imaginary part of DFT")

stem(0:N-1, Xdct)

%% Compact and measure
mseDFT = []; % Mean Squared Error
mseDCT = [];
energyDFT = []; % Energy preserved
energyDCT = [];
%In case of DFT we must zero 1,3,5,... bins starting from Nyquist
for m=1:N/2
    xRec = dftReconstructCompact(Xdft, m);
    mseDFT(m) = mean(abs(x-xRec).^2);
    energyDFT(m) = norm(xRec) / norm(x);

for m=1:N
    xRec = dctReconstructCompact(Xdct, m);
    mseDCT(m) = mean(abs(x-xRec).^2);
    energyDCT(m) = norm(xRec) / norm(x);
%% Plot the errors
plot(1:N, mseDCT, '-x')
hold on
plot(1:2:N, mseDFT, '-o')
grid on
legend({"DCT", "DFT"})
title("MSE between original and truncated")

plot(1:N, energyDCT, '-x')
hold on
plot(1:2:N, energyDFT, '-o')
grid on
legend({"DCT", "DFT"})
title("Energy Preserved after truncation")

%% Helper functions

function xRec = dftReconstructCompact(X, m)
% Zero-out 2*m-1 points from the DFT (starting from Nyquist bin and move 
% left and right from there) then reconstruct the time domain signal.
Nyq = length(X)/2+1;
X(Nyq-m+1:Nyq+m-1) = 0;
xRec = ifft(X);

function xRec = dctReconstructCompact(X, m)
% Starting from the highest bin, zero out `m` values and reconstruct 
% the time domain signal.
N = length(X);
X(N-m+1:N) = 0;
xRec = idct(X);

My copy of MATLAB documents the dct() function by a first example showing how many coefficients are required to represent 99% of the energy of a signal. I guess you could extend that example code to also do fft() or possibly pca()?



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.