メモ

yukicoderでゆるふわgolf

Berlekamp–Massey algorithm

この記事ではBerlekamp–Massey algorithmの「気持ち」を形式的べき級数(母関数)を用いて説明します。
(日本語で詳しく説明しているサイトが見つからなかったので)
間違った説明はしていないつもりですが、(故意に)不正確な記述があるかもしれません。
連分数を使うという発想はhttp://www.math.sci.hiroshima-u.ac.jp/~m-mat/TEACH/sentan2005.pdfを参考にしました。
アルゴリズムの説明のみであり、実装については一切説明していません。


○Berlekamp–Massey algorithmとは何か
線形漸化式で与えられる数列の最初の何項かが与えられたとき、その漸化式を求めるアルゴリズム
正確には「線形漸化式で与えられる数列の最初の2N項が与えられた時、その数列を生成するN次以下の最小の線形漸化式を求めるアルゴリズム
(N次の漸化式なら必ず最初の2N項を一致させられることに留意)


○形式的べき級数
多項式とはi=0naixiという形で書ける式のことだった。
ここで、高次の項は無限に存在してもよいような物を考える。つまりi=0aixiを考えよう。
例えば1+x+x2+x3+というようなもの。
このようなもの全体は環をなし、「形式的べき級数環」と呼ばれる。
(環とは、足し算、引き算、掛け算の3つが自由にできるようなもののこと)
これの商体を「形式的べき級数体」という。
(体とは、加減乗除が自由にできるようなもののこと)
証明は省略するが、形式的べき級数体の元はi=kaixiというような形で書ける。
(負ベキの項が有限個しかないべき級数として書ける)
さらに、有理関数体は形式的べき級数体に含まれる。
つまり有理式はべき級数で書ける(収束半径を気にせずに、0を中心としてローラン展開したものだと思えばよい)


○線形漸化式の母関数
特性方程式
g(an+k,an+k1,,an+1,an)=0という線形漸化式で与えられる数列を考える。
このとき、f(x):=g(xk,xk1,,x,1)をこの数列の特性方程式という。
例えばフィボナッチ数列ならan+2an+1an=0なので特性方程式x2x1となる。
・母関数
数列{an}に対し、形式的べき級数i=0aixiを母関数という。
例えばフィボナッチ数列の母関数は0+1x+1x2+2x3+3x4+5x5+となる。
・母関数と特性方程式
線形漸化式で与えられる数列{an}があり、母関数をF(x)特性方程式f(x)k=degf(x)とする。
このとき、xkf(1/x)F(x)多項式である。
xkf(1/x)f(x)の「xの冪を逆順にしたもの」であり多項式。例えば、f(x)=x2x1ならxkf(1/x)=1xx2となる)
xkf(1/x)F(x)多項式になることはk次以上の項について具体的に係数を計算すると0になることから分かる)
つまりF(x)xkf(1/x)を分母とする有理式として表すことができる。


○ここまでのまとめ
ここまでをまとめると
「線形漸化式で与えられる数列の最初の何項かが与えられたとき、その漸化式を求めよ」
という問題は
「有理式を形式的べき級数で表したものの低次の項が与えられたとき、元の有理式(特にその分母)を求めよ」
と同じであることが分かる


ユークリッドの互除法と連分数
・連分数
連分数とは、次のような形をした分数のことである。
a+1b+1c+1d+
詳しい説明はwikipediaなどに譲るが「有理数を連分数の形で表すと、有限ステップで止まる」という重要な性質がある。
つまり、任意の有理数pqに対して、ある整数の有限列{ai}i=0nが存在して
pq=a0+1a1+1+an1+1an
となる。このことは連分数で表すことが本質的にユークリッドの互除法と対応していることから分かる
ユークリッドの互除法と連分数
例えば2710を連分数の形で書くことを考えてみる。
2710=2+710=2+1107=2+11+37=2+11+173=2+11+12+13
よく見れば分かる通り、これはユークリッドの互除法をしていることにほかならない
27=102+710=71+37=32+13=13


○線形漸化式の母関数と連分数
・形式的べき級数における割り算のあまり
形式的べき級数体においても「あまりのある割り算」を適切に定める事ができるので、ユークリッドの互除法が適用できる。
形式的べき級数の世界においては「次数」とは「最低次」の事を指す。
(x=0でのローラン展開だったので、低次の項ほど影響力が強い……という「気持ち」)
例えばx+x2+2x3+の次数は1であり、x2+x1+1+x+x2+の次数は-2である。
割り算をする際の余りは、「割る数」よりも「余り」の次数の方が大きくなるように求める。
(次数が大きい方が影響力が弱い……という「気持ち」だったので)
例えば、(1x)÷(1+x)は商が1で余りが2xとなり、
1÷(x+x2)は商がx11で余りがx2となる。
・形式的べき級数表示での連分数展開
フィボナッチ数列の場合を例とする。
まずは有理式の形の場合についてやってみる。
母関数はx1xx2だったので
x1xx2=11xx2x=1(x11)+x2x=1(x11)+1x1
となる。ではこれをべき級数の形のままやってみよう
x+x2+2x3+3x4+5x5+1=11x+x2+2x3+3x4+5x5+=1(x11)+x2x32x43x5x+x2+2x3+3x4+5x5+=1(x11)+1x+x2+2x3+3x4+5x5+x2x32x43x5=1(x11)+1x1
ということで同じ結果が得られた。
つまり、「べき級数の世界で連分数の形にする」→「連分数を有理式の世界で戻す」という操作によって、有理式が得られる。


○実装について
互除法の部分を非再帰で上手く実装したものがBerlekamp–Massey algorithmである。(と理解しているが、間違っていれば指摘してください)
具体的な実装はwikipedia英語版か、ドイツ語版を参考にするとよい。
微妙に異なる実装がなされており、自分には後者の方が理解しやすかった。
いずれにせよ、「一個前の値を保存しておいて、それを定数倍して足す」という操作が、互除法を戻す操作と対応していると理解すると分かりやすいかと思います。