当前位置:首页 > JavaScript

fft js实现

2026-03-02 04:24:00JavaScript

FFT 的 JavaScript 实现

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

fft js实现

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);

优化版本(迭代实现)

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

fft js实现

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 实现得到:

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的实现方法。 HTML结构 构建轮播图的HT…

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…

js jquery

js jquery

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够…

js验证码的实现

js验证码的实现

验证码的基本实现原理 验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。 纯前端验证码…

js实现定位

js实现定位

使用Geolocation API获取当前位置 在JavaScript中,可以通过浏览器内置的Geolocation API获取用户的地理位置信息。该API需要用户授权才能访问位置数据。 if (n…

实现继承js

实现继承js

实现继承的方式 在JavaScript中,实现继承可以通过多种方式完成,每种方式都有其优缺点。以下是几种常见的实现继承的方法: 原型链继承 原型链继承是最基本的继承方式,通过将子类的原型指向父类的实…