有没有办法生成准周期信号(具有特定频率分布的信号,如正态分布)?此外, 信号不应该有平稳的频率分布,因为高斯函数的傅里叶逆变换仍然是高斯函数,而我想要的是一个振荡信号。
我使用了一系列离散的正态分布频率来生成信号,即
频率分布如下:
初始阶段也是如此
我收到信号了
不过,信号是这样的
它的FFT频谱就像
我发现最终的频谱只在t=0之后的短时间内类似于高斯函数(对应图4中左边的几个峰非常高),其余信号只促成了图中峰值两侧的毛刺5 .
我认为问题可能出在初始阶段。我尝试了随机分布的初始阶段,但它也没有用。
那么,产生这种信号的正确方法是什么?
这是我的python代码:
import numpy as np
from scipy.special import erf, erfinv
def gaussian_frequency(array_length = 10000, central_freq = 100, std = 10):
n = np.arange(array_length)
f = np.sqrt(2)*std*erfinv(2*n/array_length - erf(central_freq/np.sqrt(2)/std)) + central_freq
return f
f = gaussian_frequency()
phi = np.linspace(0,2*np.pi, len(f))
t = np.linspace(0,100,100000)
signal = np.zeros(len(t))
for k in range(len(f)):
signal += np.sin(phi[k] + 2*np.pi*f[k]*t)
def fourierPlt(signal, TIMESTEP = .001):
num_samples = len(signal)
k = np.arange(num_samples)
Fs = 1/TIMESTEP
T = num_samples/Fs
frq = k/T # two sides frequency range
frq = frq[range(int(num_samples/2))] # one side frequency range
fourier = np.fft.fft(signal)/num_samples # fft computing and normalization
fourier = abs(fourier[range(int(num_samples/2))])
fourier = fourier/sum(fourier)
plt.plot(frq, fourier, 'r', linewidth = 1)
plt.title("Fast Fourier Transform")
plt.xlabel('$f$/Hz')
plt.ylabel('Normalized Spectrum')
return(frq, fourier)
fourierPlt(signal)
最佳答案
如果您希望信号具有实值,则需要镜像频率分量:您需要正频率和负频率是彼此的复共轭。我想您已经想到了这一点。
高斯形频谱(均值为 f=0)产生高斯形信号。
将频谱移动 f0 会使时域信号乘以 exp(j 2 π f<子>0 t)。也就是说,您只需改变它的相位。
假设您仍然需要实值时间信号,则必须复制频谱并在两个方向上移动它。这导致乘以
exp(j 2 π f0 t)+exp(-j 2 π f0 t) = 2 cos(2 π f0 t) .
因此,您的信号是高斯调制余弦信号。
我在这里使用 MATLAB 作为示例,希望您可以轻松地将其转换为 Python:
t=0:300;
s=exp(-(t-150).^2/30.^2) .* cos(2*pi*0.1*t);
subplot(2,1,1)
plot(t,s)
xlabel('time')
S=abs(fftshift(fft(s)));
f=linspace(-0.5,0.5,length(S));
subplot(2,1,2)
plot(f,S)
xlabel('frequency')
对于那些对图像处理感兴趣的人:Gabor filter正是这样,但频谱仅向一个方向移动。得到的滤波器是复杂的,使用滤波结果的量级。这导致相位无关的滤波器。
关于python - 生成准周期信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48606120/