ضرب ماتریسها
ماتریس n×m را در m×p ضرب میکند: هر خانهی حاصل، ضرب داخلی یک سطر از A و یک ستون از B است.
اگر A ماتریس n×m و B ماتریس m×p باشد، حاصلضرب C = A·B ماتریس n×p است و
- زمان:
O(n·m·p) - حافظه:
O(n·p) - CLRS، بخش ۴.۱
- گریمالدی، فصل ۷
- جانسونباو، فصل ۳
A دو در سه و B سه در دو؛ حاصل دو در دو است و هر خانه جمع سه ضرب.
def matrix_multiply(A, B):n, m, p = len(A), len(B), len(B[0])if len(A[0]) != m:return NoneC = [[0] * p for _ in range(n)]for i in range(n):for j in range(p):total = 0for k in range(m):total = total + A[i][k] * B[k][j]C[i][j] = totalreturn C
شروع اجرا
i—
j—
total—
A
| 1 | 2 | 3 |
| 4 | 5 | 6 |
B
| 7 | 8 |
| 9 | 10 |
| 11 | 12 |
C
جدول هنوز خالی است.
متغیرهای محلی
نارنجی = در همین گام عوض شد
A list
[1, 2, 3][4, 5, 6]
B list
[7, 8][9, 10][11, 12]
Call stack
- matrix_multiply()خط 1
گام ۱ از ۵۰
توضیح
ایده
اگر A ماتریس n×m و B ماتریس m×p باشد، حاصلضرب C = A·B ماتریس n×p است و
C[i][j] = Σ A[i][k] · B[k][j] برای k = 1 … m
یعنی ضرب داخلی سطر i از A و ستون j از B. تعداد ستونهای A باید با تعداد سطرهای B برابر باشد.
هزینه
برای هر خانه از n·p خانه، m ضرب: O(n·m·p)؛ برای ماتریسهای مربعی O(n³). روش اشتراسن با ۷ ضرب بهجای ۸ در هر تقسیم به O(n^2.81) میرسد.
نکتهها
- ضرب ماتریس جابهجاییپذیر نیست: معمولاً
A·B ≠ B·A. - ترتیب ضرب چند ماتریس هزینه را عوض میکند (صفحهی «ضرب زنجیرهای ماتریسها»).
در trace به چه چیزی نگاه کنی
- سه جدول کنار هماند؛ برای هر خانهی
Cببین کدام سطرAو ستونBخوانده میشود.