当前位置:首页 > JavaScript

fft js实现

2026-03-02 04:24:00JavaScript

FFT 的 JavaScript 实现

快速傅里叶变换(FFT)是一种高效计算离散傅里叶变换(DFT)的算法。以下是一个基于 Cooley-Tukey 算法的递归实现:

function fft(signal) {
  const N = signal.length;
  if (N <= 1) return signal;

  // 分离偶数和奇数部分
  const even = [];
  const odd = [];
  for (let i = 0; i < N; i += 2) {
    even.push(signal[i]);
    odd.push(signal[i + 1]);
  }

  // 递归计算
  const evenTransformed = fft(even);
  const oddTransformed = fft(odd);

  // 合并结果
  const result = new Array(N);
  for (let k = 0; k < N / 2; k++) {
    const angle = -2 * Math.PI * k / N;
    const exp = {
      re: Math.cos(angle),
      im: Math.sin(angle)
    };

    // 复数乘法
    const oddTerm = {
      re: exp.re * oddTransformed[k].re - exp.im * oddTransformed[k].im,
      im: exp.re * oddTransformed[k].im + exp.im * oddTransformed[k].re
    };

    result[k] = {
      re: evenTransformed[k].re + oddTerm.re,
      im: evenTransformed[k].im + oddTerm.im
    };
    result[k + N/2] = {
      re: evenTransformed[k].re - oddTerm.re,
      im: evenTransformed[k].im - oddTerm.im
    };
  }
  return result;
}

使用示例

// 输入信号(复数形式)
const signal = [
  {re: 1, im: 0},
  {re: 1, im: 0},
  {re: 1, im: 0},
  {re: 1, im: 0},
  {re: 0, im: 0},
  {re: 0, im: 0},
  {re: 0, im: 0},
  {re: 0, im: 0}
];

// 计算FFT
const spectrum = fft(signal);
console.log(spectrum);

优化版本(迭代实现)

递归实现虽然直观,但效率较低。以下是更高效的迭代实现:

function fftIterative(signal) {
  const N = signal.length;
  let result = [...signal];

  // 位反转重排
  for (let i = 0, j = 0; i < N; i++) {
    if (i < j) {
      [result[i], result[j]] = [result[j], result[i]];
    }
    let m = N >> 1;
    while (m >= 1 && j >= m) {
      j -= m;
      m >>= 1;
    }
    j += m;
  }

  // 蝶形运算
  for (let s = 1; s <= Math.log2(N); s++) {
    const m = 1 << s;
    const wm = {
      re: Math.cos(-2 * Math.PI / m),
      im: Math.sin(-2 * Math.PI / m)
    };

    for (let k = 0; k < N; k += m) {
      let w = {re: 1, im: 0};
      for (let j = 0; j < m / 2; j++) {
        const t = {
          re: w.re * result[k + j + m/2].re - w.im * result[k + j + m/2].im,
          im: w.re * result[k + j + m/2].im + w.im * result[k + j + m/2].re
        };
        const u = result[k + j];
        result[k + j] = {
          re: u.re + t.re,
          im: u.im + t.im
        };
        result[k + j + m/2] = {
          re: u.re - t.re,
          im: u.im - t.im
        };
        w = {
          re: w.re * wm.re - w.im * wm.im,
          im: w.re * wm.im + w.im * wm.re
        };
      }
    }
  }
  return result;
}

性能注意事项

  1. 输入信号长度应为 2 的幂次方,如果不是,需要补零
  2. 对于大型信号,考虑使用 WebAssembly 或 GPU 加速
  3. 实际应用中可能需要添加窗函数以减少频谱泄漏

逆 FFT 实现

逆 FFT 可以通过简单修改 FFT 实现得到:

fft js实现

function ifft(spectrum) {
  const N = spectrum.length;
  // 取共轭
  const conjugated = spectrum.map(bin => ({
    re: bin.re,
    im: -bin.im
  }));

  // 计算FFT
  const result = fft(conjugated);

  // 取共轭并缩放
  return result.map(bin => ({
    re: bin.re / N,
    im: -bin.im / N
  }));
}

标签: fftjs
分享给朋友:

相关文章

js实现游标

js实现游标

使用JavaScript实现游标 在JavaScript中,可以通过操作DOM元素的cursor样式属性来实现自定义游标效果。以下是几种常见的实现方法: 修改默认鼠标指针样式 通过CSS的curso…

js 实现滚动

js 实现滚动

实现滚动的方法 使用 window.scrollTo() window.scrollTo() 方法可以滚动到文档中的特定位置。可以指定 x 和 y 坐标,或者使用平滑滚动的选项。 // 滚动到指定位…

js实现弹框

js实现弹框

使用 alert 实现简单弹框 JavaScript 的 alert 方法可以直接显示一个简单的弹框,内容为纯文本: alert("这是一个简单的弹框"); 使用 confirm 实现确认弹框…

js实现文件夹

js实现文件夹

使用JavaScript创建文件夹 在浏览器端的JavaScript中无法直接操作文件系统创建文件夹,这是出于安全考虑。但在Node.js环境中可以通过文件系统模块(fs)实现。 Node.js中使…

js实现图片移动

js实现图片移动

使用CSS和JavaScript实现图片移动 方法一:使用CSS动画结合JavaScript控制 通过CSS定义动画关键帧,JavaScript动态添加或移除动画类。 /* CSS部分 */ .m…

js实现刷新

js实现刷新

刷新当前页面 使用 location.reload() 方法可以强制刷新当前页面。该方法接受一个布尔参数,默认为 false,表示从缓存中加载页面;设为 true 时强制从服务器重新加载。 // 从…