ストラッセン-ショーンハーゲ法

梅谷 武
作成:2000-08-19 更新:2005-04-20
多倍長整数の高速乗算法であるストラッセン-ショーンハーゲ法の実装法について検討する。作譜に必要な個々の算法について見渡した後、32ビット語長の場合について、その主要部分を算譜としてまとめる。
IMS:20000819001; NDC:412.1; keywords:ストラッセン-ショーンハーゲ法, 離散Fourier変換;
目  次
1. ストラッセン-ショーンハーゲ法
2. 整数の算法
3. 32ビット語長の場合
参考文献
1. ストラッセン-ショーンハーゲ法
1.1 離散Fourier変換の型
 整数n,m>0及び、R=Z/mZ上の1の原始n乗根ζを適当に定めることによって、R上の離散Fourier変換を定義することができる。([F1]参照) ストラッセン-ショーンハーゲ法においては、K=2kとして、
(n,m,ζ)(K,22K+1,24)
という離散Fourier変換を使用する。この変換はK=2kであることから、Cooley-Tukey型の高速算法が適用できることと、1の原始K乗根ζ=24を乗ずることが、乗算命令ではなくて、2進演算では非常に効率がいいビットシフト命令で実行することができることから効率の良い最適化が期待できる。まず、これが離散Fourier変換の必要条件を満たしていることを証明する。
補題1.1
 K=2k(k>0)として、
(n,m,ζ)(K,22K+1,24)
とするとき、整数の剰余環R=Z/mZは、次の離散Fourier変換の必要条件を満たす。
  1. ζは1の原始K乗根
  2. ∃K-1∈R=Z/mZ
  3. K>l>0 → i=0K-1ζil=0
証明 1.は次の式による。
ζK/2=22K≡-1(mod 22K+1), ζK≡1(mod 22K+1)
2.は(K, 22K+1)=1による。3.については、まず、
l0(mod K)l-1,22K+1)=1
となることを示す。
ζl1(mod p),22K-1(mod p)
なる素数pが存在したと仮定すると
ζl24l1(mod p)
より、4K|4lからK|lとなりl≡0(mod K)が導かれる。
ζlK-1
Σ
i=0
ζil
=
K-1
Σ
i=0
ζ(i+1)l
K-1
Σ
i=0
ζil+ζKl-ζ0l(mod 22K+1)
K-1
Σ
i=0
ζil(mod 22K+1)
より、
l-1)K-1
Σ
i=0
ζil
0(mod 22K+1)
したがってl-1, 22K+1)=1より、
K-1
Σ
i=0
ζil
0(mod 22K+1)
1.2 ストラッセン-ショーンハーゲ法の改良
 ここではストラッセン-ショーンハーゲ法を少し改良した形で述べる。これにより計算量を少し減らすことができる。
仮定1.2 (多倍長整数の高速乗算法)
 
K2k(k>0),NK2
とし、正の整数a,bが、基数P=2Kにより次のようにP進表現されるものとする。
a
aK-1PK-1++a1P+a0,0≦ai<P
b
bK-1PK-1++b1P+b0,0≦bi<P
この場合、0≦a,b≦2N-1であるが、さらに
0≦ab≦2N-1
と仮定する。
 仮定より、ab2N-1を法として求めればよい。PK≡1(mod 2N-1)より、
cabK-1
Σ
r=0
(
Σ
s+t≡r(mod K)
asbt)Pr
(mod 2N-1)
となる。この係数cr=s+t≡r(mod K)asbtの大きさを評価すると、
0crK(2K-1)2K(22K+1)
となる。したがってcrK(22K+1)を法として求めればよい。(K, 22K+1)=1であるから、孫子の剰余定理から次のことがわかる。
補題1.3
 crは、c'r及びc''rが既知であるとして、連立合同式
cr
c'r(mod K)
cr
c''r(mod 22K+1)
を解くことによって求めることができる。
 K22K+1に対して小さいのでc'rは直接計算する。
