![](/img/trans.png)
[英]Efficient slicing of matrices using matrix multiplication, with Python, NumPy, SciPy
[英]Python Numpy matrix multiplication using loop to multiply multiple matrices together
我编写了创建名称为matrixi
的矩阵的代码,其中i
被当前循环号替换:
for i in range(len(node2)):
if sOrP[i] == 'S':
#print('series connection')
matrixTemplate = numpy.array([[1.0, 0.0], [0.0, 1.0]]) #Got to put 1.0 else it doesnt work
matrixTemplate[0][1] = frequenciesList[0][i]
globals()['matrix%s' % i] = matrixTemplate
#print(matrixTemplate)
elif sOrP[i] == 'P':
#print('parallel connection')
matrixTemplate = numpy.array([[1.0, 0.0], [0.0, 1.0]])
matrixTemplate[1][0] = 1 / frequenciesList[0][i]
globals()['matrix%s' % i] = matrixTemplate
#print(matrixTemplate)
然后我需要将创建的矩阵相乘:
Ty = matrix0 @ matrix1 @ matrix2 @ matrix3 @ matrix4 @ matrix5 @ matrix6 @ matrix7 @ matrix8 @ matrix9
这可行,但代码必须能够接受多个输入,并可能创建更多或更少的矩阵。 在那种情况下,它是行不通的。
是否可以使用循环或 function 进行乘法部分?
您可以使用列表(或字典)来保存您的矩阵:
matrices = []
for i in range(len(node2)):
if (sOrP[i] == 'S'):
#print('series connection')
matrixTemplate = numpy.array([[1.0, 0.0],[0.0, 1.0]]) #Got to put 1.0 else it doesnt work
matrixTemplate[0][1] = frequenciesList[0][i]
matrices.append(matrixTemplate)
#print(matrixTemplate)
elif (sOrP[i] == 'P'):
#print('parallel connection')
matrixTemplate = numpy.array([[1.0, 0.0],[0.0, 1.0]])
matrixTemplate[1][0] = 1/frequenciesList[0][i]
matrices.append(matrixTemplate)
#print(matrixTemplate)
然后使用reduce
和numpy.matmul
计算您的总矩阵乘积:
from functools import reduce
Ty = reduce(numpy.matmul, matrices)
您可以使用循环或 numpy function。
循环实现:
matrixes = [M1, M2, ..., Mn]
A = matrixes[0]
for i in range(1, len(matrixes)):
B = matrixes[i]
A = np.dot(A, B)
第一次迭代:A = M1,B = M2; M1.M2
第二次迭代:A = M1.M2,B = M3; M1.M2.M3
...
Numpy function: numpy.linalg.multi_dot(matrixes)
正如您似乎已经意识到的那样,如果这样做,设置您所做的变量是一种非常糟糕的方式。 如果你的矩阵都是很好的正方形,你只需要一个变量来保存整个堆栈,shape (len(node2), 2, 2)
。
另一点是您的索引。 Numpy arrays 不是列表。 您的索引应该看起来像[1, 0]
,而不是[1][0]
。 像下面这个无耻的插件这样的答案解释了原因: https://stackoverflow.com/a/60919478/2988730 。
假设sOrP
和frequenciesList
列表是 numpy arrays。 如果不是,请将它们包装在对np.array
的调用中。 您可以像这样制作堆栈:
matrices = np.broadcast_to([[[1, 0], [0, 1]]], (len(node2), 2, 2)).copy()
maskS = (sOrP == 'S')
maskP = (sOrP == 'P')
matrices[maskS, 0, 1] = frequenciesList[maskS]
matrices[maskP, 1, 0] = 1 / frequenciesList[maskP]
您可以验证matrices[i]
与原始构造中的matrixi
等效。
将所有矩阵相乘的简单方法是使用循环:
Ty = np.eye(2)
for mat in matrices:
Ty @= mat
但是 numpy 都是关于矢量化的。 碰巧, np.linalg.multidot
被用来优化这个精确的操作:
Ty = np.linalg.multidot(matrices)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.