MCPcopy Create free account
hub / github.com/ddbourgin/numpy-ml / DFT

Function DFT

numpy_ml/preprocessing/dsp.py:224–273  ·  view source on GitHub ↗

A naive :math:`O(N^2)` implementation of the 1D discrete Fourier transform (DFT). Notes ----- The Fourier transform decomposes a signal into a linear combination of sinusoids (ie., basis elements in the space of continuous periodic functions). For a sequence :math:`\mathbf

(frame, positive_only=True)

Source from the content-addressed store, hash-verified

222
223
224def DFT(frame, positive_only=True):
225 """
226 A naive :math:`O(N^2)` implementation of the 1D discrete Fourier transform (DFT).
227
228 Notes
229 -----
230 The Fourier transform decomposes a signal into a linear combination of
231 sinusoids (ie., basis elements in the space of continuous periodic
232 functions). For a sequence :math:`\mathbf{x} = [x_1, \ldots, x_N]` of N
233 evenly spaced samples, the `k` th DFT coefficient is given by:
234
235 .. math::
236
237 c_k = \sum_{n=0}^{N-1} x_n \exp(-2 \pi i k n / N)
238
239 where `i` is the imaginary unit, `k` is an index ranging from `0, ..., N-1`,
240 and :math:`X_k` is the complex coefficient representing the phase
241 (imaginary part) and amplitude (real part) of the `k` th sinusoid in the
242 DFT spectrum. The frequency of the `k` th sinusoid is :math:`(k 2 \pi / N)`
243 radians per sample.
244
245 When applied to a real-valued input, the negative frequency terms are the
246 complex conjugates of the positive-frequency terms and the overall spectrum
247 is symmetric (excluding the first index, which contains the zero-frequency
248 / intercept term).
249
250 Parameters
251 ----------
252 frame : :py:class:`ndarray <numpy.ndarray>` of shape `(N,)`
253 A signal frame consisting of N samples
254 positive_only : bool
255 Whether to only return the coefficients for the positive frequency
256 terms. Default is True.
257
258 Returns
259 -------
260 spectrum : :py:class:`ndarray <numpy.ndarray>` of shape `(N,)` or `(N // 2 + 1,)` if `real_only`
261 The coefficients of the frequency spectrum for `frame`, including
262 imaginary components.
263 """
264 N = len(frame) # window length
265
266 # F[i,j] = coefficient for basis vector i, timestep j (i.e., k * n)
267 F = np.arange(N).reshape(1, -1) * np.arange(N).reshape(-1, 1)
268 F = np.exp(F * (-1j * 2 * np.pi / N))
269
270 # vdot only operates on vectors (rather than ndarrays), so we have to
271 # loop over each basis vector in F explicitly
272 spectrum = np.array([np.vdot(f, frame) for f in F])
273 return spectrum[: (N // 2) + 1] if positive_only else spectrum
274
275
276def dft_bins(N, fs=44000, positive_only=True):

Callers 2

test_dftFunction · 0.90
magnitude_spectrumFunction · 0.85

Calls

no outgoing calls

Tested by 1

test_dftFunction · 0.72