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;
}