Матрица эффективного умножения матрицы (матрица грамм)

Я хочу размножаться B = A @ A.T в клочья. Очевидно, что ответом будет симметричная матрица (т.е. B[i, j] == B[j, i]).

Тем не менее, мне не ясно, как использовать это легко, чтобы сократить время вычислений вдвое (путем вычисления только нижнего треугольника B и затем использовать это, чтобы получить верхний треугольник бесплатно).

Есть ли способ сделать это оптимально?

2 ответа

Решение

Как отмечено в ссылке @PaulPanzer, dot может обнаружить этот случай. Вот подтверждение времени:

In [355]: A = np.random.rand(1000,1000)
In [356]: timeit A.dot(A.T)
57.4 ms ± 960 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [357]: B = A.T.copy()
In [358]: timeit A.dot(B)
98.6 ms ± 805 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Numpy точка слишком умная о симметричных умножениях

Вы всегда можете использовать sklearns's pairwise_distances

Использование:

from sklearn.metrics.pairwise import pairwise_distances
gram = pairwise_distance(x, metric=metric)

куда metric является вызываемой или строкой, определяющей одну из их реализованных метрик (полный список в ссылке выше)


Но я написал это для себя некоторое время назад, чтобы я мог поделиться тем, что я сделал:

import numpy as np

def computeGram(elements, dist):
    n    = len(elements)
    gram = np.zeros([n, n])
    for i in range(n):
        for j in range(i + 1):
            gram[i, j] = dist(elements[i], elements[j])

    upTriIdxs       = np.triu_indices(n)
    gram[upTriIdxs] = gram.T[upTriIdxs]

    return gram

куда dist вызываемый, в вашем случае np.inner

Другие вопросы по тегам