Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Strassenのアルゴリズムによる 行列積の計算 /strassen-algorithm

Miyakawa Taku
December 27, 2017

Strassenのアルゴリズムによる 行列積の計算 /strassen-algorithm

このスライドの著者は宮川拓です。
CC BY 3.0 Licenseの元に利用を許諾します。

Miyakawa Taku

December 27, 2017
Tweet

More Decks by Miyakawa Taku

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. 三重ループ
     = (
    ), = (
    )を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

    View Slide

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

    View Slide

  8. 分割統治
    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

    View Slide

  9. 分割統治
    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

    View Slide

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

    View Slide

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

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

  14. 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

    View Slide

  15. 実装&計測
    #jjug
    15/19

    View Slide

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

    View Slide

  17. 計測
    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

    View Slide

  18. 総括
    #jjug
    18/19

    View Slide

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

    View Slide