Python 改变傅里叶系数相位后振幅谱的变化

Python 改变傅里叶系数相位后振幅谱的变化,python,numpy,random,fft,Python,Numpy,Random,Fft,我试图通过改变给定数组(y)傅里叶系数的相位来生成一些随机的一维序列(r)。我假设这两个序列(y和r)的振幅谱在这样做后不会改变,如果我使用numpy.fft.fft(),它们确实不会改变,如下所示: import numpy as np import numpy.fft as fft n=512 x=np.linspace(0,10*np.pi,n) y=np.sin(x)+2*np.sin(2*x)+2*np.sin(5*x) #-------------Get Fourier coef

我试图通过改变给定数组(
y
)傅里叶系数的相位来生成一些随机的一维序列(
r
)。我假设这两个序列(
y
r
)的振幅谱在这样做后不会改变,如果我使用
numpy.fft.fft()
,它们确实不会改变,如下所示:

import numpy as np
import numpy.fft as fft

n=512
x=np.linspace(0,10*np.pi,n)
y=np.sin(x)+2*np.sin(2*x)+2*np.sin(5*x)

#-------------Get Fourier coefficients-------------
cf1=fft.fft(y)
amp1=np.abs(cf1)
theta1=np.angle(cf1)

#-Randomly alter phase keeping amplitude unchanged-
theta2=np.random.normal(0,1.,size=theta1.shape)+theta1
cf2=amp1*np.cos(theta2)+1j*amp1*np.sin(theta2)

#-----------------------IFFT-----------------------
y2=fft.ifft(cf2)

#------------Compare amplitude spectrum------------
cf3=fft.fft(y2)
amp2=np.abs(cf3)

import matplotlib.pyplot as plt
figure=plt.figure()
ax=figure.add_subplot(111)
ax.plot(amp1-amp2,'k-')

plt.show(block=False)
结果图为1e-13级的随机序列。所以实际上没有改变

但我感兴趣的是生成随机的真实数据,而不是复杂的数据。相反,使用
numpy.fft.rfft()
numpy.fft.irfft()
,除了最后一个频率(
amp1[-1]
amp2[-1]
),振幅在所有频率上都一致,差值约为0.1。根据文档,这对应于奈奎斯特频率,如果数据大小为奇数,则差异不会消失。我不明白是什么导致了这种差异,或者我应该如何生成具有相同振幅谱的实值数组

提前感谢。

我认为
rfft
的(单个)“Nyquist-bin”是问题所在,它看起来不应该在假设
rfft
使用以下各项的情况下改变其相位:

当输入为纯实时,其变换为厄米变换,即频率f_k处的分量是频率-f_k处分量的复共轭,这意味着对于实输入,负频率分量中没有从正频率分量中不可用的信息。rfft函数族设计用于对实际输入进行操作,并通过仅计算正频率分量(包括奈奎斯特频率)来利用这种对称性。因此,n个输入点产生n/2+1个复杂的输出点。该族的逆函数假定其输入具有相同的对称性,对于n个点的输出,使用n/2+1个输入点

当我修补最后一个rfft箱以保持原始阶段时,绘图看起来很好

cf1=fft.rfft(y)
amp1=np.abs(cf1)
theta1=np.angle(cf1)
tlast=theta1[-1] # quick patch, save last (Nyquist) phase
#-Randomly alter phase keeping amplitude unchanged-
theta2=np.random.normal(0,1.,size=theta1.shape)+theta1
theta2[-1] = tlast # restore Nyquist bin original phase
cf2=amp1*np.cos(theta2)+1j*amp1*np.sin(theta2)

是的,我想你是对的。之前我手动删除了最后一个箱子的虚部,但忘记了实部也已更改。奇数数组不匹配的原因是默认情况下,
np.fft.irfft()
返回长度为
2*(m-1)
的输出,因此总是偶数。我必须明确地给它第二个参数来强制输出大小为原始大小:
np.fft.irfft(cf2,len(y))
。或者,仍然可以使用
fft()
,但随机扰动频域的正或负部分,并将扰动镜像到另一半。对于均匀大小的输入,再次保持奈奎斯特频率不变。然后,IFFT输出是具有相同功率谱的期望实值随机序列。