2010-08-19 15 views
1

Hey là, j'ai eu de la difficulté à écrire l'équivalent matlab de la fonction conv(x,y). Je n'arrive pas à comprendre pourquoi cela donne la sortie incorrecte. Pour les réseaux x1 = [1 2 1] et x2 = [3 1 1].Fonction de convolution écrite dans MATLAB donnant des problèmes

Voici ce que j'ai

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) donne 3 7 6 3 1 que la sortie mais cela me donne 3 5 6 6 6 pour réponse. Où est-ce que je me suis trompé?

Aussi, désolé pour le formatage je suis sur Opera Mini.

Répondre

3

En plus de ne pas avoir x défini, et ayant tous des zéros pour vos variables x1, x2, buffer, et answer, je ne sais pas pourquoi vous avez configuré vos boucles imbriquées comme elles sont. Je ne sais pas pourquoi vous avez besoin de reproduire le comportement de CONV cette façon, mais voici comment je mettre en place une solution imbriquée pour boucle:

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 

Cependant, puisque ce est Matlab, il y a vectorisé alternatives à la boucle de cette manière. Une telle solution est la suivante, qui utilise les fonctions SUM, SPDIAGS et FLIPUD:

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

can output = somme (spdiags (flipud (X (:)) * Y)); être étendu pour la convolution 2D? – user1816546

0

Dans le code tel que donné, tous les vecteurs sont remis à zéro avant de commencer, à l'exception de x qui n'est jamais défini. Il est donc difficile de voir exactement ce que vous voulez dire. Mais deux ou trois choses à noter:

  • Dans votre boucle for intérieure vous utilisez des valeurs de buffer qui n'ont pas encore été fixé par votre boucle extérieure.
  • La boucle interne couvre toujours la plage complète 1:len plutôt que de décaler un vecteur par rapport à l'autre.

Vous pourriez aussi penser à « vectorisation » une partie de ce plutôt que l'imbrication for boucles - par exemple, la boucle intérieure est simplement calculer un produit de points, pour lesquels une très bonne fonction Matlab existe déjà.

(Bien sûr, la même chose peut être dit pour conv - mais je suppose que vous réimplémentant soit comme devoirs ou pour comprendre comment cela fonctionne)