长度大于 L 的序列的长度 L 的循环卷积

信息处理 离散信号 自由度 卷积 混叠
2022-02-14 04:19:05

我试图了解当我试图卷积的序列的长度大于 L 时,我如何获得长度为 L 的循环卷积。

例如,这个使用长度为 5 的序列的 Matlab 代码:

c = cconv([0,0.5,1,1,0.5],[0,0.5,1,1,0.5],4);

产生一个 4 点序列

2.25  2.5  2.25  2.0

这个 Matlab 代码

cconv([0,0.5,1,1,0.5],[0,0.5,1,1,0.5],3)

产生一个 3 点序列

3 3 3

我知道循环卷积可能被视为具有混叠的线性卷积,并且如果我执行线性卷积并构建每隔 N 个样本间隔的重叠周期,我将得到 N 点循环卷积,但是有没有一种方法可以获得循环卷积而无需计算第一个线性卷积?我正在考虑进行卷积的经典方法,我及时翻转其中一个序列并对其进行移位,对于每个移位,我将 2 个序列相乘并相加以获得该移位的输出样本

2个回答

圆形卷积与线性卷积非常接近。两者都是基于相同的原理计算的。然而,循环卷积有一个周期性的结果(基于它的输入是周期性的),因此它的计算可能会受此影响。

在实现循环卷积时,如果您实际上在引擎盖下使用线性卷积(反之亦然),则不会降低效率,因为它们的计算效率非常接近,除非您正在处理架构优化代码。

另一方面,点周期性序列点循环卷积,您可能会要求为计算比必要的线性卷积更长的时间付出代价在这种情况下,您可以通过以下斩波方法(借用自@DilipSarwate 的相关答案)来提高效率,我在这里给出了一个基本的 MATLAB 实现,从中您可以看到线性卷积是在较短的长度上执行的,而不是较长的一个LNL<NLN

下面为您提供了一种计算点序列点循环卷积的方法LNL<N

clc; clear all; close all;

% S0 - Define the Signals
% Note this is meaningful only when L < signal lengths
L = 3;                 % circular convolution length that we want to compute
x = [0 0.5 1 1 0.5];   % signal length is greater than L
h = x;

xL = zeros(1,L);       % these are for short, chopped signals.
hL = zeros(1,L);
for k=1:L              % compute the CHOPPED signals...
    xL(k) = sum( x(k:L:end) );
    hL(k) = sum( h(k:L:end) );
end
yN = conv(xL,hL);     % compute the linear convolution at the chopped length
yL = yN(1:N) + [yN(L+1:end) 0] ; post-process the result.

到目前为止,我还没有找到一种方法来计算不涉及应用线性卷积+混叠的循环卷积(对于大于 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)