На этот вопрос сложно ответить авторитетно. Стандартными реализациями умножения матриц и собственного разложения являются O (n ^ 3), поэтому нет априорной причины ожидать, что одно будет быстрее другого. И, как ни странно, мой опыт показывает, что собственное разложение обычно намного медленнее, чем умножение одной матрицы, поэтому этот результат меня не совсем удивляет.
Поскольку операция питания матрицы в этом случае включает двадцать умножений, я понимаю, почему вы можете ожидать, что она будет медленнее, чем собственное разложение. Но если вы посмотрите на исходный код , обнаружится этот интересный фрагмент:
# Use binary decomposition to reduce the number of matrix multiplications.
# Here, we iterate over the bits of n, from LSB to MSB, raise `a` to
# increasing powers of 2, and multiply into the result as needed.
z = result = None
while n > 0:
z = a if z is None else fmatmul(z, z)
n, bit = divmod(n, 2)
if bit:
result = z if result is None else fmatmul(result, z)
Так что на самом деле он не выполняет 20 умножений! Он использует подход «разделяй и властвуй», который уменьшает это число. После продумывания алгоритма, который действительно довольно элегантен, я считаю, что он никогда не будет делать больше, чем 2*log(p)
умножений для данной степени p
. Этот максимум достигается, когда все биты p
равны единице, т. Е. Когда p
на единицу меньше степени двойки.
В результате получается, что хотя собственное разложение в теории может быть быстрее, чем повторное умножение матриц , он несет постоянные накладные расходы, что делает его менее эффективным, пока p
не станет очень большим - возможно, больше, чем любое практическое значение.
Я должен добавить это: не будет ли умножение вектора напрямую быстрее, чем повышение матрицы до сила? Двадцать векторных умножений все равно будут O(n^2)
, нет? Но, возможно, что вы действительно хотите сделать, это выполнить эту операцию для векторов по 10 Кб, и в этом случае матричный подход к мощности явно превосходит.