算法1.4
 c'rは、次の手順で計算する。
  1. a'r≡ar (mod K)
  2. b'r≡br (mod K)
  3. c'rs+t≡r(mod K)a'sb't (mod K)
 c''rは、(K, 22K+1, 24)型の離散Fourier変換と多項式の高速乗算法を利用して計算する。([F1]参照)
算法1.5
 c''rは次のように計算する。
F(a)i
K-1
Σ
s=0
asζsi(mod 22K+1)
F(b)i
K-1
Σ
t=0
btζti(mod 22K+1)
c''r
K-1K-1
Σ
i=0
F(a)iF(b)iζ-ir(mod 22K+1)
 ここまででcr, r=0,…,K-1を求めることができた。これに桁上げ処理を施すことで、c=abP進表現が得られる。
2. 整数の算法
2.1 孫子の剰余定理
 孫子の剰余定理は、3世紀後半に著された「孫子算経」に連立合同式を満たす整数を求める問題があることから付けられた現代中国で使われている名称である。欧米では中国の剰余定理(Chinese remainder thorem)と呼ばれている。([A2]参照)
定理2.1 (孫子の剰余定理)
 正の整数m1,m2,…,mkはどの2つも互いに素であると仮定する。このとき、任意の整数u1,u2,…,ukに対して、連立合同式:
u≡u1(mod m1),u≡u2(mod m2),…,u≡uk(mod mk)
を満たす整数uが存在し、m1m2…mkを法として一意的に定まる。したがって、特に
0um1m2…mk
を満たすものはただ一つ存在する。
証明 一意性をまず示す。整数u,vが連立合同式を満たすとすると
uv(mod mj),1≦j≦k
となり、u-vはすべてのmjの倍数であり、したがってm=m1m2…mkの倍数となる。すなわち、
uv(mod m1m2…mk)
である。存在することを構成的に証明する。
Mj(m/mj)φ(mj),1≦j≦k
とおく。ここでφ(mj)はオイラーの関数である。そうするとオイラーの定理により
Mj
1(mod mj)
Mj
0(mod mk),k≠j
が成り立つ。このとき、
k
Σ
i=1
uiMi
はすべての合同式を満足する。 ■
 上の証明は構成的ではあるが、実際に解を求める方法としてはあまり効率がよくない。この高速算法をH. L. Garnerが与えている。([S2]参照)
算法2.2 (孫子の剰余定理の解の高速算法)
 まず、ユークリッドの互除法により、
cijmi1(mod mj),1≦i<j≦k
なるcijを計算しておく。これは
ami+bmj1
においてcij=aとすればよい。このとき、vr, 1≦r≦k
v1
u1%m1
v2
(u2-v1)c12%m2
vr
(…((ur-v1)c1r-v2)c2r--vr-1)c(r-1)r%mr
とする。このとき、
uvkmk-1…m1++v3m2m1+v2m1+v1
が解である。
証明 
vjmj-1…m1
mj-1…m1(…((uj-v1)c1j-v2)c2j--vj-1)c(j-1)j
mj-2…m1(…((uj-v1)c1j-v2)c2j--vj-2)c(j-2)j-vj-1mj-2…m1
uj-v1-v2m1--vj-1mj-2…m1(mod mj)
 孫子の剰余定理の解法を算譜としてまとめておく。integerは無限精度整数型を表わしており、実際の作譜にあたっては桁あふれに対する考慮が必要である。
算譜2.3 (孫子の剰余定理の解法)
 
integer c[k][k], m[k], u[k], v[k];
integer i, r, u;

// v[k]の計算
for (r = 0; r < k; r++)
{ i = 0;
  tmp = u[r];
  while (i < r)
  { tmp = (tmp - v[i])*c[i][r];
    i++;
  }
  v[r] = tmp % m[r];
}

// 解uの計算
u = 0;
for (r = 0; r < k; r++)
{ i = 0;
  tmp = v[r];
  while (i < r)
  { tmp *= m[i];
    i++;
  }
  u += tmp;
}
2.2 ユークリッドの互除法
 ユークリッドの互除法は最大公約数を求める算法であり、「原論」のZ巻に定理として述べられている。近代の多くの初等整数論の教科書においても、そのまま最大公約数を求める算法として解説されているが、これが必ずしも最良の算法であるとはいえない。ここでは最大公約数を求める算法をある種の有限列を計算する方法として形式化し、その形式でユークリッドの互除法を表現した後、J. Steinにより発見された除算命令を使わない算法について述べる。([S2]参照)
