#fft #transform #fourier #dft #dsp

nightly bin+lib yfft

简单快速傅里叶变换库,针对小型、2的幂次、单精度变换和x86系统进行了优化

1 个不稳定版本

使用旧的 Rust 2015

0.1.0 2020年4月25日

#490科学

MIT/Apache

315KB
3.5K SLoC

yfft

docs.rs

仅使用 Rust 编写的简单 FFT 库。需要 Nightly Rust 编译器以使用 x86 内置函数。

特性

  • 为小型、2的幂次、单精度变换提供了适度优化的 FFT 内核。
  • 支持实数到复数和复数到实数的变换。
  • 当客户端不需要自然顺序的数据时,可以选择使用乱序输入/输出数据顺序。

限制

此库于2017年编写,用于内部使用(特别是实时游戏音频处理),并且不再积极维护。因此,此库有以下重要限制

  • 它仅针对小型、2的幂次、单精度变换进行优化。它可能适用于其他大小,但将使用非常慢的代码路径。
  • 它仅支持1D变换。
  • 它不支持在运行时检测处理器功能。
  • 实现依赖于 大量不安全的 Rust 代码。请自行承担风险!

有关编译的说明

截至版本 1.19.0,cargo 不支持将代码生成标志传递给 rustc。因此,您需要通过 RUSTFLAGS 环境变量传递以下标志,以启用 AVX 内核

export RUSTFLAGS='-Ctarget-feature=+avx,+sse3'

注意:这会导致代码生成将 VEX 前缀添加到所有 SSE 指令,并使二进制文件与不支持 AVX 的处理器不兼容。

示例:往返转换

use yfft::{Setup, Options, DataOrder, DataFormat, Env};

let size = 128;

let setup1: Setup<f32> = Setup::new(&Options {
    input_data_order: DataOrder::Natural,
    output_data_order: DataOrder::Swizzled,
    input_data_format: DataFormat::Complex,
    output_data_format: DataFormat::Complex,
    len: size,
    inverse: false,
})
.unwrap();
let setup2: Setup<f32> = Setup::new(&Options {
    input_data_order: DataOrder::Swizzled,
    output_data_order: DataOrder::Natural,
    input_data_format: DataFormat::Complex,
    output_data_format: DataFormat::Complex,
    len: size,
    inverse: true,
})
.unwrap();

// Allocate temporary buffers
let mut env1 = Env::new(&setup1);
let mut env2 = Env::new(&setup2);

// Input data (interleaved complex format)
let mut pat = vec![0.0f32; size * 2];
pat[42] = 100.0;
pat[82] = 200.0;

let mut result = vec![0.0f32; size * 2];
result.copy_from_slice(&pat);

// Round-trip transform
env1.transform(&mut result);
env2.transform(&mut result);

for e in &mut result {
    *e = *e / size as f32;
}

assert_num_slice_approx_eq(
    &result,
    &pat,
    1.0e-3f32
);

许可证:MIT/Apache-2.0

依赖关系

~1.5MB
~34K SLoC