(w / r / t последнее предложение OP: я не осведомлен о таком методе numpy / scipy, но w / r / t Вопрос в Заголовке OP (т. Е. Улучшается NumPy точка производительности), то, что ниже, должно помочь. Другими словами, мой ответ направлен на улучшение производительности большинства шагов, включающих вашу функцию для Y).
Во-первых, это должно дать вам заметное усиление по сравнению с ванильным NumPy точка метод:
>>> from scipy.linalg import blas as FB
>>> vx = FB.dgemm(alpha=1., a=v1, b=v2, trans_b=True)
Обратите внимание, что два массива v1, v2 оба в порядке C_FORTRAN
Вы можете получить доступ к порядку байтов массива NumPy через атрибут flags массива, например:
>>> c = NP.ones((4, 3))
>>> c.flags
C_CONTIGUOUS : True # refers to C-contiguous order
F_CONTIGUOUS : False # fortran-contiguous
OWNDATA : True
MASKNA : False
OWNMASKNA : False
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
чтобы изменить порядок одного из массивов так, чтобы оба были выровнены, просто вызовите конструктор массива NumPy, передайте массив и установите соответствующий флаг order в True
>>> c = NP.array(c, order="F")
>>> c.flags
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : True
MASKNA : False
OWNMASKNA : False
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
Дальнейшую оптимизацию можно выполнить, применив выравнивание порядка массива до , уменьшив избыточное потребление памяти, вызванное копированием исходных массивов .
Но почему массивы копируются перед передачей в dot ?
Точечный продукт опирается на операции BLAS. Для этих операций требуются массивы, хранящиеся в C-смежном порядке - именно это ограничение вызывает копирование массивов.
С другой стороны, транспонирует делает не эффект копии, хотя, к сожалению, возвращает результат в порядке Фортрана :
Поэтому, чтобы устранить узкое место в производительности, необходимо исключить этап копирования массива предикатов ; для этого просто необходимо передать оба массива в dot в C-смежном порядке *.
Таким образом, чтобы вычислить точку (А.Т., А) без создания дополнительной копии:
>>> import scipy.linalg.blas as FB
>>> vx = FB.dgemm(alpha=1.0, a=A.T, b=A.T, trans_b=True)
В итоге, выражение чуть выше (вместе с оператором импорта предиката) может заменить точку, чтобы обеспечить ту же функциональность, но лучшую производительность
Вы можете привязать это выражение к функции следующим образом:
>>> super_dot = lambda v, w: FB.dgemm(alpha=1., a=v.T, b=w.T, trans_b=True)