拡張されたユークリッドの互除法


自分用メモ。

Euclid整域

\(R\) はEuclid整域で、 \(R\) 上の関係 \(\prec\) はwell-foundedな前順序であるとする。

Euclid整域の公理:\(x, y\in R, y\ne 0\) に対して、\(x=qy+r, r\prec y\) を満たす \(q, r\in R\) が存在する(一意性は要求しない)。

特に、この公理から、 0 は \(\prec\) に関する最小元であることがわかる。

TODO: この定式化で良い?

互除法

\(x_0=x, x_1=y\) とおき、 \(\prec\) に関する減少列 \(\{x_k\}\) を \(x_{k-1}=q_{k} x_{k}+x_{k+1}\) を満たすように取る。(途中の商と余りには任意性があるが、ここでは1つ固定する)

関係 \(\prec\) がwell-foundedなので、この列は有限列である。つまり、ある \(n\) について \(x_{n+1}=0\) となる。このとき、 \(x_n\) が \(x\) と \(y\) の最大公約数である。

このとき、 \(x_n=u x + v y\) となる \(u\), \(v\) も同時に求めるのが、拡張されたユークリッドの互除法である。

列 \(\{x_k\}\) と初項 \(x_0, x_1\) の関係を、行列を使って書けば次のようになる:

\begin{align*}
\begin{pmatrix}x_k\\x_{k+1}\end{pmatrix}&=\begin{pmatrix}0&1\\1&-q_{k}\end{pmatrix}\begin{pmatrix}x_{k-1}\\x_{k}\end{pmatrix} \\
&=\begin{pmatrix}0&1\\1&-q_{k}\end{pmatrix}\cdots\begin{pmatrix}0&1\\1&-q_{1}\end{pmatrix}\begin{pmatrix}x_{0}\\x_{1}\end{pmatrix}.
\end{align*}

この右辺の係数を1つの行列で書きたい。そのために、数列 \(\{u_k\}\), \(\{v_k\}\) を、次により定める:

\begin{align*}
\begin{pmatrix}u_0&v_0\\u_1&v_1\end{pmatrix}&=\begin{pmatrix}1&0\\0&1\end{pmatrix},\\
\begin{pmatrix}u_k&v_k\\u_{k+1}&v_{k+1}\end{pmatrix}&=\begin{pmatrix}0&1\\1&-q_{k}\end{pmatrix}\begin{pmatrix}u_{k-1}&v_{k-1}\\u_{k}&v_{k}\end{pmatrix} & (k>0).
\end{align*}

すると、 \(\begin{pmatrix}0&1\\1&-q_{k}\end{pmatrix}\cdots\begin{pmatrix}0&1\\1&-q_{1}\end{pmatrix}=\begin{pmatrix}u_k&v_k\\u_{k+1}&v_{k+1}\end{pmatrix}\) なので、列 \(\{x_k\}\) と初項 \(x_0, x_1\) の関係は、

\[\begin{pmatrix}x_k\\x_{k+1}\end{pmatrix}=\begin{pmatrix}u_k&v_k\\u_{k+1}&v_{k+1}\end{pmatrix}\begin{pmatrix}x_{0}\\x_{1}\end{pmatrix}\]

となる。特に \(k=n\) の場合は

\[\begin{pmatrix}x_n\\0\end{pmatrix}=\begin{pmatrix}u_n&v_n\\u_{n+1}&v_{n+1}\end{pmatrix}\begin{pmatrix}x_{0}\\x_{1}\end{pmatrix}\]

であり、 \(x_n=u_n x_0+v_n x_1\) となる。この \(u_n\) と \(v_n\) が求める \(u\), \(v\) である。

行列を使わずに書くと、 \(u_k\), \(v_k\) の初期値は

\begin{align*}
u_0&=1, & v_0&=0, \\
u_1&=0, & v_1&=1,
\end{align*}

で、漸化式は

\begin{align*}
x_{k-1}&=q_k  x_k+x_{k+1} & \text{(除算)}, \\
u_{k+1}&=u_{k-1}-q_k u_k, \\
v_{k+1}&=v_{k-1}-q_k v_k
\end{align*}

である。

実装例

Haskell による実装例:

-- (u,v,g) = extGcd x y
-- abs g == gcd x y, g == u * x + v * y
extGcd :: Integer -> Integer -> (Integer,Integer,Integer)
extGcd = loop 1 0 0 1
  where
    loop u v u' v' x 0 = (u,v,x)
    loop u v u' v' x y = case quotRem x y of
      (q,r) -> loop u' v' (u - q * u') (v - q * v') y r

実行例:

*Main> extGcd 12 7
(3,-5,1)
*Main> 12 * 3 + 7 * (- 5)
1
*Main> extGcd 12 78
(-6,1,6)
*Main> 12 * (-6) + 78 * 1
6
*Main> extGcd 12 0
(1,0,12)
*Main> extGcd (-75) 36
(1,2,-3)
*Main> (-75) * 1 + 36 * 2
-3

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です