Онлайн произведение матрицы: Онлайн калькулятор. Умножение матриц

n-1)
и т.д.
со столбцами посложнее
их надо выделять побитово. как не знаю.
лучше бы конечно это на асме накидать, но я в нем уже почти ноль.
Помогите это все как-то нормально оформить буду очень благодарен.


 
MBo ©   (2005-01-18 22:14) [1]

Определи, что означает умножение таких матриц.
Например, обычное матричное умножение A*B=C, где Cij=Sum (по к) Aik*Bkj
Что будет в твоем случае?
Приведи пример для матриц 2*2


 
palva ©   (2005-01-18 23:34) [2]

Предлагаю хранить матрицу следующим образом: Первые 6 байтов матрица по строкам, т. е. каждая строка в младших битах байта. Следующие 6 байтов матрица по столбцам, т. е. каждый столбец в младших битах байта. Первое представление используется, когда матрица является левым множителем, второе представление — когда правым.

При перемножении никаких сдвигов не будет. Нужно взять AND соответствующих байтов, представляющих строку левой матрицы и столбец правой и сразу после этого проверить флаг четности. Если он установлен, то элемент произведения равен 1, иначе 0. Это надо делать на ассемблере, но тут будет буквально три команды.


 
palva ©   (2005-01-18 23:38) [3]

MBo ©   (18.01.05 22:14) [1]
Это будет как обычное произведение матриц из нулей и единиц, только умножение заменяется на AND, а сложение на XOR.


 
jack128 ©   (2005-01-18 23:40) [4]

palva ©   (18.01.05 23:38) [3]

а сложение на XOR
почему на xor то?? Может на or?


 
MBo ©   (2005-01-18 23:47) [5]

>palva ©   (18. 01.05 23:38) [3]
Вот и хотелось бы от автора точно узнать, как именно должно быть.
Про бинарное представление + транспонированная матрица — все разумно. Я полагаю, что может быть не xor, а or.


 
palva ©   (2005-01-18 23:48) [6]

jack128 ©   (18.01.05 23:40) [4]
Сложение по модулю два, т. е. 1+1=0. Так должно быть. Получается XOR.

Ведь у сложения должно быть и вычитание. Если бы было
1+1=1, то отнимем от обеих частей единицу, получим 1=0, что нехорошо.


 
palva ©   (2005-01-18 23:54) [7]

Если я неправильно понял и нужен OR, тогда нужно проверять не флаг четности а флаг нуля


 
d-alone   (2005-01-19 18:18) [8]

Поясню
1*1=1
1*0=0*1=0*0=0
1+1=1+0=0+1=1
0+0=0
дальше матрицы из нулей и единиц перемножаются как обычные строка-на-столбец, только с соответствующими операциями. 2) у меня огромная прога — и это самое узкое место
Большое спасибо будет тому, кто сообразит как развить алгоритм вынесенный в тему или тому кто предложит как бысто умножить эти матрицы


 

default ©   (2005-01-19 18:28) [9]

d-alone   (19.01.05 18:18) [8]
1+1=1
если в суммировании появляется хоть одна единица то можно считать результатом 1 без разницы есть ли ещё единичные слагаемые
то есть тут будет прибавка в скорости
она будет и в сложении и в умножении(поскольку при умножении тоже сложение есть)


 
Jeer ©   (2005-01-19 18:32) [10]

Так может и надо заниматься логическими операциями, а не арифметическими ? (palva ©   (18.01.05 23:38) [3])
Если размерность — константа и форму хранения матриц можно выбирать, то можно упростить.


 

default ©   (2005-01-19 18:34) [11]

Jeer ©   (19.01.05 18:32) [10]
ясен перец
дело в том что он не знает как это закодировать
я бы написал соотв-ий класс


 
palva ©   (2005-01-19 18:57) [12]

Побайтно надо кодировать. Каждую строчку в отдельном байте. Тогда не будет сдвигов перед умножением. Только размерность при этом будет ограничена числом 8. Я сначала понял, что размерность фиксированная — 6. Перед умножением хорошо было бы правый сомножитель транспонировать, то есть перейти к хранению по столбцам. Чем больше размер матрицы, тем большую выгоду это даст. Вычисление одного элемента результирующей матрицы сведется тогда к команде AND между байтами и проверке флага.

