views:

37

answers:

2

Hey there, I've been having difficulty writing the matlab equivalent of the conv(x,y) function. I cant figure out why this gives the incorrect output. For the arrays x1 = [1 2 1] and x2 = [3 1 1].

Here's what I have

x1 = [1 2 1];
x2 = [3 1 1];

x1len = leng(x1);
x2len = leng(x2);
len = x1len + x2len - 1;

x1 = zeros(1,len);
x2 = zeros(1,len);
buffer = zeros(1,len);
answer = zeros(1,len);

for n = 1:len
    buffer(n) = x(n);
    answer(n) = 0;

    for i = 1:len
        answer(n) = answer(n) + x(i) * buffer(i);
    end
end

The matlab conv(x1,x2) gives 3 7 6 3 1 as the output but this is giving me 3 5 6 6 6 for answer. Where have I gone wrong?

Also, sorry for the formatting I am on opera mini.

A: 

In the code as given, all vectors are zeroed out before you start, except for x which is never defined. So it's hard to see exactly what you're getting at. But a couple of things to note:

  • In your inner for loop you are using values of buffer which have not yet been set by your outer loop.
  • The inner loop always covers the full range 1:len rather than shifting one vector relative to the other.

You might also want to think about "vectorizing" some of this rather than nesting for loops -- eg, your inner loop is just calculating a dot product, for which a perfectly good Matlab function already exists.

(Of course the same can be said for conv -- but I guess you're reimplementing either as homework or to understand how it works?)

walkytalky
+1  A: 

Aside from not having x defined, and having all zeroes for your variables x1, x2, buffer, and answer, I'm not certain why you have your nested loops set up like they are. I don't know why you need to reproduce the behavior of CONV this way, but here's how I would set up a nested for-loop solution:

X = [1 2 1];
Y = [3 1 1];

nX = length(X);
nY = length(Y);
nOutput = nX+nY-1;

output = zeros(1,nOutput);

for indexY = 1:nY
  for indexX = 1:nX
    indexOutput = indexY+indexX-1;
    output(indexOutput) = output(indexOutput) + X(indexX)*Y(indexY);
  end
end

However, since this is MATLAB, there are vectorized alternatives to looping in this way. One such solution is the following, which uses the functions SUM, SPDIAGS, and FLIPUD:

output = sum(spdiags(flipud(X(:))*Y));
gnovice

related questions