R中的卷积
我尝试直接在 R 中进行卷积并使用 FFT 然后取逆。但从简单的观察看来,这是不正确的。看这个例子:
# DIRECTLY
> x2$xt
[1] 24.610 24.605 24.610 24.605 24.610
> h2$xt
[1] 0.003891051 0.003875910 0.003860829 0.003845806 0.003830842
> convolve(h2$xt,x2$xt)
[1] 0.4750436 0.4750438 0.4750435 0.4750437 0.4750435
# USING INVERSE FOURIER TRANSFORM
> f=fft(fft(h2$xt)*fft(x2$xt), inv=TRUE)
> Re(f)/length(f)
[1] 0.4750438 0.4750435 0.4750437 0.4750435 0.4750436
>
让我们取索引 0。在 0 处,卷积应该只是 x2$xt (24.610) 的最后一个值乘以 h2$xt (0.003891051) 的第一个值,这应该给出索引 0 = 24.610* 处的卷积0.003891051 = 0.09575877,与 0.4750436 相差甚远。
我做错了什么吗?为什么这些值与预期相差如此之大?
I tried to do convolution in R directly and using FFTs then taking inverse. But it seems from simple observation it is not correct. Look at this example:
# DIRECTLY
> x2$xt
[1] 24.610 24.605 24.610 24.605 24.610
> h2$xt
[1] 0.003891051 0.003875910 0.003860829 0.003845806 0.003830842
> convolve(h2$xt,x2$xt)
[1] 0.4750436 0.4750438 0.4750435 0.4750437 0.4750435
# USING INVERSE FOURIER TRANSFORM
> f=fft(fft(h2$xt)*fft(x2$xt), inv=TRUE)
> Re(f)/length(f)
[1] 0.4750438 0.4750435 0.4750437 0.4750435 0.4750436
>
Lets take the index 0. At 0, the convolution should simply be the last value of x2$xt (24.610) multiplied by first value of h2$xt (0.003891051) which should give convolution at index 0 = 24.610*0.003891051 = 0.09575877 which is way off from 0.4750436.
Am I doing something wrong? Why is the values so different from expected?
convolve
和fft
都是循环。卷积的第一个元素必须是这两个级数的点积。从这个意义上讲,您获得的结果是正确的。要执行线性卷积,请使用:
在这种情况下也应用循环卷积,但将所需数量的零填充到输入以实现线性卷积。
我相信在 R 中没有直接的方法可以用
fft
实现线性卷积。但这并不重要,因为convolve
本身使用您发布的 FFT 方法。循环卷积
如果存在一个周期N,使得对于所有的x[n] = x[n+N],则离散信号x是周期性的n。这些信号可以用从x[0]到x[N-1]的N个样本来表示。
非周期x和y之间卷积的常规定义定义为:
但是,对于周期信号,该公式不会产生有限结果。为了克服这个问题,我们定义了周期性x和y之间的循环卷积。
当这两个信号仅用N值表示时,我们可以使用y[n-k+N]代替y[nk]对于负值nk。
循环卷积最酷的地方在于它可以计算框信号之间的线性卷积,框信号是具有有限数量的非零元素的离散信号。
长度为N的盒信号可以输入到具有2N周期的循环卷积,原始样本为N,零为N最后填充。结果将是具有 2N 个样本的循环卷积,以及用于线性卷积的 2N-1 和一个额外的零。
循环卷积通常比直接线性卷积实现更快,因为它可以利用快速傅里叶变换,这是一种计算离散傅里叶变换的快速算法,该算法仅定义为周期性离散信号。
请参阅:
另请参阅:
Both
convolve
andfft
are circular. The first element of convolution must be the dot product of these two series. The results you obtain are correct in this sense.To perform a linear convolution use:
Circular convolution is also applied in this case but a required amount of zeros are padded to inputs to achieve linear convolution.
I believe there is not a direct way to achieve linear convolution with
fft
in R. However this doesn't really matter beacuseconvolve
itself uses the FFT approach you posted.Circular Convolution
A discrete signal x is periodic if there is a period N such that x[n] = x[n+N] for all n. Such signals can be represented by N samples from x[0] to x[N-1].
A regular definition of convolution between aperiodic x and y is defined as:
However, for periodic signals, this formula does not produce finite results. To overcome this problem we define the circular convolution between periodic x and y.
When these two signals are represented with N values only, we can use y[n-k+N] in place of y[n-k] for negative values of n-k.
The cool thing with circular convolution is that it can calculate the linear convolution between box signals, which are discrete signals that have a finite number of non-zero elements.
Box signals of length N can be fed to circular convolution with 2N periodicity, N for original samples and N zeros padded at the end. The result will be a circular convolution with 2N samples with 2N-1 for linear convolution and an extra zero.
Circular convolution is generally faster than a direct linear convolution implementation, because it can utilize the Fast Fourier Transform, a fast algorithm to calculate the Discrete Fourier Transform, which is only defined for periodic discrete signals.
Please see:
Also see: