Вот один из способов замены np.correlate
(я полагаю, что это основная трудность; я также предполагаю, что у вас нет желания сдавать код в FFT):
def autocorr_direct(a, debug=False):
n, _ = a.shape
out = np.zeros((n+1, 2*n-1), a.dtype)
out.reshape(-1)[:2*n*n].reshape(n, 2*n)[::-1, :n] = a*a.T
if debug:
print(out.reshape(-1)[:2*n*n].reshape(n, 2*n))
print(out)
return out.sum(0)
Например:
>>> a = np.array([[1, 1, 2, -1]]).T
>>> autocorr_direct(a, True)
[[-1 -1 -2 1 0 0 0 0]
[ 2 2 4 -2 0 0 0 0]
[ 1 1 2 -1 0 0 0 0]
[ 1 1 2 -1 0 0 0 0]]
[[-1 -1 -2 1 0 0 0]
[ 0 2 2 4 -2 0 0]
[ 0 0 1 1 2 -1 0]
[ 0 0 0 1 1 2 -1]
[ 0 0 0 0 0 0 0]]
array([-1, 1, 1, 7, 1, 1, -1])
>>> np.correlate(a[:, 0], a[:, 0], 'full')
array([-1, 1, 1, 7, 1, 1, -1])
Обратите внимание на трюк с изменением формы, который срезает квадратный массив a[::-1]*a.T
.
Примечание 2; чтобы получить вектор столбца из 1D вектора X
используйте X[:, None]
.