Task 4 of 5
Noise is broadband; a tone is not. In the time domain they are hopelessly mixed —
noisy looks like grass. In the frequency domain they come apart: three tones
put nearly all their energy into three bins, while the noise spreads its energy thinly over
all 256. Concentration versus dilution is the entire trick, and it is the best argument
anyone has ever made for paying the cost of a transform.
The numbers here: the three tones land at magnitudes 124, 71 and 42, and the loudest noise bin reaches 19.5. Anything between about 22 and 40 separates them; the gate is set to 30, comfortably in the middle of that gap.
A convenience falls out of the conjugate symmetry that made task 2 painful. Bin
k and bin n − k are conjugates, and conjugates have
equal magnitude — so a gate that reads magnitude keeps or drops both mirrors
together, automatically, and the result comes back real without you doing anything about
it. Magnitude needs both planes though:
const mag = Math.sqrt(re * re + im * im);
The starter gates on Math.abs(re) alone, which throws away any tone whose
energy happens to sit in the imaginary part. Run it and watch the SNR go the wrong way.
You are given clean as well as noisy — you would not have it
in real life, and that is the point: it is here so the improvement can be a number instead
of an impression.
gate so every bin quieter than
this.constants.gate is zeroed on both planes, then read the two SNR figures
off the console. Before is about 4.8 dB; after should be over
20 dB.output: [256, 2]; the spectrum arrives as spec[0][k] / spec[1][k]Math.sqrt(re * re + im * im)0 on both planes when that magnitude is below this.constants.gate; otherwise pass the bin through unchangedEvery thread of a bin has to reach the same verdict, so read both planes whichever one you are on:
const k = this.thread.x;
const re = spec[0][k];
const im = spec[1][k];
const mag = Math.sqrt(re * re + im * im);
if (mag < this.constants.gate) return 0;
Dropping the Math.sqrt and comparing re*re + im*im against
30 is not the same test — it is a gate at magnitude 5.5, and 171 of the 256 bins
clear it.
Signal-to-noise in dB is ten times the log of a power ratio: the clean signal's energy over the energy of whatever you got wrong.
let signal = 0;
let error = 0;
for (let i = 0; i < 256; i++) {
signal += clean[i] * clean[i];
error += (test[i] - clean[i]) * (test[i] - clean[i]);
}
const db = 10 * Math.log10(signal / error);This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.