当前位置:首页 > JavaScript

js实现FFT

2026-04-06 19:57:21JavaScript

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

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

复数类辅助实现

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

js实现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 算法:

js实现FFT

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

现成库推荐

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

标签: jsFFT
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 或直接使用 window.location 实现页面跳转,适用于普通跳转或带参数的 URL。 // 方…

js实现轮播

js实现轮播

实现基础轮播效果 使用HTML结构创建轮播容器和图片元素: <div class="carousel"> <div class="carousel-inner">…

js实现防洪

js实现防洪

防抖(Debounce)实现 防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口调整等场景。 function debounce(f…

使用js实现

使用js实现

使用JavaScript实现 JavaScript可以通过Math.random()函数生成随机数,结合其他方法可以实现多种随机数生成需求。 // 生成0到1之间的随机小数 const random…

js实现交换

js实现交换

交换变量的方法 在JavaScript中,交换两个变量的值有多种方法。以下是常见的几种实现方式: 使用临时变量 通过引入一个临时变量来存储其中一个变量的值,实现交换: let a = 1; le…

js实现下拉刷新

js实现下拉刷新

监听触摸事件 通过监听 touchstart、touchmove 和 touchend 事件来检测用户下拉手势。记录触摸起始位置和移动距离。 let startY = 0; let curr…