Предположим, что у вас есть n квадратных матриц A1,..., An. Нужно ли все-таки умножить эти матрицы аккуратным способом? Насколько я знаю, точка в numpy принимает только два аргумента. Одним из очевидных способов является определение функции для вызова себя и получения результата. Есть ли лучший способ сделать это?
Умножить несколько матриц в numpy
Ответ 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 )
Здесь первый аргумент указывает функции, которые индексы применяются к матрицам аргументов, а затем все дважды отображаемые индексы суммируются, что дает желаемый результат.
Обратите внимание, что вычислительная эффективность зависит от нескольких факторов (так что вам, вероятно, лучше всего просто проверить ее):