Подтвердить что ты не робот

Умножить несколько матриц в numpy

Предположим, что у вас есть n квадратных матриц A1,..., An. Нужно ли все-таки умножить эти матрицы аккуратным способом? Насколько я знаю, точка в numpy принимает только два аргумента. Одним из очевидных способов является определение функции для вызова себя и получения результата. Есть ли лучший способ сделать это?

4b9b3361

Ответ 1

Это может быть относительно недавняя функция, но мне нравится:

A.dot(B).dot(C)

или если у вас была длинная цепочка, которую вы могли бы сделать:

reduce(numpy.dot, [A1, A2, ..., An])

Update:

Подробнее о сокращении здесь. Вот пример, который может помочь.

>>> A = [np.random.random((5, 5)) for i in xrange(4)]
>>> product1 = A[0].dot(A[1]).dot(A[2]).dot(A[3])
>>> product2 = reduce(numpy.dot, A)
>>> numpy.all(product1 == product2)
True

Обновление 2016: Начиная с python 3.5 появляется новый символ matrix_multiply, @:

R = A @ B @ C

Ответ 2

Воскрешение старого вопроса с обновлением:

Начиная с 13 ноября 2014 г. теперь есть функция np.linalg.multi_dot, которая делает именно то, что вы хотите. Это также помогает оптимизировать порядок звонков, хотя это не обязательно в вашем случае.

Обратите внимание, что это доступно, начиная с numpy версии 1.10.

Ответ 3

Если вы вычисляете все матрицы априорно, вам следует использовать схему оптимизации для умножения цепочки матриц. См. эту статью в Википедии.

Ответ 4

A_list = [np.random.randn(100, 100) for i in xrange(10)]
B = np.eye(A_list[0].shape[0])
for A in A_list:
    B = np.dot(B, A)

C = reduce(np.dot, A_list)

assert(B == C)

Ответ 5

Другим способом достижения этой цели будет использование einsum, который реализует Соглашение об объединении Эйнштейна для NumPy.

Чтобы вкратце объяснить это соглашение в отношении этой проблемы: когда вы записываете свой продукт с несколькими матрицами в виде одной большой суммы продуктов, вы получаете что-то вроде:

P_im = sum_j sum_k sum_l A1_ij A2_jk A3_kl A4_lm

где P - результат вашего продукта, а A1, A2, A3 и A4 - входные матрицы. Обратите внимание, что вы суммируете именно те индексы, которые появляются дважды в слагаемых, а именно j, k и l. Поскольку сумма с этим свойством часто появляется в физике, векторном исчислении и, возможно, в некоторых других полях, для него есть инструмент NumPy, а именно einsum.

В приведенном выше примере вы можете использовать его для вычисления вашего матричного продукта следующим образом:

P = np.einsum( "ij,jk,kl,lm", A1, A2, A3, A4 )

Здесь первый аргумент указывает функции, которые индексы применяются к матрицам аргументов, а затем все дважды отображаемые индексы суммируются, что дает желаемый результат.

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