定義2.4 (最大公約数の算法のベクトル列表現)
 2つの負でない整数a,bについて、算法について考える。
ax+by=z
を満たす整数ベクトル(x,y,z)の組の有限列{(xi,yi,zi),(si,ti,ui)}i=0nが、次の条件を満たすものとする。
  1. z0=a, u0=b
  2. zi>ui≧0, i=1,…,n
  3. max(zi,ui)>max(zi+1,ui+1), i=0,…,n-1
  4. (zi,ui)=(zi+1,ui+1), i=0,…,n-1
  5. zn=d, un=0
もしこのような有限列を何らかの手段で生成することができれば最大公約数d=zn及び不定方程式の解m=xn,y=znが求まる。これを最大公約数の算法のベクトル列表現と呼ぶ。
 ユークリッドの互除法をベクトル列表現で述べる。
算法2.5 (拡張されたユークリッドの互除法)
 2つの負でない整数a,bが与えられたとき、
  1. (x0,y0,z0)=(1,0,a),(s0,t0,u0)=(0,1,b)
  2. ui≠0ならば
    (xi+1,yi+1,zi+1)=(si,ti,ui)
    (si+1,ti+1,ui+1)=(xi,yi,zi)-(si,ti,ui)zi/ui
によって生成されるベクトル列は、最大公約数の算法のベクトル列表現である。
証明 a=qb+rのとき(a,b)=(b,r)であることからわかる。 ■
 拡張されたユークリッドの互除法を算譜としてまとめておく。
算譜2.6 (拡張されたユークリッドの互除法)
 
integer a, b;
integer x, y, z, s, t, u;
integer q, d, e, f;

x = 1; y = 0; z = a;
s = 0; t = 1; u = b;
while (u != 0)
{ q = z/u;
  d = s; e = t; f = u;
  s = x - s*q; t = y - t*q; u = z - u*q;
  x = d; y = e; z = f;
}
 J. Steinによる最大公約数の算法は、2進演算機で最適化できるように工夫されたものである。
算法2.7 (J. Steinによる最大公約数の算法)
 二つの負でない整数a,bが与えられたとき、もしともに2を素因数としてもつならば、必要なだけ2のべき乗で割ることによって、2を共通の約数としてもたないようにしておく。このとき、
  1. (x0,y0,z0)=(1,0,a),(s0,t0,u0)=(b,1-a,b)
  2. ziが偶数のとき、
    • xi,yiがともに偶数のとき、
      (xi+1,yi+1,zi+1)=(xi,yi,zi)/2
    • xi,yiのいずれかが奇数のとき、
      (xi+1,yi+1,zi+1)=(xi+b,yi-a,zi)/2
  3. uiが偶数のとき、
    • si,tiがともに偶数のとき、
      (si+1,ti+1,ui+1)=(si,ti,ui)/2
    • si,tiのいずれかが奇数のとき、
      (si+1,ti+1,ui+1)=(si+b,ti-a,ui)/2
  4. zi,uiがともに奇数のとき、
    (xi+1,yi+1,zi+1)=(xi,yi,zi)-(si,ti,ui)
    (si+1,ti+1,ui+1)=(si,ti,ui)
  5. もし2.3.4.の操作で、zi+1<ui+1となればベクトルの順序を入れ替える。
によって生成されるベクトル列は、最大公約数の算法のベクトル列表現である。
証明 最大公約数が求まることは、aが偶数でbが奇数のとき(a,b)=(a/2,b)であることと(a,b)=(a-b,b)からわかる。2.と3.の操作で、ax+by=zが偶数で、x,yがともに偶数でないときx+by-aがともに偶数になることを示す。xが奇数であるとする。aが奇数のとき、byはともに奇数でなければならない。aが偶数のとき、仮定からbは奇数である。したがってyは偶数である。yが奇数である場合も同様である。 ■
 J. Steinによる最大公約数の算法を算譜としてまとめておく。
