假设我们要计算从 0 到 10 的正弦函数和高斯函数的 convolution。下面您可以看到使用两种方法执行此操作的代码。第一种方法使用MATLAB函数conv(),第二种方法直接计算。
clear all
clc
x = linspace(0, 10, 101);
dx = x(2) - x(1);
a = @(x) sin(x);
b = @(x) -exp(-x.^2);
y = conv(a(x), b(x),'same') * dx;
t = linspace(-10, 10, 100);
z = zeros(size(x));
for i = 1:length(x)
uu = a(t).*b(x(i)-t);
z(i) = trapz(t,uu);
end
figure(1)
hold on
plot(x, y, 'DisplayName','conv()')
plot(x, z, 'DisplayName','direct')
两种方法给出的结果不同,如下图所示。
但是如果我们在-10到10之间使用conv(),并且在计算之后只保留结果中对应于0到10区间的那部分结果,两种方法给出的结果是一样的。
clear all
clc
x = linspace(0, 10, 101);
xf = linspace(-10,10,201);
dx = x(2) - x(1);
x0 = find(xf==0);
a = @(x) sin(x);
b = @(x) -exp(-x.^2);
y = conv(a(xf), b(xf),'same') * dx;
y = y(x0:end);
t = linspace(-10, 10, 100);
z = zeros(size(x));
for i = 1:length(x)
uu = a(t).*b(x(i)-t);
z(i) = trapz(t,uu);
end
figure(1)
hold on
plot(x, y, 'DisplayName','conv()')
plot(x, z, 'DisplayName','direct')
如下图所示,结果是一样的。
我有两个问题:
1- 为什么 conv() 对正域不起作用,只有当包含负数时,我们才能得到正确的结果?
2- 有没有办法只使用函数 conv() 和区间 0 到 10 并获得相同的结果?我想在非常复杂的代码中使用卷积积分,而直接方法非常慢,所以我想使用 conv()。然而,代码的结构使得我不能使用我在这个例子中使用的负域。
答案 0 :(得分:1)
绘制要卷积的两个采样信号。你会注意到你只有半个高斯。使用 (-10,10) 区间时,您对完整的高斯进行采样,因此会得到正确的结果。
要获得正确的结果,您需要移动高斯以使其完全采样:
y = conv(a(x), b(x-5),'same') * dx;
如果您移动高斯函数使其原点位于样本中间,则输出函数似乎不会移动,conv
假设原点位于数组的中间。