Если 1+1=1, то нужно проверять флаг нуля, то есть на этом этапе можно обойтись без ассемблера. Хуже, когда придется записывать результат в произведение. Если он должен быть в том же закодированном виде, что и сомножители, надо будет уметь установить определенный бит. Ассеблер позволяет сделать это очень эффективно, без сдвигов.

1+1=1 это называется не логическое сложение а дизъюнкция. Или иначе 1V1=1. Конечно, хозяин — барин. Но тогда перемножение матриц будет очень странным. При таком определении сложения летит к чертям вся теория определителей и обратных матриц, то есть невырожденные матрицы уже не будут являться группой по умножению.


 
d-alone   (2005-01-19 19:31) [13]

Булевы матрицы относительно данных операций образуют циклическую полугруппу. Можно не привязываться к кодированию матриц. Мне необходимо как-то ускорить работу алгоритма умножения матриц.

Жду предложний. А логическое сложение и дизъюнкция — это одно и тоже- не путайте со сложением по модулю 2 — там 1+1=0.
Буду очень благодарен если кто-то накидает процедуру умножения двух матриц размерности от 3*3 до 7*7


 
default ©   (2005-01-19 19:47) [14]

d-alone   (19.01.05 19:31) [13]
так размер матрицы только 6*6 или… как?


 
Jeer ©   (2005-01-19 20:46) [15]

default ©   (19.01.05 19:47) [14]

Это называется — «Новые вводные» :))))
Зачем мне чай, если есть кофе или на худой конец коньяк:)


 
d-alone   (2005-01-19 22:30) [16]

ограничиваемся 6*6 (если что я там сам допридумываю), просто на мой взгяд процесс умножение для матриц размерности  от 2*2 до 8*8 будет одинаков,  вот когда за байт вылезет, тогда возникают другие сложности, кстати всего матриц размерности 6*6 — 2^36 — т. 2), потому что при больших N строка матрицы не уложится в одно машинное слово, вам придется организовывать внутренний цикл по этим словам и у вас добавится множитель, пропорциональный N.

> Идея следующая: каждую матрицу закодировать десятичным числом

Идея плохая. Зачем кодировать десятичным, если для работы ее нужно опять переводить в двоичное. Зачем кодировать одним числом, объединяя несколько чисел соответствующих строкам, если при работе алгорима придется всё равно разбивать это число на первоначальные составляющие? Было бы лучше кодировать, как я уже два раза предлагал, но боюсь что это тоже бесполезно. Ускорения на таких маленьких матрицах вы не получите, поскольку много времени уйдет на перекодирования.

Имхо.


 
default ©   (2005-01-19 23:41) [18]

d-alone   (19.01.05 22:30) [16]
все советы по алгоритму уже розданы осталось уже только писать
лично я пока не вижу явной нужды тут применять ассемблер
(если Вы поняли о чём говорилось в [12] и ранее)
советую всё реализовать классом
будет операция, например, MatrObj. Add(A, «Name»)
то есть операция кодирования матрицы A и присвоение ей определённого имени для использования потом в вычислениях
(либо обращаться к ней по индексу — как лучше Вам решать естественно Вам)
на счёт удобства произведения операций
нужно допустим вычислить выражение A*B+C*D+E
или Вы будете писать что-то типа
MatrObj.Sum(MatrObj.Sum(MatrObj.Mult(1, 2), MatrObj.Mult(3, 4)), 5)  
цифры — это индексы закодированных матриц либо как говорил используйте имена    
или же как-то по-другому
например, MatrObj.Calc([1, 2, 3, 4, 5], «*+*+»)
с соблюдение приоритета операций если нужно
вообщем сами решайте как Вам лучше сделать


 
d-alone   (2005-01-19 23:42) [19]

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


 
default ©   (2005-01-19 23:48) [20]

если ответ на следующий вопрос положительный
Каждая матрица участвует только в одной операции?
то перекодировка мало чего даст если вообще не заберёт(особенно на маленьких матрицах)
об этом говорилось в [17]
я подразумевал что ответ на вопрос выше отрицательных раз Вы взялись за кодирование матриц…


 
default ©   (2005-01-19 23:51) [21]

d-alone   (19.01.05 23:42) [19]
вообщем правильно делать как написано в [12]
оптимальней с точки зрения идеи я думаю некуда


 
d-alone   (2005-01-20 22:20) [22]

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


