使用FFT的高斯分布之和的PDF

时间:2018-05-07 13:57:56

标签: python statistics signal-processing fft convolution

我试图推导出独立随机变量之和的PDF。首先,我想为一个简单的例子做这件事:高斯随机变量之和。

当我对偶数个高斯随机变量求和时,我很惊讶地发现我没有得到高斯密度函数。我实际得到:

enter image description here

看起来像高斯分布的两半。 另一方面,当我对奇数个高斯分布求和时,得到了正确的分布:

enter image description here

在我用来生成上述结果的代码下面:

public Object invokeMethod(Object service, Method method, RoutingContext routingContext) throws Exception {
        MultiMap queryParams = routingContext.queryParams();
        Map<String, String> pathParams = routingContext.pathParams();
        Buffer body = routingContext.getBody();

        // 1. type, 2. name, 3. value
        List<Tuple3<Class<?>, String, Object>> list = List.empty();

        for (Parameter par : method.getParameters()) {
            ParamQuery paramQuery = par.getAnnotation(ParamQuery.class);
            if (paramQuery != null) {
                list = list.push(new Tuple3<Class<?>, String, Object>(par.getType(), paramQuery.value(),
                        queryParams.get(paramQuery.value())));
            }
        }

// TypeConverterManager used to "covnert" each object (String) from the HTTP call to the correct data type
        return method.invoke(service, list.reverse()
                .map(mapper -> TypeConverterManager.lookup(mapper._1()).convert(mapper._3())).toJavaArray());
    }

有人可以帮助我理解为什么我得到偶数和高斯分布的奇数结果吗?

2 个答案:

答案 0 :(得分:0)

即使您的代码创建了零均值高斯PDF:

sample=np.linspace(end,-end,1000)
pdf=norm(0,1).pdf(sample)

FFT不知道sample,只看到pdf样本为0,1,2,3,... 999.FFT期望原点是第一个样本信号。对于FFT函数,您的PDF不是零均值,但平均值为500。

因此,这里发生的是你要添加两个带有500均值的PDF,导致一个带有1000均值的PDF。并且因为FFT对空间域信号施加周期性,所以您看到PDF退出右侧的图形并返回到左侧。

添加3个PDF会将平均值移至1500,由于周期性与500相同,这意味着它最终与原始PDF相同。

解决方案是将原点移动到FFT的第一个样本,并将结果移回:

from scipy.fftpack import fftshift, ifftshift
pdf2 = fftshift(ifft(fft(ifftshift(pdf))**2))

ifftshift移动信号,使中心样本在第一个样本处结束,fftshift将其移回您想要显示的位置。

但请注意,您生成PDF的方式,原点不在于样本,因此上述内容无法正常工作。相反,使用:

sample=np.linspace(end,-end,1001)
pdf=norm(0,1).pdf(sample)

通过选择1001个样本而不是1000个样本,零正好位于中间样本。

答案 1 :(得分:-1)

使用R!

library(ggplot2) 
f <- function(n) {
   x1 <- rnorm(n)
   x2 <- rnorm(n)
   X <- x1+x2
   return(ds)
}
ds.list <- lapply(10^(2:5),f)
ds <- Reduce(rbind,ds.list)
ggplot(ds,aes(X,fill = n)) + geom_density(alpha = 0.5) + xlab("")

这是分布图:

enter image description here