Приложение 10
Умножение плотной неособенной матрицы на вектор (последовательный вещественный вариант)
Свойства и структура алгоритма
Общее описание алгоритма
Умножение матрицы на вектор - одна из базовых задач в алгоритмах линейной алгебры, широко применяется в большом количестве разных методов. Здесь мы рассмотрим умножение [math]\displaystyle{ y = Ax }[/math] плотной неособенной матрицы на вектор (последовательный вещественный вариант)[1], то есть тот вариант, где никак не используются ни специальный вид матрицы, ни ассоциативные свойства операции сложения.
Математическое описание алгоритма
Исходные данные: плотная матрица [math]\displaystyle{ A }[/math] (элементы [math]\displaystyle{ a_{ij} }[/math]), умножаемый на неё вектор [math]\displaystyle{ x }[/math] (элементы [math]\displaystyle{ x_{i} }[/math]).
Вычисляемые данные: вектор решения [math]\displaystyle{ y }[/math] (элементы [math]\displaystyle{ y_{i} }[/math]).
Формулы метода:
- [math]\displaystyle{ \begin{align} y_{i} = \sum_{j = 1}^{n} a_{ij} x_{j}, \quad i \in [1, m]. \end{align} }[/math]
Существует также блочная версия метода, однако в данном описании разобран только точечный метод.
Вычислительное ядро алгоритма
Вычислительное ядро умножения матрицы на вектор можно составить из множественных (всего их [math]\displaystyle{ m }[/math]) вычислений скалярных произведений строк матрицы [math]\displaystyle{ A }[/math] вектор [math]\displaystyle{ x }[/math]:
- [math]\displaystyle{ \sum_{j = 1}^{n} a_{ij} x_{j} }[/math]
в режиме накопления или без него, в зависимости от требований задачи.
Макроструктура алгоритма
Как уже записано в описании ядра алгоритма, основную часть умножения матрицы на вектор составляют множественные (всего [math]\displaystyle{ m }[/math]) вычисления скалярных произведений строк матрицы [math]\displaystyle{ A }[/math] вектор [math]\displaystyle{ x }[/math]
- [math]\displaystyle{ \sum_{j = 1}^{n} a_{ij} x_{j} }[/math]
в режиме накопления или без него.
Схема реализации последовательного алгоритма
Для всех [math]\displaystyle{ i }[/math] от [math]\displaystyle{ 1 }[/math] до [math]\displaystyle{ m }[/math] по возрастанию выполняются
- [math]\displaystyle{ y_{i} = \sum_{j = 1}^{n} a_{ij} x_{j} }[/math]
Особо отметим, что вычисления сумм вида [math]\displaystyle{ \sum_{j = 1}^{n} a_{ij} x_{j} }[/math] производят в режиме накопления прибавлением к текущему (временному) значению вычисляемой компоненты вектора [math]\displaystyle{ y_{i} }[/math] произведений [math]\displaystyle{ a_{ij} x_{j} }[/math] для [math]\displaystyle{ j }[/math] от [math]\displaystyle{ 1 }[/math] до [math]\displaystyle{ n }[/math], c возрастанием [math]\displaystyle{ j }[/math], вначале все компоненты инициализируются нулями. При суммировании "по убыванию" общая схема принципиально не отличается и потому нами не рассматривается. Другие порядки выполнения суммирования приводят к изменению параллельных свойств алгоритма и будут рассматриваться нами в отдельных описаниях.
Последовательная сложность алгоритма
Для умножения квадратной матрицы на вектор порядка [math]\displaystyle{ n }[/math] (т.е. при [math]\displaystyle{ m=n }[/math]) в последовательном (наиболее быстром) варианте требуется:
- по [math]\displaystyle{ n^2 }[/math] умножений и сложений.
Для умножения матрицы размером [math]\displaystyle{ m }[/math] строк на [math]\displaystyle{ n }[/math] столбцов на вектор порядка [math]\displaystyle{ n }[/math] в последовательном (наиболее быстром) варианте требуется:
- по [math]\displaystyle{ mn }[/math] умножений и сложений.
При этом использование режима накопления требует совершения умножений и сложений в режиме двойной точности (или использования функции вроде DPROD в Фортране), что ещё больше увеличивает затраты во времени, требуемом для выполнения умножения матрицы на вектор.
При классификации по последовательной сложности, таким образом, алгоритм умножения матрицы на вектор относится к алгоритмам с квадратической сложностью (в случае неквадратной матрицы - с билинейной).
Информационный граф
Опишем граф алгоритма как аналитически, так и в виде рисунка.

