Matlabのconv()をPythonで


matlabで畳み込みを計算するconv。
ガウシアンフィルターなんかでおなじみのやつ。

numpy.convolve

matlabのconvはnumpy.convolveとほぼ同じ。

matlabの

conv(u,v,shape)

をpythonで書くと

numpy.convolve(u,v,shape)

となる。
shapeが 'full' 'same' 'valid' のいずれか、というのも同じ

ただし、u,vの長さが両方とも偶数で'same'のとき、返す範囲が1つだけ違うらしい。
まぁフィルタリングだとvはだいたい対称で長さは奇数なので、あまり問題にならないと思うけど。

u,vの長さの少なくとも一方が奇数のとき

in Matlab

x=1:10;
y=[0,1,0.5];

conv(x,y,'full')
conv(x,y,'same')
conv(x,y,'valid')

Matlab 出力

ans =
         0    1.0000    2.5000    4.0000    5.5000    7.0000    8.5000   10.0000   11.5000   13.0000   14.5000    5.0000

ans =
    1.0000    2.5000    4.0000    5.5000    7.0000    8.5000   10.0000   11.5000   13.0000   14.5000


ans =
    2.5000    4.0000    5.5000    7.0000    8.5000   10.0000   11.5000   13.0000

in Python

import numpy as np

x = range(1, 11)
y = (0, 1, 0.5)

print(np.convolve(x, y, 'full'))
print(np.convolve(x, y, 'same'))
print(np.convolve(x, y, 'valid'))

Python 出力

[ 0.   1.   2.5  4.   5.5  7.   8.5 10.  11.5 13.  14.5  5. ]
[ 1.   2.5  4.   5.5  7.   8.5 10.  11.5 13.  14.5]
[ 2.5  4.   5.5  7.   8.5 10.  11.5 13. ]

どちらも同じ。

u,vの長さが両方とも偶数のとき

in Matlab

x=1:9;
y=[0,1,0.5,0.1];

conv(x,y,'full')
conv(x,y,'same')
conv(x,y,'valid')

Matlab出力

ans =
         0    1.0000    2.5000    4.1000    5.7000    7.3000    8.9000   10.5000   12.1000   13.7000    5.3000    0.9000

ans =
    2.5000    4.1000    5.7000    7.3000    8.9000   10.5000   12.1000   13.7000    5.3000


ans =
    4.1000    5.7000    7.3000    8.9000   10.5000   12.1000

in Python

x = range(1, 10)
y = (0, 1, 0.5,0.1)

print(np.convolve(x, y, 'full'))
print(np.convolve(x, y, 'same'))
print(np.convolve(x, y, 'valid'))

Python 出力

[ 0.   1.   2.5  4.1  5.7  7.3  8.9 10.5 12.1 13.7  5.3  0.9]
[ 1.   2.5  4.1  5.7  7.3  8.9 10.5 12.1 13.7]
[ 4.1  5.7  7.3  8.9 10.5 12.1]

sameのとき、Matlabの方が出力が1つ長い