Содержание

Произведение матриц | это… Что такое Произведение матриц?

Ма́трица — математический объект, записываемый в виде прямоугольной таблицы чисел (или элементов кольца) и допускающий алгебраические операции (сложение, вычитание, умножение и др.) между ним и другими подобными объектами.

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

Обычно матрицу обозначают заглавной буквой латинского алфавита и выделяют круглыми скобками «(…)» (встречается также выделение квадратными скобками «[…]», двойными прямыми линиями «||…||»).

Числа, составляющие матрицу (элементы матрицы), часто обозначают той же буквой, что и саму матрицу, но строчной.

У каждого элемента матрицы есть 2 нижних индекса (aij) — первый «i» обозначает номер строки, в которой находится элемент, а второй «j» — номер столбца. Говорят «матрица размерности », подразумевая, что в матрице m строк и n столбцов.

Содержание

  • 1 История
  • 2 Матрица как запись коэффициентов системы линейных уравнений
  • 3 Операции над матрицами
  • 4 Квадратная матрица и смежные определения
  • 5 Свойства матриц
  • 6 Элементарные преобразования матриц
  • 7 Типы матриц
  • 8 Матрица линейного оператора
  • 9 См. также
  • 10 Литература
  • 11 Ссылки

История

Понятие матрицы впервые появилось в середине XIX века в работах Уильяма Гамильтона и Артура Кэли. Фундаментальные результаты в теории матриц принадлежат Вейерштрассу, Жордану, Фробениусу.

Матрица как запись коэффициентов системы линейных уравнений

Систему из m уравнений с n неизвестными

можно представить в матричном виде

и тогда всю систему можно записать так:

AX = B,

где A имеет смысл таблицы коэффициентов aij системы уравнений.

Если m = n и матрица A невырожденная, то решение этого уравнения состоит в нахождении обратной матрицы A — 1, поскольку умножив обе части уравнения на эту матрицу слева

A — 1AX = A — 1B

A − 1A — превращается в E (единичную матрицу). И это даёт возможность получить столбец корней уравнений

X = A — 1B.

Все правила, по которым проводятся операции над матрицами выводятся из операций над системами уравнений.

Операции над матрицами

Пусть aij — элементы матрицы A, а bij — элементы матрицы B.

Линейные операции:

Умножение матрицы A на число λ (обозначение: λA) заключается в построении матрицы B, элементы которой получены путём умножения каждого элемента матрицы A на это число, то есть каждый элемент матрицы B равен

bij = λaij

Сложение матриц A + B есть операция нахождения матрицы C, все элементы которой равны попарной сумме всех соответствующих элементов матриц A и B, то есть каждый элемент матрицы C равен

cij = aij + bij

Вычитание матриц AB определяется аналогично сложению, это операция нахождения матрицы C, элементы которой

cij = aijbij

Сложение и вычитание допускается только для матриц одинакового размера.

Существует нулевая матрица Θ такая, что её прибавление к другой матрице A не изменяет A, то есть

A + Θ = A

Все элементы нулевой матрицы равны нулю.

Нелинейные операции:

Умножение матриц (обозначение: AB, реже со знаком умножения ) — есть операция вычисления матрицы C, элементы которой равны сумме произведений элементов в соответствующей строке первого множителя и столбце второго.

cij =aikbkj
k

В первом множителе должно быть столько же столбцов, сколько строк во втором. Если матрица A имеет размерность , B — , то размерность их произведения AB = C есть . Умножение матриц не коммутативно.

Умножение матриц ассоциативно. Возводить в степень можно только квадратные матрицы.

Транспонирование матрицы (обозначение: AT) — операция, при которой матрица отражается относительно главной диагонали, то есть

Если A — матрица размера , то AT — матрица размера

Квадратная матрица и смежные определения

Если количество строк матрицы равно количеству столбцов, то такая матрица называется квадратной.

Для квадратных матриц существует единичная матрица E (аналог единицы для операции умножения чисел) такая, что умножение любой матрицы на неё не влияет на результат, а именно

EA = AE = A

У единичной матрицы единицы стоят только по главной диагонали, остальные элементы равны нулю

Для некоторых квадратных матриц можно найти так называемую обратную матрицу. Обратная матрица A — 1 такова, что если умножить матрицу на неё, то получится единичная матрица:

