Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 351a745

Browse files
committed
Refactor DFT and add common tests for Fourier.
1 parent 13ed506 commit 351a745

File tree

3 files changed

+314
-164
lines changed

3 files changed

+314
-164
lines changed
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
import ComplexNumber from '../../complex-number/ComplexNumber';
2+
3+
export const fourierDirectTestCases = [
4+
{
5+
input: [
6+
{ amplitude: 1 },
7+
],
8+
output: [
9+
{
10+
frequency: 0, amplitude: 1, phase: 0, re: 1, im: 0,
11+
},
12+
],
13+
},
14+
{
15+
input: [
16+
{ amplitude: 1 },
17+
{ amplitude: 0 },
18+
],
19+
output: [
20+
{
21+
frequency: 0, amplitude: 0.5, phase: 0, re: 0.5, im: 0,
22+
},
23+
{
24+
frequency: 1, amplitude: 0.5, phase: 0, re: 0.5, im: 0,
25+
},
26+
],
27+
},
28+
{
29+
input: [
30+
{ amplitude: 2 },
31+
{ amplitude: 0 },
32+
],
33+
output: [
34+
{
35+
frequency: 0, amplitude: 1, phase: 0, re: 1, im: 0,
36+
},
37+
{
38+
frequency: 1, amplitude: 1, phase: 0, re: 1, im: 0,
39+
},
40+
],
41+
},
42+
{
43+
input: [
44+
{ amplitude: 1 },
45+
{ amplitude: 0 },
46+
{ amplitude: 0 },
47+
],
48+
output: [
49+
{
50+
frequency: 0, amplitude: 0.3333, phase: 0, re: 0.3333, im: 0,
51+
},
52+
{
53+
frequency: 1, amplitude: 0.3333, phase: 0, re: 0.3333, im: 0,
54+
},
55+
{
56+
frequency: 2, amplitude: 0.3333, phase: 0, re: 0.3333, im: 0,
57+
},
58+
],
59+
},
60+
{
61+
input: [
62+
{ amplitude: 1 },
63+
{ amplitude: 0 },
64+
{ amplitude: 0 },
65+
{ amplitude: 0 },
66+
],
67+
output: [
68+
{
69+
frequency: 0, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
70+
},
71+
{
72+
frequency: 1, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
73+
},
74+
{
75+
frequency: 2, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
76+
},
77+
{
78+
frequency: 3, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
79+
},
80+
],
81+
},
82+
{
83+
input: [
84+
{ amplitude: 0 },
85+
{ amplitude: 1 },
86+
{ amplitude: 0 },
87+
{ amplitude: 0 },
88+
],
89+
output: [
90+
{
91+
frequency: 0, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
92+
},
93+
{
94+
frequency: 1, amplitude: 0.25, phase: -90, re: 0, im: -0.25,
95+
},
96+
{
97+
frequency: 2, amplitude: 0.25, phase: 180, re: -0.25, im: 0,
98+
},
99+
{
100+
frequency: 3, amplitude: 0.25, phase: 90, re: 0, im: 0.25,
101+
},
102+
],
103+
},
104+
{
105+
input: [
106+
{ amplitude: 0 },
107+
{ amplitude: 0 },
108+
{ amplitude: 1 },
109+
{ amplitude: 0 },
110+
],
111+
output: [
112+
{
113+
frequency: 0, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
114+
},
115+
{
116+
frequency: 1, amplitude: 0.25, phase: 180, re: -0.25, im: 0,
117+
},
118+
{
119+
frequency: 2, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
120+
},
121+
{
122+
frequency: 3, amplitude: 0.25, phase: 180, re: -0.25, im: 0,
123+
},
124+
],
125+
},
126+
{
127+
input: [
128+
{ amplitude: 0 },
129+
{ amplitude: 0 },
130+
{ amplitude: 0 },
131+
{ amplitude: 2 },
132+
],
133+
output: [
134+
{
135+
frequency: 0, amplitude: 0.5, phase: 0, re: 0.5, im: 0,
136+
},
137+
{
138+
frequency: 1, amplitude: 0.5, phase: 90, re: 0, im: 0.5,
139+
},
140+
{
141+
frequency: 2, amplitude: 0.5, phase: 180, re: -0.5, im: 0,
142+
},
143+
{
144+
frequency: 3, amplitude: 0.5, phase: -90, re: 0, im: -0.5,
145+
},
146+
],
147+
},
148+
{
149+
input: [
150+
{ amplitude: 0 },
151+
{ amplitude: 1 },
152+
{ amplitude: 0 },
153+
{ amplitude: 2 },
154+
],
155+
output: [
156+
{
157+
frequency: 0, amplitude: 0.75, phase: 0, re: 0.75, im: 0,
158+
},
159+
{
160+
frequency: 1, amplitude: 0.25, phase: 90, re: 0, im: 0.25,
161+
},
162+
{
163+
frequency: 2, amplitude: 0.75, phase: 180, re: -0.75, im: 0,
164+
},
165+
{
166+
frequency: 3, amplitude: 0.25, phase: -90, re: 0, im: -0.25,
167+
},
168+
],
169+
},
170+
{
171+
input: [
172+
{ amplitude: 4 },
173+
{ amplitude: 1 },
174+
{ amplitude: 0 },
175+
{ amplitude: 2 },
176+
],
177+
output: [
178+
{
179+
frequency: 0, amplitude: 1.75, phase: 0, re: 1.75, im: 0,
180+
},
181+
{
182+
frequency: 1, amplitude: 1.03077, phase: 14.0362, re: 0.99999, im: 0.25,
183+
},
184+
{
185+
frequency: 2, amplitude: 0.25, phase: 0, re: 0.25, im: 0,
186+
},
187+
{
188+
frequency: 3, amplitude: 1.03077, phase: -14.0362, re: 1, im: -0.25,
189+
},
190+
],
191+
},
192+
{
193+
input: [
194+
{ amplitude: 4 },
195+
{ amplitude: 1 },
196+
{ amplitude: -3 },
197+
{ amplitude: 2 },
198+
],
199+
output: [
200+
{
201+
frequency: 0, amplitude: 1, phase: 0, re: 1, im: 0,
202+
},
203+
{
204+
frequency: 1, amplitude: 1.76776, phase: 8.1301, re: 1.75, im: 0.25,
205+
},
206+
{
207+
frequency: 2, amplitude: 0.5, phase: 180, re: -0.5, im: 0,
208+
},
209+
{
210+
frequency: 3, amplitude: 1.76776, phase: -8.13010, re: 1.75, im: -0.24999,
211+
},
212+
],
213+
},
214+
{
215+
input: [
216+
{ amplitude: 1 },
217+
{ amplitude: 2 },
218+
{ amplitude: 3 },
219+
{ amplitude: 4 },
220+
],
221+
output: [
222+
{
223+
frequency: 0, amplitude: 2.5, phase: 0, re: 2.5, im: 0,
224+
},
225+
{
226+
frequency: 1, amplitude: 0.70710, phase: 135, re: -0.5, im: 0.49999,
227+
},
228+
{
229+
frequency: 2, amplitude: 0.5, phase: 180, re: -0.5, im: 0,
230+
},
231+
{
232+
frequency: 3, amplitude: 0.70710, phase: -134.99999, re: -0.49999, im: -0.5,
233+
},
234+
],
235+
},
236+
];
237+
238+
export default class FourierTester {
239+
/**
240+
* @param {function} fourierTransform
241+
*/
242+
static testDirectFourierTransform(fourierTransform) {
243+
fourierDirectTestCases.forEach((testCase) => {
244+
const { input, output: expectedOutput } = testCase;
245+
246+
// Convert input into complex numbers.
247+
const complexInput = input.map(sample => new ComplexNumber({ re: sample.amplitude }));
248+
249+
// Try to split input signal into sequence of pure sinusoids.
250+
const currentOutput = fourierTransform(complexInput);
251+
252+
// Check the signal has been split into proper amount of sub-signals.
253+
expect(currentOutput.length).toBeGreaterThanOrEqual(complexInput.length);
254+
255+
// Now go through all the signals and check their frequency, amplitude and phase.
256+
expectedOutput.forEach((expectedSignal, frequency) => {
257+
// Get template data we want to test against.
258+
const currentSignal = currentOutput[frequency];
259+
const currentPolarSignal = currentSignal.getPolarForm(false);
260+
261+
// Check all signal parameters.
262+
expect(frequency).toBe(expectedSignal.frequency);
263+
expect(currentSignal.re).toBeCloseTo(expectedSignal.re, 4);
264+
expect(currentSignal.im).toBeCloseTo(expectedSignal.im, 4);
265+
expect(currentPolarSignal.phase).toBeCloseTo(expectedSignal.phase, 4);
266+
expect(currentPolarSignal.radius).toBeCloseTo(expectedSignal.amplitude, 4);
267+
});
268+
});
269+
}
270+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /