Python Numpy умножение матриц с использованием l oop для умножения нескольких матриц вместе - PullRequest
3 голосов
/ 06 апреля 2020

Я написал код, который создает матрицы с именем matrixi, где i заменяется текущим числом l oop:

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

Это работает, но код должен иметь возможность принимать несколько входных данных с потенциально большим или меньшим количеством создаваемых матриц. В этом случае это не сработает.

Можно ли выполнить часть умножения, используя al oop или функцию?

Ответы [ 3 ]

3 голосов
/ 06 апреля 2020

Вы можете использовать список (или словарь) для хранения ваших матриц:

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)
0 голосов
/ 07 апреля 2020

Установка переменных, которые вы сделали, - довольно ужасный способ, если вы делаете это, как вы, кажется, уже поняли. Если все ваши матрицы хороши и квадратны, вам нужна только одна переменная для хранения всего стека в форме (len(node2), 2, 2).

Еще один момент - это индексирование. Numpy массивы не списки. Ваши индексы должны выглядеть как [1, 0], а не [1][0]. Ответы вроде следующего бесстыдного плагина объясняют, почему: { ссылка }.

Предположим, что sOrP и frequenciesList - это 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 в вашей первоначальной конструкции.

Простой способ умножить все матрицы вместе будет использовать al oop:

Ty = np.eye(2)
for mat in matrices:
    Ty @= mat

Но numpy это все о векторизации. Как оказалось, np.linalg.miltidot было сделано для оптимизации этой точной операции:

Ty = np.linalg.multidot(matrices)
0 голосов
/ 06 апреля 2020

Вы можете использовать либо функцию al oop, либо функцию numpy.

L oop реализация:

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)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...