AA − 1 = E

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

Свойства матриц

  1. A + (B + C) = (A + B) + C
  2. A + B = B + A
  3. A(BC) = (AB)C
  4. A(B + C) = AB + AC
  5. (B + C)A = BA + CA
  6. (AT)T = A
  7. (A * B)T = BT * AT

Элементарные преобразования матриц

Основная статья: Элементарные преобразования матрицы

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

  1. Умножение строки на число отличное от нуля
  2. Прибавление одной строки к другой строке

Элементарные преобразование столбцов матрицы определяются аналогично.

Типы матриц

  • Антиперестановочная: AB = − BA
  • Единичная
  • Блочно-диагональная
  • Ганкелева
  • Верхнетреугольная
  • Вырожденная
  • Диагональная
    • Трёхдиагональная
  • Заполненная — в вычислительной математике матрица, которая практически не содержит нулей. Такую матрицу приходится хранить в памяти целиком. Антоним: разреженная.
  • Квадратной называют матрицу, количество строк в которой равно количеству столбцов. Для квадратных матриц существует определитель.
  • Кососимметрическая
  • Нижнетреугольная
  • Нормальная
  • Нулевая
  • Ортогональная
  • Перестановочная: AB = BA
  • Разреженная — в вычислительной математике матрица, содержащая много нулей. Организовав подходящую структуру данных, вычисления с разреженными матрицами можно проводить очень быстро. Частные случаи: диагональная, трёхдиагональная, жорданова. Антоним: заполненная.
  • Симметричная
    1. Симметричная матрица A положительно определена (A > 0), если значения у всех ее главных угловых миноров Ak > 0
    2. Симметричная матрица A отрицательно определена (A < 0), если матрица ( − A) положительно определена, то есть если для любого k главный минор k-го порядка Ak имеет знак ( − 1)k
  • Теплицева
  • Треугольная
  • Эрмитова
  • Циркулянт
  • Унитарная
  • Унимодулярная

Матрица линейного оператора

Матрица линейного оператора — матрица, выражающая линейный оператор в некотором базисе. Для того, чтобы ее получить, необходимо подействовать оператором на векторы базиса и координаты полученных векторов (образов базисных векторов) записать в столбцы матрицы.

Матрица оператора аналогична координатам вектора. При этом действие оператора на вектор равносильно умножению матрицы на столбец координат этого вектора в том же базисе.

Выберем базис . Пусть  — произвольный вектор. Тогда его можно разложить по этому базису:

,

где xk — координаты вектора в выбранном базисе.

Здесь и далее предполагается суммирование по немым индексам.

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

.

Вектора также разложим в выбранном базисе, получим

,

где  — j-я координата k-го вектора из .

Подставим разложение в предыдущую формулу, получим

.

Выражение , заключённое в скобки, есть ни что иное, как формула умножения матрицы на столбец, и, таким образом, матрица при умножении на столбец xk даёт в результате координаты вектора , возникшего от действия оператора на вектор , что и требовалось получить.

См. также

  • Норма матрицы
  • Определитель матрицы
  • Массив — тип данных в программировании, соответствующий многомерной матрице.
  • Разрежённый массив — компьютерная форма представления матриц со множеством нулей.
  • Линейные матричные неравенства — аппарат для решения задач синтеза законов управления.

Литература

  • Дж. Голуб, Ч.Ван Лоун Матричные вычисления. — М.: Мир, 1999 (djvu).
  • Беллман Р. Введение в теорию матриц. — М.: Мир, 1969 (djvu).
  • Гантмахер Ф. Р. Теория матриц (2-е издание). — М.: Наука, 1966 (djvu).
  • Ланкастер П. Теория матриц. — М.: Наука, 1973 (djvu).
  • Соколов Н. П. Пространственные матрицы и их приложения. — М.: ГИФМЛ, 1960 (djvu).

Ссылки

  • Операции над матрицами онлайн
Умножение матриц

NumPy — Studytonight

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

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

Процесс умножения матрицы в Numpy широко известен как Векторизация . Основной целью процесса векторизации является сокращение использования for циклов для проведения таких операций. А при использовании 9Цикл 0025 for пропущен из программы, это уменьшит общее время выполнения кода.

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

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

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

  • Использование умножения() Функция
    Эта функция вернет поэлементное умножение двух заданных массивов.

  • Использование функции matmul()
    Эта функция вернет матричное произведение двух входных массивов.

  • Использование функции dot()
    Эта функция возвращает скалярное произведение двух заданных массивов.

