python — Оптимизированное умножение матриц. Numpy

У меня есть массив obj, в котором хранятся матрицы, каждый из которых мне надо умножить на матрицу projection_vec. Когда программа перебирает все элементы obj, и умножает каждый из них на projection_vec, и тогда результаты умножения такие какие мне нужны, но когда программа умножает сразу весь массив obj на projection_vec, результаты немного отличаются, я не знаю как это исправить, так как умножение сразу всего массива obj в разы быстрее чем перебирать и умножать каждый элемент массива по отдельности, скажите пожалуйста что мне нужно изменить во втором фрагменте кода, чтобы результаты были как в первом фрагменте, но при этом код выполнялся с такой же скоростью (или даже быстрее) как второй фрагмент.

Фрагмент 1

import numpy as np
from math import *
def matrix_multiply(inp_tri, matrix):
    out_tri = inp_tri @ matrix[:3, :3] + matrix[3, :3]
    w = inp_tri @ matrix[:3, 3] + matrix[3, 3]
    w[w == 0] = 1.
0 out_tri = out_tri / w[:, None] return out_tri perspective_matrix = np.array([ [(1.0 / tan(45 / 180 * pi)), 0.0, 0.0, 0.0], [0.0, (WIDTH / HEIGHT) * (1.0 / tan(45 / 180 * pi)), 0.0, 0.0], [0.0, 0.0, 1.0, 1.0], [0.0, 0.0, -1.0, 0.0] ]) def get_projection(translated_vec): projection_vec = matrix_multiply(translated_vec, perspective_matrix) projection_vec += 1.0 projection_vec = projection_vec * H_SIZE return projection_vec obj = np.array([[ [0, 0, 0], [1, 1, 1], [-2, -2, 2] ], [ [1, 1, 1], [0, 1, 2], [-2, -2, -2] ]]) drawig_obj = [] for i, translated_vec in enumerate(obj): translated_vec = get_projection(translated_vec) drawing_obj.append(translated_vec) print(drawing_obj)

Выходные данные:

[(array([[            nan,             nan,            -inf],
       [ 1.28000000e+03,  1.00000000e+03,  1.00000000e+00],
       [-1.42108547e-13, -2. 80000000e+02,  1.50000000e+00]]), (255, 255, 255)), (array([[1.28e+03, 1.00e+03, 1.00e+00],
       [6.40e+02, 6.80e+02, 1.50e+00],
       [1.28e+03, 1.00e+03, 2.50e+00]]), (255, 255, 255))] 

Фрагмент 2

import numpy as np
from math import *
def matrix_multiply(inp_tri, matrix):
    out_tri = inp_tri @ matrix[:3, :3] + matrix[3, :3]
    w = inp_tri @ matrix[:3, 3] + matrix[3, 3]
    w[w == 0] = 1.0
    out_tri = out_tri / w[:, None]
    return out_tri
perspective_matrix = np.array([
        [(1.0 / tan(45 / 180 * pi)), 0.0, 0.0, 0.0],
        [0.0, (WIDTH / HEIGHT) * (1.0 / tan(45 / 180 * pi)), 0.0, 0.0],
        [0.0, 0.0, 1.0, 1.0],
        [0.0, 0.0, -1.0, 0.0]
    ])
def get_projection(translated_vec):
    projection_vec = matrix_multiply(translated_vec, perspective_matrix)
    projection_vec += 1.0
    projection_vec = projection_vec * H_SIZE
    return projection_vec
obj = np.array([[
        [0, 0, 0],
        [1, 1, 1],
        [-2, -2, 2]
    ],
    [
        [1, 1, 1],
        [0, 1, 2],
        [-2, -2, -2]
    ]])
projection_vecs = get_projection(obj)
print(projection_vecs)

Выходные данные:

[(array([[ 6. 40e+02,  3.60e+02,  5.00e-01],
       [ 1.28e+03,  1.00e+03,  1.00e+00],
       [-6.40e+02, -9.20e+02,  1.50e+00]]), (255, 255, 255)), (array([[ 1.28e+03,  6.80e+02,  1.00e+00],
       [ 6.40e+02,  6.80e+02,  5.00e-01],
       [-6.40e+02, -2.80e+02,  2.50e+00]]), (255, 255, 255))] 

python — Ошибка с умножением матриц. Numpy

Я хочу ускорить свою программу на python3 с помощью библиотеки numpy, но выходные данные у двух решений различаются, я не могу понять в чем проблема. Вот два фрагмента кода, первый фрагмент выдает правильные выходные данные, но он медленный, а второй фрагмент быстрый, но выдает неправильные выходные данные. Я хочу сделать так, чтобы код был быстрым как втрой фрагмент и при этом выдавал правильные выходные данные как первый. Первый фрагмент:

import numpy as np
def matrix_multiply(inp_tri, matrix):
    out_tri = inp_tri @ matrix[:3, :3] + matrix[3, :3]
    w = inp_tri @ matrix[:3, 3] + matrix[3, 3]
    w[w == 0] = 1.0
    out_tri = out_tri / w[:, None]
    return out_tri
perspective_matrix = np.
array([ [(1.0 / tan(45 / 180 * pi)), 0.0, 0.0, 0.0], [0.0, (WIDTH / HEIGHT) * (1.0 / tan(45 / 180 * pi)), 0.0, 0.0], [0.0, 0.0, 1.0, 1.0], [0.0, 0.0, -1.0, 0.0] ]) def get_projection(translated_vec): projection_vec = matrix_multiply(translated_vec, perspective_matrix) projection_vec += 1.0 projection_vec = projection_vec * H_SIZE return projection_vec obj = np.array([[ [0, 0, 0], [1, 1, 1], [-2, -2, 2] ]]) for i, translated_vec in enumerate(obj): translated_vec = get_projection(translated_vec) drawing_obj.append(translated_vec) print(drawing_obj)

Второй фрагмент:

import numpy as np
def matrix_multiply(inp_tri, matrix):
    out_tri = inp_tri @ matrix[:3, :3] + matrix[3, :3]
    w = inp_tri @ matrix[:3, 3] + matrix[3, 3]
    w[w == 0] = 1.0
    out_tri = out_tri / w[:, None]
    return out_tri
perspective_matrix = np.array([
        [(1.0 / tan(45 / 180 * pi)), 0.0, 0.0, 0.0],
        [0.
0, (WIDTH / HEIGHT) * (1.0 / tan(45 / 180 * pi)), 0.0, 0.0], [0.0, 0.0, 1.0, 1.0], [0.0, 0.0, -1.0, 0.0] ]) def get_projection(translated_vec): projection_vec = matrix_multiply(translated_vec, perspective_matrix) projection_vec += 1.0 projection_vec = projection_vec * H_SIZE return projection_vec obj = np.array([[ [0, 0, 0], [1, 1, 1], [-2, -2, 2] ]]) projection_vecs = get_projection(obj) print(projection_vecs)

Выходные данные первого фрагмента:

 [[[360.         432.           1.8       ]
  [343.05238413 560.22497458   1.72190976]
  [576.86750905 282.77045599   1.78547349]]]

Выходные данные второго фрагмента:

 [[[360.         460.11248729   1.85810604]
  [347.81142717 560.22497458   1.55690117]
  [562.18247889 259.88751271   1.78547349]]]

Правка 1. Я убрал ту часть кода которая идентична в обоих фрагментах кода и которая не влияет на выходные данные.

Правка 2. Я добавил пример массива obj, при котором выходные данные будут отличаться.

Правка 3. Я добавил выходные данные каждого фрагмента и сделал полноценный код, чтобы каждый смог его запустить.

Как сделать умножение матриц в NumPy

Распространение любви

Умножение матриц NumPy — это математическая операция, которая принимает две матрицы и дает одну матрицу путем умножения строк первой матрицы на столбец второй матрицы. Для умножения двух матриц NumPy предоставляет три разные функции.

  • numpy.multiply(arr1, arr2) – Поэлементное матричное умножение двух массивов
  • numpy.matmul(arr1, arr2) – Матричное произведение двух массивов
  • numpy.dot(arr1, arr2) – Скалярное или скалярное произведение двух массивов

При выполнении матричного умножения в NumPy убедитесь, что количество столбцов первой матрицы должно быть равно количество строк второй матрицы.

Учебное пособие по PySpark для начинающих (Spa…

Пожалуйста, включите JavaScript

Учебное пособие по PySpark для начинающих (Spark с Python)

1. Краткие примеры умножения матриц в NumPy

Если вы спешите, ниже приведены несколько кратких примеров использования умножения матриц NumPy.

# Ниже приведены краткие примеры
# Пример 1: Используйте функцию numpy.mutiply() и
# Получить умножение матрицы
arr2 = np.multiply (arr, arr1)
# Пример 2: Получить определенное умножение строк
arr2 = np.multiply(arr[0,: 2], arr1[1,: 2])
# Пример 3: Получение скалярного произведения массивов
массив = np.массив([[1, 3],
                [4, 1]])
обр1 = 2
обр2 = np.dot (обр, обр1)
# Пример 4: Использование функции numpy.dot()
# Получить произведение двух массивов
обр2 = np.dot (обр, обр1)
# Пример 5: # Используйте функцию numpy.matmul()
# Получить продукт
обр2 = np.matmul (обр, обр1)
 

2. Используйте NumPy.multiply(). Получите поэлементное умножение матриц.

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

импортировать numpy как np
# Создаем двумерные массивы numpy
массив = np.массив ([[2, 4, 3, 1], [2, 3, 6, 1]])
arr1 = np.массив ([[2, 1, 5, 2], [4, 8, 3, 2]])
                 
# Используйте функцию numpy.mutiply() и
# Получить умножение матрицы
arr2 = np.multiply (arr, arr1)
печать (обр2)
# Выход:
# [[ 4 4 15 2]
# [8 24 18 2]]
 

Чтобы передать определенные строки, столбцы или подматрицы методу numpy.multiply() и получить умножение определенных строк, столбцов и подматриц. Мы должны следовать тем же размерам строк, столбцов или подматриц, которые мы передаем в качестве наших операндов. Возьмем, к примеру,

.
# Получить определенное умножение строк
arr2 = np.multiply(arr[0,: 2], arr1[1,: 2])
печать (обр2)
# Выход :
# [5 12]
arr3 = np.multiply (arr [1,: 3], arr1 [0,: 3])
печать (обр3)
# Выход :
# [ 2 8 18 ]
 

3.

Используйте NumPy.dot() для скалярного умножения.

Простая форма умножения матриц — скалярное умножение, мы можем сделать это с помощью функции NumPy dot(). При скалярном умножении мы можем умножать скаляр на матрицу или умножать матрицу на скаляр. Каждый элемент в матрице умножается на скаляр, который возвращает тот же массив форм, что и исходный массив.

При скалярном умножении порядок не имеет значения. Это возвращает тот же результат, если мы умножаем скаляр на матрицу или матрицу на скаляр.

# Получить скалярное произведение массивов
массив = np.массив([[1, 3],
                [4, 1]])
обр1 = 2
обр2 = np.dot (обр, обр1)
печать (обр2)
# Выход :
# [[2 6]
# [8 2]]
 

Мы можем умножить 2-мерную матрицу на другую 2-мерную матрицу, используя np.dot() . когда мы умножаем две матрицы, они должны следовать порядку, т. Е. матрица X , умноженная на матрицу Y, не совпадает с матрицей Y, умноженной на матрицу X. Давайте создадим изображение для лучшего понимания.

число.точка()
# Создаем пустые массивы
массив = np.массив([[1, 3],
                [4, 1]])
arr1 = np.массив([[1, 2],
                 [2, 5]])
# Использовать функцию numpy.dot()
# Получить произведение двух массивов
обр2 = np.dot (обр, обр1)
печать (обр2)
# Выход :
# [[ 7 17]
# [6 13]]
 

4. Используйте matmul() — умножение двух массивов NumPy

Метод np.matmul() используется для определения матричного произведения двух массивов. Функция matmul() принимает arr1 и arr2 в качестве аргументов и возвращает матричное произведение входных массивов NumPy. Скаляр создается только тогда, когда и arr1, и arr2 являются одномерными векторами.

# Использовать функцию numpy.matmul()
# Получить продукт
обр2 = np.matmul (обр, обр1)
печать (обр2)
# Выход :
# [[ 7 17]
# [6 13]]
 

5. Заключение

В этой статье я объяснил концепцию умножения матриц Python NumPy и как ее использовать, используя numpy.multiply() , numpy. matmul() и numpy.dot() Функция с примерами.

Счастливого обучения!!

  • Как транспонировать массив NumPy?
  • Получить сумму двух массивов
  • Как получить значение мощности массива?
  • Получить совокупную сумму numpy
  • Как удалить столбцы и строки массива NumPy?
  • Преобразование матрицы NumPy в массив /numpy.matmul. html

Умножение матриц в NumPy | Различные типы умножения матриц

Обновлено 20 марта 2023 г.

Умножение матриц в NumPy — это библиотека Python, используемая для научных вычислений. Используя эту библиотеку, мы можем выполнять сложные матричные операции, такие как умножение, скалярное произведение, мультипликативное обратное и т. Д., За один шаг. В этом посте мы узнаем о различных типах умножения матриц в библиотеке numpy.

Различные типы умножения матриц

В основном существует три различных типа умножения матриц:

Функция Описание
np. matmul (массив а, массив б) Возвращает матричное произведение двух заданных массивов
np.multiply (массив а, массив б) Возвращает поэлементное умножение двух заданных массивов
np.dot (массив а, массив б) Возвращает скаляр или скалярное произведение двух заданных массивов
1. Произведение матриц двух заданных массивов

Чтобы найти матричное произведение двух заданных массивов, мы можем использовать следующую функцию:

 np.matmul(массив a, массив b) 

Вход для этой функции не может быть скалярным значением

A = все а12 а13
а21 а22 а23
Б = б11 б12 б13
б21 б22 б23
б31 б32 б33

A @B =

a11*b11 + a12*b21 + a13*b31 а11*б12 + а12*б22 + а13*б32 а11*b13 + а12*b23 + а13*b33
а21*b11 + а22*b21 + а23*b31 а21*b12 + а22*b22 + а23*b32 а21*b13 + а22*b23 + а23*b33
Пример #1

Программа для иллюстрации матричного произведения двух заданных массивов n-d.

Код:

 импортировать numpy как np
A = np.массив ([[1,2,3], [4,5,6]])
B = np.массив([[1,1,1], [0,1,0], [1,1,1]])
print("Матрица A:\n",A)
print("Матрица A:\n",B)
С = np.matmul(A,B)
print("Матричное умножение матриц A и B равно:\n",C) 

Произведение матриц данных массивов вычисляется следующими способами:

А= 1 2 3
4 5 6
Б= 1 1 1
0 1 0
1 1 1

А @ В =

1*1 + 2*0 + 3*1 = 4 1*1 + 2*1 + 3*1 = 6 1*1 + 2*0 + 3*1 = 4
4*1 + 5*0 + 6*1 = 10 4*1 + 5*1 + 6*1 = 15 4*1 + 5*0 + 6*1 = 10
2.
Поэлементное умножение двух заданных массивов

Чтобы найти поэлементное произведение двух заданных массивов, мы можем использовать следующую функцию.

 np.multiply(массив a, массив b) 
A = все а12 а13
а21 а22 а23
Б = а21 а22 а23
а21 а22 а23

А*В =

a11*b11 а12*б12 а13*б13
а21*б21 а22*б22 а23*б23
Пример №2

Программа для иллюстрации поэлементного умножения двух заданных матриц

Код:

 import numpy as np
A = np. массив ([[1,2,3], [4,5,6]])
B = np.массив ([[1,2,3], [4,5,6]])
print("Матрица A:\n",A)
print("Матрица A:\n",B)
C = np.умножить (A, B)
print("Матричное умножение матриц A и B равно:\n",C) 

Поэлементное матричное умножение заданных массивов вычисляется следующими способами:

А = 1 2 3
4 5 6
Б = 1 1 1
0 1 0
1 1 1

А * В =

1*1 = 1 2*2 = 4 3*3 = 9
4*4 = 16 5*5 = 25 6*6 = 36
3. Скалярное или скалярное произведение двух данных массивов

Скалярное произведение любых двух заданных матриц — это, по сути, их матричное произведение. Единственное отличие состоит в том, что в скалярном произведении мы также можем иметь скалярные значения.

А= а11 а12 а13
Б= б11
б12
б13

A.B = a11*b11 + a12*b12 + a13*b13

Пример #3

Программа для иллюстрации скалярного произведения двух заданных одномерных матриц

Код:

 импортировать numpy как np
А = np.массив ([1,2,3])
B = np.массив ([4,5,6])
print("Матрица A:\n",A)
print("Матрица A:\n",B)
С = np.точка (А, В)
print("Матричное умножение матриц A и B равно:\n",C) 

Скалярное произведение двух заданных одномерных массивов вычисляется следующими способами:

A= 1 2 3
Б= 4 5 6

A. B = 1*4 + 2*5 + 3*6 = 32

Пример #4

Программа для иллюстрации скалярного произведения двух заданных двумерных матриц

Код:

 импортировать numpy как нп
А = np.массив([[1,2],[2,1]])
B = np.массив([[4,5],[4,5]])
print("Матрица A:\n",A)
print("Матрица A:\n",B)
С = np.точка (А, В)
print("Матричное умножение матриц A и B равно:\n",C) 

Скалярный продукт данных двумерных или n-D массивов вычисляется следующими способами:

A = л 2
2 1
Б= 4 5
4 5

A.B =

1*4 + 2*4 = 12 1*5+2*5 = 15
2*4+ 1*4 = 12 2*5+ 1*5 = 15
Пример #5

Программа для иллюстрации скалярного произведения скалярного значения и двумерной матрицы

Код:

 A = np. array([[1,1],[1, 1]])
print("Матрица A:\n",A)
С = np.точка (2, А)
print("Матричное умножение матриц A и B равно:\n",C) 

A = 1 1
1 1

Скалярное значение = 2

Тогда np.dot(2,A) = 2* A

2*A =

1 *2 = 2 1*2 = 2
1*2 = 2 1*2 = 2

Заключение

Numpy предлагает широкий набор функций для выполнения матричного умножения. Если вы хотите выполнить поэлементное умножение матриц, используйте функцию np.multiply(). Размеры входных матриц должны быть одинаковыми. И если вам нужно вычислить матричное произведение двух заданных массивов/матриц, используйте функцию np.matmul(). Размерность входных массивов должна быть в форме mxn и nxp. Наконец, если вам нужно умножить скалярное значение и n-мерный массив, используйте np.