I found a way to do the convolution operation only with the array operation of numpy's ndarray. However, I am using the tensor-like class of my own module. Variables and subscripts mean the elements of a set (general definitions are unstudied and unclear).
However, it uses self-defined arithmetic rules.
will do.
\bar{I}_{ij} = I_{x_{ik}y_{jl}}h^{kl}
Compared with the result of scipy.signal.fftcomvolve.
from scipy.signal import *
def convolve2d_tensorlike(I, h, mode="full"):
hrows = h.shape[0]
hcols = h.shape[1]
add = zeros(h.shape[0]-1)
rows = I.shape[0]
cols = I.shape[1]
add = array(h.shape)-1
if mode=="full":
I_zeros = zeros(array(I.shape) + 2*add)
I_zeros[add[0]:-add[1], add[0]:-add[1]] = I
I = I_zeros
elif mode=="valid":
add = array(h.shape)-1
else:
I_zeros = zeros(array(I.shape) + add)
I_zeros[add[0]/2:-add[0]/2,add[1]/2:-add[1]/2] = I
I = I_zeros
rows = I.shape[0]
cols = I.shape[1]
i = tensor(cols*arange(rows-add[0]), "i", "d")
j = tensor(arange(cols-add[0]), "j", "d")
k = tensor(cols*arange(hrows), "k", "d")
l = tensor(arange(hcols), "l", "d")
h = tensor(h, "kl", "uu")
x = (i + j + k + l)
x.transpose("ijkl") #X in the above equation_{ik}y_{jl}Corresponds to
I_bar = tensor(I.flatten()[x.arr.flatten().astype(int)]
.reshape(x.arr.shape), "ijkl", "dddd")
I_bar = I_bar * h
I_bar.transpose("ij")
return I_bar.arr
I = array([[1,5,99,7,6],
[6,5,38,7,2],
[1,6,8,2,6],
[7,5,2,3,7],
[3,5,8,7,1]])
h = ones((3,3))
print "fftconvolve(I, h,'full')"
print convolve2d_tensorlike(I, h,"full")
print
print "fftconvolve(I, h,'full')"
print convolve2d_tensorlike(I, h, 'full')
print
print "fftconvolve(I, h,'same'')"
print fftconvolve(I, h,"same")
print
print "convolve2d_tensorlike(I, h,'same'')"
print convolve2d_tensorlike(I, h,"same")
print
print "fftconvolve(I, h,'valid'')"
print fftconvolve(I, h,"valid")
print
print "convolve2d_tensorlike(I, h,'valid'')"
print convolve2d_tensorlike(I, h,"valid")
print
Execution result
fftconvolve(I, h,'full')
[[ 1. 6. 105. 111. 112. 13. 6.]
[ 7. 17. 154. 161. 159. 22. 8.]
[ 8. 24. 169. 177. 175. 30. 14.]
[ 14. 30. 78. 76. 75. 27. 15.]
[ 11. 27. 45. 46. 44. 26. 14.]
[ 10. 20. 30. 30. 28. 18. 8.]
[ 3. 8. 16. 20. 16. 8. 1.]]
fftconvolve(I, h,'full')
[[ 1. 6. 105. 111. 112. 13. 6.]
[ 7. 17. 154. 161. 159. 22. 8.]
[ 8. 24. 169. 177. 175. 30. 14.]
[ 14. 30. 78. 76. 75. 27. 15.]
[ 11. 27. 45. 46. 44. 26. 14.]
[ 10. 20. 30. 30. 28. 18. 8.]
[ 3. 8. 16. 20. 16. 8. 1.]]
fftconvolve(I, h,'same'')
[[ 17. 154. 161. 159. 22.]
[ 24. 169. 177. 175. 30.]
[ 30. 78. 76. 75. 27.]
[ 27. 45. 46. 44. 26.]
[ 20. 30. 30. 28. 18.]]
convolve2d_tensorlike(I, h,'same'')
[[ 17. 154. 161. 159. 22.]
[ 24. 169. 177. 175. 30.]
[ 30. 78. 76. 75. 27.]
[ 27. 45. 46. 44. 26.]
[ 20. 30. 30. 28. 18.]]
fftconvolve(I, h,'valid'')
[[ 169. 177. 175.]
[ 78. 76. 75.]
[ 45. 46. 44.]]
convolve2d_tensorlike(I, h,'valid'')
[[ 169. 177. 175.]
[ 78. 76. 75.]
[ 45. 46. 44.]]
a = arange(9).reshape((3,3))
#a=
#[[0 1 2]
# [3 4 5]
# [6 7 8]]
#
print a[ix_([0,1,2],[2,0,1])]
#<-Returns the elements of matrix a as the following matrix(line,Column)
#[[(0,2), (0,0), (0,1)]
# [(1,2), (1,0), (1,1)]
# [(1,2), (1,0), (1,1)]]
print a[ix_([0,1],[2,0])]
#[[(0,2), (0,0)]
# [(1,2), (1,0)]]
#Applicable to N dimensions
a = arange(27).reshape((3,3,3))
print a
print
print a[ix_([0,1,2],[2,0,1],[0,2,1])] #OK
print
print a[ix_([0,1,2],[2,0,1])] #This is also OK
print
print a[ix_([0,1,2],[2,0,1],[0,1,2])] #a[ix_([0,1,2],[2,0,1])]Equivalent to
print
print a[ix_([0,1,2],[2,0,1],[0,1,2],[0,1,2])] #NG,
Therefore, $ I_ {x_ {ik} y_ {jk}} $ passes the tensor for indexing $ x_ {ik}, y_ {jl} $ of rank 2 to $ I \ (x, y ) $ and ranks. It means to get $ I $ of 4, but I can't just assign it to python. Therefore, in the above, indexing is performed after setting the rank to 1 with flatten ().