问题描述
背景:我观察到一个变量z的样本,该变量z是两个独立且分布均匀的变量x和y的总和。我想在f对称于零的假设下,从z的分布(称为g)中恢复x,y(称为f)的分布。根据{{3}},我们得出f的傅立叶变换等于sqrt(| G |),其中G是g的傅立叶变换。
示例:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde,laplace
# sample size
size = 10000
# Number of points to preform FFT on
N = 501
# Scale of the laplace rvs
scale = 3.0
# Test deconvolution
laplace_f = laplace(scale=scale)
x = laplace_f.rvs(size=size)
y = laplace_f.rvs(size=size)
z = x + y
t = np.linspace(-4 * scale,4 * scale,size)
laplace_pdf = laplace_f.pdf(t)
t2 = np.linspace(-4 * scale,N)
# Get density from z. Kind of cheating using gaussian
z_density = gaussian_kde(z)(t2)
z_density = (z_density + z_density[::-1]) / 2
z_density_half = z_density[:((N - 1) // 2) + 1]
ft_z_density = np.fft.hfft(z_density_half)
inv_fz_density = np.fft.ihfft(np.sqrt(np.abs(ft_z_density)))
inv_fz_density = np.r_[inv_fz_density,inv_fz_density[::-1][:-1]]
f_deconv_shifted = np.real(np.fft.fftshift(inv_fz_density))
f_deconv = np.real(inv_fz_density)
# normalize to be a pdf
f_deconv_shifted /= f_deconv_shifted.mean()
f_deconv /= f_deconv.mean()
# Plot
plt.subplot(221)
plt.plot(t,laplace_pdf)
plt.title('laplace pdf')
plt.subplot(222)
plt.plot(t2,z_density)
plt.title("z density")
plt.subplot(223)
plt.plot(t2,f_deconv_shifted)
plt.title('Deconvolved with shift')
plt.subplot(224)
plt.plot(t2,f_deconv)
plt.title('Deconvolved without shift')
plt.tight_layout()
plt.show()
结果 Horowitz and Markatou (1996)
问题:这里显然有问题。我认为我不需要转移,但是转移的pdf似乎更接近事实。我怀疑这与通过sqrt(abs())操作而改变的IFFT范围有关,但我不确定。
解决方法
定义FFT使得与输入采样相关的时间为 t = 0 .. N -1。也就是说,原点在第一个样本中。输出也是如此,相关的频率是 k = 0 .. N -1。
您的分布对称于零,但忽略了t
(您无法将其传递给FFT函数),并且知道FFT定义隐含的 t 值是什么,您可以看到您的分布实际上发生了偏移,从而在频域中增加了相位分量。您可以忽略那里的相位(通过使用hfft
而不是fft
,这意味着您要对输入信号进行移位,使其相对于FFT定义的原点(而不是原点)对称。
fftshift
将IFFT产生的信号移位,以使原点回到您想要的位置。我建议您在调用ifftshift
之前先使用hfft
,以确保信号实际上是该函数所期望的对称。我不知道它是否会有所作为,这取决于如何实现此功能。