Функция multi_dot
Функция multi_dot из модуля numpy.linalg предназначена для перемножения двух и более матриц. В отличие от последовательного применения dot или оператора @, она вычисляет оптимальный порядок умножения, что позволяет сократить количество арифметических операций. Первым параметром функция принимает список или кортеж матриц (массивов) для перемножения. Дополнительно можно указать параметр out для сохранения результата в заранее выделенный массив.
Синтаксис
np.linalg.multi_dot(arrays, *, out=None)
Пример
Давайте перемножим три матрицы с помощью multi_dot и сравним результат с обычным умножением:
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = np.array([[9, 10], [11, 12]])
res = np.linalg.multi_dot([A, B, C])
print(res)
Результат выполнения кода:
[[325 362]
[741 826]]
Пример
Покажем, что multi_dot эквивалентна последовательному умножению, но может работать быстрее для цепочек матриц:
import numpy as np
A = np.random.default_rng(0).random((10, 10))
B = np.random.default_rng(1).random((10, 10))
C = np.random.default_rng(2).random((10, 10))
D = np.random.default_rng(3).random((10, 10))
res1 = np.linalg.multi_dot([A, B, C, D])
res2 = A @ B @ C @ D
print(np.allclose(res1, res2))
Результат выполнения кода:
True
Пример
Важно, чтобы размерности матриц согласовывались для перемножения. В этом примере перемножим три матрицы с размерами (2x3), (3x4) и (4x2):
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]])
B = np.array([[7, 8, 9, 10], [11, 12, 13, 14], [15, 16, 17, 18]])
C = np.array([[19, 20], [21, 22], [23, 24], [25, 26]])
res = np.linalg.multi_dot([A, B, C])
print(res)
print(res.shape)
Результат выполнения кода:
[[3392 3536]
[7712 8048]]
(2, 2)
Пример
Функция multi_dot работает не только с двумерными матрицами, но и с одномерными массивами (векторами), интерпретируя их как матрицы с одной строкой или одним столбцом:
import numpy as np
A = np.array([[1, 2], [3, 4]])
x = np.array([5, 6])
y = np.array([7, 8])
res = np.linalg.multi_dot([x, A, y])
print(res)
Результат выполнения кода:
328