Теперь мы подробно разберем каждый из вышеперечисленных способов, один за другим.

1. Использование функции

умножить()

Функция numpy.multiply() используется, когда мы хотим выполнить умножение двух массивов. Этот метод вернет произведение arr1 и arr2 с поэлементным умножением.

Если матрица А равна:

и, матрица B:

, тогда A*B будут вычисляться следующим образом:

Синтаксис

numpy.multiply() :

Для использования этой функции требуется следующий синтаксис:

 numpy. multiply(arr1, arr2, /, out, *, где, кастинг, порядок, dtype=None, subok=True[ подпись, extobj], ufunc ‘multiply’) 

Обсудим приведенные выше параметры:

  • arr1
    Этот параметр используется для указания первого входного массива.

  • arr2
    Этот параметр используется для указания массива 2-го вывода.

  • dtype
    Этот параметр используется для указания типа возвращаемого массива.

  • out
    Этот параметр в основном указывает место, где сохраняется результат.

    • Если указан этот параметр, он должен иметь форму, которая может хранить результат умножения.

    • Если этот параметр либо не указан, либо None , в этом случае будет возвращен только что выделенный массив.

  • где
    В этом параметре значение True указывает на вычисление ufunc в этой позиции, а в случае значения False оставляет значение в выводе отдельно.

  • **kwargs
    Этот параметр позволяет передавать в функцию пару ключ-значение.

Основной пример:

Ниже у нас есть фрагмент кода, охватывающий multi() 9Функция 0026, которая используется для умножения матриц в NumPy:

 импортировать numpy как np
a = np.array([[11,2,23],[14,75,6],[17,8,9]], ndmin=3)
print("А это:\n",а)
b = np.array([[9,8,7],[6,5,4],[3,2,1]], ndmin=3)
print("В:\n",b)
выход = np.multiply (а, б)
print("Результирующая матрица:")
распечатать(выйти) 

Вывод вышеуказанного кода будет:

2. Использование функции

matmul()

Функция matmul() в библиотеке NumPy используется для возврата матричного произведения двух заданных массивов.

Если матрица А равна:

и, матрица B:

, тогда A*B с использованием функции matmul() будет рассчитано следующим образом:

Синтаксис для

matmul() :

Для использования этой функции требуется следующий синтаксис:

 np. matmul (массив а, массив б) 

Важно отметить, что хотя он возвращает нормальный продукт для двумерных массивов , если размеры любого из заданных массивов равны >2 , то он обрабатывается как стек матриц , находящихся в двух последних индексах, и передается соответствующим образом. И, с другой стороны, если какой-либо аргумент представляет собой одномерный массив , то он преобразуется в матрицу путем добавления 1 к его размерности, которая удаляется после умножения.

Пример 1:

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

 импортировать numpy как np
A = np.массив([[1,2,3], [4,5,6],[1,2,1]])
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)
 

Вывод вышеуказанного кода будет:

Пример 2:

Возьмем другой пример, в котором два перемножаемых массива (матрицы) имеют разные размеры:

 импорт numpy. matlib
импортировать numpy как np
а = [[1,4],[2,1]]
print("А есть",а)
б = [1,2]
печать("В есть",б)
print("AxB ​​есть")
печать (np.matmul (а, б))
print("BxA есть")
печать (np.matmul(b,a)) 


A равно [[1, 4], [2, 1]]
B равно [1, 2]
AxB равно
[9 4]
BxA равно
[5 6]

3. Использование функции

dot()

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

Синтаксис

numpy.dot() :

Для использования этой функции требуется следующий синтаксис:

 numpy.dot(a, b, out=Нет) 

Если, матрица A равна:

и матрица Б есть,

Произведение точек A и B вычисляется как:

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

Теперь давайте рассмотрим несколько примеров кода, чтобы увидеть это в действии.

Пример 1:

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

 импортировать numpy как np
A = np.массив([7,9,8])
B = np.массив ([2,5,6])
print("Матрица A:\n", A)
print("Матрица A:\n", B)
С = np.точка (А, В)
print("Скалярное произведение матриц A и B равно:\n", C) 


