Написанная функция свертки в matlab доставляет неприятности - PullRequest
1 голос
/ 20 августа 2010

Привет, у меня возникли трудности при написании эквивалента matlab функции conv(x,y).Я не могу понять, почему это дает неправильный вывод.Для массивов x1 = [1 2 1] и x2 = [3 1 1].

Вот что у меня есть

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

Matlab conv(x1,x2) дает 3 7 6 3 1 в качестве вывода, но это дает мне 3 5 6 6 6для ответа.Где я ошибся?

Также, извините за форматирование, которое я использую в Opera Mini.

Ответы [ 2 ]

3 голосов
/ 20 августа 2010

Помимо отсутствия определения x и наличия всех нулей для ваших переменных x1, x2, buffer и answer, я не уверен, почему ваши вложенные циклы настроены как они есть. Я не знаю, почему вам нужно воспроизвести поведение CONV таким образом, но вот как я бы настроил решение для вложенного цикла:

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

Однако, поскольку этот является MATLAB, существуют векторизованные альтернативы зацикливанию таким образом. Одним из таких решений является следующее, в котором используются функции SUM , SPDIAGS и FLIPUD :

output = sum(spdiags(flipud(X(:))*Y));
0 голосов
/ 20 августа 2010

В указанном коде все векторы обнуляются перед началом, кроме x, который никогда не определяется.Так что трудно точно понять, к чему вы клоните.Но обратите внимание на пару вещей:

  • Во внутреннем цикле for вы используете значения buffer, которые еще не были установлены внешним циклом.
  • Внутренний цикл всегда охватывает весь диапазон 1:len, а не смещает один вектор относительно другого.

Возможно, вы также захотите подумать о «векторизации» некоторых из них, а не о вложении циклов for -- Например, ваш внутренний цикл просто вычисляет скалярное произведение, для которого уже существует совершенно хорошая функция Matlab.

(Конечно, то же самое можно сказать и о conv - но я полагаю, вы реализуете зановоили как домашнее задание или чтобы понять как это работает?)

...