Как эффективно вычислить logsumexp верхнего треугольника во вложенном цикле? - PullRequest
0 голосов
/ 04 января 2019

У меня есть вложенный цикл for, который перебирает строки матрицы весов и применяет logsumexp к верхней треугольной части внешней матрицы сложения из этих строк весов.Это очень медленно, поэтому я пытаюсь выяснить, как ускорить это путем векторизации или удаления циклов вместо матричных операций.

'''
Wm: weights matrix, nxk
W: updated weights matrix, nxn
triu_inds: upper triangular indices of Wxy outer matrix
'''

for x in range(n-1):
    wx = Wm[x, :]
    for y in range(x+1, n):
        wy = Wm[y, :]
        Wxy = np.add.outer(wx, wy)
        Wxy = Wxy[triu_inds]
        W[x, y] = logsumexp(Wxy)

logsumexp: вычисляет журнал суммы экспонент входного массива

a: [1, 2, 3]
logsumexp(a) = log( exp(1) + exp(2) + exp(3) )

Входные данные Wm - это матрица весов измерений nxk.K представляет местоположения датчика пациента, а n представляет все такие возможные местоположения датчика.Значения в Wm в основном показывают, насколько датчик пациента находится близко к известному датчику.

пример:

Wm  = [1   2   3]
      [4   5   6]
      [7   8   9]
      [10 11  12]

wx  = [1   2   3]
wy  = [4   5   6]

Wxy = [5   6   7]
      [6   7   8]
      [7   8   9]

triu_indices = ([0, 0, 1], [1, 2, 2])
Wxy[triu_inds] = [6, 7, 8]
logsumexp(Wxy[triu_inds]) = log(exp(6) + exp(7) + exp(8))

1 Ответ

0 голосов
/ 04 января 2019

Можно выполнить внешнее произведение для полной матрицы Wm, а затем поменять оси, соответствующие столбцам в операнде 1 и строкам в операнде 2, чтобы применить индексы треугольника к столбцам.Полученная матрица заполняется для всех комбинаций строк, поэтому вам нужно выбрать верхнюю часть треугольника.

W = logsumexp(
    np.add.outer(Wm, Wm).swapaxes(1, 2)[(slice(None),)*2 + triu_inds],
    axis=-1  # Perform summation over last axis.
)
W = np.triu(W, k=1)
...