Матрица A:
[7 9 8]
Матрица A:
[2 5 6]
Скалярное произведение матриц A и B:
107

Пример 2:

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

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

Пример 3:

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

.
 А = np.массив([[2,4],[3,5]])
print("Матрица A:\n", A)
С = np.dot (3, А)
print("Матричное умножение матрицы A на скаляр :\n", C) 

Резюме

В этом уроке мы рассмотрели различные способы умножения матриц. Мы рассмотрели функцийmulti() , функций matmul() и dot() с их синтаксисом, а также несколькими примерами кода для каждой из этих функций.

NumPy, SymPy и математика, стоящая за этим

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

Объявления

Поскольку это очень важная операция, полезно понять, как это сделать в коде и как сделать это вручную. Однако, чтобы упростить поиск того, что вам нужно, мы собираемся «начать с конца». То есть мы сразу же погрузимся и сосредоточимся сначала на том, как выполнять умножение матриц в Python, используя две популярные библиотеки, NumPy и SymPy.

В первую очередь мы сосредоточимся на так называемом «стандартном» умножении матриц (или просто на «произведении матриц»). Однако мы также кратко обсудим редко используемое поэлементное умножение, также известное как «произведение Адамара». Различные инструменты имеют разные подходы к тому, как сделать и то, и другое, поэтому мы хотим понять это.

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

Как только мы узнаем, как это сделать, мы более подробно рассмотрим, что означает умножение двух матриц. Мы определим стандартное матричное умножение, которое гораздо менее интуитивно понятно, чем произведение Адамара. Мы также покажем, как мы можем использовать NumPy в качестве учебного инструмента для настройки матриц, которые мы можем решить вручную и сверить с решением.

Умножение матриц NumPy: используйте @ или Matmul

Если вы новичок в NumPy и особенно если у вас есть опыт работы с другими инструментами линейной алгебры, такими как MatLab, вы можете ожидать, что матричное произведение двух матриц, A и B, будет равно A * B . Однако оператор умножения звездочки NumPy возвращает поэлементное произведение (Адамара).

Рекламные объявления

Чтобы получить стандартное матричное произведение двух матриц A и B в NumPy вместо продукта Адамара, вы можете либо вызвать NumPy matmul или используйте перегруженный оператор @ , как показано здесь для двух матриц:

 import numpy as np
# Матрицы в numpy реализованы как массивы NumPy
A = np.массив([1,2,3,4]).изменить форму(2,2)
B = np.массив([5,6,7,8]).изменить форму(2,2)
# Отображение матричного произведения с помощью оператора @
print("Произведение матрицы с использованием @: \n\n", A @ B, "\n")
# Отобразить матричное произведение, используя matmul"
print("Идентичный результат от matmul:\n\n", np. matmul(A, B), "\n")
# Показать продукт Адамара
print("Поэлементное умножение с использованием *:\n\n", A * B, "\n") 

Вывод:

Advertisements

Обратите внимание, что оператор @ был добавлен в Python в версии 3.5, поэтому, если вы используете более раннюю версию, вам нужно будет использовать matmul . Однако, как обсуждалось в PEP 465, оператор @ в Python предназначался для предоставления стандарта между библиотеками, поэтому он является предпочтительным выбором для нового кода.

Обратите внимание, что мы использовали заглавные буквы для A и B, а не обычное соглашение Python о строчных буквах. Математики обычно используют заглавные буквы для матричных переменных, поэтому здесь мы следовали этому соглашению.

Advertisements

Как умножать матрицы в SymPy

Массивы Numpy основаны на C и обладают высокой производительностью. Из-за этого NumPy является очень популярным выбором для «матричных» операций в Python, особенно в производственной среде или для больших массивов. Напротив, SymPy обычно более высоко ценится за интерактивную символьную математику.

Однако, поскольку он также поддерживает операции с матрицами и векторами, мы должны кратко рассмотреть, как перемножать матрицы в SymPy. Пользователи MatLab будут чувствовать себя как дома благодаря тому факту, что в SymPy вы можете получить матричное произведение двух sympy.matrices.Matrix объектов с использованием стандартного оператора умножения « * ». В SymPy также реализована поддержка нового стандартного оператора Python « @ ». Для менее распространенной операции поиска продукта Адамара вы можете использовать функцию SymPy matrix_multiply_elementwise .

