Умножьте каждую матрицу навороченного массива с транспонированием каждого другого эффективно - PullRequest
0 голосов
/ 01 июня 2019

При заданном числовом массиве M Я хочу вычислить матричное произведение M[i] @ M[j].T каждой 2-комбинации матриц этого массива. После применения некоторых операций к этой матрице (продукту) я хочу сохранить результаты в другой матрице в позиции [i,j]. Есть ли способ вычислить это быстро без итерации двух вложенных циклов?

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

import numpy as np

M = np.random.rand(7000,3,3)
r = np.zeros((len(M), len(M)))

for i in range(len(r)):
    for j in range(len(r[0])):
        n = M[i] @ M[j].T
        r[i,j] = np.linalg.norm(n)

1 Ответ

2 голосов
/ 01 июня 2019

Предполагая, что Вы хотели, чтобы форма r была (M.shape[0],M.shape[0]).

M = np.random.rand(700,3,3)
t = M.shape[0]
r = np.zeros((t, t))

Это эквивалентно первому утверждению вашего внутреннего цикла

q = M[:,None,...] @ M.swapaxes(1,2)

И это завершает внутренний / внешний цикл

p = np.linalg.norm(q, axis=(2,3))

for i in range(len(r)):
    for j in range(len(r[0])):
        n = M[i] @ M[j].T
        r[i,j] = np.linalg.norm(n)

>>> np.all(np.isclose(p,r))
True

С M.shape -> (70,3,3) это примерно в 42 раза быстрее, чем цикл for.
С M.shape -> (700,3,3) это примерно в 36 раз быстрее, чем для цикла.
Мой бедный компьютер не может справиться M.shape --> (7000,3,3) ... MemoryError.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...