dist-javascript-algorithms-and-data-structures
Version:
Algorithms and data-structures implemented on JavaScript
433 lines (416 loc) • 7.64 kB
JavaScript
"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;