1+ import numpy as np
2+
3+
4+ def DFT_slow (x ):
5+ """ Compute the discrete Fourier Transform of the one-dimensional array x"""
6+ x = np .asarray (x )
7+ N = x .shape [0 ]
8+ n = np .arange (N )
9+ k = n .reshape ((N , 1 ))
10+ M = np .exp (- 2j * np .pi * k * n / N )
11+ return np .dot (M , x )
12+
13+
14+ def FFT_vectorized (x ):
15+ """A vectorized, non-recursive version of the Cooley-Tukey FFT"""
16+ x = np .asarray (x )
17+ N = x .shape [0 ]
18+
19+ if np .log2 (N ) % 1 > 0 :
20+ raise ValueError ("size of x must be a power of 2" )
21+
22+ # N_min here is equivalent to the stopping condition above,
23+ # and should be a power of 2
24+ N_min = min (N , 32 )
25+
26+ # Perform an O[N^2] DFT on all length-N_min sub-problems at once
27+ n = np .arange (N_min )
28+ k = n [:, None ]
29+ M = np .exp (- 2j * np .pi * n * k / N_min )
30+ X = np .dot (M , x .reshape ((N_min , - 1 )))
31+
32+ # build-up each level of the recursive calculation all at once
33+ while X .shape [0 ] < N :
34+ X_even = X [:, :X .shape [1 ] // 2 ]
35+ X_odd = X [:, X .shape [1 ] // 2 :]
36+ factor = np .exp (- 1j * np .pi * np .arange (X .shape [0 ])
37+ / X .shape [0 ])[:, None ]
38+ X = np .vstack ([X_even + factor * X_odd ,
39+ X_even - factor * X_odd ])
40+
41+ return X .ravel ()
42+
43+
44+ def fftfreq (n , d = 1.0 ):
45+ """
46+ Return the Discrete Fourier Transform sample frequencies.
47+
48+ The returned float array `f` contains the frequency bin centers in cycles
49+ per unit of the sample spacing (with zero at the start). For instance, if
50+ the sample spacing is in seconds, then the frequency unit is cycles/second.
51+
52+ Given a window length `n` and a sample spacing `d`::
53+
54+ f = [0, 1, ..., n/2-1, -n/2, ..., -1] / (d*n) if n is even
55+ f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n) if n is odd
56+
57+ Parameters
58+ ----------
59+ n : int
60+ Window length.
61+ d : scalar, optional
62+ Sample spacing (inverse of the sampling rate). Defaults to 1.
63+
64+ Returns
65+ -------
66+ f : ndarray
67+ Array of length `n` containing the sample frequencies.
68+
69+ Examples
70+ --------
71+ >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
72+ >>> fourier = np.fft.fft(signal)
73+ >>> n = signal.size
74+ >>> timestep = 0.1
75+ >>> freq = np.fft.fftfreq(n, d=timestep)
76+ >>> freq
77+ array([ 0. , 1.25, 2.5 , 3.75, -5. , -3.75, -2.5 , -1.25])
78+
79+ """
80+
81+ val = 1.0 / (n * d )
82+ results = np .empty (n , int )
83+ N = (n - 1 )// 2 + 1
84+ p1 = np .arange (0 , N , dtype = int )
85+ results [:N ] = p1
86+ p2 = np .arange (- (n // 2 ), 0 , dtype = int )
87+ results [N :] = p2
88+ return results * val
0 commit comments