# 二维卷积运算

import numpy as np
from copy import deepcopy

def corr2d(X, K):
'''
2D 卷积运算（实际是互相关）
'''
h, w = K.shape
Y = np.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i, j] = (X[i: i + h, j: j + w] * K).sum()
return Y


X = np.array([[7, 1, 4, 3], [3, 9, 5, 1], [5, 1, 8, 9], [7, 9, 3, 1]])
K = np.array([[7, 1], [2, 3]])

corr2d(X, K)

array([[83., 44., 44.],
[43., 94., 79.],
[77., 42., 74.]])


### 矩阵乘法来计算卷积

class Exchange:
def exchangeTwo(self, L, i=0, j=-1):
'''
交换列表中的元素顺序
'''
L[i], L[j] = L[j], L[i]

def loopInterchange(self, L, offset=0):
'''
循环列表
'''
n = len(L)
assert offset < n
for i in range(n):
self.exchangeTwo(L, offset, i)

def corr2d(self, X, K):
'''
使用矩阵乘法计算 2D 卷积
'''
X_ = X.flatten()
h, w = K.shape
A = np.zeros_like(X)
A[:w, :h] = K
A_ = A.flatten().tolist()
h_ = X.shape[0] - h + 1
w_ = X.shape[1] - w+1
L = deepcopy(A_)
M = []
for i in range(w_):
for j in range(w_):
M.append(deepcopy(L))
self.loopInterchange(L)
continue
self.loopInterchange(L)
Y = np.dot(np.array(M), X_)
Y_ = Y.reshape((h_, w_))
return Y_

ex = Exchange()

ex.corr2d(X, K)

array([[83, 44, 44],
[43, 94, 79],
[77, 42, 74]])