在 MATLAB 中计算正域上的卷积积分
Calculation of Convolution Integral Over a Positive Domain in MATLAB
假设我们要计算正弦的 convolution 和从 0 到 10 的高斯函数。下面您可以看到使用两种方法执行此操作的代码。第一种方法使用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()。但是,代码的结构使我不能像我在本例中使用的那样使用否定域。
绘制您正在卷积的两个采样信号。你会注意到你只有半个高斯分布。使用 (-10,10) 区间时,您对完整的高斯进行采样,因此得到正确的结果。
要获得正确的结果,您需要移动高斯以使其完全采样:
y = conv(a(x), b(x-5),'same') * dx;
如果您移动高斯使其原点位于中间样本,则输出函数看起来不会移动,conv
假定原点位于数组中间。
假设我们要计算正弦的 convolution 和从 0 到 10 的高斯函数。下面您可以看到使用两种方法执行此操作的代码。第一种方法使用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()。但是,代码的结构使我不能像我在本例中使用的那样使用否定域。
绘制您正在卷积的两个采样信号。你会注意到你只有半个高斯分布。使用 (-10,10) 区间时,您对完整的高斯进行采样,因此得到正确的结果。
要获得正确的结果,您需要移动高斯以使其完全采样:
y = conv(a(x), b(x-5),'same') * dx;
如果您移动高斯使其原点位于中间样本,则输出函数看起来不会移动,conv
假定原点位于数组中间。