# [SciPy-User] ndimage.convolve

Zachary Pincus zachary.pincus@yale....
Thu Dec 10 12:08:39 CST 2009

> I want to take the laplacian of a 2-d field which has periodic
> boundary conditions. I tried doing this using ndimage.convolve, but
> when I test this on a simple function I don't get the result I
> expect. Why aren't the boundary elements going to zero as well in
> the following example?
>
>
> A= np.array([[x + y for x in np.arange(0,10)] for y in
> np.arange(0,10)])
> stencil=[[0,0,-1,0,0],[0,0,16,0,0],[-1,16,-60,16,-1],[0,0,16,0,0],
> [0,0,-1,0,0]]
> ndimage.convolve(A,stencil,mode='wrap')
>
> array([[ 300,  140,  150,  150,  150,  150,  150,  150,  160,    0],
>        [ 140,  -20,  -10,  -10,  -10,  -10,  -10,  -10,    0, -160],
>        [ 150,  -10,    0,    0,    0,    0,    0,    0,   10, -150],
>        [ 150,  -10,    0,    0,    0,    0,    0,    0,   10, -150],
>        [ 150,  -10,    0,    0,    0,    0,    0,    0,   10, -150],
>        [ 150,  -10,    0,    0,    0,    0,    0,    0,   10, -150],
>        [ 150,  -10,    0,    0,    0,    0,    0,    0,   10, -150],
>        [ 150,  -10,    0,    0,    0,    0,    0,    0,   10, -150],
>        [ 160,    0,   10,   10,   10,   10,   10,   10,   20, -140],
>        [   0, -160, -150, -150, -150, -150, -150, -150, -140, -300]])

I feel that I am missing something, because this seems like the
expected behavior.

You're convolving this matrix:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
[ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
[ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
[ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13],
[ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14],
[ 6,  7,  8,  9, 10, 11, 12, 13, 14, 15],
[ 7,  8,  9, 10, 11, 12, 13, 14, 15, 16],
[ 8,  9, 10, 11, 12, 13, 14, 15, 16, 17],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]])

With this kernel:
array([[  0,   0,  -1,   0,   0],
[  0,   0,  16,   0,   0],
[ -1,  16, -60,  16,  -1],
[  0,   0,  16,   0,   0],
[  0,   0,  -1,   0,   0]])

using *wraparound* boundary conditions (not mirroring!). I fail to see
why the result is unexpected...

For simplicity, let's look at the equivalent 1D case:
matrix:
[ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14]
kernel:
[ -1,  16, -30,  16,  -1]

At the right edge, you have this:
[ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14]  5   6
*
[ -1, 16,-30, 16, -1]

where the "phantom" 5 and 6 come from the wraparound boundary condition.
-1*12 + 16*13 + -30*14 + 16*5 + -1*6 does not equal zero!

ndimage.convolve([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14],  [ -1,
16,-30, 16, -1], mode='wrap')
array([ 150,  -10,    0,    0,    0,    0,    0,    0,   10, -150])

Zach

ps: more straightforward way to construct A matrix above: