Slide 1

Slide 1 text

Strassenのアルゴリズムによる 行列積の計算 2017-12-27 ビール&LT大会 ハッシュタグ: #jjug 宮川 拓

Slide 2

Slide 2 text

 @miyakawa_taku  JJUG幹事です  SI屋で賃労働してます  オレオレJVM言語Kinkを作っています https://bitbucket.org/kink/kink  尾上部屋の里山さんのファンです 自己紹介 #jjug 2/19

Slide 3

Slide 3 text

あらまし  本物のプログラマになりたい!  ということで、 『アルゴリズムイントロダクション』 を読み進めています  n次正方行列の積が、Θ(3)よりも小さい計 算量で計算できるらしい(§4.2)  びっくり! #jjug 3/19

Slide 4

Slide 4 text

背景  機械学習の計算は行列計算のかたまり  行列計算が速いと嬉しい #jjug 4/19

Slide 5

Slide 5 text

まずはふつうに計算 #jjug 5/19

Slide 6

Slide 6 text

三重ループ  = ( ), = ( )をn次の正方行列とする  = ∙ の要素は = σ=1 ∙  すなおに三重ループで実装: for i in 1~n: for j in 1~n: c[i, j] = 0 for k in 1~n: c[i, j] += a[i, k] * b[k, j] 3 回繰り返す → 計算量は() #jjug 6/19

Slide 7

Slide 7 text

準備: 分割統治 #jjug 7/19

Slide 8

Slide 8 text

分割統治 A, B, Cを縦横半分に分割すると、 = ∙ は次のように書き直せる 11 12 21 22 = 11 12 21 22 ∙ 11 12 21 22 = 11 ∙ 11 + 12 ∙ 21 11 ∙ 12 + 12 ∙ 22 21 ∙ 11 + 22 ∙ 21 21 ∙ 12 + 22 ∙ 22 #jjug 8/19

Slide 9

Slide 9 text

分割統治 def prod(a, b): if a.order == b.order == 1: return matrix_1x1(a[0, 0] * b[0, 0]) a11, a12, a21, a22 = partition(a) b11, b12, b21, b22 = partition(b) c11 = prod(a11, b11) + prod(a12, b21) c12 = prod(a11, b12) + prod(a12, b22) c21 = prod(a21, b11) + prod(a22, b21) c22 = prod(a21, b12) + prod(a22, b22) return concat(c11, c12, c21, c22) 計算量はスカラ値の掛け算の回数に比例 n次行列の乗算は 2 次行列の乗算を8回再帰呼び出し #jjug 9/19

Slide 10

Slide 10 text

分割統治 n: 行列の次数 スカラ値の 掛け算の回数 1 1 2 8 4 64 8 512 16 4,096 2倍 8 = 23 倍 2倍 8 = 23 倍 2倍 8 = 23 倍 計算量はやっぱり() #jjug 10/19

Slide 11

Slide 11 text

Strassenのアルゴリズム #jjug 11/19

Slide 12

Slide 12 text

Strassenのアルゴリズム A, Bを分割した上で1 ~7 を次のように置く  1 = 11 (12 − 22 )  2 = (11 + 12 )22  3 = (21 + 22 )11  4 = 22 21 − 11  5 = (11 + 22 )(11 + 22 )  6 = 12 − 22 21 + 22  7 = 11 − 21 11 + 12 2 次行列を 計7回乗算 #jjug 12/19

Slide 13

Slide 13 text

Strassenのアルゴリズム ここで、次が成り立つ  11 = 11 11 + 12 21 = 5 + 4 − 2 + 6  12 = 11 12 + 12 22 = 1 + 2  21 = 21 11 + 22 21 = 3 + 4  22 = 21 12 + 22 22 = 5 + 1 − 3 − 7 Cは1 ~7 の和で表せる 2 次行列の乗算を7回再帰呼び出しすれば良い! #jjug 13/19

Slide 14

Slide 14 text

Strassenのアルゴリズム Strassen 計算量 n 三重ループ 計算量 1 1 1 7 2 8 49 4 64 343 8 512 2,401 16 4,096 8倍 8倍 8倍 7倍 7倍 7倍 Θ 27 = .… Θ 28 = Θ 3 < #jjug 14/19

Slide 15

Slide 15 text

実装&計測 #jjug 15/19

Slide 16

Slide 16 text

実装 https://bitbucket.org/miyakawataku/matrix- multiplication/src/default/matrix.go #jjug 16/19

Slide 17

Slide 17 text

計測 0.000010 0.000100 0.001000 0.010000 0.100000 1.000000 10.000000 100.000000 1,000.000000 10,000.000000 16 64 256 1,024 4,096 実行時間(秒) n (行列の次数) 三重ループ Strassen #jjug 17/19

Slide 18

Slide 18 text

総括 #jjug 18/19

Slide 19

Slide 19 text

総括 素敵なアルゴリズムは、nが小さい時には遅い。 そして大抵の場合、nは小さい。 素敵なアルゴリズムの計算量の式には、大きな 定数項が掛かっている。 nが大きくなることが分かっていない限り、素敵 にしてはならない。 ― Rob Pike “Notes on Programming in C” #jjug 19/19