Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка эффективных алгоритмов.doc
Скачиваний:
118
Добавлен:
24.11.2019
Размер:
1.2 Mб
Скачать

5.2. Умножение матриц

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

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

При умножении матриц размером 3х4 на матрицу размером 4х7 мы получаем матрицу размером 3х7.

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

Для вычисления произведения двух матриц каждая строка первой матрицы умножается почленно на каждый столбец второй. Затем подсчитывается сумма таких произведений и записывается в соответствующую клетку результата:

a

b

c

A

B

aA+bC+cE

aB+bD+cF

C

D

=

d

e

f

E

F

dA+eC+fE

dB+eD+fF

Умножение вышеприведенных матриц требует 12 умножений и 8 сложений.

5.2.1 Стандартный алгоритм умножения матриц

Стандартный алгоритм умножения матрицы размером ab на матрицу размером bc выполняет abc умножений и a(b - 1)c сложений.

MultMatrix(G,H,R)

// R = G  H

// размеры матриц R(ac), G(ab), H(bc)

for i=1 to a do

for j=1 to c do

R [i,j]  0

for k = 1 to b do

R[i, j]  R[i, j] +G[i, k] * H[k, j]

end for // (k)

end for // (j)

end for // (i)

end

На первый взгляд это минимальный объем работы, необходимый для перемножения 2-х матриц. Однако исследователям не удалось доказать его минимальность, и в результате они обнаружили другие алгоритмы, умножающие более эффективно.

5.2.2. Умножение матриц по Винограду

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

Рассмотрим два вектора V = (v1, v2, v3, v1) и W =(w1, w2, w3, w4 )

Их скалярное произведение V *W = v1w1 + v2w2 + v3w3 + v4w4

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

V*W = (v1 + w2) (v2 + w1) + (v3 + w4 ) (v4 + w3 ) - v1v2 - v3v4 - w1w2 - w3w4

Кажется, что второе выражение задает больше работы, чем первое: вместо четырех умножений их шесть, а вместо трех сложений – десять. Менее очевидно, что выражение в правой части допускает предварительную обработку: его части (v1v2 , v3v4 , w1w2 , w3w4) можно вычислить заранее и запомнить для каждой строки первой матрицы и для каждого столбца второй.

То есть над предварительно обработанными элементами нам придется выполнять лишь первые два умножения и последующие 5 сложений, а также – дополнительно 2 сложения.

MultMatrixVinograd( G, H, R)

d  b/2

// вычислить построчные произведения rowF для G

for i=1 to a do

rowf[i]  G [i, 1] * G [i, 2]

for j = 2 to d do

rowf [i]  rowf[i] + G [i, 2j – 1] * G [i, 2j]

endfor j

endfor i

// вычислить произведения для столбцов colF матрицы H

for i = 1 to c do

colf [i]  H [1, i] * H [2, i]

for j = 2 to d do

colf [i]  colf [i] + H [2j - 1, i ] * H [2j, i ]

endfor j

endfor i

// вычисление R

for i=1 to a do

for j = 1 to c do

R [i, j]  - rowf [i] - colf [j]

for k = 1 to d do

R [i, j]  R[i, j] + ( G[i,2k-1] + H[2k, j]) * (G[i, 2k] + H[2k-1,j)

endfor k

endfor j

endfor i

// прибавление членов в случае нечетной общей размерности

if (2 * (b/2)) <> b then

for i = 1 to a do

for j =1 to c do

R[i, j]  R [i, j] + G [ i, b] * H [b, j]

endfor j

endfor i

endif

end

В случае четной общей размерности b общее число умножений (abc+ab+bc)/2 и сложений (a(b-2)+c(b-2)+ac(3b+2))/2.