Для согласованности давайте покажем, как мы можем запустить практически тот же код из последнего примера в SymPy:

 из sympy.matrices import Matrix
из sympy.matrices.dense импорта matrix_multiply_elementwise
C = Матрица ([[1,2],[3,4]])
D = Матрица ([[5,6],[7,8]])
print("Матричное произведение с использованием оригинального оператора sympy *:")
дисплей (С * Д)
print("\n", "Тот же продукт с новым оператором Python @:")
дисплей (С * Д)
print("\n", "Получить произведение Адамара с помощью matrix_multiply_elementwise:")
дисплей (matrix_multiply_elementwise (C, D)) 

Использование функции отображения использует встроенную поддержку SymPy для форматирования LaTeX, отображая следующий вывод:

Рекламные объявления

Обратите внимание, что, как и в NumPy, здесь также работает оператор @.

Оператор @ сейчас так широко поддерживается в библиотеках Python, что можно сказать, что ответ на вопрос «Как выполнить умножение матриц в Python» имеет однозначный ответ: «Используйте оператор @». Помимо NumPy и SymPy, например, TensorFlow также реализует этот оператор. В Tensorflow это эквивалентно функция матмуль из пакета tf.linalg .

Математика, стоящая за умножением матриц

Теперь, когда у нас есть довольно четкое представление о том, как умножать матрицы в Python, давайте представим (или повторим), что это значит сделать это в математических терминах. Я максимально упрощу это, так как знаю, что матричное умножение может немного сбивать с толку, когда вы впервые изучаете его. (В моем случае я все еще не понимал, как это работает, даже после того, как начал постоянно получать правильные ответы!)

Прежде чем мы разберемся, как это сделать, не запутавшись, нам нужны некоторые основные идеи, и мы проиллюстрируем их еще одним кодом Python.

Advertisements

Умножение матриц не является коммутативным

Первое, что нужно понять о умножении матриц, это то, что оно не является коммутативным. Это означает, что в отличие от «обычного» (скалярного) умножения, вы не можете поменять местами члены. Хотя мы еще не знали, что это «коммутативное свойство», мы, вероятно, впервые столкнулись с этой идеей, когда изучили нашу таблицу умножения. Возможно, наши учителя пытались утешить нас по поводу всего этого заучивания, говоря нам: «Если вы выучите 2 х 3, то вы уже знаете ответ на 3 х 2!»

За исключением нескольких особых случаев, это , а не верно для умножения матриц. Мы можем доказать это себе для матриц C и D из нашего примера SymPy.

Учебное пособие по Python: арифметика Python...

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

Учебное пособие по Python: объяснение арифметических операторов Python с простыми примерами

 print("C умножить на D:")
дисплей (С * Д)
print("\nD раз C:")
display(D * C) 

Мало того, что мы не получим один и тот же ответ для двух матриц, когда мы изменим порядок умножения множителей — иногда такая замена членов означает, что мы больше не можем их умножать! Только потому, что мы можем умножить A x B, нет никакой гарантии, что мы сможем умножить B x A. Чтобы понять, почему это так, нам нужно начать изучать размерности матрицы.

Размеры матрицы

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

Измерения всегда сначала выражаются количеством строк, а затем количеством столбцов. Мы часто говорим о матрице M x N, но для меня R x C было бы более простым — сначала строки, затем столбцы. Но не важно. Вам понравится, если вы помните колу «Royal Crown» или «радиоуправляемые» самолеты.

Advertisements

До сих пор мы имели дело с квадратными матрицами (с тем же количеством строк и столбцов), но давайте посмотрим, как это работает с двумя новыми матрицами, которые не являются квадратными:

Допустим, мы хотим умножить J на K. В этом случае размеры равны «4 на 2, умноженные на 2 на 3». Другими словами, количество столбцов в J соответствует количеству строк в K — или, можно сказать, совпадают «внутренние измерения». Внутренние измерения говорят нам, можем ли мы умножать. Когда они совпадают, мы в деле, и мы можем умножить J * K. Победитель-победитель, куриный ужин!

Внешние размеры определяют размер результирующей матрицы. Поэтому мы ожидаем, что наш результат будет иметь четыре строки и 3 столбца (4 x 3). Другими словами, у него будет количество строк первой матрицы и количество столбцов второй.

