I have implemented the 3Blue1Brown's description of Fourier transform in Python+numpy for irregular and unsorted data, as described here.
import numpy as np
import matplotlib.pyplot as plt
def polarToRectangular(radii, angles):
return radii * np.exp(1j * angles)
def frequencyGenerator(time, steps = 100):
πΏ = time.max() - time.min()
M = np.arange(1, steps + 1)[:, np.newaxis]
return M / πΏ
def easyFourierTransform(time, values, frequency = None, steps = 100):
if frequency is None:
ft = frequencyGenerator(time, steps)
frequency = ft.reshape(ft.shape[0])
else:
ft = frequency[:, np.newaxis]
# sorting the inputs
order = np.argsort(time)
ts = np.array(time)[order]
Xs = np.array(values)[order]
π = (ts - time.min()) * 2 * np.pi * ft
Y = polarToRectangular(Xs, π)[:, :-1] * np.diff(ts)
amplitude = np.abs(Y.sum(axis=1))
return frequency, amplitude
I'm thinking maybe I can suggest this to be added to numpy/scypy. However, I'm not sure if this small piece of code is qualified to be added upstream. I was wondering if you could help me know:
- Is this code correct? Does it actually return the Fourier transform? I want to be sure there are no logical errors.
- Is this a performant code or there is any way to improve performance?
- Is the formating good enough? Should I comply with PEP8 standard or numpy/scipy require different best practices?
- How can I add typing annotation? Especially to be sure ndarrays dimensions are OK.
- Is this novel or it has been done before? (not necessarily relevant to this forum but still my question)
I would appreciate it if you could help me with the above points. Thanks in advance.
Keywords: nonuniform, uniformly, unevenly, sampled, distributed
P.S. Updated version of the code plus examples in this Jupyter notebook.