How are high frequencies less present in discrete Fourier transforms?

33 Views Asked by At

I'm reading about Fourier transforms and how they are used for compression in mp3 and jpg.

$X_k = \Sigma_{n=0}^{N}x_n e^{2\pi ikn/N}$

I focus only on the real part and I assume my observations wlog extend to the imaginary part:

$\Re(X_k) = \Sigma_{n=0}^{N}x_n \cos(2\pi kn/N)$

When they say "frequency", they are referring to $k$ and its presence $X_k$. I then say that the $n$th coefficient for frequency $k$ is $\cos(2\pi kn/N)$

Lossy compression is based on the habit that many frequencies aren't present very much (i.e. $X_k\approx 0$ for many $k$) so such presences can be assumed zero. I read (https://www.analog.com/media/en/technical-documentation/dsp-book/dsp_book_Ch27.pdf) that this holds especially for the higher frequencies ($k > N/2$):

[N]early all of the signal is contained in the low frequency components. This means the highest frequency components can be eliminated, while only degrading the signal a small amount. [pg. 499] ... This places all of the high frequency components together, where the large number of zeros can be efficiently compressed with run-length encoding. [pg. 500]

I don't understand why it should hold particularly for the higher frequencies, because I don't see a fundamental difference between high and low frequencies. In my view, a different frequency just gives a different permutation of the coefficients (as opposed to another set of values), or at least this seems to be the case for the set of frequencies $k$ that are co-prime with $N$. Since a different value for $k$ just gives another permutation of the coefficients, I don't see why higher values of $k$ should more often lead to $X_k$ values close to zero, even for rhythmic input $x_i$.

The following Java program prints "All the same", which illustrates my thought that another frequency is nothing more than another permutation of the coefficients.

public static void main(String[] args) {
    double[] X5 = new double[1024]; // coefficients for X5, a low frequency.
    double[] X999 = new double[1024]; // coefficients for X999, a high frequency.
    int N = X5.length;

    int k = 5;
    for (int n=0; n<N; n++) {
        X5[n] = Math.cos(2 * Math.PI * n * k / N);
    }

    k = 999;
    for (int n=0; n<N; n++) {
        X999[n] = Math.cos(2 * Math.PI * n * k / N);
    }

    Arrays.sort(X5);
    Arrays.sort(X999);

    for (int i=0; i<N; i++) {
        if (!equal(X5[i], X999[i])) {
            System.out.println("Not the same: " + i);
            System.exit(0);
        }
    }
    System.out.println("All the same");
}

private static boolean equal(double v1, double v2) {
    return Math.abs(v1-v2) < 0.0000001d;
}