在NumPy
中,可以指定名为np.dot
的{{1}}和np.multiply
的参数,以便他们不会创建新的返回结果时的数组。但是,在我的用例中,我需要计算以下内容:
out
c = c + np.dot(a, b) # where a and b are matrices of shape n x m, and m x p
有没有办法在不创建新数组的情况下每次都这样做?例如,像这样:
c = c + np.multiply(a, b) # where a and b are matrices of equal shape n x m
np.dot(a, b, add_to=c)
答案 0 :(得分:4)
似乎是一个完美的设置,可以利用scipy.linalg.blas
支持的blas包装器,它支持矩阵乘法并累积到现有数组中。
因此,对于第一个dot
问题,我们可以简单地使用他们的sgemm (single-precision)/dgemm (double-precision)
,就像这样 -
from scipy.linalg.blas import dgemm, sgemm
dgemm(alpha=1.0, a=a, b=b, c=c, beta=1.0)
格式为C = alpha*(a x b) + beta*C
。
*
:元素乘法
x
:矩阵乘法
示例运行 -
1)设置输入:
In [549]: a = np.random.randint(0,9,(3,4))
...: b = np.random.randint(0,9,(4,5))
...: c = np.random.randint(0,9,(3,5))
...:
In [550]: c
Out[550]:
array([[2, 4, 7, 6, 1],
[8, 7, 2, 1, 7],
[4, 3, 5, 4, 4]])
2)制作输出数组的副本以供以后测试:
In [551]: c_copy1 = c.copy()
3)在原始输出数组上使用np.dot
:
In [552]: c = c + np.dot(a, b)
In [553]: c
Out[553]:
array([[88, 94, 75, 66, 93],
[55, 51, 55, 38, 65],
[61, 51, 25, 45, 68]])
3)在副本上使用dgemm
-
In [554]: dgemm(alpha=1.0, a=a, b=b, c=c_copy1, beta=1.0)
Out[554]:
array([[ 88., 94., 75., 66., 93.],
[ 55., 51., 55., 38., 65.],
[ 61., 51., 25., 45., 68.]])
请注意,如果您在迭代中执行此操作,我们需要将其分配回输出数组。
对于第二个问题,同样我们可以使用同一模块中的saxpy/daxpy
。 this other post
中已经涵盖了其他一些替代方案。