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

如何正确缩放Python中的FFT函数以通过矩形函数(rect)与sinc函数对进行验证

Troubleshooting FFT/IFFT Scaling & Symmetry Issues in Python

Let's break down the problems you're facing with your FFT implementation and fix them step by step:


1. Core Issues Identified

Your main pain points stem from three key mistakes:

  • Asymmetric time-domain signal causing phase shifts in the frequency domain
  • Misaligned frequency sampling points leading to "double" curve artifacts
  • Incorrect scaling factors between DFT (numpy's FFT) and continuous-time Fourier transform (CTFT)

2. Fixed Implementation Code

First, let's rewrite your functions with corrections for symmetry, scaling, and numerical stability:

Helper Functions (Rect & Sinc)

import numpy as np
import matplotlib.pyplot as plt
from numpy.fft import fft, ifft, fftfreq, fftshift, ifftshift

def rect(t, T):
    # Center the rectangular function at t=0 for real-valued frequency output
    return np.where(np.abs(t) < T/2, 1.0, 0.0)

def Tsinc_hz(f, T):
    # Handle division by zero at f=0 (sinc(0) = 1, so Tsinc_hz(0, T) = T)
    with np.errstate(divide='ignore', invalid='ignore'):
        sinc_val = np.sin(np.pi * f * T) / (np.pi * f)
    sinc_val[f == 0] = T
    return sinc_val

FFT & IFFT Conversion Functions

def to_frequency_domain(t, ys):
    N = len(t)
    T = t[1] - t[0]  # Get actual sample interval (assumes uniform sampling)
    
    xf = fftfreq(N, T)
    xf = fftshift(xf)
    
    # Scale by sample interval T to approximate CTFT from DFT
    yf = fft(ys, N) * T
    yf = fftshift(yf)
    return xf, yf

def to_time_domain(xf, yf):
    N = len(xf)
    Fs = 2 * np.max(np.abs(xf))  # Nyquist frequency is xf[-1], so Fs = 2*xf[-1]
    T_time = 1 / Fs
    
    # Generate symmetric time-domain points matching frequency sampling
    t = np.linspace(-(N*T_time)/2, (N*T_time)/2 - T_time, N)
    
    # Scale by Fs to reverse CTFT approximation and get correct time-domain amplitude
    ys = ifft(ifftshift(yf)) * Fs
    return t, ys

Validation Code

# Test 1: Rectangular Signal -> FFT vs Analytic Sinc
Fs = 250
duration = 20
N = int(Fs * duration)
t = np.linspace(-duration/2, duration/2 - 1/Fs, N)

rect_signal = rect(t, 1)
xf, yf = to_frequency_domain(t, rect_signal)
sinc_analytic = Tsinc_hz(xf, 1)

plt.figure(figsize=(10,5))
plt.plot(xf, yf.real, label='FFT Result')
plt.plot(xf, sinc_analytic, label='Analytic Sinc', linestyle='--', color='r')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Magnitude')
plt.title('FFT of Rectangular Signal vs Analytic Sinc')
plt.legend()
plt.xlim(-5,5)  # Zoom in on main lobe
plt.show()

# Test 2: Sinc Signal -> IFFT vs Original Rect
t_recovered, rect_recovered = to_time_domain(xf, sinc_analytic)

plt.figure(figsize=(10,5))
plt.plot(t_recovered, rect_recovered.real, label='IFFT Result', linewidth=2, alpha=0.7)
plt.plot(t, rect_signal, label='Original Rect', linestyle='--', color='r')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title('IFFT of Sinc Signal vs Original Rectangular Signal')
plt.legend()
plt.xlim(-2,2)  # Zoom in on rectangular pulse
plt.show()

3. Key Fixes Explained

Symmetry Correction

Your original time-domain signal was defined from 0 to 10, making the rectangular pulse asymmetric around t=0. This introduced a linear phase shift in the frequency domain, causing the real part of your FFT output to mismatch the analytic sinc function. By using a symmetric time interval (-10 to 10), the rectangular signal becomes an even function, resulting in a real-valued frequency spectrum that matches the analytic solution exactly.

Frequency Point Alignment

The "double curve" artifact occurred because your manually generated f = np.linspace(-125,125,2500) had a slightly different interval than the fftfreq output. fftfreq uses exact spacing of Fs/N = 0.1Hz, while linspace uses 250/2499 ≈ 0.10004Hz, leading to misalignment. Using the xf output directly from to_frequency_domain ensures perfect alignment.

Scaling Rules

Numpy's FFT implements an unnormalized DFT. To map between DFT and CTFT:

  • Forward FFT: Multiply by the sample interval T to approximate the continuous Fourier transform integral.
  • Inverse FFT: Multiply by the sampling rate Fs (equivalent to dividing by T) to reverse the CTFT approximation and recover the correct time-domain amplitude.

Sampling Rate & Amplitude Relationship

When fixing N (number of samples) and reducing Fs (sampling rate):

  • The time-domain length N/Fs increases
  • The frequency range Fs/2 shrinks (x-axis compression)
  • The frequency-domain amplitude scales by 1/Fs (y-axis stretching), since the CTFT integral over a longer time interval results in a larger magnitude.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 14:07:37