このスライドの著者は宮川拓です。 CC BY 3.0 Licenseの元に利用を許諾します。
Strassenのアルゴリズムによる行列積の計算2017-12-27 ビール&LT大会ハッシュタグ: #jjug宮川 拓
View Slide
@miyakawa_taku JJUG幹事です SI屋で賃労働してます オレオレJVM言語Kinkを作っていますhttps://bitbucket.org/kink/kink 尾上部屋の里山さんのファンです自己紹介#jjug2/19
あらまし 本物のプログラマになりたい! ということで、『アルゴリズムイントロダクション』を読み進めています n次正方行列の積が、Θ(3)よりも小さい計算量で計算できるらしい(§4.2) びっくり!#jjug3/19
背景 機械学習の計算は行列計算のかたまり 行列計算が速いと嬉しい#jjug4/19
まずはふつうに計算#jjug5/19
三重ループ = (), = ()をn次の正方行列とする = ∙ の要素は= σ=1 ∙ すなおに三重ループで実装:for i in 1~n:for j in 1~n:c[i, j] = 0for k in 1~n:c[i, j] += a[i, k] * b[k, j]3 回繰り返す→ 計算量は()#jjug6/19
準備: 分割統治#jjug7/19
分割統治A, B, Cを縦横半分に分割すると、 = ∙ は次のように書き直せる11122122=11122122∙11122122=11∙ 11+ 12∙ 2111∙ 12+ 12∙ 2221∙ 11+ 22∙ 2121∙ 12+ 22∙ 22#jjug8/19
分割統治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回再帰呼び出し#jjug9/19
分割統治n:行列の次数スカラ値の掛け算の回数1 12 84 648 51216 4,0962倍 8 = 23 倍2倍 8 = 23 倍2倍 8 = 23 倍計算量はやっぱり()#jjug10/19
Strassenのアルゴリズム#jjug11/19
StrassenのアルゴリズムA, Bを分割した上で1~7を次のように置く 1= 11(12− 22) 2= (11+ 12)22 3= (21+ 22)11 4= 2221− 11 5= (11+ 22)(11+ 22) 6= 12− 2221+ 22 7= 11− 2111+ 122次行列を計7回乗算#jjug12/19
Strassenのアルゴリズムここで、次が成り立つ 11= 1111+ 1221= 5+ 4− 2+ 6 12= 1112+ 1222= 1+ 2 21= 2111+ 2221= 3+ 4 22= 2112+ 2222= 5+ 1− 3− 7Cは1~7の和で表せる2次行列の乗算を7回再帰呼び出しすれば良い!#jjug13/19
StrassenのアルゴリズムStrassen計算量n三重ループ計算量1 1 17 2 849 4 64343 8 5122,401 16 4,0968倍8倍8倍7倍7倍7倍Θ 27 = .… Θ 28 = Θ 3<#jjug14/19
実装&計測#jjug15/19
実装https://bitbucket.org/miyakawataku/matrix-multiplication/src/default/matrix.go#jjug16/19
計測0.0000100.0001000.0010000.0100000.1000001.00000010.000000100.0000001,000.00000010,000.00000016 64 256 1,024 4,096実行時間(秒)n (行列の次数)三重ループStrassen#jjug17/19
総括#jjug18/19
総括素敵なアルゴリズムは、nが小さい時には遅い。そして大抵の場合、nは小さい。素敵なアルゴリズムの計算量の式には、大きな定数項が掛かっている。nが大きくなることが分かっていない限り、素敵にしてはならない。― Rob Pike “Notes on Programming in C”#jjug19/19