Граф алгоритма умножения плотной матрицы на вектор состоит из одной группы вершин, расположенной в целочисленных узлах двумерной области, соответствующая ей операция [math]\displaystyle{ a+bc }[/math].
Естественно введённые координаты области таковы:
- [math]\displaystyle{ i }[/math] — меняется в диапазоне от [math]\displaystyle{ 1 }[/math] до [math]\displaystyle{ m }[/math], принимая все целочисленные значения;
- [math]\displaystyle{ j }[/math] — меняется в диапазоне от [math]\displaystyle{ 1 }[/math] до [math]\displaystyle{ n }[/math], принимая все целочисленные значения.
Аргументы операции следующие:
- [math]\displaystyle{ a }[/math]:
- при [math]\displaystyle{ j = 1 }[/math] константа [math]\displaystyle{ 0. }[/math];
- при [math]\displaystyle{ j \gt 1 }[/math] — результат срабатывания операции, соответствующей вершине с координатами [math]\displaystyle{ i, j-1 }[/math];
- [math]\displaystyle{ b }[/math] — элемент входных данных, а именно [math]\displaystyle{ a_{ij} }[/math];
- [math]\displaystyle{ c }[/math] - элемент входных данных [math]\displaystyle{ x_{j} }[/math];
Результат срабатывания операции является:
- при [math]\displaystyle{ j \lt n }[/math] - промежуточным данным алгоритма;
- при [math]\displaystyle{ j = n }[/math] - выходным данным.
Описанный граф можно посмотреть на рисунке, выполненном для случая [math]\displaystyle{ m = 4, n = 5 }[/math]. Здесь вершины обозначены голубым цветом. Изображена подача только входных данных из вектора [math]\displaystyle{ x }[/math], подача элементов матрицы [math]\displaystyle{ A }[/math], идущая во все вершины, на рисунке не представлена.
Ресурс параллелизма алгоритма
Для алгоритма умножения квадратной матрицы на вектор порядка n в параллельном варианте требуется последовательно выполнить следующие ярусы:
- по [math]\displaystyle{ n }[/math] ярусов умножений и сложений (в каждом из ярусов — [math]\displaystyle{ n }[/math] операций).
Для умножения матрицы размером [math]\displaystyle{ m }[/math] строк на [math]\displaystyle{ n }[/math] столбцов на вектор порядка [math]\displaystyle{ n }[/math] в последовательном (наиболее быстром) варианте требуется:
- по [math]\displaystyle{ n }[/math] ярусов умножений и сложений (в каждом из ярусов — [math]\displaystyle{ m }[/math] операций).
При этом использование режима накопления требует совершения умножений и сложений в режиме двойной точности, а в параллельном варианте это означает, что практически все промежуточные вычисления для выполнения алгоритма в режиме накопления должны быть двойной точности. В отличие от последовательного варианта это означает некоторое увеличение требуемой памяти.
При классификации по высоте ЯПФ, таким образом, алгоритм умножения матрицы на вектор относится к алгоритмам с линейной сложностью. При классификации по ширине ЯПФ его сложность также будет линейной.
Входные и выходные данные алгоритма
Входные данные: матрица [math]\displaystyle{ A }[/math] (элементы [math]\displaystyle{ a_{ij} }[/math]), вектор [math]\displaystyle{ x }[/math] (элементы [math]\displaystyle{ x_{i} }[/math]).
Объём входных данных: [math]\displaystyle{ mn+n }[/math] .
Выходные данные: вектор [math]\displaystyle{ y }[/math] (элементы [math]\displaystyle{ y_{i} }[/math]).
Объём выходных данных: [math]\displaystyle{ m }[/math].
Свойства алгоритма
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является линейным (отношение квадратической или билинейной к линейной).
При этом вычислительная мощность алгоритма умножения матрицы на вектор, как отношение числа операций к суммарному объему входных и выходных данных – всего лишь константа.
При этом алгоритм умножения матрицы на вектор полностью детерминирован. Использование другого порядка выполнения ассоциативных операций в данной версии нами не рассматривается.
Литература
- ↑ В.В.Воеводин, Ю.А.Кузнецов. Матрицы и вычисления. М.: Наука, 1984.