pari-gpによる数論的不変量の計算iwao/ps/hokurikunt-2004.pdf†組み込み関数をいくつか呼び出す程度では、大差ない...
TRANSCRIPT
Pari-GPによる数論的不変量の計算
木村巌(富山大学理学部)
目 次
1 Pari-gpとは? 21.1 Pari-gpについてよく受ける質問 . . . . . . . . . . . . . . . 3
2 gpの基本概念 42.1 gp入門 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1 gpの起動と終了 . . . . . . . . . . . . . . . . . . . 52.1.2 簡単な計算 . . . . . . . . . . . . . . . . . . . . . . 62.1.3 組み込み関数の呼び出し . . . . . . . . . . . . . . . 72.1.4 ヘルプ機能 . . . . . . . . . . . . . . . . . . . . . . 8
2.2 2次体の計算のデモ . . . . . . . . . . . . . . . . . . . . . . 92.2.1 qfbclassno() . . . . . . . . . . . . . . . . . . . . 92.2.2 qfbclassno()のデモ . . . . . . . . . . . . . . . . 102.2.3 quadclassunit() . . . . . . . . . . . . . . . . . . 102.2.4 quadclassunit()のデモ . . . . . . . . . . . . . . 10
2.3 一般の代数体 . . . . . . . . . . . . . . . . . . . . . . . . . 102.3.1 bnfinit() . . . . . . . . . . . . . . . . . . . . . . 112.3.2 bnfinit()の引数 techについて . . . . . . . . . . 122.3.3 bnfcertify() . . . . . . . . . . . . . . . . . . . . 12
2.4 gpの文法 . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.4.1 複数の文 . . . . . . . . . . . . . . . . . . . . . . . . 13
1
2.4.2 if文 . . . . . . . . . . . . . . . . . . . . . . . . . . 132.4.3 繰返し構文 . . . . . . . . . . . . . . . . . . . . . . 132.4.4 関数定義 . . . . . . . . . . . . . . . . . . . . . . . . 142.4.5 例 . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3 その他の話題 163.1 Pari-gpのコンパイル . . . . . . . . . . . . . . . . . . . . . 163.2 初期設定ファイル . . . . . . . . . . . . . . . . . . . . . . . 173.3 C言語と Pariライブラリによる開発 . . . . . . . . . . . . 183.4 GP2C —GPから Cへのトランスレータ— . . . . . . . . . 18
3.4.1 GP2Cのインストール . . . . . . . . . . . . . . . . 183.4.2 GP2Cの使い方 . . . . . . . . . . . . . . . . . . . . 19
1 Pari-gpとは?
Pari-gp[4]は、数論の計算に特化した、freeの数値計算パッケージである.他の計算ソフトと比較すると、GNU Octave1は数値計算全般をターゲットとしている点で、また、MathematicaやMapleは商品であり、数式処理系であるという点で、対照的である.
Pari-gpは、対話的に計算を行なうためのインタプリタ処理系 gpと、計算のコア部分を提供する Pariライブラリ(C言語のライブラリ)とで構成されている.gpが理解するスクリプト言語をGPと呼ぶ.開発は、当初 H. Cohenによって開始され、現在は K. Belabasらが引
き継いでいる.Pari-gpは現在、GNU GPLというライセンスにより提供されている free softwareである.最新版のソースコードも、CVSによって提供されている.サポートされている実行環境としては、各種 Unix(ならびに Linuxや
FreeBSD, Apple Mac OS XのようなUnix互換環境)、Microsoft Windows上の cygwin環境が挙げられる.
1http://www.octave.org/
2
FreeBSDや Linuxなどでは、コンパイル済みのバイナリパッケージが提供されているため、それを使って導入するのが一番手間が少ない.また、Microsoft Windows上では、インストーラ附属のバイナリパッケージが開発陣から提供されているので、それを使うのが簡単である.ソースコードから、自分でコンパイルするのも、(Microsoft Windows上の cygwin環境も含めて)多くの環境でまったく簡単にできる.§3.1を参照の事.
1.1 Pari-gpについてよく受ける質問
Pari-gpについて良く受ける、一般的な事項についての一問一答を列挙しよう.
……は計算できるか?場合による:
• 組み込み関数を呼び出すだけでできる• 組み込み関数をいくつか組み合わせるとできる• 既知のアルゴリズムを実装するとできる• アルゴリズムを考案し、それを実装するとできる
……はどのくらいの範囲まで計算できるか?マシンの性能、メモリ容量などによる
• gpを起動した時、割り当てるメモリサイズ(デフォルトでは4MB)
• 同じく、起動した時に計算する素数のリスト(デフォルトでは500,000まで).デフォルトの値の変更の仕方については、§3.2を参照の事
• 使えるデータ(既存の数表など)を使えるか• 待ち時間(忍耐力)
C言語で書いたほうが、gpで書くよりも速いのか?これも場合による.
3
• 組み込み関数をいくつか呼び出す程度では、大差ない• ループを回す場合、gpの for()などは非常に遅い
• Cでプログラムを書いた場合、動くようになるまでの時間が掛かる
• gp2Cトランスレータがある(gpのスクリプトをCに変換してくれる §3.4参照)
数学的な概念/量を、どのように計算機に載せているのか?マニュアルに記載あり:有限Abel群……Smith Normal Form, 自由Abel群……Hermite Normal Form, 指標、イデアル、イデール等々).
~はどうやって計算しているのか?組み込み関数に実装されているアルゴリズムは、ほとんどがH. Cohenの二冊の本 [2], [3]に解説されている(はず).
~の計算結果は正しいのか?何を仮定して正しいのか?状況による:
• 無条件に正しい• GRHを仮定して正しい
• GRHよりも強いHeuristicを仮定して正しい
いずれにしても、Pari-gpのマニュアルの記述を注意深く確認する必要がある(§2.2.3, §2.3.2参照).
2 gpの基本概念
gpで簡単な計算をするための基礎知識を述べる.とりあえず起動してみたい読者は §2.1.1へ進まれたい.組み込み型:次の組み込み型が用意されている.それぞれの型を識別するために、型を表す文字列が定義されている.例えば、有理整数は t INT
など:
4
有理整数(t INT)、有理整数環の剰余環の元(t INTMOD)、有理数(t FRAC)、実数(t REAL)、複素数(t COMPLEX)、p進数(t PADIC)、(多変数、係数も任意な)多項式(t POL)、形式巾級数(t SER)、……ただし、多変数の多項式に関する因数分解などは十分には実装されていない.Pari-gpは、あくまで数値計算パッケージであると思った方が良い.組み込みのデータ型:(縦・横)ベクトル、行列.ベクトル(t VEC)は要素としてベクトルを含む事ができる.C 言語のポインタや構造体、多くのスクリプト言語に含まれる連想配列(hash)に相当するものはないので、GPで複雑なデータ構造を構築する事はかなり難しい.多くの場合、ベクトルのベクトルの……といった表現で代用している.行列は t MATである.exactな型とそうでない型:exactな型:有理整数、有理整数の剰余環の元、有理数、それらを係数とする多項式・有理式…….これらは基本的に無限多倍長である(最近のバージョン Pari-gpは、多
倍長計算にGMP2を使うこともできる)それ以外:「精度」の概念がある.実数、p進数、巾級数など.実数のデフォルトの 10進での桁数は、26. 巾級数のデフォルトの精度
は 16項まで(任意に変更できる).
2.1 gp入門
2.1.1 gpの起動と終了
Unix互換環境を使っているなら、shellのコマンドラインから gpを起動する.起動時のメッセージは、使用している Pari-gpのバージョンや、初期設定ファイル(§3.2で触れる)の内容により異同がある:iwao@jeff:~/DocMath/HokurikuNTWS-2004Dec {537}$ gp
Reading GPRC: /home/iwao/.gprc ...Done.
GP/PARI CALCULATOR Version 2.2.10 (development CHANGES-1.1159)
i386 running freebsd (ix86/GMP-4.1.4 kernel) 32-bit version
compiled: Apr 18 2005, gcc-3.4.2 [FreeBSD] 20040728
(readline v4.3 enabled, extended help available)
2GNU Multiple Precision Arithmetic Library, http://www.swox.com/gmp/
5
Copyright (C) 2000-2005 The PARI Group
PARI/GP is free software, covered by the GNU General Public License, and comes WITHOUT
ANY WARRANTY WHATSOEVER.
Type ? for help, \q to quit.
Type ?12 for how to get moral (and possibly technical) support.
parisize = 10000000, primelimit = 1000000
?
コピーライト表示の直前の行に、“readline v4.3 enabled”の表示が見える.この表示があれば、端末での行編集機能が組み込まれている.また、”extended help available”とあるが、この表示があれば、組み込み関数のリファレンスマニュアルを、dviファイルのプレビューアーで表示する機能が組み込まれている(後述).以下、?が gpのプロンプトとする.終了は、\qである.
parisize = 4000000, primelimit = 500000
? \q
Goodbye!
2.1.2 簡単な計算
整数は多倍長計算が行なわれ、有理数の四則は有理数の範囲で行なわれる.有理数を実数に丸める場合は、0.0を加える事が一番簡単である.
? 2^100
%2 = 1267650600228229401496703205376
? 1/2 + 1/3
%3 = 5/6
? %+ 0.0
%4 = 0.8333333333333333333333333333
%で直前の計算結果を引用できる.先に述べたように、データ型としてはベクトル位しか用意されていない.各成分の型が異なっていても良く、成分としてベクトルを含む事も許される.入力としては、
6
横ベクトル: [1,2,3]
縦ベクトル: [1,2,3]~
行列: [1,2,3;4,5,6;7,8,9]
のようになる.最後の行列は、(
1 2 34 5 67 8 9
)である.
変数には型はない.例えば、同じ変数に、ある時はスカラーを、別の時にはベクトルを代入することもできる:
? a = 1;
? a = [1, 2, 3];
? a[1]
1
多項式は、例えば x2 + 2x + 1を
? x^2+2*x+1
%5 = x^2 + 2*x + 1
のように入力する.
2.1.3 組み込み関数の呼び出し
多項式ならびに整数の因子分解は factor()である:
? factor(%)
%6 =
[x + 1 2]
x2 + 2x + 1 = (x + 1)2の右辺が、上記のように返される.gpの関数の引数の個数は、見かけ上、可変である.正確には、必須の引数と、オプションとしての引数があり、後者を指定しない場合は入力を省略できる(この場合、デフォルトの値が暗黙の内に指定される).
7
例えば上記の factor()は、二つの引数 x, flagをとる.前者は分解したい値、後者は、xが有理数または有理整数の場合、因数の最大値を指定する.
? factor(2^15+1,10)
%5 =
[3 2]
[3641 1]
? factor(2^15+1)
%6 =
[3 2]
[11 1]
[331 1]
最初の計算では、10以下の因数のみを探索した.
2.1.4 ヘルプ機能
gpのプロンプトに対して?だけ入力すると、gpの組み込み関数を用途別に大別した一覧が表示される:? ?
Help topics: for a list of relevant subtopics, type ?n for n in
0: user-defined identifiers (variable, alias, function)
1: Standard monadic or dyadic OPERATORS
2: CONVERSIONS and similar elementary functions
3: TRANSCENDENTAL functions
4: NUMBER THEORETICAL functions
5: Functions related to ELLIPTIC CURVES
6: Functions related to general NUMBER FIELDS
7: POLYNOMIALS and power series
8: Vectors, matrices, LINEAR ALGEBRA and sets
9: SUMS, products, integrals and similar functions
10: GRAPHIC functions
11: PROGRAMMING under GP
12: The PARI community
(以下略)
gpのプロンプトに、例えば?4のように入力すると、上記の 4番目の項目”NUMBER THEORETICAL functions”の一覧が表示される:? ?4
addprimes bestappr bezout bezoutres bigomega
binomial chinese content contfrac contfracpnqn
core coredisc dirdiv direuler dirmul
8
divisors eulerphi factor factorback factorcantor
factorff factorial factorint factormod ffinit
fibonacci gcd hilbert isfundamental ispower
isprime ispseudoprime issquare issquarefree kronecker
(以下略)
関数名の前に?をつけると、その関数のマニュアルを端末で見る事ができる:
? ?factor
factor(x,{lim}): factorization of x. lim is optional and can be set
whenever x is of (possibly recursive) rational type. If lim is set
return partial factorization, using primes up to lim (up to primelimit
if lim=0)
更に、関数名の前に??をつけると、その関数名のリファレンスマニュアルが、TEXで処理され、dvi fileのプレビューアーが起動して表示される.この機能は、Pari-gpのコンパイル時に有効化された時に限り使用できる.起動時のメッセージに、”extended help avairable”とあれば、この機能が組み込まれている.自分の行ないたい計算が、gpの組み込み関数として実現されているか否かは、このようにして検索していく事で探す事ができる.
2.2 2次体の計算のデモ
2次体の類数、単数基準などの計算には、quad一族、qfb一族を使う.quaddisc(x). . . . . .Q(
√x)の判別式を返す.
2.2.1 qfbclassno()
qfbclassno(x). . . . . .Q(√
x) の判別式を返す(Shanks のアルゴリズム).負の判別式については、類群の exponent が小さい場合、誤った結果を返す事があるので注意が必要である.
9
2.2.2 qfbclassno()のデモ
? qfbclassno (-3299)
%10 = 27
qfbclassno (-3299,1) ……Euler積を使う%11 = 27
2.2.3 quadclassunit()
quadclassunit(x). . . . . .Q(√
x)のイデアル類群(Buchmann-McCarthyの sub exponentialアルゴリズムにより、Abel群としての構造と、二次形式の形での生成元)と、判別式が正の時は単数基準を返す.quadclassunit(x,,tech)のように、3つめのパラメータを指定する事ができる.techは 2つの正の実数を要素とするベクトル [c,d]で、計算時間と、計算に必要なメモリの送料に影響を及ぼす.計算速度を重視するなら d=bとする.GRH のもとで厳密な結果を得たい場合は、d=6とする.b としては、0.1から 2.0の範囲が妥当である.
2.2.4 quadclassunit()のデモ
? quadclassunit(-10^25-3)
time = 10,810 ms.
%20 = [491852207132, [245926103566, 2], [Qfb(7, 1,
357142857142857142857143), Qfb(13, 13, 192307692307692307692311)], 1]
結果は順に、[類数, 類群の巡回群の直和としての表示, 各巡回成分の生成元(二次形式として), 単数基準].
2.3 一般の代数体
一般の代数体の計算には nf一族、bnf一族を使う(big number field).
10
2.3.1 bnfinit()
bnfinit()は、引数として有理数係数の 1変数多項式をとり、その多項式の最小分解体に関するさまざまなデータ(整数底、類群、単数、単数基準その他)を、Buchmannの sub exponential algorithm[2, Chap. 6.5]で計算する.bnfinit()の必須の引数は 1つで、体を定義する有理数係数の多項式を指定する.例えば、x4 + 24x2 + 585x + 1791 = 0が定義する代数体K
を考えよう.
? T = x^4 + 24*x^2 + 585*x + 1791;
? bnf = bnfinit(T);
bnfinit()の返す結果は、多くの場合数十行以上に及ぶ巨大なベクトルなので、行末の;で端末への表示を抑制している.変数 bnfに格納された結果から、必要な情報を得るためには、いわゆる”member function”を用いる.C言語の構造体のメンバーを参照するのと同様の字面で、ピリオドから始まるメンバー関数を適用する.上記の例で、多項式 Tの分解体 bnfの類群を参照するには、bnf.clgp(classgroupの略)とする:
? bnf.clgp
%69 [4, [4], [[7, 4, 5, 6; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1]]]
この他、整数底、判別式、単数、単数基準などを得るためのメンバー関数が用意されている.これらの一覧は、?.で表示される:
? ?.
Member functions, followed by relevant objects
a1-a6, b2-b8, c4-c6 : coeff. of the curve. ell
area : area ell
bnf : big number field bnf, bnr
clgp : class group bnf, bnr
(以下略)
11
2.3.2 bnfinit()の引数 techについて
bnfinit()には、必須ではない引数 flagと techがある.flagは、0から 3までの自然数であり、bnfinit()が計算する不変量の種類と精度を指定する.例えば flag=1ならば、単数を厳密に計算する(かわりに、計算時間とメモリ量が増大する).flag=2ならば、単数を計算しない.詳細はマニュアルを参照の事.一方、techは、3成分の実数からなるベクトルで、計算速度と計算に必要なメモリ量に関係するのみならず、結果の正確さをコントロールする量である.tech=[c,c2,nrpid]とする.
• c2=cのとき、最も短時間で結果を返す.GRHよりも強い仮定の元での結果
• c2=12のとき、GRHの元で正しい結果を返す
cの適切な値は 0.1 ∼ 2.0で、デフォルトの値(techを指定しない場合)は c=c2=0.3である.nrpidは、類群の構造を決めるための素イデアルの間の関係式の計算をコントロールする量である.詳細はマニュアルを参照の事.
2.3.3 bnfcertify()
この関数は、bnfinit()の計算結果が、GRHを仮定せずに正しいか否かを判定する.bnfinit()の結果を引数として取り、それが無条件に正しい(GRHを仮定せずに正しい)とき、1を返す.そうでない場合、何らかのエラーメッセージを表示するか、無限ループに突入する.§2.3.2での bnfを検証してみよう:
? bnfcertify(bnf)
%14 = 1
よって、結果は無条件に正しい事が確かめられた.
12
2.4 gpの文法
基本的な文法を組み合わせるだけで、できることがぐっと増える.
2.4.1 複数の文
gpの入力をセミコロン;で括ることで、同時に複数の文を実行できる.
2.4.2 if文
■条件分岐:if()if(判定条件, 真の場合に実行する部分, 偽の場合に実行する部分)gpの構文は少し独特で、例えば C言語で if(cond){body;}と書くところを、上記のように、関数呼び出しのように(関数呼び出しについては下記 2.4.4参照)記述する.しかし、判定条件の部分が真ならば、「偽の場合に実行する部分」は評価されない.同様に、判定条件が偽ならば、「真の場合に実行する部分」は評価されない.例:? if(1, 1, 1/0)
%1 = 1
? if(1, 1/0, 1)
*** division by zero
関数呼び出しの場合は、呼び出し前に全ての引数が評価されるので、if()が関数ならば、先の例でも零除算例外が起きるはずである.
2.4.3 繰返し構文
■くりかえし:for()
for(変数の初期化, 上限, 実行する文)
13
例:? for(d=1,100,if(isfundamental(d), h=qfbclassno(d);
if(Mod(h,3)==Mod(0,3),print(d, ", ", h))))
■総和関数:sum()
sum(X=a,b,expr,x=0) 変数Xを含む式 exprを、X = aからX = bまで評価し、xに足した値を返す.例:? sum(n=1,100,1/n^2)+.0
%2 = 1.634983900184892865077169498
この例では、∑100
n=1 1/n2を計算し(この時点では結果は有理数)、0.0を足す事で実数に変換している.π2/6 = 1.644934066848226436472415167...sum()は他にいくつかバリエーションがある.交代和を計算するsumalt(),自然数の約数に渡る和を計算する sumdiv()など.
2.4.4 関数定義
■関数定義の仕方:funcname(arg1, arg2, ...) =
{local(v1, v2, ...);
関数の実体}
GPでは、変数は基本的に大域変数である.一度値を割り当てられた変数は、プログラムの全体で可視となる.local()は関数の本体の中でのみ使える特殊な関数で、その中に宣言されている変数を、関数に局所化する働きを持つ.上記の例だと、local()
宣言によって、v1, v2 は、関数 funcname() 内に局所化される.関数funcname()の外に同じ名前の変数 v1, v2があったとしても、それとは無関係となる.定義した関数を呼び出すには、引数とともに関数名を書けば良い.
14
2.4.5 例
H(3, N) = L(1− 3, χD)× simple factorを計算する(−N = Df2).正確な定義は以下の通り:自然数 r と N ∈ Zに対して、(−1)rN = Df2,Dは二次体の判別式、とする.この時、Cohen [1]が定義した一般化類数H(r,N)は、
H(r,N) =
ζ(1− r) (N = 0),
L(1− r, χD)∑
d|f µ(d)χD(d)dr−1σ2r−1
(fd
)(N ≡ 0, 1(mod 4)),
0 otherwise,
ここで、ζ(s)はRiemannゼータ関数で、負の整数点での値はBernoulli数で与えられる.基本判別式Dに対して χD(·) は Legendre記号、L(s, χD)は χDに関するDirichlet L関数.負の整数点での値は、一般化 Bernoulli数で与えられる.µ(·)はMobius関数、σk(·)は約数の k乗和.ここでは、上の定義から直接計算するのではなく、Cohen(同論文)による
H(3, N) =−1126
∑s
s2(N − s2)
を使う.ただし、s2(0) = 1/2,
s2(n) =∑
d|n
((n
d
)2− 2d2
)χ−4(d), (n > 0).
関数 s2(n)をGPで書くと、以下のようになる.χd(a)が kronecker(d,a)
となる:
s2(n) =
{
if (n < 0, error("in s2(), arguments < 0"));
if (n > 0,
sumdiv(n, d, ((n/d)^2 - 2*d^2)*kronecker(-4,d)),
1/2)
}
15
error()は、ユーザ定義のエラーを発生させる.プログラムの実行をその時点で中断し、引数の文字列を表示する.関数H(3, N)を、上の s2(n)を使って書くと、以下の h3(N) のようになる:
h3(N) =
{
local(s);
s = s2(N) + 2 * sum(s=1, sqrt(N), s2(N-s^2));
(-1/126)*s
}
3 その他の話題
3.1 Pari-gpのコンパイル
Unix互換環境では、Pari-gpをソースコードからコンパイルすることも簡単である.自前でコンパイルすると、CPUに応じた最適化が可能であったり、多倍長計算ライブラリをGMPにしたり、グラフィックライブラリにQtやGNUplotを使うように指定できたり、といった利点がある.コンパイルの手続きを簡単に述べる.Pari-gpのソースコード一式を、
[4]に記載の web pageから手に入れる.展開すると、Configureというスクリプトが同梱されているので、それを実行すると、環境に合わせてソースコード一式を整えてくれるので、make一発である.rootになって、make installすると、データファイルやマニュアル類も含めて、然るべき場所にインストールされる(下記の/some/whereというのは、Pari-gpのソースが展開されているディレクトリ).
$ ./Configure
$ make all && make bench
$ su -
# cd /some/where/; make install
16
開発中の最新版を入手する事もできる.まず、コンパイルしようとしている環境に、CVS(というバージョン管理システム3)がインストールされている事を確認する.インストールされていなければ、バイナリパッケージなどから適宜導入しておく.開発版のPari-gpのソースを展開したいディレクトリへ移動する.shellのコマンドラインから、次のように入力:
$ cvs -d :pserver:[email protected]:/home/cvs login
パスワードを聞かれるが、単にリターンキーを押すのみで良い.
$ cvs -z3 -d :pserver:[email protected]:/home/cvs co pari
現在のディレクトリに pariというディレクトリが作成され、そこに開発中の最新版の Pari-gpのソースコードが展開される.コンパイルの仕方は、上述のとおり.ただし、最新版には、最新版のバグが含まれる事があるので、注意が必要である.
3.2 初期設定ファイル
.gprcというファイルを、自分のホームディレクトリに用意しておくと、gpの起動時に自動的に読み込まれる.Pari-gpのソースファイルを展開すると、misc/gprc.dftというファイルがあるので、これを /.gprcへコピーし、必要に応じて編集する.起動時に割り当てる pari stackの大きさや、あらかじめ計算しておく素数の上限などの設定の他、よく使う自前の関数定義などを書いておくと、手間が省ける.行頭に連続する 2つのバックスラッシュがあると、その行の最後までがコメントとなり、gpはその行を無視する.以下の例では、起動時に割り当てる pari stackのサイズを 10M bytesに、素数のリストを 106 まで計算し、各計算毎に消費した時間を表示するように設定する:
3http://www.cvshome.org/
17
\\ Stack size : 10^7 Bytes.
parisize = 10M
\\ Biggest precomputed prime (= prevprime(10^6))
primelimit = 1M
\\ Set timer on
timer = 1
3.3 C言語とPariライブラリによる開発
「仙台数論小セミナー 2000および仙台数論小研究集会 2000報告集」、2001年 2 月発行、所収の筆者の記事「Computer Aided Number Theory—Introduction to Pari—」をご参照頂きたい.
3.4 GP2C —GPからCへのトランスレータ—
GP2Cは、ボルドー大のBill Allombert氏が開発を進めている、GPからC言語へのトランスレータである.出力されたC言語のプログラムを、ダイナミックリンクライブラリーにコンパイルし、gpにダイナミックリンクして使う.
3.4.1 GP2Cのインストール
GP2Cは、今のところPari-gpに同梱されていない.gp2cのソースコード一式をhttp://pari.math.u-bordeaux.fr/pub/pari/GP2C/
から取得するか、CVSで最新のソースツリーをチェックアウトするかして、自分でビルドするしかない.後者からコンパイルするには、autoconf,automake, などの開発ツールが必要である.
18
まず、Pari-gpのソースツリーが展開してあるディレクトリに移動する(ソースが展開されていなければ、展開しておく.できればCVSにより取得した最新版がよい.§3.1参照).次に、gp2cのソースコードを展開する.上記のURLからソースコードを取得した場合は、それを展開する.CVSで最新版を取得する場合は、
$ cvs -d :pserver:[email protected]:/home/cvs login
(パスワードを聞かれるが、単にリターンキーを押すのみで良い).
$ cvs -z3 -d :pserver:[email protected]:/home/cvs co gp2c
とすると、現在いるディレクトリの下に、gp2cというディレクトリが作成され、その下に gp2cのソースコード一式が展開される.そこへ移動して(下記の/some/whereは、gp2cのソースコード一式が展開してあるディレクトリ)、
$ ./cvsinit
$ ./configure && make
$ su -
# cd /some/where
# make install
のようにして、gp2cをインストールする.
3.4.2 GP2Cの使い方
gp2cは、引数として与えられた GPのプログラムファイルを、Cのプログラムファイルへと変換し、標準出力へ吐き出すので、標準出力をリダイレクトしてファイルに保存する.ここでは、sample.gpというGPのプログラムファイルがあるとする.この例は、2から uptoの範囲で dを動かし、Q(
√−d)の類数が 3で割り切れるものの個数 cを出力するものである.プログラムの中の:intという接尾子は、変数が整数型であることを明示するもので、gpは現在のところ、無視する(upto:intと uptoは同
19
じ変数とみなされる).しかし、gp2cはこの指定を理解し、変数の間の四則や比較などの際に、より効率の良い関数を適用するコードを出力する.
$ cat sample.gp
f(upto:int) =
{
local(c:int, d:int, h);
c = 0;
for(d=2,upto, if(isfundamental(-d), h=qfbclassno(-d);\
if(Mod(h,3)==Mod(0,3), c++)));
c
}
$ gp2c -g sample.gp > sample.gp.c
上記で gp2cに与えられているオプション-gは、メモリ管理の為のコードも出力するよう指示するものである.sample.gp.cの冒頭に、
/*-*- compile-command: "/usr/bin/gcc -c -o sample.gp.o -O3
-DGCC_INLINE -Wall -fno-strict-aliasing -fomit-frame-pointer
-I/usr/local/include sample.gp.c && /usr/bin/gcc -o sample.gp.so
-shared -O3 -DGCC_INLINE -Wall -fno-strict-aliasing
-fomit-frame-pointer -Wl,-shared sample.gp.o -lc -lm -L/usr/local/lib
-lgmp -L/usr/local/lib -lpari"; -*-*/
のように、sample.gp.ccをコンパイルする為のコマンドの指示(これは当然コンパイルする環境によって異なる)があるので、その通りに入力して、ダイナミックリンクライブラリを得る:
$ /usr/bin/gcc -c -o sample.gp.o -O3 \
-DGCC_INLINE -Wall -fno-strict-aliasing -fomit-frame-pointer \
-I/usr/local/include sample.gp.c && /usr/bin/gcc -o sample.gp.so \
-shared -O3 -DGCC_INLINE -Wall -fno-strict-aliasing \
20
-fomit-frame-pointer -Wl,-shared sample.gp.o -lc -lm -L/usr/local/lib \
-lgmp -L/usr/local/lib -lpari
$ ls sample.gp.so
sample.gp.so*
この sample.gp.soを、gpに動的にリンクすれば、上記の関数 f()が使えるようになる.そのための install()関数(これは、gpにダイナミックリンクライブラリから関数を導入する gpの組み込み関数である)への引数も、sample.gp.cの冒頭にかいてある:
/*
GP;install("f","G","f","./sample.gp.so");
GP;install("init_sample","v","init_sample","./sample.gp.so");
*/
gpを起動して、このとおりに入力すれば良い:
? install("f","G","f","./sample.gp.so");
? install("init_sample","v","init_sample","./sample.gp.so");
? f
f: installed function
上記のように、f()の説明を求めると、installed functionと表示されれば、無事に使えるようになっている.
gp2cにより C言語に変換して効率が良くなるのは、例えば、何重かに渡るループを含むようなプログラムである.gpの処理系では、残念ながらこう言った処理が十分に洗練されていない.
gp2cには、その他いくつかの機能があるが、それについては同梱のドキュメントに譲る.
おわりに
北陸数論研究集会にお力添えを賜わりました皆様に御礼申し上げます.報告集の編集に手間取り、出版が遅れてしまいました事をこの場をお借り
21
してお詫び申し上げます.
参考文献
[1] Henri Cohen, Sums involving the values at negative integers of L-functions of quadratic characters, Math. Ann. 217 (1975), no. 3,271–285. MR 52 #3080
[2] , A course in computational algebraic number theory,Springer-Verlag, Berlin, 1993. MR 94i:11105
[3] , Advanced topics in computational number theory, Springer-Verlag, New York, 2000. MR 1 728 313
[4] The PARI Group, Bordeaux, PARI/GP, Version 2.2, 2004, availablefrom http://pari.math.u-bordeaux.fr/.
〒 930-8555 富山市五福 4548富山大学理学部
22