到目前为止,我还没有找到一种方法来计算不涉及应用线性卷积+混叠的循环卷积(对于大于 N 的序列,大小为 N)。这是我原来的问题
但是,我在 Sophocles J. Orfanidis 的信号处理简介第 518 页中发现了一个聪明的算法,它允许我以一种可以理解的方式从线性卷积 + 混叠中获得循环卷积。
这是我的解释:
首先我们必须获得线性卷积,然后我们将线性卷积输出以 L 个样本的间隔放置在时间轴上(一种周期性扩展)。由于线性卷积输出大于L个样本,一些样本会重叠(实际上来自多个“周期”的样本会在0到L-1的主要“周期”上重叠)。在获得循环卷积时,我们只对区间 0 到 L-1(或 Matlab 中的 1 到 L)感兴趣
例如计算 3 点循环卷积一书中的这个例子:
[1, 3, 3, 5, 3, 7, 4, 3, 3, 0, 1] main period (direct linear convolution output)
[5, 3, 7, 4, 3, 3, 0, 1, 0, 0, 0] 1 period to the left contribution on main period
[4, 3, 3, 0, 1, 0, 0, 0, 0, 0, 0] 2 periods to the left contribution on main period
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] 3 periods to the left contribution on main period
左侧不再考虑其他周期,因为它们不会在主周期中产生混叠(线性卷积输出小于 3 个样本的 3 个移位)。最后形成序列的前 3 个位置(主周期)相加,以形成 3 点循环卷积,即
(1+5+4+0,3+3+3+1,3+7+3+0) = (10,10,13)
右侧的句点被忽略,因为它们不会导致主“句点”中的混叠
这是我的 Matlab 代码(用于通用序列):
modulo = 4;
sequence1 = [0,0.5,1,1,0.5];
sequence2 = [0,0.5,1,1,0.5];
linealConvolution = conv(sequence1,sequence2);
stem(linealConvolution)
hold on
periods = linealConvolution;
times = 1;
while length(linealConvolution) >= times*modulo
%shift the linealConvolution sequence modulo(amount) samples at a time and add
%it to the previosly stored sequence (this adds the contribution of time
%aliased lineal convolutions on adjacent periods)
aliasingPeriodToTheLeft = [ linealConvolution(times*modulo + 1: end) zeros(1,times*modulo) ] ;
stem(aliasingPeriodToTheLeft)
periods = periods + aliasingPeriodToTheLeft;
times = times+1;
end
inTheEnd = periods(1:modulo);
figure
stem(inTheEnd)
%checking
isequal(cconv(sequence1,sequence2,modulo),inTheEnd)