-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add more examples and fix typos in readme/plots
- Added rust bindings of FFTW as an example, which will be used for benchmarks - Add fftw (rust bindings) crate as a dev-dependency - Add an example of using pyphastft to reproduce an example use case of FFT from the FFT wikipedia page - Fix typos in the README and distinguish pyphastft from phastft in the python benchmarks plots
- Loading branch information
Showing
6 changed files
with
108 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use std::{env, ptr::slice_from_raw_parts_mut, str::FromStr}; | ||
|
||
use fftw::{ | ||
array::AlignedVec, | ||
plan::{C2CPlan, C2CPlan64}, | ||
types::{Flag, Sign}, | ||
}; | ||
use utilities::{gen_random_signal, rustfft::num_complex::Complex}; | ||
|
||
fn benchmark_fftw(n: usize) { | ||
let big_n = 1 << n; | ||
|
||
let mut reals = vec![0.0; big_n]; | ||
let mut imags = vec![0.0; big_n]; | ||
|
||
gen_random_signal(&mut reals, &mut imags); | ||
let mut nums = AlignedVec::new(big_n); | ||
reals | ||
.drain(..) | ||
.zip(imags.drain(..)) | ||
.zip(nums.iter_mut()) | ||
.for_each(|((re, im), z)| *z = Complex::new(re, im)); | ||
|
||
let now = std::time::Instant::now(); | ||
C2CPlan64::aligned( | ||
&[big_n], | ||
Sign::Backward, | ||
Flag::DESTROYINPUT | Flag::ESTIMATE, | ||
) | ||
.unwrap() | ||
.c2c( | ||
// SAFETY: See above comment. | ||
unsafe { &mut *slice_from_raw_parts_mut(nums.as_mut_ptr(), big_n) }, | ||
&mut nums, | ||
) | ||
.unwrap(); | ||
let elapsed = now.elapsed().as_micros(); | ||
println!("{elapsed}"); | ||
} | ||
|
||
fn main() { | ||
let args: Vec<String> = env::args().collect(); | ||
assert_eq!(args.len(), 2, "Usage {} <n>", args[0]); | ||
|
||
let n = usize::from_str(&args[1]).unwrap(); | ||
benchmark_fftw(n); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
from pyphastft import fft | ||
|
||
|
||
def main(): | ||
fs = 100 # Sampling frequency (100 samples/second for this synthetic example) | ||
t_max = 6 # maximum time in "seconds" | ||
|
||
# Find the next lower power of 2 for the number of samples | ||
n_samples = 2 ** int(np.log2(t_max * fs)) | ||
|
||
t = np.linspace(0, n_samples / fs, n_samples, endpoint=False) # Adjusted time vector | ||
|
||
# Generate the signal | ||
s_re = 2 * np.sin(2 * np.pi * t) + np.sin(2 * np.pi * 10 * t) | ||
s_im = np.ascontiguousarray([0.0] * len(s_re), dtype=np.float64) | ||
|
||
# Plot the original signal | ||
plt.figure(figsize=(10, 7)) | ||
|
||
plt.subplot(2, 1, 1) | ||
plt.plot(t, s_re, label="f(x) = 2sin(x) + sin(10x)") | ||
plt.title("signal: f(x) = 2sin(x) + sin(10x)") | ||
plt.xlabel("time [seconds]") | ||
plt.ylabel("f(x)") | ||
plt.legend() | ||
|
||
# Perform FFT | ||
fft(s_re, s_im, direction="f") | ||
|
||
# Plot the magnitude spectrum of the FFT result | ||
plt.subplot(2, 1, 2) | ||
plt.plot( | ||
np.abs(s_re), | ||
label="frequency spectrum", | ||
) | ||
plt.title("Signal after FFT") | ||
plt.xlabel("frequency (in Hz)") | ||
plt.ylabel("|FFT(f(x))|") | ||
|
||
# only show up to 11 Hz as in the wiki example | ||
plt.xlim(0, 11) | ||
|
||
plt.legend() | ||
plt.tight_layout() | ||
plt.savefig("wiki_fft_example.png", dpi=600) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |