问题描述
# define a 3x3 array
A = np.array([[-2,1,1],[1,-2,-2]])
# define a 1D array of scalars to multiply A with
test = np.arange(10)
for i in range(len(test)):
matrix = scipy.linalg.expm(A*test[i])
我想看看是否有一种无需使用for循环即可进行乘法的方法。我不尝试使用矩阵乘法将两个数组相乘。我将测试数组视为一组标量值,我想将A乘以1。必须有某种偷偷摸摸的麻木的方式来做到这一点。有什么想法吗?
解决方法
这是对“如何在没有for循环的情况下通过多个标量缩放矩阵”这一问题的答案。这无视矩阵求幂,因为我认为没有for循环就没有办法做到这一点,但是问题似乎并不在问求幂步骤。
您可以使用3D数组来使用numpy的矢量化乘法。
import numpy as np
A = np.array([[[-2,1,1],[1,-2,-2]]])
test = np.arange(10).reshape(-1,1)
result = test*A
,
scipy.linalg.expm
不能应用于非平方矩阵:
ValueError: expected a square matrix
所以我认为最简单的方法是:
list_result = list(map(lambda i: scipy.linalg.expm(A*i),range(10)))
那么,如果您只需要一个数组:
np.concatenate(list_result) #for 2D
或
np.stack(list_result) #for 3D
,
您可以通过堆叠乘以要使用的值的单位矩阵来构建特殊的矩阵。
我将以3x3矩阵为例,但是对于任意矩阵,想法是相同的:
想象一下我们要乘以矩阵:
A = np.array([
[1,[0,0],1]
])
通过[2、3和5]。没有循环。
我们可以构建一个包含身份的特殊矩阵来做到这一点:
[ 2 * np.eye(3),3 * np.eye(3),5 * np.eye(3)]
[ 0 0 2 ] [ 0 0 3] [ 0 0 5 ]
[ 0 2 0 ] [ 0 3 0] [ 0 5 0 ]
[ 2 0 0 ] [ 3 0 0] [ 5 0 0 ]
我们可以通过列表理解来做到这一点:
multiply_values = [2,3,5]
special_matrix = np.concatenate( [ x * eye(3) for x in multiply_values ],axis=1)
# special_matrix is:
# array([[2.,0.,3.,5.,0.],# [0.,2.,5.]])
现在我们可以一步将矩阵相乘:
result = np.dot(,special_matrix)
# result is
array([[2.,[0.,5.]])
也许我们不需要这个大的宽矩阵。
我们可以得到将产品切片的部分结果:
result[:,0:3]
# array([[2.,2.],# [0.,2.]])
我们可以用另一种理解来处理切片:
[ special_matrix[:,x:x+3] for x in [0,6] ]
# or in a more general way
[ special_matrix[:,x:x+A.shape[0]] for x in list(range(0,A.shape[0]**2,A.shape[0] ]