Как насчет умножения K * J? Что ж, в таком случае размеры выстраиваются как «2 x 3 x 4 x 2». Внутренние члены 3 и 4 не совпадают. Другими словами, в K три столбца, а в J четыре строки. Умножение матриц в этом случае не определено.

Advertisements

В следующем коде мы создаем эти матрицы в NumPy, а затем пытаемся умножить их в обоих направлениях:

 # Настройка матриц
J = np.array([2, 1, 1, 3, 2, 8, 4, 2]).reshape(4,2)
K = np.массив([[5, 2, 6],[7, 8, 3]])
# Умножение и отображение результатов (вторая строка вызовет исключение)
print(f"J @ K = \n {J @ K}")
print(f"K @ J = \n {K @ J}") 

Вывод:

Конечно, это сообщение об ошибке могло бы быть немного яснее, но последняя его часть указывает вам правильное направление: «4 отличается от 3”.

Также обратите внимание, что результат для случая, который действительно работал, имеет внешние измерения из наших двух исходных массивов. Ответ состоит из четырех строк по три столбца.

Умножение матриц вручную

Чтобы выполнить умножение матриц вручную, нам сначала нужно создать резервную копию и определить то, что называется скалярным произведением. Допустим, у нас есть два вектора одинакового размера, где вектор — это просто ряд чисел. (В Python мы бы назвали это списком или одномерным массивом).

Помимо создания списка или одномерного массива, мы можем получить вектор, взяв всего одну строку или столбец из матрицы. Например, давайте снова посмотрим на наши матрицы J и K:

Что, если мы возьмем первую строку J, [2, 1] и развернем ее так, чтобы она выглядела так:

Обратите внимание, что два «столбца» этой строки теперь выглядят как строки, и они совпадают с строки матрицы K. Глядя на первый столбец K, мы имеем:

Рекламы

Если мы умножим соответствующие ячейки двух вышеуказанных векторов и сложим результат, мы получим ответ 17, как показано здесь:

Когда мы берем два таких вектора и умножаем каждый элемент, а затем суммируем результаты, это называется скалярным произведением.

Если мы построим строку, повторив эту процедуру, взяв нашу повернутую первую строку J:

, умноженную на оставшиеся столбцы K, мы можем создать строку из трех скалярных значений, начиная с 17, которые мы только что вычислили:

 [ 17 12 15] 

Теперь, еще раз, когда мы позволили Python сделать за нас умножение J и K ранее, он дал следующий результат:

 J @ K =
 [[17 12 15]
 [26 26 15]
 [66 68 36]
 [34 24 30]] 

Обратите внимание, что первая строка — это именно то, что мы создали, когда нашли скалярное произведение первой строки J, умноженной на каждый столбец K. Если мы повторим процедуру еще три раза для оставшихся трех строк K, заполним полученную матрицу.

Другими словами, если матрица результатов M имеет форму значения строки из J и значения столбца из K, то каждая ячейка M с координатами j, k является скалярным произведением соответствующей строки j и столбца к.

Не делайте этой ошибки

Ранее я упоминал, что по-прежнему озадачен умножением матриц даже после того, как начал делать это правильно. Возьмем случай умножения J на ​​K. Моя путаница возникла из-за того, что количество столбцов J должно совпадать с числом строки из K, но, используя поэлементный подход, мы берем точечную матрицу каждой строки J, умноженную на столбец K.

Рекламные объявления

Это не проблема. Помните, поскольку внутренние размеры совпадают, каждая строка J имеет точно такое же количество «столбцов» (индивидуальных значений), как и количество строк в K. Вот почему мы могли бы сделать это вручную, вращая строку J и обрабатывая скалярное произведение каждого столбца K.

Python как инструмент исследования матриц

Конечно, если вы знаете, как выполнять умножение матриц, использование NumPy и SymPy в Python или какой-либо другой системе линейной алгебры менее подвержено ошибкам и быстрее. Однако, если вы изучаете, как это делать, либо в рамках курса, либо потому, что вам это интересно, мы должны отметить, что показанный здесь построчный метод соответствует более обширному Инструкции «сделай это вручную» вы можете найти в статье «Как быстро и правильно умножать матрицы за шесть простых шагов».

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *