How to efficiently compute logsumexp of upper triangle in a nested loop?

柔情痞子 提交于 2019-12-11 17:56:13

问题


I have a nested for loop that iterates over rows of the weight matrix and applies logsumexp to the upper triangular portion of the outer addition matrix from these weights rows. It is very slow so I'm trying to figure out how to speed this up by either vectorizing or taking out the loops in lieu of matrix operations.

'''
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: computes the log of the sum of exponentials of an input array

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

The input data Wm is a weights matrix of nxk dimensions. K represents a patients sensor locations and n represents all such possible sensor locations. The values in Wm are basically how close a patients sensor is to a known sensor.

example:

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:


You can perform the outer product on the full matrix Wm and then swap the axes corresponding to columns in operand 1 and rows in operand 2 in order to apply the triangle indices to the columns. The resulting matrix is filled for all combinations of rows, so you need to select the upper triangle part.

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)


来源:https://stackoverflow.com/questions/54031980/how-to-efficiently-compute-logsumexp-of-upper-triangle-in-a-nested-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!