У меня есть массив a длины N и мне нужно выполнить следующую операцию:
С p в [0..1].Это уравнение представляет собой сумму с потерями, где первые индексы в сумме взвешиваются с большей потерей (p ^ {ni}), чем последние.Последний индекс (i = n) всегда взвешивается на 1. Если p = 1, то операция является простой суммой.
b = np.cumsum(a)
Если, если p! = 1, я могу реализовать эту операцию вНеэффективный для процессора способ:
b = np.empty(np.shape(a))
# I'm using the (-1,-1,-1) idiom for reversed ranges
p_vec = np.power(p, np.arange(N-1, 0-1, -1))
# p_vec[0] = p^{N-1}, p_vec[-1] = 1
for n in range(N):
b[n] = np.sum(a[:n+1]*p_vec[-(n+1):])
Или неэффективным с точки зрения памяти, но векторизованным способом (ИМО тоже неэффективен с точки зрения использования процессора, поскольку тратится много времени):
a_idx = np.reshape(np.arange(N+1), (1, N+1)) - np.reshape(np.arange(N-1, 0-1, -1), (N, 1))
a_idx = np.maximum(0, a_idx)
# For N=4, a_idx looks like this:
# [[0, 0, 0, 0, 1],
# [0, 0, 0, 1, 2],
# [0, 0, 1, 2, 3],
# [0, 1, 2, 3, 4]]
a_ext = np.concatenate(([0], a,), axis=0) # len(a_ext) = N + 1
p_vec = np.power(p, np.arange(N, 0-1, -1)) # len(p_vec) = N + 1
b = np.dot(a_ext[a_idx], p_vec)
Есть лилучший способ достичь этого «с потерями» cumum?