算譜2.8 (J. Steinによる最大公約数の算法)
 
integer a, b;
integer x, y, z, s, t, u;
integer d, e, f;
integer k;

k = 0;
while (a,bはともに偶数)
{ a >>= 1; b >>= 1;
  k++;
}

x = 1; y = 0; z = a;
s = 0; t = 1; u = b;
if (u > z)
{ d = s; e = t; f = u;
  s = x; t = y; u = z;
  x = d; y = e; z = f;
}
while (u != 0)
{ if (zは偶数)
  { if (x,yはともに偶数)
    { x >>= 1; y >>= 1; z >>= 1;
    } else {
      x += b; y -= a;
      x >>= 1; y >>= 1; z >>= 1;
    }
  }
  else if (uは偶数)
  { if (s,tはともに偶数)
    { s >>= 1; t >>= 1; u >>= 1;
    } else {
      s += b; t -= a;
      s >>= 1; t >>= 1; u >>= 1;
    }
  }
  else
  { x -= s; y -= t; z -= u;
  }
  if (u > z)
  { d = s; e = t; f = u;
    s = x; t = y; u = z;
    x = d; y = e; z = f;
  }
}
z <<= k;
2.3 法演算
 ストラッセン-ショーンハーゲ法の中に22K+1を法とする演算がでてくるが、ここでは一般に2e+1を法とする加法と乗法を2eを法とする加法と乗法を利用して計算する方法についてまとめておく。証明は自明なので省略する。
命題2.9
 0≦u,v<2e+1とするとき、
(u+v)%(2e+1)
u+v, u+v2e+1
(u+v)%2e-1, otherwise
uv%(2e+1)
uv%2e-uv/2e, uv%2e-uv/2e0
uv%2e-uv/2e+2e+1, otherwise
3. 32ビット語長の場合
3.1 桁あふれの判定
仮定3.1 (多倍長整数の高速乗算法(32ビット語長))
 
K=25=32,N=K2=1024
とし、正の整数a,bが、基数P=232により次のようにP進表現されるものとする。
a
aK-1PK-1++a1P+a0,0≦ai<P
b
bK-1PK-1++b1P+b0,0≦bi<P
この場合、0≦a,b≦2N-1であるが、さらに
0≦ab≦2N-1
と仮定する。
 au,bv0でない最大の係数としたとき、0≦ab≦2N-1の判定を次の条件によって行なう。
(u+1)+(v+1)K-1
この条件はきびしすぎるが、正確な判定を行なうにはかなりの計算量が必要になるので簡単のためにこうしておく。
3.2 c'の計算
(c'rを計算する算譜を参照する。)
3.3 c''の計算
(c''rを計算する算譜を参照する。)
3.4 連立合同式の解法
 c'r,c''rが与えられたときに、補題1.3の連立合同式を解いてcrを求める部分をまとめておく。算法2.2を適用するとm1=25,m2=264+1である。まず、
c12m1≡1(mod m2)
なるc12を求める。
25925≡-1(mod 264+1)
の両辺を2乗することによって、
212325≡1(mod 264+1)
c12は264+1を法として求めればよいので、
c12
2123259(264+1)-259
264-259+1(mod 264+1)
25931+1(mod 264+1)
となる。
参考文献
代数学
[A1] 松坂 和夫, 代数系入門, 岩波書店, 1976
[A2] 上野 健爾, 代数入門, 岩波書店, 2004
Fourier解析
[F1] 梅谷 武, 離散Fourier変換
[F2] 大浦 拓哉, FFTの概略と設計法
数論
[N1] 和田 秀男, コンピュータと素因子分解, 遊星社, 1999
[N2] 和田 秀男, 高速乗算法と素数判定法, 上智大学数学教室, 1983
算法
[S1] 野下 浩平, 高岡 忠雄, 町田 元, 基本的算法, 岩波書店, 1983
[S2] D. E. Knuth(中川 圭介訳), 準数値算法―算術演算, サイエンス社, 1986
ディジタル信号処理
[D1] 電子情報通信学会, ディジタル信号処理の基礎, コロナ社, 1988