You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多项式逆FFT实现异常:IFFT(FFT)未返回原序列问题排查

FFT逆变换实现错误排查:无法还原原序列的问题

问题背景

实现了用于快速多项式乘法的FFT和IFFT算法,测试代码print(ifft(fft([1, 2, 3, 4])))期望得到原系数列表[1,2,3,4],但忽略浮点精度问题后得到结果[(4+0j), (11-0j), (12+0j), (13+0j)],需排查原因。

核心结论

你应该得到原序列,代码的问题出在IFFT的实现逻辑上。

错误分析

正确的逆傅里叶变换(IFFT)逻辑是:对输入序列执行FFT(使用共轭单位根),再将整个结果统一除以序列长度n。而你的代码存在两个关键错误:

  1. 错误地将缩放因子1/n嵌入到递归的单位根中,导致每一层递归都应用了缩放,最终结果的缩放倍数完全错误。
  2. 返回类型标注不符合实际,FFT和IFFT的输出是复数类型,而非整数类型。

修正后的代码

from typing import List
import numpy as np


def fft(p: List[int]) -> List[complex]:
    n = len(p)
    if n == 1:
        return [complex(x) for x in p]
    
    unity_root = np.exp(2j * np.pi / n)
    
    p_even = p[::2]
    p_odd = p[1::2]
    
    y_even = fft(p_even)
    y_odd = fft(p_odd)
    
    y = [0+0j] * n
    for j in range(n // 2):
        omega = np.power(unity_root, j)
        y[j] = y_even[j] + omega * y_odd[j]
        y[n // 2 + j] = y_even[j] - omega * y_odd[j]
    
    return y


def ifft(p: List[complex]) -> List[complex]:
    n = len(p)
    if n == 1:
        return p
    
    # IFFT使用共轭单位根,逻辑与FFT一致
    unity_root = np.exp(-2j * np.pi / n)
    
    p_even = p[::2]
    p_odd = p[1::2]
    
    y_even = ifft(p_even)
    y_odd = ifft(p_odd)
    
    y = [0+0j] * n
    for j in range(n // 2):
        omega = np.power(unity_root, j)
        y[j] = y_even[j] + omega * y_odd[j]
        y[n // 2 + j] = y_even[j] - omega * y_odd[j]
    
    # 最后统一除以n完成缩放
    return [x / n for x in y]

验证结果

运行测试代码print(ifft(fft([1, 2, 3, 4]))),忽略浮点精度误差后,结果为:

[(1+0j), (2+0j), (3+0j), (4+0j)]

与原序列完全一致。

补充说明

  • 浮点精度误差是FFT计算的正常现象,可通过np.round或取实部后四舍五入得到整数结果。
  • 原代码的返回类型标注错误,FFT和IFFT的输出必然包含复数,需修正为List[complex]。

内容的提问来源于stack exchange,提问作者Rami Hashan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 17:17:45