3
votes

I am trying to implement the following filter on a discrete signal x:

enter image description here

I'm supposed to write a MATLAB function that takes a length-M (> N) vector x and a scalar N as input. The output should be a length-M vector y.

I should then test the filter with M = 50, x[n]=cos(n*pi/5)+dirac[n-30]-dirac[n-35] and N = 4, 8, 12.

Here is my try, which returns Inf with the given input and 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

I also tried using the built-in filter function but I can't get it to work.

Code for using the 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)

Thanks in advance.

1

1 Answers

5
votes

That's because dirac(0) gives you Inf. This will happen in two places in your signal, where n=30 and n=35. I'm assuming you want the unit impulse instead. As such, create a signal where at n = 31 and n = 36, the output is 1, then add this with your cosine signal. This is because MATLAB starts indexing at 1 and not 0, and so dirac[0] would mean that the first point of your signal is non-zero, so translating this over by 30: dirac[n-30] would mean that the 31st point is non-zero. Similar case for dirac[n-35], so the 36th point is non-zero:

p = zeros(1,50);
p(31) = 1; p(36) = 1;
p = p + cos((0:49)*pi/5);
y = filt(p,4);

I also have some reservations with your code. It doesn't do what you think it's doing. Specifically, I'm looking at this section:

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

Doing v = x(:) would produce a column vector, and using a loop with a column vector will have unintentional results. Specifically, this loop will only execute once, with v being the entire signal. You also aren't checking the conditions properly for each window. You are doing max(x), which applies the maximum to the entire signal, and not the window.


If I can suggest a rewrite, this is what you should be doing instead:

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

Take note that the if statement is n <= N. This is because in MATLAB, we start indexing at 1, but the notation in your equation starts indexing at 0. Therefore, instead of checking for n <= N-1, it must now be n <= N.