defplot(array): print(array) plt.matshow(array, cmap='Wistia') plt.colorbar() for x inrange(len(array)): for y inrange(len(array)): plt.annotate(round(array[x, y], 3),xy=(x,y),horizontalalignment='center', verticalalignment='center') return plt
1.66s ± 341ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1
import scipy.signal
1 2
%%timeit scipy.signal.fftconvolve(arr1, arr2)
10.8ms ± 1.24ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
定义法
1 2 3 4 5 6 7 8 9 10
defconv(a, b): N = len(a) M = len(b) YN = N + M - 1 y = [0.0for i inrange(YN)] for n inrange(YN): for m inrange(M): if0 <= n - m and n - m < N: y[n] += a[n - m] * b[m] return y
1
conv((1, 2, 3), (4, 5, 6))
[4.0, 13.0, 28.0, 27.0, 18.0]
使用 numpy 库
1 2 3
import numpy as np
np.convolve((1, 2, 3), (4, 5, 6))
array([ 4, 13, 28, 27, 18])
FFT 快速卷积
1 2 3 4 5 6 7 8 9 10
defconvfft(a, b): N = len(a) M = len(b) YN = N + M - 1 FFT_N = 2 ** (int(np.log2(YN)) + 1) afft = np.fft.fft(a, FFT_N) bfft = np.fft.fft(b, FFT_N) abfft = afft * bfft y = np.fft.ifft(abfft).real[:YN] return y
defrun(func, a, b): n = 1 start = time.perf_counter() for j inrange(n): func(a, b) end = time.perf_counter() run_time = end - start return run_time / n
n_list = [] t1_list = [] t2_list = [] for i inrange(10): count = i * 1000 + 10 print(count) a = np.ones(count) b = np.ones(count) t1 = run(conv, a, b) # 直接卷积 t2 = run(convfft, a, b) # FFT 卷积 n_list.append(count) t1_list.append(t1) t2_list.append(t2)