Python Numpy矩阵乘法使用循环将多个矩阵相乘

Posted

技术标签:

【中文标题】Python Numpy矩阵乘法使用循环将多个矩阵相乘【英文标题】:Python Numpy matrix multiplication using loop to multiply multiple matrices together 【发布时间】:2020-07-18 15:04:02 【问题描述】:

我编写了代码来创建名称为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

这可行,但代码必须能够接受多个输入,并可能创建更多或更少的矩阵。在这种情况下,它不会起作用。

是否可以使用循环或函数进行乘法部分?

【问题讨论】:

【参考方案1】:

您可以使用列表(或字典)来保存您的矩阵:

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)

然后使用reducenumpy.matmul 计算您的总矩阵乘积:

from functools import reduce

Ty = reduce(numpy.matmul, matrices)

【讨论】:

【参考方案2】:

您可以使用循环或 numpy 函数。

循环实现:

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 函数:numpy.linalg.multi_dot(matrixes)

【讨论】:

顺便说一句,np.linalg.multi_dot 的想法与 dzang 所描述的完全相同,但使用np.dot 而不是np.matmul。想知道dot和matmul的区别可以看这个post。【参考方案3】:

设置你所做的变量是一种非常糟糕的方式,你似乎已经意识到了。如果你的矩阵都是很好的正方形,你只需要一个变量来保存整个堆栈,形状为(len(node2), 2, 2)

另一点是您的索引。 Numpy 数组不是列表。你的索引应该看起来像[1, 0],而不是[1][0]。像下面这个无耻的插件这样的答案解释了原因:https://***.com/a/60919478/2988730。

假设sOrPfrequenciesList 是numpy 数组。如果不是,请将它们封装在对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)

【讨论】:

以上是关于Python Numpy矩阵乘法使用循环将多个矩阵相乘的主要内容,如果未能解决你的问题,请参考以下文章

比较 Python、Numpy、Numba 和 C++ 的矩阵乘法

[使用Python,NumPy,SciPy使用矩阵乘法对矩阵进行有效切片

numpy中数组(矩阵)的乘法

numpy矩阵向量乘法[重复]

numpy的矩阵乘法

使用 Numpy 进行大规模矩阵乘法