在 Matlab 中实现过滤器
Implementing a filter in Matlab
我正在尝试对离散信号实施以下滤波器 x
:
我应该编写一个 MATLAB 函数,它将长度为 M (> N) 的向量 x
和标量 N 作为输入。输出应该是长度为 M 的向量 y
.
然后我应该用 M = 50、x[n]=cos(n*pi/5)+dirac[n-30]-dirac[n-35]
和 N = 4、8、12 测试过滤器。
这是我的尝试,其中 returns Inf 具有给定的输入和 N
:
function y = filt( x, N )
% filter function
if(~isvector(x))
error('Input must be a vector')
end
y = zeros(1,length(x));
temp = zeros(1,length(x));
n=1;
for v = x(:)
temp(n) = v(n);
if(n <= N-1)
y(n) = max(x);
n = n+1;
elseif(n >= N-1)
y(n) = max(temp);
end
end
end
我也试过使用内置的 filter
函数,但我无法让它工作。
过滤器使用代码:
p = zeros(1,50);
for i=0:50
p(i+1)= cos(i*pi/5)+dirac(i-30)-dirac(i-35)
end
y = filt(p,4)
提前致谢。
那是因为 dirac(0)
给你 Inf
。这将在您的信号中的两个位置发生,其中 n=30
和 n=35
。我假设您想要 unit impulse。因此,在 n = 31
和 n = 36
处创建一个信号,输出为 1,然后将其与余弦信号相加。这是因为 MATLAB 从 1 而不是 0 开始索引,因此 dirac[0]
意味着信号的第一个点不为零,因此将其转换为 30:dirac[n-30]
将意味着第 31 个点不为零。 dirac[n-35]
的类似情况,因此第 36 个点不为零:
p = zeros(1,50);
p(31) = 1; p(36) = 1;
p = p + cos((0:49)*pi/5);
y = filt(p,4);
我对你的代码也有一些保留意见。它不做你认为它在做的事情。具体来说,我正在看这个部分:
n=1;
for v = x(:)
temp(n) = v(n);
if(n <= N-1)
y(n) = max(x);
n = n+1;
elseif(n >= N-1)
y(n) = max(temp);
end
end
执行 v = x(:)
会产生一个 列 向量,并且使用带有列向量的循环会产生意想不到的结果。具体来说,这个循环只会执行一次,v
是整个信号。您也没有正确检查每个 window 的条件。您正在执行 max(x)
,它将最大值 应用于整个信号 ,而不是 window。
如果我可以建议重写,那么您应该这样做:
function y = filt( x, N )
% filter function
if(~isvector(x))
error('Input must be a vector')
end
y = zeros(1,length(x));
%///// CHANGE
for n = 1 : numel(x)
if (n <= N)
y(n) = max(x(1:n));
else
y(n) = max(x(n:-1:n-N+1));
end
end
end
请注意 if
语句是 n <= N
。这是因为在 MATLAB 中,我们从 1 开始索引,但是等式中的符号从 0 开始索引。因此,不是检查 n <= N-1
,现在它必须是 n <= N
.
我正在尝试对离散信号实施以下滤波器 x
:
我应该编写一个 MATLAB 函数,它将长度为 M (> N) 的向量 x
和标量 N 作为输入。输出应该是长度为 M 的向量 y
.
然后我应该用 M = 50、x[n]=cos(n*pi/5)+dirac[n-30]-dirac[n-35]
和 N = 4、8、12 测试过滤器。
这是我的尝试,其中 returns Inf 具有给定的输入和 N
:
function y = filt( x, N )
% filter function
if(~isvector(x))
error('Input must be a vector')
end
y = zeros(1,length(x));
temp = zeros(1,length(x));
n=1;
for v = x(:)
temp(n) = v(n);
if(n <= N-1)
y(n) = max(x);
n = n+1;
elseif(n >= N-1)
y(n) = max(temp);
end
end
end
我也试过使用内置的 filter
函数,但我无法让它工作。
过滤器使用代码:
p = zeros(1,50);
for i=0:50
p(i+1)= cos(i*pi/5)+dirac(i-30)-dirac(i-35)
end
y = filt(p,4)
提前致谢。
那是因为 dirac(0)
给你 Inf
。这将在您的信号中的两个位置发生,其中 n=30
和 n=35
。我假设您想要 unit impulse。因此,在 n = 31
和 n = 36
处创建一个信号,输出为 1,然后将其与余弦信号相加。这是因为 MATLAB 从 1 而不是 0 开始索引,因此 dirac[0]
意味着信号的第一个点不为零,因此将其转换为 30:dirac[n-30]
将意味着第 31 个点不为零。 dirac[n-35]
的类似情况,因此第 36 个点不为零:
p = zeros(1,50);
p(31) = 1; p(36) = 1;
p = p + cos((0:49)*pi/5);
y = filt(p,4);
我对你的代码也有一些保留意见。它不做你认为它在做的事情。具体来说,我正在看这个部分:
n=1;
for v = x(:)
temp(n) = v(n);
if(n <= N-1)
y(n) = max(x);
n = n+1;
elseif(n >= N-1)
y(n) = max(temp);
end
end
执行 v = x(:)
会产生一个 列 向量,并且使用带有列向量的循环会产生意想不到的结果。具体来说,这个循环只会执行一次,v
是整个信号。您也没有正确检查每个 window 的条件。您正在执行 max(x)
,它将最大值 应用于整个信号 ,而不是 window。
如果我可以建议重写,那么您应该这样做:
function y = filt( x, N )
% filter function
if(~isvector(x))
error('Input must be a vector')
end
y = zeros(1,length(x));
%///// CHANGE
for n = 1 : numel(x)
if (n <= N)
y(n) = max(x(1:n));
else
y(n) = max(x(n:-1:n-N+1));
end
end
end
请注意 if
语句是 n <= N
。这是因为在 MATLAB 中,我们从 1 开始索引,但是等式中的符号从 0 开始索引。因此,不是检查 n <= N-1
,现在它必须是 n <= N
.