在Matlab中实现过滤器

Lig*_*ind 3 matlab filtering signal-processing

我试图在离散信号上实现以下过滤器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.

这是我的尝试,它使用给定的输入返回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
Run Code Online (Sandbox Code Playgroud)

我也试过使用内置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)
Run Code Online (Sandbox Code Playgroud)

提前致谢.

ray*_*ica 5

那是因为dirac(0)给你Inf.这将发生在信号的两个地方,其中n=30n=35.我假设你想要单位冲动.因此,创建一个信号,其中at n = 31n = 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);
Run Code Online (Sandbox Code Playgroud)

我对你的代码也有一些保留意见.它没有做你认为它正在做的事情.具体来说,我正在看这个部分:

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
Run Code Online (Sandbox Code Playgroud)

执行v = x(:)会生成向量,并且使用带有列向量的循环将产生无意的结果.具体来说,这个循环只执行一次,v作为整个信号.您也没有正确检查每个窗口的条件.你正在做max(x),它将最大值应用于整个信号,而不是窗口.


如果我可以建议重写,那么你应该做的就是:

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
Run Code Online (Sandbox Code Playgroud)

请注意if声明是n <= N.这是因为在MATLAB中,我们开始索引为1,但是等式中的符号开始索引为0.因此,n <= N-1现在必须是,而不是检查n <= N.