UNPKG

dist-javascript-algorithms-and-data-structures

Version:

Algorithms and data-structures implemented on JavaScript

433 lines (416 loc) 7.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.fourierTestCases = void 0; var _ComplexNumber = _interopRequireDefault(require("../../complex-number/ComplexNumber")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const fourierTestCases = [{ input: [{ amplitude: 1 }], output: [{ frequency: 0, amplitude: 1, phase: 0, re: 1, im: 0 }] }, { input: [{ amplitude: 1 }, { amplitude: 0 }], output: [{ frequency: 0, amplitude: 0.5, phase: 0, re: 0.5, im: 0 }, { frequency: 1, amplitude: 0.5, phase: 0, re: 0.5, im: 0 }] }, { input: [{ amplitude: 2 }, { amplitude: 0 }], output: [{ frequency: 0, amplitude: 1, phase: 0, re: 1, im: 0 }, { frequency: 1, amplitude: 1, phase: 0, re: 1, im: 0 }] }, { input: [{ amplitude: 1 }, { amplitude: 0 }, { amplitude: 0 }], output: [{ frequency: 0, amplitude: 0.33333, phase: 0, re: 0.33333, im: 0 }, { frequency: 1, amplitude: 0.33333, phase: 0, re: 0.33333, im: 0 }, { frequency: 2, amplitude: 0.33333, phase: 0, re: 0.33333, im: 0 }] }, { input: [{ amplitude: 1 }, { amplitude: 0 }, { amplitude: 0 }, { amplitude: 0 }], output: [{ frequency: 0, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }, { frequency: 1, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }, { frequency: 2, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }, { frequency: 3, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }] }, { input: [{ amplitude: 0 }, { amplitude: 1 }, { amplitude: 0 }, { amplitude: 0 }], output: [{ frequency: 0, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }, { frequency: 1, amplitude: 0.25, phase: -90, re: 0, im: -0.25 }, { frequency: 2, amplitude: 0.25, phase: 180, re: -0.25, im: 0 }, { frequency: 3, amplitude: 0.25, phase: 90, re: 0, im: 0.25 }] }, { input: [{ amplitude: 0 }, { amplitude: 0 }, { amplitude: 1 }, { amplitude: 0 }], output: [{ frequency: 0, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }, { frequency: 1, amplitude: 0.25, phase: 180, re: -0.25, im: 0 }, { frequency: 2, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }, { frequency: 3, amplitude: 0.25, phase: 180, re: -0.25, im: 0 }] }, { input: [{ amplitude: 0 }, { amplitude: 0 }, { amplitude: 0 }, { amplitude: 2 }], output: [{ frequency: 0, amplitude: 0.5, phase: 0, re: 0.5, im: 0 }, { frequency: 1, amplitude: 0.5, phase: 90, re: 0, im: 0.5 }, { frequency: 2, amplitude: 0.5, phase: 180, re: -0.5, im: 0 }, { frequency: 3, amplitude: 0.5, phase: -90, re: 0, im: -0.5 }] }, { input: [{ amplitude: 0 }, { amplitude: 1 }, { amplitude: 0 }, { amplitude: 2 }], output: [{ frequency: 0, amplitude: 0.75, phase: 0, re: 0.75, im: 0 }, { frequency: 1, amplitude: 0.25, phase: 90, re: 0, im: 0.25 }, { frequency: 2, amplitude: 0.75, phase: 180, re: -0.75, im: 0 }, { frequency: 3, amplitude: 0.25, phase: -90, re: 0, im: -0.25 }] }, { input: [{ amplitude: 4 }, { amplitude: 1 }, { amplitude: 0 }, { amplitude: 2 }], output: [{ frequency: 0, amplitude: 1.75, phase: 0, re: 1.75, im: 0 }, { frequency: 1, amplitude: 1.03077, phase: 14.03624, re: 0.99999, im: 0.25 }, { frequency: 2, amplitude: 0.25, phase: 0, re: 0.25, im: 0 }, { frequency: 3, amplitude: 1.03077, phase: -14.03624, re: 1, im: -0.25 }] }, { input: [{ amplitude: 4 }, { amplitude: 1 }, { amplitude: -3 }, { amplitude: 2 }], output: [{ frequency: 0, amplitude: 1, phase: 0, re: 1, im: 0 }, { frequency: 1, amplitude: 1.76776, phase: 8.13010, re: 1.75, im: 0.25 }, { frequency: 2, amplitude: 0.5, phase: 180, re: -0.5, im: 0 }, { frequency: 3, amplitude: 1.76776, phase: -8.13010, re: 1.75, im: -0.24999 }] }, { input: [{ amplitude: 1 }, { amplitude: 2 }, { amplitude: 3 }, { amplitude: 4 }], output: [{ frequency: 0, amplitude: 2.5, phase: 0, re: 2.5, im: 0 }, { frequency: 1, amplitude: 0.70710, phase: 135, re: -0.5, im: 0.49999 }, { frequency: 2, amplitude: 0.5, phase: 180, re: -0.5, im: 0 }, { frequency: 3, amplitude: 0.70710, phase: -134.99999, re: -0.49999, im: -0.5 }] }]; exports.fourierTestCases = fourierTestCases; class FourierTester { /** * @param {function} fourierTransform */ static testDirectFourierTransform(fourierTransform) { fourierTestCases.forEach(testCase => { const { input, output: expectedOutput } = testCase; // Try to split input signal into sequence of pure sinusoids. const formattedInput = input.map(sample => sample.amplitude); const currentOutput = fourierTransform(formattedInput); // Check the signal has been split into proper amount of sub-signals. expect(currentOutput.length).toBeGreaterThanOrEqual(formattedInput.length); // Now go through all the signals and check their frequency, amplitude and phase. expectedOutput.forEach((expectedSignal, frequency) => { // Get template data we want to test against. const currentSignal = currentOutput[frequency]; const currentPolarSignal = currentSignal.getPolarForm(false); // Check all signal parameters. expect(frequency).toBe(expectedSignal.frequency); expect(currentSignal.re).toBeCloseTo(expectedSignal.re, 4); expect(currentSignal.im).toBeCloseTo(expectedSignal.im, 4); expect(currentPolarSignal.phase).toBeCloseTo(expectedSignal.phase, 4); expect(currentPolarSignal.radius).toBeCloseTo(expectedSignal.amplitude, 4); }); }); } /** * @param {function} inverseFourierTransform */ static testInverseFourierTransform(inverseFourierTransform) { fourierTestCases.forEach(testCase => { const { input: expectedOutput, output: inputFrequencies } = testCase; // Try to join frequencies into time signal. const formattedInput = inputFrequencies.map(frequency => { return new _ComplexNumber.default({ re: frequency.re, im: frequency.im }); }); const currentOutput = inverseFourierTransform(formattedInput); // Check the signal has been combined of proper amount of time samples. expect(currentOutput.length).toBeLessThanOrEqual(formattedInput.length); // Now go through all the amplitudes and check their values. expectedOutput.forEach((expectedAmplitudes, timer) => { // Get template data we want to test against. const currentAmplitude = currentOutput[timer]; // Check if current amplitude is close enough to the calculated one. expect(currentAmplitude).toBeCloseTo(expectedAmplitudes.amplitude, 4); }); }); } } exports.default = FourierTester;