dist-javascript-algorithms-and-data-structures
Version:
Algorithms and data-structures implemented on JavaScript
59 lines (44 loc) • 1.98 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = inverseDiscreteFourierTransform;
var _ComplexNumber = _interopRequireDefault(require("../complex-number/ComplexNumber"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const CLOSE_TO_ZERO_THRESHOLD = 1e-10;
/**
* Inverse Discrete Fourier Transform (IDFT): frequencies to time.
*
* Time complexity: O(N^2)
*
* @param {ComplexNumber[]} frequencies - Frequencies summands of the final signal.
* @param {number} zeroThreshold - Threshold that is used to convert real and imaginary numbers
* to zero in case if they are smaller then this.
*
* @return {number[]} - Discrete amplitudes distributed in time.
*/
function inverseDiscreteFourierTransform(frequencies, zeroThreshold = CLOSE_TO_ZERO_THRESHOLD) {
const N = frequencies.length;
const amplitudes = []; // Go through every discrete point of time.
for (let timer = 0; timer < N; timer += 1) {
// Compound amplitude at current time.
let amplitude = new _ComplexNumber.default(); // Go through all discrete frequencies.
for (let frequency = 0; frequency < N; frequency += 1) {
const currentFrequency = frequencies[frequency]; // Calculate rotation angle.
const rotationAngle = 2 * Math.PI * frequency * (timer / N); // Remember that e^ix = cos(x) + i * sin(x);
const frequencyContribution = new _ComplexNumber.default({
re: Math.cos(rotationAngle),
im: Math.sin(rotationAngle)
}).multiply(currentFrequency);
amplitude = amplitude.add(frequencyContribution);
} // Close to zero? You're zero.
if (Math.abs(amplitude.re) < zeroThreshold) {
amplitude.re = 0;
}
if (Math.abs(amplitude.im) < zeroThreshold) {
amplitude.im = 0;
} // Add current frequency signal to the list of compound signals.
amplitudes[timer] = amplitude.re;
}
return amplitudes;
}