下采样和卷积:什么时候可以在它们之间交换?

信息处理 matlab 卷积 下采样
2022-02-02 18:54:00

(代码片段与下面的示例)。

在 MATLAB 中,假设我有一个长信号向量y(长度N),我希望与方波h(由H1 组成)进行卷积。这将给出长度的卷积结果N+H-1

由于我必须经常执行此操作,我认为我可以通过对信号y(以及方波h)进行下采样来加速我的代码,然后执行卷积。下采样的信号称为y_dsh_ds

但是,与卷积结果的下采样版本相比,结果会发生偏移(如果针对缩放差异进行了校正)。所以总的来说,我发现:

conv(y_ds,h_ds) downsample(conv(y,h))

然而,两个结果之间的偏移不是恒定的,即偏移使得最大值对齐,导致边缘不同。

我的问题

  • 这种转变从何而来?
  • 如何修改此代码以使下采样卷积结果等于下采样信号的卷积结果?

亲切的问候

N = 100;
dsfactor = 3;
H = dsfactor*3;
x = linspace(0,10,N);
y = sind(18*x);
h = ones(H,1);

convyh = conv(y,h);

convyh_ds = downsample(convyh,dsfactor)./H;
convyh_ds3 = conv(downsample(y,dsfactor),downsample(h,dsfactor))./(ceil(H/dsfactor));

figure;
plot(convyh_ds,'DisplayName','downsample(conv)','LineWidth',1);
hold on;
plot(convyh_ds3,'DisplayName','conv(downsample)','LineWidth',1);
grid minor
legend('show');
line([0 length(convyh_ds2)],[0 0],'LineStyle','--');

在此处输入图像描述

1个回答

我认为这是因为在一次下采样操作期间您的信号出现混叠。但是,我在 R 中重新编写了您的代码(包括在下面),但我没有看到我怀疑conv正在做一些奇怪的事情的相同效果。您可能想查看使用shape参数,看看是否有区别。

以下是您的不同变体的四个图:

  • 左上:你的。
  • 右上角:使用略有不同x值的变体。
  • 左下:你的频率是你的两倍。
  • 右下:x以两倍频率使用略有不同值的变体。

如您所见,在所有四个示例中,红色和黑色完全重叠。

四个不同顺序的抽取/过滤图。

是的,一般来说,这些是不一样的。下面是一个带有锯齿波的例子,两者不对齐。

锯齿示例。

这是您询问三角波的具体示例。

三角波示例。


仅在下面的 R 代码

#43794
#N = 100;
N <- 100
#dsfactor = 3;
dsfactor <- 3
#H = dsfactor*3;
H <- dsfactor * 3
#x = linspace(0,10,N);
x1 <- seq(0,10,10/(N-1))
x2 <- seq(0,10*(N-1)/N,10/N)
#y = sind(18*x);
y1 <- sin(18*x1/180*pi)
y2 <- sin(18*x2/180*pi)
y3 <- sin(36*x1/180*pi)
y4 <- sin(36*x2/180*pi)
#h = ones(H,1);
h <- rep(1,H)

#convyh = conv(y,h);
convy1h <- filter(y1,h)
convy2h <- filter(y2,h)
convy3h <- filter(y3,h)
convy4h <- filter(y4,h)

downsample <- function(signal, factor) 
{
  return(signal[seq(1,length(signal), factor)])
}

#convyh_ds = downsample(convyh,dsfactor)./H;
convy1h_ds <- downsample(convy1h, dsfactor)/H
convy2h_ds <- downsample(convy2h, dsfactor)/H
convy3h_ds <- downsample(convy3h, dsfactor)/H
convy4h_ds <- downsample(convy4h, dsfactor)/H
#convyh_ds3 = conv(downsample(y,dsfactor),downsample(h,dsfactor))./(ceil(H/dsfactor));
convy1h_ds3 <- filter(downsample(y1,dsfactor), downsample(h,dsfactor))/ceiling(H/dsfactor)
convy2h_ds3 <- filter(downsample(y2,dsfactor), downsample(h,dsfactor))/ceiling(H/dsfactor)
convy3h_ds3 <- filter(downsample(y3,dsfactor), downsample(h,dsfactor))/ceiling(H/dsfactor)
convy4h_ds3 <- filter(downsample(y4,dsfactor), downsample(h,dsfactor))/ceiling(H/dsfactor)
#figure;
#plot(convyh_ds,'DisplayName','downsample(conv)','LineWidth',1);
#hold on;
#plot(convyh_ds3,'DisplayName','conv(downsample)','LineWidth',1);
#grid minor
#legend('show');
#line([0 length(convyh_ds2)],[0 0],'LineStyle','--');

par(mfrow=c(2,2))
plot(convy1h_ds)
lines(convy1h_ds3, col='red')

plot(convy2h_ds)
lines(convy2h_ds3, col='red')

plot(convy3h_ds)
lines(convy3h_ds3, col='red')

plot(convy4h_ds)
lines(convy4h_ds3, col='red')