当前位置:首页 > JavaScript

js实现FFT

2026-04-06 19:57:21JavaScript

JavaScript 实现 FFT(快速傅里叶变换)

快速傅里叶变换(FFT)是一种高效计算离散傅里叶变换(DFT)的算法。以下是一个基于 Cooley-Tukey 算法的 JavaScript 实现,适用于长度为 2 的幂的输入序列。

复数类辅助实现

FFT 涉及复数运算,需先定义复数类及基本运算方法:

class Complex {
    constructor(real, imag = 0) {
        this.re = real;
        this.im = imag;
    }

    add(other) {
        return new Complex(this.re + other.re, this.im + other.im);
    }

    subtract(other) {
        return new Complex(this.re - other.re, this.im - other.im);
    }

    multiply(other) {
        return new Complex(
            this.re * other.re - this.im * other.im,
            this.re * other.im + this.im * other.re
        );
    }

    magnitude() {
        return Math.sqrt(this.re  2 + this.im  2);
    }
}

FFT 核心算法

递归实现 Cooley-Tukey 算法:

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

    // 确保输入长度为 2 的幂
    if (Math.log2(N) % 1 !== 0) {
        throw new Error("Input length must be a power of 2.");
    }

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

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

    // 合并结果
    const output = new Array(N);
    for (let k = 0; k < N / 2; k++) {
        const angle = -2 * Math.PI * k / N;
        const exp = new Complex(Math.cos(angle), Math.sin(angle));
        const term = oddTransformed[k].multiply(exp);

        output[k] = evenTransformed[k].add(term);
        output[k + N / 2] = evenTransformed[k].subtract(term);
    }

    return output;
}

使用示例

计算实数信号的频谱:

// 输入信号(示例:8 个采样点)
const signal = [1, 1, 1, 1, 0, 0, 0, 0].map(x => new Complex(x));

// 执行 FFT
const spectrum = fft(signal);

// 计算幅度谱
const magnitudes = spectrum.map(c => c.magnitude());
console.log(magnitudes); // 输出频域幅度

注意事项

  1. 输入长度:必须为 2 的幂(如 256、512),否则需补零。
  2. 性能优化:递归实现适合教学,实际应用建议用迭代版(如位反转置换)。
  3. 逆变换:实现 IFFT 只需调整角度符号并除以 N:
function ifft(input) {
    const N = input.length;
    const conjugated = input.map(c => new Complex(c.re, -c.im));
    const transformed = fft(conjugated);
    return transformed.map(c => new Complex(c.re / N, -c.im / N));
}

现成库推荐

生产环境建议使用成熟库:

js实现FFT

标签: jsFFT
分享给朋友:

相关文章

js实现报表

js实现报表

使用JavaScript实现报表 在JavaScript中实现报表功能可以通过多种方式完成,常见的方法包括使用原生JavaScript、第三方库(如Chart.js、D3.js)或结合后端数据渲染。以…

js实现dh

js实现dh

JavaScript 实现 DH(Diffie-Hellman)密钥交换 Diffie-Hellman(DH)密钥交换是一种安全协议,允许双方在不安全的通信信道上建立一个共享密钥。以下是如何在 Jav…

vue实现js休眠

vue实现js休眠

实现 JavaScript 休眠的方法 在 Vue 中实现 JavaScript 休眠(延迟执行)可以通过以下方式实现。由于 JavaScript 本身没有内置的 sleep 函数,通常使用 Prom…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…

js实现滚动

js实现滚动

实现滚动效果的方法 在JavaScript中实现滚动效果可以通过多种方式完成,以下是一些常见的方法: 使用window.scrollTo() window.scrollTo()方法可以将页面滚动到指…

js实现截图

js实现截图

使用HTML2Canvas库实现截图 HTML2Canvas是一个流行的JavaScript库,可以将网页元素或整个页面转换为Canvas图像。安装方式: npm install html2canv…