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

如何使用Python获取数值黑盒函数的频率响应

固定间隔调用黑盒系统的频率响应计算方案

随机噪声激励方案可行性

可以使用随机噪声作为激励计算频率响应,相比脉冲法不需要对齐黑盒内部更新时序,结果更稳定。直接使用fft(out)/fft(in)的方法存在频谱泄露、低能量频点误差放大的问题,推荐使用功率谱比值法计算,这是线性系统频率响应测量的标准工程方案。

原理是通过计算输入信号的自功率谱Pxx和输入输出的互功率谱Pxy,得到系统频率响应H = Pxy / Pxx,该方法天然抗干扰,结果平滑度远高于直接FFT相除。

实现步骤与代码

from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

class blackBox:
    tick = 0
    result = 0
    er1 = er2 = er3 = er4 = er5 = er6 = er7 =  0

    def __call__(s,input):
        s.tick+=1        
        if (s.tick==5):        
            s.tick = 0
            s.result = input + 5.0*s.er1 + 9.0*s.er2 + 5.0*s.er3 -5.0*s.er4 -9.0*s.er5 -5.0*s.er6 - s.er7
            s.er7 = s.er6
            s.er6 = s.er5
            s.er5 = s.er4
            s.er4 = s.er3
            s.er3 = s.er2
            s.er2 = s.er1
            s.er1 = input
        return s.result        

# 参数配置
sample_rate = 10000  # 对应100微秒调用一次,可按需修改
input_len = 200000   # 输入序列越长,频率分辨率越高、结果越平滑
nperseg = 1024       # welch法分段长度,可平衡分辨率和平滑度

# 生成白噪声输入,喂入黑盒得到输出
x = np.random.randn(input_len)
p = blackBox()
y = np.array([p(val) for val in x])

# 计算功率谱与频率响应
freq, Pxx = signal.welch(x, fs=sample_rate, nperseg=nperseg)
freq, Pxy = signal.csd(x, y, fs=sample_rate, nperseg=nperseg)
H = Pxy / Pxx

# 绘制幅频、相频响应
plt.figure(figsize=(10,6))
plt.subplot(211)
plt.plot(freq, 20*np.log10(np.abs(H)))
plt.ylabel('幅值 [dB]')
plt.grid(True)

plt.subplot(212)
plt.plot(freq, np.angle(H, deg=True))
plt.ylabel('相位 [度]')
plt.xlabel('频率 [Hz]')
plt.grid(True)

plt.tight_layout()
plt.show()

原有脉冲法的问题修正

你原有代码存在频率轴错位问题:使用rfft计算单边频谱,但调用fftfreq生成双边频率轴,替换为rfftfreq即可修正该问题:

# 原有代码修正片段
f = np.fft.rfft(out)
f1 = abs(f)
freq = np.fft.rfftfreq(n, d=1./sample_rate)  # 替换fftfreq为rfftfreq
plt.plot(freq, f1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:06:01