Asir

Asir User’s Manual Edition 2.0 for Asir-940420

May 1994

by Masayuki Noro and Takeshi Shimoyama

第 1 章: Introduction 1

1 Introduction

1.1 マニュアルの構成

このマニュアルの構成は次の通りである.

1. Introduction

マニュアルの構成および notation

2. Risa/Asir

Asir の概要, インストレーション

3. 型

Asir における型

4. ユーザ言語 Asir

Asir のユーザ言語の解説

5. デバッガ

ユーザ言語のデバッガの解説

6. 組み込み函数

さまざまな組み込み函数の詳細

7. グレブナ基底の計算

グレブナ基底に関する函数, 演算の解説

8. 代数的数に関する演算

代数的数に関する函数, 演算の解説

9. 付録

文法の詳細, パソコン版 Risa/Asir, サンプルファイルの紹介, 文献

1.2 Notation

このマニュアルでは, いくつかの記法上の慣習がある. それらについて説明する.

• 函数名は, タイプライタ体で表される.

gcd(), gr()

• 函数の説明における函数の引数は, 斜字体で表される.

int, poly

• ファイル名は, シングルクォートつきのタイプライタ体で表される.

‘dbxinit’, ‘asir_plot’

• 例は字下げされ, タイプライタ体で表される.

     [0] 1;
     1
     [1] quit;

• 文献の参照は, [] つきのタイプライタ体で表される.

[Boehm,Weiser]

第 1 章: Introduction 2

• 函数の引数で, 省略可能なものは, [] で囲って示される. また, 0 個以上の繰り返しは, []* で示される.

  setprec([n]), diff(rat[,varn]*)

• shell (csh) のプロンプトは % で表される. ただし, インストール時など, root として作業している場合

のプロンプトは # で表される.

       % cat afo
       afo
       bfo
       % su
       Password:XXXX
       # cp asir /usr/local/bin
       # exit
       %

• 有理整数環は Z, 有理数体は Q, 実数体は R, 複素数体は C で表す.

第 2 章: Risa/Asir 3

2 Risa/Asir

2.1 Risa および Asir

Risa は, 富士通情報研で開発中の数式処理システム/ライブラリの総称である. Risa の構成は次の通りである.

• 基本演算部

これは, Risa の内部形式に変換されたオブジェクト (数, 多項式など) の間の演算を実行する部分であり, UNIX の ‘libc.a’ などと同様の, ライブラリとして存在する. エンジンは, C およびアセンブラで記述され, 後述する言語インタフェース Asir の基本演算部として用いられている一方, 数式計算を必要とするさまざまなプログラム中にリンクして用いることができる.

• メモリ管理部

Risa では, メモリ管理部として, [Boehm,Weiser] によるフリーソフトウェアを用いている. これはガーベジコレクション (以下 GC と呼ぶ) を自動的に行うメモリ割り当て機構を持ち, Risa の各部分はすべてこれにより必要なメモリを得ている.

• Asir

Asir は, Risa の計算エンジンの言語インタフェースの一つである. Risa では, 比較的容易にユーザ用の言語インタフェースを作ることができる. Asir はその一つの例として作ったもので, C 言語に近い文法をもつ. また, C のデバッガとして広く用いられている dbx 風のデバッガも備えている.

2.2 Asir の特徴

Asir は, 前述の通り, 計算エンジンの言語インタフェースの一つである. 通常 ‘asir’ という名前の実行可能ファイルとして提供される. 現在サポートされている機能は概ね次の通りである.

• C 言語風のユーザ言語

• 数, 多項式, 有理式の加減乗 (除)

• ベクトル, 行列の演算

• 最小限のリスト処理

• 組み込み函数 (因数分解, GCD など)

• ユーザ定義函数によるツール (グレブナ基底など)

• dbx 風のデバッガ

• 陰函数の描画

• PARI (第 6.1.10 節 [pari], 31 ページ参照) による初等超越函数を含む式の評価

2.3 インストレーション

ソースファイルからのインストレーションは, Installation Manual を参照. ここではバイナリ形式のファイルをインストールする場合の手続きについて述べる.

以下の手続きで不明な点, 不都合な点があった場合の問い合わせは

noro@iias.flab.fujitsu.co.jp

宛に e-mail でお願いします.

2.3.1 UNIX 版

提供されているファイルとしては,

‘asir.gz’ Asir 本体

‘asir_ping.gz’

通信テスト用プログラム

‘asir_plot.gz’

陰函数描画用プログラム

‘asir.o.gz’

バイナリ函数追加用ファイル

‘asirlib.tar.gz’

ユーザ定義函数ファイル, help 用ファイル

の 5 つがある. このうち ‘asir_ping.gz’ は必須ではない. また, ‘asir.o.gz’ は, C で記述した函数を追加

した Asir を作るためのもので, やはり必須ではない. これらは全て gzip で圧縮してあるので, 入手後 gzip で展開する.

# gzip -dc asir > /usr/local/bin/asir
# gzip -dc asir_plot > /usr/local/bin/asir_plot
# chmod 755 /usr/local/bin/asir /usr/local/bin/asir_plot
‘asir’, ‘asir_plot’, ‘asir_ping’ は, ‘/usr/local/bin’ などのコマンドディレクトリあるいは個人的に

使用する場合には, ‘$HOME/bin’ などに置く.

‘asirlib.tar.gz’ の中のファイルは, デフォルトでは ‘/usr/local/lib/asir’ というディレクトリに置

かれる.

# mkdir /usr/local/lib/asir
# gzip -dc asirlib.tar.gz | ( cd /usr/local/lib/asir; tar xf - )

もし, 異なるディレクトリに置く場合には, そのディレクトリの名前を環境変数 ASIR_LIBDIR に設定する必要がある.

% mkdir $HOME/lib/asir
% gzip -dc asirlib.tar.gz | ( cd $HOME/lib/asir; tar xf - )
% setenv ASIR_LIBDIR $HOME/lib/asir

ライブラリをインストールしたら, ライブラリディレクトリから ‘asir’ に ‘asir_symtab’ という名前でシンボリックリンクを作る.

# cd /usr/local/lib/asir
# ln -s /usr/local/bin/asir asir_symtab

この状態で ‘asir’ を起動してみる.

     % /usr/local/bin/asir
     asir_key not found.
     ID for this machine is XXXXXXXX.
     See the file ASIR_INSTALL to get the correct key.

すると, このようなメッセージが出て ‘asir’ は終了する. UNIX 版では, マシンごとに key と呼ばれる文字列が必要である. key を入手するためには,

     risa@iias.flab.fujitsu.co.jp

宛に,

     ASIR XXXXXXXX

という 1 行のみからなる e-mail を送ればよい. XXXXXXXX は表示された ID である. 折り返し

     YYYYYYYY YYYYYYYY YYYYYYYY

という形の 1 行のみからなる e-mail が届くので, この 1 行を含む ‘asir_key’ なるファイルをカレントディレクトリに作って ‘asir’ を起動してみる.

     % /usr/local/bin/asir
     This is Asir, Version 940420.
     Copyright (C) FUJITSU LABORATORIES LIMITED.
     3 March 1994. All rights reserved.
     [0]

このようなプロンプトが出れば, 入手した key はそのマシンに対して有効である. key を書いておくファイルに関しては, 環境変数 ASIR_KEY の説明の項 (第 2.5 節 [環境変数], 7 ページ) で詳しく述べるが, ライブラリディレクトリにここで作成したファイル ‘asir_key’ を置けば, そのマシン上で全てのユーザが ‘asir’ を使用できるようになる. ‘asir_key’ には複数のマシンに対する key を書けるので, ライブラリディレクトリを共有している場合でも ‘asir_key’ に行を追加していけばよい.

     # cp asir_key /usr/local/lib/asir

2.3.2 Macintosh 版

提供されているファイルは次の 3 つである.

‘asir.sea’

CPU が 68020 以上で, 浮動小数演算機能をもつ Mac 用.

‘asir-sc.sea’

CPU が 68020 以上で, 浮動小数演算機能をもたない Mac 用.

‘asir-00.sea’

CPU が 68000 の Mac 用.

いずれもダブルクリックすると, フォルダが 1 つできる. このフォルダには Asir の実行可能ファイルと, ユーザ定義函数ファイルの入ったサブフォルダが入っている. Mac 版は key は必要ないので, このまま起動でき

る. 詳しくは, 付録 B [Macintosh 版 Risa/Asir], 88 ページ参照.

2.3.3 DOS 版

提供されているファイルは,

‘asir.lzh’

Asir 本体

‘asirlib.lzh’

ユーザ定義函数ファイル

‘go32.lzh’

IBM-PC, PC98, FM 用 ‘go32.exe’ V1.10

の 3 つである. これらは ‘lha.exe’ により圧縮してあるので ‘lha.exe’ により解凍する.

     C> lha x asir
     C> lha x asirlib

DOS 版も key は必要ない. またデフォルトのライブラリディレクトリも設定されていないが, ASIR_LIBDIR および ASIRLOADPATH の設定は必須となる. DOS の場合, 環境変数の設定の仕方が UNIX と異なる.

ASIRLOADPATH に対しては, パスのデリミタは ‘;’ を用いる.

     C> set ASIR_LIBDIR=C:\usr\lib\asir
     C> set ASIRLOADPATH=.;C:\usr\noro\lib\asir

‘go32.exe’ がインストールされていない場合, ‘go32.exe’ のインストールおよび環境設定は必須である. また, ‘go32.exe’ のバージョンが古い場合, 既に組み込まれているデバイスドライバによっては go32 がメモリを確保できずに Asir の動作速度が極めて遅くなる (スワップし続ける) 場合がある. これは, Windows の DOS Window での動作でも同様である. V1.10 ではこのようなことはないようなので, 少なくとも V1.10 のものを使用することをお勧めする.

‘go32.lzh’ には,
‘go32-pc.exe’

IBM-PC clone 用

‘go32-98.exe’

PC98 用

‘go32-fm.exe’

FMR, FMTOWNS 用

‘emu387’ 387 エミュレーションモジュール

‘readme’ go32 の readme

が入っている. ‘go32-xx.exe’ のバージョンはいずれも 1.10 である. これらのいずれかを適当なコマンドディレクトリに ‘go32.exe’ として置く. さらに, 環境変数 GO32TMP および GO32 を正しく設定する. これ

らについては go32 の ‘readme’ 参照.

C> set GO32TMP=C:\tmp
C> set GO32=ansi

特に, 80387 がない, あるいは浮動小数点演算機能のない 486 マシンでは, ‘emu387’ を用いることが必須となる. これは

C> set GO32=emu C:\usr\djgpp\lib\emu387

などと指定する. これについても ‘readme’ 参照. これ以降の操作および DOS 版 Asir の制限事項などにつ

いては付録 C [MS-DOS/DOS-Extender 版 Risa/Asir], 90 ページ参照.

2.4 コマンドラインオプション

コマンドラインオプションは次の通り.

-heap number

Risa/Asir では, 4KB のブロックをメモリ割り当ての単位として用いている. デフォルトでは, 初期 heap として, 16 ブロック (64KB) 割り当てるが, それを変更する場合, -heap を用いる. 単位はブロックである. heap の大きさは, heap() 函数で調べることができる (単位はバイト).

-adj number

GC で回収されたメモリの量が, 1/number 以下の場合に, メモリ管理部は heap を伸ばす. デフォルトでは 4 である. メモリ量の制限のため, heap をなるべく伸ばさずに, GC を主体にしてメモリ管理したい場合には, この値を大きく (例えば 16) 設定する.

-norc  初期化ファイル ‘$HOME/.asirrc’ を読まない.
-paristack number

PARI (第 6.1.10 節 [pari], 31 ページ参照) 専用の領域の大きさを指定する. 単位はバイト. デ

フォルトでは 1 MB ( MSDOS マシンおよび Macintosh では 64 KB ).

2.5 環境変数

Asir の実行に関するいくつかの環境変数が存在する.

• ASIR_KEY

UNIX 版では, Asir が起動されたマシンに対する key がなければそのマシン上で Asir は動作しない. key は 16 進 8 桁 3 ワードからなり,

% cat asir_key
cf6f236c 61a35091 dddc4529 geisha
82281685 d1929945 a8bd24ca yorktown
34b75d30 63f8df93 3e881113 nyanchu

という形で複数台のマシンに対する key を一つのファイルにまとめて書くことができる. key の後ろは無視されるので, コメントを書くことができる. key を含むファイルは, 以下の順でサーチされる.

1. 環境変数 ASIR_KEY に指定されたファイル

2. カレントディレクトリの ‘asir_key’

3. 環境変数 ASIR_LIBDIR で指定されたディレクトリ (指定がなければ ‘/usr/local/lib/asir’)
の ‘asir_key’

  • ASIR_LIBDIR

Asir のライブラリディレクトリ, すなわちユーザ言語で書かれたファイルなどがおかれるディレクトリ. 指定がない場合 ‘/usr/local/lib/asir’ が用いられる. バイナリを個人のディレクトリにインストールする場合など, この環境変数を適当に設定することになる.

  • ASIRLOADPATH

ロードされるファイルがあるディレクトリを ‘:’ (DOS 上では ‘;’) で区切って並べる. ディレクトリは左から順にサーチされる. この指定がない場合, および指定されたファイルが ASIRLOADPATH になかった場合, ライブラリディレクトリもサーチされる.

2.6 起動から終了まで

Asir を起動すると, 著作権などの表示のあと

     [0]

なるプロンプトが表示され, セッションが開始する. ‘$HOME/.asirrc’ が存在している場合, このファイルを Asir ユーザ言語でかかれたファイルと見なし, 解釈実行する.

プロンプトは入力の番号を表す. セッションは, end; または quit; を入力することにより終了する. 入力は, ‘;’ または ‘$’ までを一区切りとして評価される. ‘;’ のとき結果は表示され, ‘$’ のとき表示されない.

     % asir
     [0] A;
     0
     [1] A=(x+y)^5;
     x^5+5*y*x^4+10*y^2*x^3+10*y^3*x^2+5*y^4*x+y^5
     [2] A;
     x^5+5*y*x^4+10*y^2*x^3+10*y^3*x^2+5*y^4*x+y^5
     [3] a=(x+y)^5;
     evalpv : invalid assignment
     return to toplevel
     [3] a;
     a
     [4] fctr(A);
     [[1,1],[x+y,5]]
     [5] quit;
     %

この例では, A, a, x, y なる文字が使用されている. A はプログラムにおける変数で, a, x, y は数学的な意味での不定元である. 一般にプログラム変数は大文字で始まり, 不定元は小文字で始まる. この例でわかるように, プログラム変数は, 数, 式などを格納しておくためのものであり, C 言語などにおける変数に対応する. 一方, 不定元はそれ自身で値を持つことはできず, 従って, 不定元に対する代入は許されない. 後に示すが, 不定元に対する代入は, 組み込み函数 subst() により明示的に行われる.

2.7 割り込み

計算を実行中に割り込みをかけたい場合, 割り込みキャラクタ (通常は^C, DOS 版では ^X, Mac 版では

command+‘.’ ) を入力する.

     @ (x+y)^1000;
     ^Cinterrupt ?(q/t/c/d/w/?)

各選択肢の意味は次の通り.

q Asir を終了する. (確認あり) t トップレベルに戻る. (確認あり) c 実行を継続する. d 次の Asir プログラムの文の先頭でデバッグモードに入る. ユーザ定義函数の中の文に対しての

み有効である. 基本演算部内の函数 (加減乗除, 因数分解など) を実行中の場合には, デバッグモードに入るまで, 長時間を要する場合も有り得る. デバッガに関しては第 5 章 [デバッガ], 23 ページ参照.

w 中断点までの函数の呼び出し列を表示する. ? 各選択肢の意味を説明する.

2.8 エラー処理

組み込み函数に不正な型の引数を渡した場合などには実行が中断されるが, ユーザ函数の中でエラーが起きた場合にはトップレベルに戻る前に自動的にデバッグモードに入る. この状態でエラーの場所, 直前の引数の値などを調べることができる. 表示されるエラーメッセージはさまざまであり, 内部の函数名に引き続いてメッセージが表示される. これは, 呼び出された組み込み函数と必ずしも対応はしない.

その他, さまざまな原因により内部演算函数においてエラーが生ずることがある. UNIX 版の場合, これは次のいずれかの internal error として報告され, 通常のエラーと同様に扱って, デバッグモードに入る.

SEGV
BUS ERROR

組み込み函数によっては, 引数の型を厳密にチェックせずに演算ルーチンに引き渡してしまうものも存在している. このような状況において, 不正なポインタ, あるいは NULL ポインタによるアクセス違反があった場合, これらのエラーとなる.

BROKEN PIPE

プロセス間通信において, 相手先のプロセスとの間のストリームが既に存在していない場合 (例えば既に相手先のプロセスが終了している場合など) に, そのストリームに入出力しようとした場合にこのエラーとなる.

UNIX 版では, signal() によるこれらのエラーの捕捉が可能のためプロセスは終了しないが, DOS/go32 版, Macintosh 版などは, プログラム自体が終了してしまう. これは現在のパソコン版における欠点であるが, この欠点を除くためには, 組み込み函数の入口において, 引数を完全にチェックすることが必要であり, 相当な手直しが必要である.

2.9 計算結果, 特殊な数

@ はエスケープ文字として使用される. 現在次のような規定がある.

@n n 番目の計算結果.

@@ 直前の計算結果. @i 虚数単位. @pi 円周率. @e 自然対数の底.

[0] fctr(x^10-1);
[[1,1],[x-1,1],[x+1,1],[x^4+x^3+x^2+x+1,1],[x^4-x^3+x^2-x+1,1]]
[1] @@[3];
[x^4+x^3+x^2+x+1,1]
[2] eval(sin(@pi/2));
1.000000000000000000000000000000000000000000000000000000000
[3] eval(log(@e),20);
0.99999999999999999999999999998
[4] @0[4][0];
x^4-x^3+x^2-x+1
[5] (1+@i)^5;
(-4-4*@i)
[6] eval(exp(@pi*@i));
-1.0000000000000000000000000000

トップレベルで計算された値はこのようにヒストリとして取り出し可能であるが, このことは, ガベージコレクタにとっては負担をもたらす可能性がある. 特に, 大きな式をトップレベルで計算した場合, その後の GC 時間が急速に増大する可能性がある.

第 3 章: 型 11

3 型

3.1 Asir で使用可能な型

Asir においては, 可読な形式で入力されたさまざまな対象は, パーザにより中間言語に変換され, インタプリタにより Risa の計算エンジンを呼び出しながら内部形式に変換される. 変換された対象は, 次のいずれかの型を持つ. 各番号は, 組み込み函数 type() により返される値に対応している. 各例は, Asir のプロンプトに対する入力が可能な形式のいくつかを示す.

0  0

実際には 0 を識別子にもつ対象は存在しない. 0 は, C における 0 ポインタにより表現されて

いる. しかし, 便宜上 Asir の type(0) は値 0 を返す.

1  数
     1 2/3  14.5  3+2*@i

数は, さらにいくつかの型に分けられる. これについては下で述べる.

2 多項式 (数でない)

     x  afo  (2.3*x+y)^10

多項式は, 全て展開され, その時点における変数順序に従って, 再帰的に 1 変数多項式として降冪の順に整理される (第 7.1 節 [分散表現多項式], 64 ページ参照). この時, その多項式に現れる順序最大の変数を主変数と呼ぶ. また, 多項式の, 主変数に関する最大次数の項の係数を主係数と呼ぶ.

3 有理式 (多項式でない)

     (x+1)/(y^2-y-x)  x/x

有理式は, 分母分子が約分可能でも, 明示的に red() が呼ばれない限り約分は行われない. これは, 多項式の GCD 演算が極めて重い演算であるためで, 有理式の演算は注意が必要である.

4 リスト

     []  [1,2,[3,4],[x,y]]

リストは読み出し専用である. [] は空リストを意味する. リストに対する操作としては, car(), cdr(), cons() などによる操作の他に, 読み出し専用の配列とみなして, [index] を必要なだけつけることにより要素の取り出しを行うことができる. 例えば

     [0] L = [[1,2,3],[4,[5,6]],7]$
     [1] L[1][1];
     [5,6]

注意すべきことは, リスト, 配列 (行列, ベクトル) 共に, インデックスは 0 から始まることと, リストの要素の取り出しをインデックスで行うことは, 結局は先頭からポインタをたどることに相当するため, 配列に対する操作に比較して大きなリストでは時間がかかる場合があるということである.

5 ベクトル

     newvect(3)  newvect(2,[a,1])

ベクトルは, newvect() で明示的に生成する必要がある. 前者の例では 2 成分の 0 ベクトルが生成され, 後者では, 第 0 成分が a, 第 1 成分が 1 のベクトルが生成される. 初期化のための第 2 引数は, 第 1 引数以下の長さのリストを受け付ける. リストの要素は左から用いられ, 足りない分は 0 が補われる. 成分は [index] により取り出せる. 実際には, 各成分に, ベクトル, 行列, リストを含む任意の型の対象を代入できるので, 多次元配列をベクトルで表現することができる.

     [0] A3 = newvect(3);
     [ 0 0 0 ]
     [1] for (I=0;I<3;I++)A3[I] = newvect(3);
     [2] for (I=0;I<3;I++)for(J=0;J<3;J++)A3[I][J]=newvect(3);
     [3] A3;
     [ [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ]
     ] [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] ]
     [4] A3[0];
     [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ]
     [5] A3[0][0];
     [ 0 0 0 ]

6 行列

     newmat(2,2)  newmat(2,3,[[x,y],[z]])

行列の生成も newmat() により明示的に行われる. 初期化も, 引数がリストのリストとなることを除いてはベクトルと同様で, リストの各要素 (これはまたリストである) は, 各行の初期化に使われ, 足りない部分には 0 が埋められる. 行列も, 各要素には任意の対象を代入できる. 行列の各行は, ベクトルとして取り出すことができる.

     [0] M=newmat(2,3);
     [ 0 0 0 ]
     [ 0 0 0 ]
     [1] M[1];
     [ 0 0 0 ]
     [2] type(@@);
     5

7 文字列

     ""  "afo"

文字列は, 主にファイル名などに用いられる. 文字列に対しては加算のみが定義されていて, 結果は 2 つの文字列の結合である.

     [0] "afo"+"take";
     afotake

8 構造体

     newstruct(afo)

構造体に関しては, 章を改めて解説する予定である.

9 分散表現多項式

     2*<<0,1,2,3>>-3*<<1,2,3,4>>

これは, ほとんどグレブナ基底専用の型で, 通常の計算でこの型が必要となることはまずないが, グレブナ基底計算パッケージ自体がユーザ言語で書かれているため, ユーザが操作できるよう独立した型として Asir で使用できるようにしてある. これについては第 7 章 [グレブナ基底の計算], 64 ページ参照.

3.2 数の型

0 有理数

有理数は, 任意多倍長整数 (bignum) により実現されている. 有理数は常に既約分数で表現される.

1 倍精度浮動小数

マシンの提供する倍精度浮動小数である. Asir の起動時には, 通常の形式で入力された浮動小数はこの型に変換される. ただし, ctrl() により bigfloat が選択されている場合には bigfloat に変換される.

     [0] 1.2;
     1.2
     [1] 1.2e-1000;
     0
     [2] ctrl("bigfloat",1);
     1
     [3] 1.2e-1000;
     1.20000000000000000513 E-1000

倍精度浮動小数と有理数の演算は, 有理数が浮動小数に変換されて, 浮動小数として演算される.

2 代数的数

第 8 章 [代数的数に関する演算], 76 ページ参照.

3 bigfloat bigfloat は, Asir では PARI ライブラリにより実現されている. PARI においては, bigfloat

は, 仮数部のみ任意多倍長で, 指数部は 1 ワード以内の整数に限られている. ctrl() で bigfloat を選択することにより, 以後の浮動小数の入力は bigfloat として扱われる. 精度はデフォルトでは 10 進 9 桁程度であるが, setprec() により指定可能である.

     [0] ctrl("bigfloat",1);
     1
     [1] eval(2^(1/2));
     1.414213562373095048763788073031
     [2] setprec(100);
     9
     [3] eval(2^(1/2));
     1.41421356237309504880168872420969807856967187537694807317654396116148

eval() は, 引数に含まれる函数値を可能な限り数値化する函数である. setprec() で指定された桁数は, 結果の精度を保証するものではなく, PARI 内部で用いられる表現のサイズを示す

ことに注意すべきである. (第 6.1.9 節 [eval], 30 ページ, 第 6.1.10 節 [pari], 31 ページ参照)

4 複素数

複素数は, 有理数, 倍精度浮動小数, bigfloat を実部, 虚部として a+b*@i (@i は虚数単位) として与えられる数である. 実部, 虚部はそれぞれ real(), imag() で取り出せる.

3.3 不定元の型

多項式の変数となり得る対象を不定元とよぶ. Asir では, 英小文字で始まり, 任意個のアルファベット, 数字, ‘_’ からなる文字列を不定元として扱うが, その他にもシステムにより不定元として扱われるものがいくつかある. Asir の内部形式としては, これらは全て多項式としての型を持つが, 数と同様, 不定元の型により区別される.

0 一般不定元

英小文字で始まる文字列. 多項式の変数として最も普通に用いられる.

     [0] [vtype(a),vtype(aA_12)];
     [0,0]

1 未定係数

uc() は, ‘_’ で始まる文字列を名前とする不定元を生成する. これらは, ユーザが入力できないというだけで, 一般不定元と変わらないが, ユーザが入力した不定元と衝突しないという性質を利用して未定係数の自動生成などに用いることができる.

     [1] U=uc();
     _0
     [2] vtype(U);
     1

2 函数形式

組み込み函数, ユーザ函数の呼び出しは, 評価されて何らかの Asir の内部形式に変換されるが, sin(x), cos(x+1) などは, 評価後もそのままの形で存在する. これは函数形式と呼ばれ, それ自身が 1 つの不定元として扱われる. またやや特殊な例として, 円周率 @pi や自然対数の底 @e も函数形式として扱われる.

     [3] V=sin(x);
     sin(x)
     [4] vtype(V);
     2
     [5] vars(V^2+V+1);
     [sin(x)]

3 函数子

函数呼び出しは, fname(args) という形で行なわれるが, fname の部分を函数子と呼ぶ. 函数子には, 函数の種類により組み込み函数子, ユーザ定義函数子, 初等函数子などがあるが, 函数子は単独で不定元として機能する.

     [6] vtype(sin);

第 4 章: ユーザ言語 Asir 15

4 ユーザ言語 Asir

Asir の組み込み函数は, 因数分解, GCD などの計算を行うもの, ファイル入出力を行うもの, あるいは数式の一部を取り出すものなどさまざまなものが用意されているが, ユーザが実際に行いたいことを実行させるためには一般にはユーザ言語によるプログラムを書く必要がある. ユーザ言語も Asir と呼ばれる. 以下では, ユーザ言語の文法規則および実際のユーザ言語プログラムを例としたプログラムの書き方について述べる.

4.1 文法 — C 言語との違い

Asir の文法は C 言語に準拠している. 文法の詳細は, 付録 A [文法の詳細], 86 ページ参照. おもな相違点は次の通りである. 以下で, 変数とは Asir におけるプログラム用の変数, すなわち大文字で始まる文字列を意味することとする.

• 変数の型がない.

既に説明したとおり, Asir で扱われる対象自身は全て何らかの型を持っている. しかし, プログラム変数自体は, どのような対象でも代入できるという意味で型がないのである.

     [0] A = 1;
     1
     [1] type(A);
     1
     [2] A = [1,2,3];
     [1,2,3]
     [3] type(A);
     4

• 函数内の変数は, デフォルトでは仮引数をこめてすべて局所変数. ただし, extern 宣言された変数は, トップレベルにおける大域変数となる. すなわち, 変数のスコープは大域変数と局所変数の 2 種類に単純化されている. トップレベル, すなわちプロンプトに対して入力された変数は全て大域変数として登録される. また函数内では次のいずれかとなる.

1. 函数が定義されるファイルにおいて, その函数定義以前に, ある変数が extern 宣言されている場合, 函数内のその変数も大域変数として扱われる.

2. extern 宣言されていない変数はその函数に局所的となる.

     % cat afo
     def afo() { return A;}
     extern A$
     def bfo() { return A;}
     end$
     % asir
     [0] load("afo")$
     [5] A = 1;
     1
     [6] afo();
     0
     [7] bfo();
     1

• プログラム変数は大文字で始まり, 不定元, 函数は小文字で始まる.

この点は, 既存の数式処理システムのほとんどと異なる点である. Asir がこの仕様を採用したのは, ユーザが不定元のつもりで使用した変数になんらかの値が代入されていた場合に混乱を招く, という, 既存のシステムにありがちな状況を避けるためである.

  • switch 文, goto がない.

goto がないため, 多重ループを一度に抜けるのがやや複雑になる場合がある.

• コンマ式は, for (A;B;C) または, while(A) の A, B, C にのみ使うことができる.

これは, リストを正式なオブジェクトとして加えたことによる.

以上は制限であるが, 拡張としては次の点が挙げられる.

• 有理式に対する計算を, 通常の C における計算と同様にできる.

• リストが扱える.

構造体を用いるまでもない要素の集合体を, リストで表すことができ, C で直接書く場合に比較してプログラムが短く, 読みやすく書ける.

4.2 ユーザ定義函数の書き方

4.2.1 ユーザ定義函数

ユーザによる函数の定義は ‘def’ 文で行う. 文法エラーは読み込み時にチェックされ, おおよその場所が表示される. 既に (引数の個数に関係なく) 同名の函数が定義されている場合には, 再定義され,

     afo() redefined.

というメッセージが表示される. ある函数の定義において, まだ未定義の函数を呼び出していても, 定義時にはエラーにならない. 実行時に未定義の函数を呼び出そうとした場合にエラーとなる.

     /* X! */
     def f(X) {
         if ( !X )
             return 1;
         else
             return X * f(X-1);
     }

/* _{i}C_{j} ( 0 ≤ i ≤ N, 0 ≤ j ≤ i ) */

     def c(N)
     {
         A = newvect(N+1); A[0] = B = newvect(1); B[0] = 1;
         for ( K = 1; K <= N; K++ ) {
             A[K] = B = newvect(K+1); B[0] = B[K] = 1;
             for ( P = A[K-1], J = 1; J < K; J++ )
                 B[J] = P[J-1]+P[J];
             }
         return A;
     }

2 つ目の例では, 長さ N+1 のベクトル (Aとする) が返される. A[I] は長さ I+1 の配列であり, そのそれぞれの要素が_{I}C_{J} を要素とする配列である.

以下では, C によるプログラミングの経験がない人のために, Asir 言語によるプログラムの書き方を解説する.

4.2.2 変数および不定元

既に述べた通り, Asir においてはプログラム変数と不定元を明確に区別している.

変数大文字で始まり, アルファベット, 数字, ‘_’ からなる文字列変数あるいはプログラム変数とは, Asir のさまざまな型の内部形式を格納するための箱であり, 格納された内部形式が, この変数の値である. 変数が式の要素として評価される時は, そこに収められた値に置き換えられる. すなわち, 内部形式の中にはプログラム変数は現れない. 変数は全て 0 で初期化されている.

               [0] X^2+X+1;
               1
               [1] X=2;
               2
               [2] X^2+X+1;
               7

不定元小文字で始まり, アルファベット, 数字, ‘_’ からなる文字列不定元とは, 多項式環を構成する際に添加される変数をいう. Asir においては, 不定元は値をもたない超越的な元であり, 不定元への値の代入は許されない.

               [3] X=x;
               x
               [4] X^2+X+1;
               x^2+x+1

4.2.3 引数

     def sum(N) {
         for ( I = 1, S = 0; I <= N; I++ )
             S += I;
         return S;
     }

これは, 1 から N までの自然数の和を求める函数 sum() の定義である. この例における sum(N) の N が引数である. この例は, 1 引数函数の例であるが, 一般に引数の個数は任意であり, 必要なだけの個数を ‘,’ で区切って指定することができる. 引数は値が渡される. すなわち, 引数を受けとった側が, その引数の値を変更しても, 渡した側の変数は変化しない. ただし, 例外がある. それは, ベクトル, 行列を引数に渡した場合である. この場合も, 渡された変数そのものを書き替えることは, その函数に局所的な操作であるが, 要素を書き換えた場合, それは, 呼び出し側のベクトル, 行列の要素を書き換えることになる.

     def clear_vector(M) {
         /* M is expected to be a vector */
         L = size(M)[0];
         for ( I = 0; I < L; I++ )
             M[I] = 0;

     }

この函数は, 引数のベクトルを 0 ベクトルに初期化するための函数である. また, ベクトルを引数に渡すことにより, 複数の結果を引数のベクトルに収納して返すことができる. 実際には, このような場合には, 結果をリストにして返すこともできる. 状況に応じて使いわけすることが望ましい.

4.2.4 コメント

C と同様 ‘/*’ と ‘*/’ で囲まれた部分はコメントとして扱われる.

     /*
      * This is a comment.
      */
     def afo(X) {

コメントは複数行に渡っても構わないが, 入れ子にすることはできない. ‘/*’ がいくつあっても最初のもののみが有効となり, 最初に現れた ‘*/’ でコメントは終了したと見なされる. プログラムなどで, コメントを含む可能性がある部分をコメントアウトした場合には, #if 0, #endifを使えばよい. (第 4.2.10 節 [プリプロセッサ], 21 ページ参照)

     #if 0
     def bfo(X) {
     /* empty */
     }
     #endif

4.2.5 文

Asir のユーザ函数は,

     def 名前 (引数, 引数,..., 引数) {

文文

         ...

文

     }

という形で定義される. このように, 文は函数の基本的構成要素であり, プログラムを書くためには, 文がどのようなものであるか知らなければならない. 最も単純な文として, 単文がある. これは,

     S = sum(N);

のように, 式に終端記号 (‘;’ または ‘$’) をつけたものである. この単文及び類似の return 文, break 文などが文の最小構成単位となる. if 文や for 文の定義 (付録 A [文法の詳細], 86 ページ参照) を見ればわかる通り, それらの本体は, 単なる一つの文として定義されている. 通常は, 本体には複数の文が書けることが必要となる. このような場合, ‘{’ と ‘}’ で文の並びを括って, 一つの文として扱うことができる. これを複文と呼ぶ.

     if ( I == 0 ) {
         J = 1;
         K = 2;
         L = 3;
     }

‘}’ の後ろには終端記号は必要ない. なぜなら, ‘{’ 文並び ‘}’が既に文となっていて, if 文の要請を満たしているからである.

4.2.6 return 文
return 文は,
     return 式;
     return;

の 2 つの形式がある. いずれも函数から抜けるための文である. 前者は函数の値として式を返す. 後者では, 函数の値として何が返されるかはわからない.

4.2.7 if 文

if 文には

     if ( 式 )             if ( 式 )

文及び文

     else

文

の 2 種類がある. これらの動作は明らかであるが, 文の位置に if 文が来た場合に注意を要する. 次の例を考えてみよう.

     if ( 式 )
         if ( 式 ) 文
     else

文

この場合, 字下げからは, else 以下は, 最初の if に対応するように見えるが, パーザは, 自動的に 2 番目の if に対応すると判断する. すなわち, 2 種類の if 文を許したために, 文法に曖昧性が現れ, それを解消するために, else 以下は, 最も近い if に対応するという規則が適用されるのである. 従って, この例は,

     if ( 式 ) {
         if ( 式 ) 文 else 文
     }

という意味となる. 字下げに対応させるためには,

 if ( 式 ) {
     if ( 式 ) 文
 } else

文

としなければならない.

4.2.8 ループ, break, return, continue

ループを構成する文は, while 文, for 文, do 文の 3 種類がある.

• while 文

形式は,

     while ( 式 ) 文

で, これは, 式を評価して, その値が 0 でない限り文を実行するという意味となる. たとえば式が 1 ならば, 単純な無限ループとなる.

• for 文

形式は,

     for ( 式並び-1; 式; 式並び-2 ) 文

で, これは式並び-1 (を単文並びにしたもの)

     while ( 式 ) {

文

式並び-2 (を単文並びにしたもの)

     }

と等価である.

• do 文
     do {

文

     } while ( 式 )

は, 先に文を実行してから条件式による判定を行う所が while 文と異なっている.

ループを抜け出す手段として, break 文及び return 文がある. また, ループの制御をある位置に移す手段と

して continue 文がある.
• break

break 文は, それを囲むループを一つだけ抜ける.

• return

return 文は, 一般に函数から抜けるための文であり, ループの中からでも有効である.

• continue

continue 文は, ループの本体の文の末端に制御を移す. 例えば for 文では, 最後の式並びの実行を行い, while 文では条件式の判定に移る.

4.2.9 さまざまな式

主な式の構成要素としては, 次のようなものがある.

• 加減乗除, 冪冪は, ‘^’ により表す. 除算 ‘/’ は, 体としての演算に用いる. 例えば, 2/3 は有理数の 2/3 を表す. 整数除算, 多項式除算 (剰余を含む演算) には別途組み込み函数が用意されている.

     x+1  A^2*B*afo X/3

• インデックスつきの変数ベクトル, 行列, リストの要素はインデックスを用いることにより取り出せる. インデックスは 0 から始まることに注意する. 取り出した要素がベクトル, 行列, リストなら, さらにインデックスをつけることも有効である.

     V[0] M[1][2]

• 比較演算

等しい (‘==’), 等しくない (‘!=’), 大小 (‘>’, ‘<’, ‘>=’, ‘<=’) の 2 項演算がある. 真ならば有理数の 1,

偽ならば 0 を値に持つ.

• 論理式論理積 (‘&&’), 論理和 (‘||’) の 2 項演算と, 否定 (‘!’) が用意されている. 値はやはり 1, 0 である.

• 代入通常の代入は ‘=’ で行う. このほか, 算術演算子と組み合わせて特殊な代入を行うこともできる. (‘+=’,

‘-=’, ‘*=’, ‘/=’, ‘^=’)

A = 2 A *= 3 (これは A = A*3 と同じ; その他の演算子も同様)

• 函数呼び出し函数呼び出しも式の一種である.

• ‘++’, ‘--’

これらは, 変数の前後について, それぞれ次のような操作, 値を表す.

     A++ 値は元の A の値, A = A+1
     A-- 値は元の A の値, A = A-1
     ++A  A = A+1, 値は変化後の値
     --A  A = A-1, 値は変化後の値

4.2.10 プリプロセッサ

Asir のユーザ言語は C 言語を模したものである. C の特徴として, プリプロセッサ cpp によるマクロ展開, ファイルのインクルードがあるが, Asir においてもユーザ言語ファイルの読み込みの際 cpp を通してから読み込むこととした. これによりユーザ言語ファイル中で #include, #define, #if などが使える.

• #include

cpp に特に引数を渡さないため, インクルードファイルは, #include が書かれているファイルと同じディレクトリでサーチされる.

• #define

これは, C におけるのと全く同様に用いることができる.

• #if

/*, */ によるコメントは入れ子にできないので, プログラムの大きな部分をコメントアウトする際に,

#if 0, #endif を使うと便利である.

次の例は, ‘gr’ の先頭部分にあるマクロ定義である.

 #define FIRST(L) (L[0])
 #define SECOND(L) (L[1])

#define THIRD(L) (L[2])
#define FOURTH(L) (L[3])
#define FIFTH(L) (L[4])
#define HM(p) dp_hm(p)
#define RP(p) dp_rest(p)
#define HT(p) dp_ht(p)
#define CO(p) dp_hc(p)
#define TD(p) dp_td(p)
#define ZERO(p) (!(p))
#define LCM(l) THIRD(l)
#define CPSUGAR(l) FOURTH(l)
#define MAX(a,b) ((a)>(b)?(a):(b))
#define CPUTIME (time()[0])

構造体を用いずにリストで代用する場合, マクロによりリストの各要素に名前をつけることは, プログラムの可読性を高めることになる.

第 5 章: デバッガ 23

5 デバッガ

5.1 デバッガとは

C 言語で書かれたプログラムのためのデバッガ dbx は, ソースレベルでのブレークポイントの設定, ステップ実行, 変数の参照などが可能な強力なデバッガである. Asir では, dbx 風のデバッガを用意している. デバッグモードに入るには, トップレベルで debug; と入力する.

     [10] debug;
     (debug)

その他, 次の方法, あるいは状況でデバッグモードに入る.

• 実行中ブレークポイントに達した場合

• 割り込みで ‘d’ を選択した場合

• 実行中エラーを起こした場合この場合, 実行の継続は不可能であるが, 直接のエラーの原因となったユーザ定義函数の文を表示してデバッグモードに入るため, エラー時における変数の値を参照でき, デバッグに役立たせることができる.

• error() が呼び出された場合

5.2 コマンドの解説

コマンドは dbx のコマンドの内必要最小限のものを採用した. 実際の機能は dbx とほぼ同様であるが, step, next は, 次の行ではなく次の文を実行する. 従って, 1 行に複数の文がある場合は, その文の数だけ next を実行しなければ次の行に進めない. また, dbx と同様 ‘.dbxinit’ を読み込むので, dbx と同じ alias を使うことができる.

step 次の文を実行する. 次の文が函数を含むとき, その函数に入る. next 次の文を実行する. cont デバッグモードから抜け, 実行を継続する.

list [startline] list function

現在行, または startline, または function の先頭から 10 行ソースファイルを表示する.

print expr

expr を表示する.

func function

対象函数を function に設定する.

stop at sourceline [if cond] stop in function

sourceline 行目, または function の先頭にブレークポイントを設定する. ブレークポイントは, 函数が再定義された場合自動的に取り消される. if が続く場合, cond が評価され, それが 0 でない場合に実行が中断し, デバッグモードに入る.

delete n ブレークポイント n を取り消す.

第 5 章: デバッガ 24

status ブレークポイントの一覧を表示する. where 現在の停止点までの呼び出し列を表示する. quit デバッグモードを抜ける. 実行中は, cont と同様の効果を持つ.

print の引数として, トップレベルにおけるほとんどすべての式がとれる. 通常は, 変数の内容の表示が主であるが, 必要に応じて次のような使い方ができる.

• 変数の書き換え

実行中のブレークポイントにおいて, 変数の値を変更して実行を継続させたい場合, 次のような操作を行えばよい.

     (debug) print A
     A = 2
     (debug) print A=1
     A=1 = 1
     (debug) print A
     A = 1

• 函数の呼び出し

函数呼び出しも式であるから, print の引数としてとれる.

     (debug) print length(List)
     length(List) = 14

この例では, 変数 List に格納されているリストの長さを length() により調べている.

     (debug) print ctrl("cputime",1)
     ctrl("cputime",1) = 1

この例は, 計算開始時に CPU 時間の表示の指定をし忘れた場合などに, 計算途中でデバッグモードから指定を行えることを示している. また, 止むを得ず計算を中断しなければならない場合, デバッグモードから bsave() などのコマンドにより途中結果をファイルに保存することもできる.

     (debug) print bsave(A,"savefile")
     bsave(A,"savefile") = 1

デバッグモードからの函数呼び出しで注意すべきことは, その函数呼び出しでエラーが起こった場合, 元の函数の実行継続は不可能になるということである.

• トレース情報の表示

trace コマンドはまだインプリメントしていないが, stop if を用いることにより, ある時点における変数の値などを自動的に表示させることができる.

     [51] debug$
     (debug) list gb
     194     def gb(F,M,SUBST)
     195     {
     196             NFMOD = 0;
     197             if ( M ) {
     198                     PSM = newvect(PSLen);
     199                     for ( I = 0; I < PSLen; I++ )
     200                             if ( PSH[I] && !validhc(PS[I],M,SUBST) )
     201                                     return 0;
     202                             else
     203                                     PSM[I] = dp_mod(PS[I],M,SUBST);
     (debug) stop at 203 if (print(PSH[I]))
     (0) stop at "/usr/local/lib/asir/gr":203 if  (print(PSH[I]))
     (debug) quit

    [52] grm(cyclic(5),[c0,c1,c2,c3,c4]);
    (1)*<<1,1,1,1,1>>
    (1)*<<1,1,1,1,0>>
    (1)*<<1,1,1,0,0>>

print() は常に 0 を返すため, if の条件式が真になることはないが, print() は実行されるため, プレークポイントを通過するたびに値が表示されることになる.

5.3 デバッガの使用例

ここでは, 階乗を再帰的に計算させるユーザ定義函数を例として, デバッガの実際の使用法を示す.

% asir
[0] load("fac")$
[3] debug$
(debug) list factorial
1   def factorial(X) {
2       if ( !X )
3           return 1;
4       else
5           return X * factorial(X - 1);
6   }
7   end$
(debug) stop at 5                     <-- ブレークポイントの設定
(0) stop at "./fac":5
(debug) quit                          <-- デバッグモードを抜ける
[4] factorial(6);                     <-- factorial(6) の呼び出し
stopped in factorial at line 5 in file "./fac"
5           return X * factorial(X - 1);

(debug) where <-- ブレークポイントまでの呼び出し列の表示

factorial(), line 5 in "./fac"
(debug) print X                       <-- X の値の表示
X = 6
(debug) step                          <-- ステップ実行 (函数に入る)
stopped in factorial at line 2 in file "./fac"
2 if ( !X )
(debug) where
factorial(), line 2 in "./fac"
factorial(), line 5 in "./fac"
(debug) print X
X = 5
(debug) delete 0                      <-- ブレークポイント 0 の消去
(debug) cont                          <-- 実行継続
720                                   <-- 結果 = 6!
[5] quit;

5.4 デバッガの初期化ファイルの例

前に述べた通り, Asir は, 起動時に ‘$HOME/.dbxinit’ を読み込む. このファイルは, dbx のさまざまな初期設定用のコマンドを記述しておくファイルであるが, Asir は, alias 行のみを認識する. 例えば,

% cat ~/.dbxinit
alias n next
alias c cont
alias p print
alias s step
alias d delete
alias r run
alias l list
alias q quit

なる設定により, print, cont など, デバッグモードにおいて頻繁に用いられるコマンドが, それぞれ p, c など, 短い文字列で代用できる.

grm(La,[a,b,c]);
[M,99999989,EVAL,[]]
stopped in gb at line 196 in file "/usr/local/lib/asir/gr"
196             NFMOD = 0;
(debug) p F
F = [0,1,2]
(debug) c
[1,2,NFT,0.01,NB,2,NAB,4,RP,2,(1)*<<1,3,1>>]

第 6 章: 組み込み函数 27

6 組み込み函数

6.1 数の演算

6.1.1 idiv, irem
idiv(i1,i2)

:: 整数除算による商.

irem(i1,i2)

:: 整数除算による剰余.

return 整数 i1,i2 整数

• i1 の i2 による整数除算による商, 剰余を求める.

• i2 は 0 であってはならない.

• 被除数が負の場合, 絶対値に対する値にマイナスをつけた値を返す.

• i1 % i2 は, 結果が正に正規化されることを除けば irem() の代わりに用いることができる.

• 多項式の場合は sdiv, srem を用いる.

   [0] idiv(100,7);
   14
   [0] idiv(-100,7);
   -14
   [1] irem(100,7);
   2
   [1] irem(-100,7);
   -2
参照  sdiv, srem, %

6.1.2 fac

fac(i) :: i の階乗.

return 整数 i 整数

• i の階乗を計算する.

• i が負の場合は 0 を返す.

   [0] fac(50);
   30414093201713378043612608166064768844377641568960512000000000000

6.1.3 igcd

igcd(i1,i2)

:: 整数の GCD (最大公約数)

return 整数 i1,i2 整数

• i1 と i2 の GCD を求める.

• 引数が整数でない場合は, エラーまたは無意味な結果を返す.

• 多項式の場合は, gcd, gcdz を用いる.

[0] igcd(12,8);
4
参照  gcd, gcdz

6.1.4 inv

inv(i,m) :: m を法とする i の逆数 return 整数 i,m 整数

• ia ≡ 1 mod (m) なる整数 a を求める.

• i と m は互いに素でなければならないが, inv() はそのチェックは行わない.

[71] igcd(1234,4321);
1
[72] inv(1234,4321);
3239
[73] irem(3239*1234,4321);
1
参照  igcd
6.1.5 prime, lprime
prime(index)
lprime(index)

:: 素数を返す

return 整数 index 整数 • prime(), lprime() いずれもシステムが内部に持つ素数表の要素を返す. index は 0 以上の整数で, 素

数表のインデックスに用いられる. prime() は高々 10 進 4 桁の素数を小さい順に 1229 個, lprime() は, 10 進 8 桁で最大の素数から大きい順に 999 個返す. それ以外のインデックスに対しては 0 を返す.

• より一般的な素数生成函数としては, pari(nextprime,number) がある.

   [95] prime(0);
   2
   [96] prime(1228);
   9973
   [97] lprime(0);
   99999989
   [98] lprime(999);
   0
参照  pari

6.1.6 random

radom() :: 乱数を生成する.

return 自然数

• 最大 2^27-1 の乱数を生成する.

• UNIX 版でのみ使用可能.

6.1.7 nm, dn

nm(rat) :: rat の分子. dn(rat) :: rat の分母.

return 整数または多項式 rat 有理数または有理式

• 与えられた有理数また有理式の分子及び分母を返す.

• 有理数の場合, 分母は常に正で, 符号は分子が持つ.

• 有理式の場合, 単に分母, 分子を取り出すだけである. 有理式に対しては, 約分は自動的には行われない. red() を明示的に呼び出す必要がある.

   [2] [nm(-43/8),dn(-43/8)];
   [-43,8]
   [3] dn((x*z)/(x*y));
   y*x
   [3] dn(red((x*z)/(x*y)));
   y
参照  red

6.1.8 conj, real, imag
real(comp)

:: comp の実数部分.

imag(comp)

:: comp の虚数部分.

conj(comp)

:: comp の共役複素数.

return comp

複素数

• 複素数に対し, 実部, 虚部, 共役を求める.

• これらは, 多項式に対しても働く.

     [111] A=(2+@i)^3;
     (2+11*@i)
     [112] [real(A),imag(A),conj(A)];
     [2,11,(2-11*@i)]

6.1.9 eval

eval(obj[,prec])

:: obj の値の評価.

return 数あるいは式 obj 一般の式 prec 整数

• obj に含まれる函数の値を可能な限り評価する.

• 計算は PARI (第 6.1.10 節 [pari], 31 ページ参照) が行う.

• prec を指定した場合, 計算は, 10 進 prec 桁程度で行われる. prec の指定がない場合, 現在設定されて

いる精度で行われる. (第 6.1.11 節 [setprec], 32 ページ参照)

• 扱える函数は, 次の通り.

              sin, cos, tan,
              asin, acos, atan,
              sinh, cosh, tanh,
              asinh, acosh, atanh,
              exp, log, pow(a,b) (a^b)

• 以下の記号を数として評価できる.

@i 虚数単位

    @pi  円周率

@e 自然対数の底

 [118] eval(exp(@pi*@i));
 -1.0000000000000000000000000000
 [119] eval(2^(1/2));
 1.414213562373095048763788073031
 [120] eval(sin(@pi/3));
 0.86602540378443864674620506632
 [121] eval(sin(@pi/3)-3^(1/2)/2,50);
 -2.78791084448179148471 E-58
参照  ctrl, setprec, pari

6.1.10 pari

pari(func,arg,prec)

:: PARI の函数 func を呼び出す.

return func 毎に異なる. func PARI の函数名 arg func の引数

prec 整数

• PARI の函数を呼び出す.

• PARI [Batut et al.] は Bordeaux 大学で開発されフリーソフトウェアとして公開されている. PARI

は数式処理的な機能を有してはいるが, 主なターゲットは整数論に関連した数 (bignum, bigfloat) の演算で, 四則演算に限らず bigfloat によるさまざまな函数値の評価を高速に行うことができる. PARI は他のプログラムからサブルーチンライブラリとして用いることができ, また, ‘gp’ という PARI ライブラリのインタフェースにより UNIX のアプリケーションとして利用することもできる. 現在のバージョン

は 1.38 でいくつかの ftp site (たとえば math.ucla.edu:/pub/pari) から anonymous ftp できる.

• 最後の引数 prec で計算精度を指定できる. prec を省略した場合 setprec() で指定した精度となる.

• 現時点で実行できる PARI の函数は次の通りである. いずれも 1 引数で Asir が対応できる型の引数をとる函数である. なお各々の機能については PARI のマニュアルを参照のこと.

abs, adj, arg, bigomega, binary, ceil, centerlift, cf, classno, classno2, conj, content,
denom, det, det2, detr, dilog, disc, discf, divisors, eigen, eintg1, erfc, eta, floor,
frac, galois, galoisconj, gamh, gamma, hclassno, hermite, hess, imag, image, image2,
indexrank, indsort, initalg, isfund, isprime, ispsp, isqrt, issqfree, issquare, jacobi,
jell, ker, keri, kerint, kerintg1, kerint2, kerr, length, lexsort, lift, lindep, lll,
lllg1, lllgen, lllgram, lllgramg1, lllgramgen, lllgramint, lllgramkerim,
lllgramkerimgen, lllint, lllkerim, lllkerimgen, lllrat, lngamma, logagm, mat, matinvr,
matrixqz2, matrixqz3, matsize, modreverse, mu, nextprime, norm, norml2, numdiv, numer,
omega, order, ordred, phi, pnqn, polred, polred2, primroot, psi, quadgen, quadpoly, real,
recip, redcomp, redreal, regula, reorder, reverse, rhoreal, roots, rootslong, round,
sigma, signat, simplify, smalldiscf, smallfact, smallpolred, smallpolred2, smith,
smith2, sort, sqr, sqred, sqrt, supplement, trace, trans, trunc, type, unit, vec, wf,
wf2, zeta

• Asir で用いているのは PARI のほんの一部の機能であるが, 今後より多くの機能が利用できるよう改良する予定である.

/* 行列の固有ベクトルを求める. */

 [0] pari(eigen,newmat(2,2,[[1,1],[1,2]]));

[ -1.61803398874989484819771921990 0.61803398874989484826 ]
[ 1 1 ]

/* 1 変数多項式の根を求める. */

[1] pari(roots,t^2-2);
[ -1.41421356237309504876 1.41421356237309504876 ]
参照  setprec

6.1.11 setprec
setprec([n])

:: bigfloat の桁数を n 桁に設定する.

return 整数 n 整数

• 引数がある場合, bigfloat の桁数を n 桁に設定する. 引数のあるなしにかかわらず, 以前に設定されていた値を返す.

• bigfloat の計算は PARI (第 6.1.10 節 [pari], 31 ページ参照) によって行われる.

• bigfloat での計算に対し有効である. bigfloat の flag を on にする方法は, ctrl を参照.

• 設定できる桁数に上限はないが, 指定した桁数に設定されるとは限らない. 大きめの値を設定するのが安全である.

[1] setprec();
9
[2] setprec(100);
9
[3] setprec(100);
96
参照  ctrl, eval, pari

6.2 多項式, 有理式の演算

6.2.1 var

var(rat) :: rat の主変数.

return 不定元 rat 有理式

• 主変数に関しては, 第 3.1 節 [Asir で使用可能な型], 11 ページ参照.

• デフォルトの変数順序は次のようになっている.

x, y, z, u, v, w, p, q, r, s, t, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, 以後は変数の現れた順.

[0] var(x^2+y^2+a^2);
x
[1] var(a*b*c*d*e);
a
[2] var(3/abc+2*xy/efg);
abc
参照  ord, vars

6.2.2 vars

vars(obj) :: obj に含まれる変数のリスト.

return リスト obj 任意

• 与えられた式に含まれる変数のリストを返す.

• 変数順序の高いものから順に並べる.

[0] vars(x^2+y^2+a^2);
[x,y,a]
[1] vars(3/abc+2*xy/efg);
[abc,xy,efg]
[2] vars([x,y,z]);
[x,y,z]
参照  var, uc, ord

6.2.3 uc

uc() :: 新たな不定元を生成する.

return vtype が 1 の不定元

• uc() を実行するたびに, _0, _1, _2,… という不定元を生成する.

• uc() で生成された不定元は, 直接キーボードから入力することができない. これは, プログラム中で未定係数を自動生成する場合, 入力などに含まれる不定元と同一のものが生成されることを防ぐためである.

• 通常の不定元 (vtype が 0) の自動生成には rtostr(), strtov() を用いる.

• uc() で生成された不定元の不定元としての型 (vtype) は 1 である. (第 3.3 節 [不定元の型], 13 ページ参照)

[0] A=uc();
_0
[1] B=uc();
_1
[2] (uc()+uc())^2;
_2^2+2*_3*_2+_3^2

[3] (A+B)^2;
_0^2+2*_1*_0+_1^2
参照  vtype, rtostr, strtov

6.2.4 coef

coef(poly,deg[,var])

:: poly の var (省略時は主変数) に関する deg 次の係数.

return 多項式 poly 多項式 var 不定元 deg 自然数

• poly の var に関する deg 次の係数を出力する.

• var は, 省略すると主変数 var(poly) だとみなされる.

• var が主変数でない時, var が主変数の場合に比較して効率が落ちる.

[0] A = (x+y+z)^3;
x^3+(3*y+3*z)*x^2+(3*y^2+6*z*y+3*z^2)*x+y^3+3*z*y^2+3*z^2*y+z^3
[1] coef(A,1,y);
3*x^2+6*z*x+3*z^2
[2] coef(A,0);
y^3+3*z*y^2+3*z^2*y+z^3
参照  var, deg

6.2.5 deg, mindeg

deg(poly,var)

:: poly の, 変数 var に関する最高次数.

mindeg(poly,var)

:: poly の, 変数 var に関する最低次数.

return 自然数 poly 多項式 var 不定元

• 与えられた多項式の変数 var に関する最高次数, 最低次数を出力する.

• 変数 var を省略することは出来ない.

• var が主変数でない時, var が主変数の場合に比較して効率が落ちる.

[0] deg((x+y+z)^10,x);

   [1] deg((x+y+z)^10,w);
   0
   [75] mindeg(x^2+3*x*y,x);
   1

6.2.6 nmono
nmono(rat)

:: rat の単項式の項数.

return 自然数 rat 有理式

• 多項式を展開した状態での 0 でない係数を持つ単項式の項数を求める.

• 有理式の場合は, 分子と分母の項数の和が返される.

• 函数形式 (第 3.3 節 [不定元の型], 13 ページ参照) は, 引数が何であっても単項とみなされる. (1 個の不定元と同じ. )

   [0] nmono((x+y)^10);
   11
   [1] nmono((x+y)^10/(x+z)^10);
   22
   [2] nmono(sin((x+y)^10));
   1
参照  vtype

6.2.7 ord

ord([varlist])

:: 変数順序の設定

return 変数のリスト varlist 変数のリスト

• 引数があるとき, 引数の変数リストを先頭に出し, 残りの変数がその後に続くように変数順序を設定する. 引数のあるなしに関わらず, ord() の終了時における変数順序リストを返す.

• この函数による変数順序の変更を行っても, 既にプログラム変数などに代入されている式の内部形式は新しい順序に従っては変更されない. 従って, この函数による順序の変更は, Asir の起動直後, あるいは, 新たな変数が現れた時点に行われるべきである. 異なる変数順序のもとで生成された式どうしの演算が行われた場合, 予期せぬ結果が生ずることもあり得る.

   [0] ord();
   [x,y,z,u,v,w,p,q,r,s,t,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,_x,_y,_z,_u,_v,_w,_p,
   _q,_r,_s,_t,_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,exp(_x),(_x)^(_y),
   log(_x),(_x)^(_y-1),cos(_x),sin(_x),tan(_x),(-_x^2+1)^(-1/2),cosh(_x),sinh(_x),

tanh(_x),(_x^2+1)^(-1/2),(_x^2-1)^(-1/2)]
[1] ord([dx,dy,dz,a,b,c]);
[dx,dy,dz,a,b,c,x,y,z,u,v,w,p,q,r,s,t,d,e,f,g,h,i,j,k,l,m,n,o,_x,_y,_z,_u,_v,
_w,_p,_q,_r,_s,_t,_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,exp(_x),
(_x)^(_y),log(_x),(_x)^(_y-1),cos(_x),sin(_x),tan(_x),(-_x^2+1)^(-1/2),
cosh(_x),sinh(_x),tanh(_x),(_x^2+1)^(-1/2),(_x^2-1)^(-1/2)]

6.2.8 sdiv, srem, sqr

sdiv(poly1,poly2)

:: poly1 を poly2 で割る除算が最後まで実行できる場合に商を求める.

srem(poly1,poly2)

:: poly1 を poly2 で割る除算が最後まで実行できる場合に剰余を求める.

sqr(poly1,poly2)

:: poly1 を poly2 で割る除算が最後まで実行できる場合に商, 剰余を求める.

return sdiv(), srem() : 多項式, sqr() : [商, 剰余] なるリスト poly1 poly2

多項式

• poly1 を poly2 の主変数 var(poly2) に関する多項式と見て, poly2 で, 割り算を行う.

• 多項式の除算は, 主係数どうしの割算により得られた商と, 主変数の適当な冪の積を poly2 に掛けて, poly1 から引くという操作を poly1 の次数が poly2 の次数より小さくなるまで繰り返して行う. この操作が, 多項式の範囲内で行われるためには, 各ステップにおいて主係数どうしの除算が, 多項式としての整除である必要がある. これが, 「除算が最後まで実行できる」ことの意味である.

• 典型的な場合として, poly2 の主係数が, 有理数である場合, あるいは, poly2 が poly1 の因子であることがわかっている場合などがある.

• sqr() は商と剰余を同時に求めたい時に用いる.

• 整数除算の商, 剰余は idiv, irem を用いる.

• 係数に対する剰余演算は % を用いる.

• 主変数が指定できるよう改良の予定.

[0] sdiv((x+y+z)^3,x^2+y+a);
x+3*y+3*z
[1] srem((x+y+z)^2,x^2+y+a);
(2*y+2*z)*x+y^2+(2*z-1)*y+z^2-a
[2] X=(x+y+z)*(x-y-z)^2;
x^3+(-y-z)*x^2+(-y^2-2*z*y-z^2)*x+y^3+3*z*y^2+3*z^2*y+z^3
[3] Y=(x+y+z)^2*(x-y-z);
x^3+(y+z)*x^2+(-y^2-2*z*y-z^2)*x-y^3-3*z*y^2-3*z^2*y-z^3
[4] G=gcd(X,Y);
x^2-y^2-2*z*y-z^2
[5] sqr(X,G);
[x-y-z,0]
[6] sqr(Y,G);
[x+y+z,0]
[7] sdiv(y*x^3+x+1,y*x+1);
divsp: cannot happen
return to toplevel

参照  idiv, irem, %

6.2.9 tdiv

tdiv(poly1,poly2)

:: poly1 が poly2 で割り切れるかどうか調べる.

return 割り切れるならば商, 割り切れなければ 0

poly1 poly2

多項式

• poly2 が poly1 を多項式として割り切るかどうか調べる.

• ある多項式が既約因子であることはわかっているが, その重複度がわからない場合に, tdiv() を繰り返し呼ぶことにより重複度がわかる.

[11] Y=(x+y+z)^5*(x-y-z)^3;
x^8+(2*y+2*z)*x^7+(-2*y^2-4*z*y-2*z^2)*x^6+(-6*y^3-18*z*y^2-18*z^2*y-6*z^3)*x^5
+(6*y^5+30*z*y^4+60*z^2*y^3+60*z^3*y^2+30*z^4*y+6*z^5)*x^3+(2*y^6+12*z*y^5
+30*z^2*y^4+40*z^3*y^3+30*z^4*y^2+12*z^5*y+2*z^6)*x^2+(-2*y^7-14*z*y^6
-42*z^2*y^5-70*z^3*y^4-70*z^4*y^3-42*z^5*y^2-14*z^6*y-2*z^7)*x-y^8-8*z*y^7
-28*z^2*y^6-56*z^3*y^5-70*z^4*y^4-56*z^5*y^3-28*z^6*y^2-8*z^7*y-z^8
[12] for(I=0,F=x+y+z,T=Y; T=tdiv(T,F); I++);
[13] I;
5
参照  sdiv, srem

6.2.10 %

poly % m :: 整数による剰余

return 整数または多項式 poly 整数または整数係数多項式 m 整数

• poly の各係数を m で割った剰余で置き換えた多項式を返す.

• 結果の係数は全て正の整数となる.

• poly は整数でもよい. この場合, 結果が正に正規化されることを除けば irem() と同様に用いることができる.

• poly の係数, m とも整数である必要があるが, チェックは行なわれない.

[0] (x+2)^5 % 3;
x^5+x^4+x^3+2*x^2+2*x+2
[1] (x-2)^5 % 3;
x^5+2*x^4+x^3+x^2+2*x+1
[2] (-5) % 4;

3
[3] irem(-5,4);
-1
参照  irem

6.2.11 subst, psubst
subst(rat[,varn,ratn]*)
psubst(rat[,var,rat]*)

:: rat の varn に ratn を代入 (n=1,2,… で左から右に順次代入する).

return 有理式 rat,ratn 有理式 varn 不定元

• 有理式の特定の不定元に, 定数あるいは多項式, 有理式などを代入するのに用いる.

• subst(rat,var1,rat1,var2,rat2,…) は, subst(subst(rat,var1,rat1),var2,rat2,…) と同じ意味である.

• 入力の左側から順に代入を繰り返すために, 入力の順によって結果が変わることがある.

• subst() は, sin() などの函数の引数に対しても代入を行う. psubst() は, このような函数を一つの独立した不定元と見なして, その引数には代入は行わない. (partial substitution のつもり)

• Asir では, 有理式の約分は自動的には行わないため, 有理式の代入は, 思わぬ計算時間の増大を引き起こす場合がある. 有理式を代入する場合には, 問題に応じた独自の函数を書いて, なるべく分母, 分子が大きくならないように配慮することもしばしば必要となる.

• 分数を代入する場合も同様である.

[0] subst(x^3-3*y*x^2+3*y^2*x-y^3,y,2);
x^3-6*x^2+12*x-8
[1] subst(@@,x,-1);
-27
[2] subst(x^3-3*y*x^2+3*y^2*x-y^3,y,2,x,-1);
-27
[3] subst(x*y^3,x,y,y,x);
x^4
[4] subst(x*y^3,y,x,x,y);
y^4
[5] subst(x*y^3,x,t,y,x,t,y);
y*x^3
[6] subst(x*sin(x),x,t);
sint(t)*t
[7] psubst(x*sin(x),x,t);
sin(x)*t

6.2.12 diff

diff(rat[,varn]*)

diff(rat,varlist)

:: rat を varn あるいは varlist の中の変数で順次微分する.

return 式 rat 有理式 (初等函数を含んでもよい) varn 不定元 varlist 不定元のリスト

• 与えられた初等函数を varn あるいは varlist の中の変数で順次微分する.

• 左側の不定元より, 順に微分していく. つまり, diff(rat,x,y) は, diff(diff(rat,x),y) と同じである.

[0] diff((x+2*y)^2,x);
2*x+4*y
[1] diff((x+2*y)^2,x,y);
4
[2] diff(x/sin(log(x)+1),x);
(sin(log(x)+1)-cos(log(x)+1))/(sin(log(x)+1)^2)
[3] diff(sin(x),[x,x,x,x]);
sin(x)

6.2.13 res

res(var,poly1,poly2)

:: var に関する poly1 と poly2 の終結式.

return 多項式 var 不定元

poly1,poly2

多項式

• 二つの多項式 poly1 と poly2 の, 変数 var に関する終結式を求める.

• 部分終結式アルゴリズムによる.

[0] res(t,(t^3+1)*x+1,(t^3+1)*y+t);
-x^3-x^2-y^3

6.2.14 fctr, sqfr
fctr(poly)

:: poly を既約因子に分解する.

sqfr(poly)

:: poly を無平方分解する.

return リスト poly 有理数係数の多項式 • 有理数係数の多項式 poly を因数分解する. fctr() は既約因子分解, sqfr() は無平方因子分解.

• 結果は [[数係数,1],[因子, 重複度],...] なるリスト.

• 数係数と全ての因子^重複度の積が poly と等しい.

• 数係数は, (poly/数係数) が, 整数係数で, 係数の GCD が 1 となるような多項式になるように選ばれ

ている. (ptozp() 参照)

[0] fctr(x^10-1);
[[1,1],[x-1,1],[x+1,1],[x^4+x^3+x^2+x+1,1],[x^4-x^3+x^2-x+1,1]]
[1] fctr(x^3+y^3+(z/3)^3-x*y*z);
[[1/27,1],[9*x^2+(-9*y-3*z)*x+9*y^2-3*z*y+z^2,1],[3*x+3*y+z,1]]
[2] A=(a+b+c+d)^2;
a^2+(2*b+2*c+2*d)*a+b^2+(2*c+2*d)*b+c^2+2*d*c+d^2
[3] fctr(A);
[[1,1],[a+b+c+d,2]]
[4] A=(x+1)*(x^2-y^2)^2;
x^5+x^4-2*y^2*x^3-2*y^2*x^2+y^4*x+y^4
[5] sqfr(A);
[[1,1],[x+1,1],[-x^2+y^2,2]]
[6] fctr(A);
[[1,1],[x+1,1],[-x-y,2],[x-y,2]]
参照  ufctrhint

6.2.15 ufctrhint
ufctrhint(poly,hint)

:: 次数情報を用いた 1 変数多項式の因数分解

return リスト poly 有理数係数の 1 変数多項式 hint 自然数

• 各既約因子の次数が hint の倍数であることがわかっている場合に poly の既約因子分解を fctr() より効率良く行う. poly が, d 次の拡大体上におけるある多項式のノルム (第 8 章 [代数的数に関する演算], 76 ページ参照) で無平方である場合, 各既約因子の次数は d の倍数となる. このような場合に用いられる.

[10] A=t^9-15*t^6-87*t^3-125;
t^9-15*t^6-87*t^3-125
0msec
[11] N=res(t,subst(A,t,x-2*t),A);
-x^81+1215*x^78-567405*x^75+139519665*x^72-19360343142*x^69+1720634125410*x^66
-88249977024390*x^63-4856095669551930*x^60+1999385245240571421*x^57
-15579689952590251515*x^54+15956967531741971462865*x^51
...
+140395588720353973535526123612661444550659875*x^6
+10122324287343155430042768923500799484375*x^3
+139262743444407310133459021182733314453125
980msec + gc : 250msec

[12] sqfr(N);
[[-1,1],[x^81-1215*x^78+567405*x^75-139519665*x^72+19360343142*x^69
-1720634125410*x^66+88249977024390*x^63+4856095669551930*x^60
-1999385245240571421*x^57+15579689952590251515*x^54
...
-10122324287343155430042768923500799484375*x^3
-139262743444407310133459021182733314453125,1]]
20msec
[13] fctr(N);
[[-1,1],[x^9-405*x^6-63423*x^3-2460375,1],
[x^18-486*x^15+98739*x^12-9316620*x^9+945468531*x^6-12368049246*x^3
+296607516309,1],[x^18-8667*x^12+19842651*x^6+19683,1],
[x^18-324*x^15+44469*x^12-1180980*x^9+427455711*x^6+2793253896*x^3+31524548679,1],
[x^18+10773*x^12+2784051*x^6+307546875,1]]
167.050sec + gc : 1.890sec
[14] ufctrhint(N,9);
[[-1,1],[x^9-405*x^6-63423*x^3-2460375,1],
[x^18-486*x^15+98739*x^12-9316620*x^9+945468531*x^6-12368049246*x^3
+296607516309,1],[x^18-8667*x^12+19842651*x^6+19683,1],
[x^18-324*x^15+44469*x^12-1180980*x^9+427455711*x^6+2793253896*x^3+31524548679,1],
[x^18+10773*x^12+2784051*x^6+307546875,1]]
119.340sec + gc : 1.300sec
参照  fctr

6.2.16 ptozp

ptozp(poly)

:: poly を有理数倍して整数係数多項式にする.

return 多項式 poly 多項式

• 与えられた多項式 poly に適当な有理数を掛けて, 整数係数かつ係数の GCD が 1 になるようにする.

• 分数の四則演算は, 整数の演算に比較して遅いため, 種々の多項式演算の前に, 多項式を整数係数にしておくことが望ましい.

• 有理式を約分する red() で分数係数有理式を約分しても, 分子多項式の係数は有理数のままであり, 有理式の分子を求める nm() では, 分数係数多項式は, 分数係数のままの形で出力されるため, 直ちに整数係数多項式を得る事は出来ない.

[0] ptozp(2*x+5/3);
6*x+5
[1] nm(2*x+5/3);
2*x+5/3
参照  nm, dn

6.2.17 prim, cont

prim(poly)

:: poly の原始的部分 (primitive part).

cont(poly)

:: poly の容量 (content).

return poly

有理数係数多項式

• poly の主変数に関する原始的部分, 容量を求める.

• 主変数の指定ができないので, 主変数でない変数について計算したい場合には, ord() で変数順序を調べて, その変数が主変数になるように変数を入れ替えて計算して, もとに戻すことになる.

• 主変数指定ができるよう改良の予定.

[0] E=(y-z)*(x+y)*(x-z)*(2*x-y);
(2*y-2*z)*x^3+(y^2-3*z*y+2*z^2)*x^2+(-y^3+z^2*y)*x+z*y^3-z^2*y^2
[1] prim(E);
2*x^3+(y-2*z)*x^2+(-y^2-z*y)*x+z*y^2
[2] cont(E);
y-z
[3] subst(prim(subst(E,x,w,z,x),x,z,w,x);
(y-z)*x-z*y+z^2
参照  var, ord

6.2.18 gcd, gcdz

gcd(poly1,poly2) gcdz(poly1,poly2)

:: poly1 と poly2 の gcd.

return 多項式

poly1,poly2

多項式

• 二つの多項式の最大公約式 (GCD) を求める. gcd() は, 有理数体上の多項式としての GCD を返す. すなわち, 結果は整数係数で, かつ係数の GCD が 1 になるような多項式, または, 互いに素の場合は 1 を返す. gcdz() は, poly1, poly2 ともに整数係数の場合に, 整数環上の多項式としての GCD を返す. すなわち, gcd() の値に, 係数全体の整数 GCD の値を掛けたものを返す.

• Extended Zassenhaus アルゴリズム (EZGCD) による.

[0] gcd(12*(x^2+2*x+1)^2,18*(x^2+(y+1)*x+y)^3);
x^3+3*x^2+3*x+1
[0] gcdz(12*(x^2+2*x+1)^2,18*(x^2+(y+1)*x+y)^3);
6*x^3+18*x^2+18*x+6
参照  igcd

6.2.19 red

red(rat) :: rat を約分したもの.

return 有理式 rat 有理式

• Asir は有理数の約分を常に自動的に行う. しかし, 有理式については通分は行うが, 約分はユーザーが指定しない限り行わない. この約分を行うコマンドが red である.

• EZGCD により rat の分子, 分母を約分する.

• 出力される有理式の分母の多項式は, 各係数の GCD が 1 の整数係数多項式である. 分子については整数係数多項式となるとは限らない.

• GCD は大変重い演算なので, 他の方法で除ける共通因子は可能な限り除くのが望ましい. また, 分母, 分子が大きくなってからのこの函数の呼び出しは, 非常に時間が掛かる場合が多い. 有理式演算を行う場合は, ある程度頻繁に, 約分を行う必要がある.

     [0] (x^3-1)/(x-1);
     (x^3-1)/(x-1)
     [1] red((x^3-1)/(x-1));
     x^2+x+1
     [2] red((x^3+y^3+z^3-3*x*y*z)/(x+y+z));
     x^2+(-y-z)*x+y^2-z*y+z^2
     [3] red((3*x*y)/(12*x^2+21*y^3*x));
     (y)/(4*x+7*y^3)
     [4] red((3/4*x^2+5/6*x)/(2*y*x+4/3*x));
     (9/8*x+5/4)/(3*y+2)
参照  nm, dn, gcd, ptozp

6.3 リストの演算

6.3.1 car, cdr, cons, append, reverse, length

car(list) :: 空でない list の先頭要素. cdr(list) :: 空でない list から先頭要素を取り除いたリスト.

cons(obj,list)

:: list の先頭に obj を付け加えたリスト.

append(list1,list2)

:: list1 と list2 をこの順に 1 つにしたリスト.

reverse(list)

:: list を逆順にしたリスト.

length(list)

:: list の長さ.

return  car() : 任意, cdr(), cons(), append(), reverse() : リスト, length() : 自然数

list,list1,list2

リスト

obj 任意

• リストは [obj1,obj2,…] と表される. obj1 が先頭要素である.

• car() は, 空でない list の先頭要素を出力する. 空リストが入力された場合は, 空リストが出力される.

• cdr() は, 空でない list から先頭要素を取り除いたリストを出力する. 空リストが入力された場合は, 空リストが出力される.

• cons() は, list の先頭に obj を付け加えたリストを出力する.

• append() は, list1 の要素と list2 のすべての要素を結合させたリスト [list1 の要素の並び,list2 の要

素の並び] を出力する.

• reverse() は, list を逆順にしたリストを出力する.

• length() は, list の長さを出力する. ベクトル及び行列の要素の個数は, size() を用いる.

• リストは読み出し専用で, 要素の入れ替えはできない.

• リストの n 番目の要素の取り出しは, cdr() を n 回適用した後 car() を適用することにより可能であるが, 便法として, ベクトル, 行列などの配列と同様, インデックス [n] を後ろに付けることにより取り出すことができる. ただし, システム内部では, 実際にポインタを n 回たどるので, 後ろの要素ほど取り出しに時間がかかる.

• cdr() は新しいセルを生成しないが, append() は, 実際には第 1 引数のリストの長さだけの cons() の繰り返しとなるため, 第 1 引数のリストが長い場合には多くのメモリを消費することになる. reverse() に関しても同様である.

   [0] L = [[1,2,3],4,[5,6]];
   [[1,2,3],4,[5,6]]
   [1] car(L);
   [1,2,3]
   [2] cdr(L);
   [4,[5,6]]
   [3] cons(x*y,L);
   [y*x,[1,2,3],4,[5,6]]
   [4] append([a,b,c],[d]);
   [a,b,c,d]
   [5] reverse([a,b,c,d]);
   [d,c,b,a]
   [6] length(L);
   3
   [7] L[2][0];
   5

6.4 配列

6.4.1 newvect
newvect(len[,list])

:: 長さ len のベクトルを生成する.

return ベクトル len 自然数

list リスト

• 長さ len のベクトルを生成する. 第 2 引数がない場合, 各成分は 0 に初期化される. 第 2 引数がある場合, インデックスの小さい成分から, リストの各要素により初期化される. 各要素は, 先頭から順に使われ, 足りない分は 0 が埋められる.

• ベクトルの成分は, 第 0 成分から第 len-1 成分となる. (第 1 成分からではない事に注意. )

• リストは各成分が, ポインタを辿る事によってシーケンシャルに呼び出されるのに対し, ベクトルは各成分が第一成分からのメモリ上の displacement (変位) によってランダムアクセスで呼び出され, その結果, 成分のアクセス時間に大きな差が出てくる. 成分アクセスは, リストでは, 成分の量が増えるに従って時間がかかるようになるが, ベクトルでは, 成分の量に依存せずほぼ一定である.

• Asir では, 縦ベクトル, 横ベクトルの区別はない. 行列を左から掛ければ縦ベクトルとみなされるし, 右から掛ければ横ベクトルとみなされる.

• ベクトルの長さは size() によって得られる.

• 函数の引数としてベクトルを渡した場合, 渡された函数は, そのベクトルの成分を書き換えることができる.

 [0] A=newvect(5);
 [ 0 0 0 0 0 ]
 [1] A=newvect(5,[1,2,3,4,[5,6]]);
 [ 1 2 3 4 [5,6] ]
 [2] A[0];
 1
 [3] A[4];
 [5,6]
 [4] size(A);
 [5]
 [5] def afo(V)  V[0] = x;
 [6] afo(A)$
 [7] A;
 [ x 2 3 4 [5,6] ]
参照  newmat, size

6.4.2 newmat

newmat(row,col [,[[a,b,…],[c,d,…],…]])

:: row 行 col 列の行列を生成する.

return 行列

row,col 自然数

a,b,c,d 任意

• row 行 col 列の行列を生成する. 第 3 引数がない場合, 各成分は 0 に初期化される. 第 3 引数がある場合, インデックスの小さい成分から, 各行が, リストの各要素 (これはまたリストである) により初期化される. 各要素は, 先頭から順に使われ, 足りない分は 0 が埋められる.

• 行列のサイズは size() で得られる.

• M が行列のとき, M[I] により第 I 行をベクトルとして取り出すことができる. このベクトルは, もとの行列と成分を共有しており, いずれかの成分を書き換えれば, 他の対応する成分も書き換わることになる.

• 函数の引数として行列を渡した場合, 渡された函数は, その行列の成分を書き換えることができる.

[0] A = newmat(3,3,[[1,1,1],[x,y],[x^2]]);
[ 1 1 1 ]
[ x y 0 ]
[ x^2 0 0 ]
[1] det(A);
-y*x^2
[2] size(A);
[3,3]
[3] A[1];
[ x y 0 ]
[4] A[1][3];
getarray : Out of range
return to toplevel
参照  newvect, size, det

6.4.3 size

size(vect|mat)

:: [vect の長さ] または [mat の行数,mat の列数].

return リスト vect ベクトル mat 行列

• vect 又は, mat のサイズをリストで出力する.

• list のサイズは length()を, 有理式に現れる単項式の数は nmono() を用いる.

[0] A = newvect(4);
[ 0 0 0 0 ]
[1] size(A);
[4]
[2] B = newmat(2,3,[[1,2,3],[4,5,6]]);
[ 1 2 3 ]
[ 4 5 6 ]
[3] size(B);
[2,3]
参照  length, nmono

6.4.4 det

det(mat) :: mat の行列式を求める. return 式 mat 行列

• 行列 mat の行列式を求める.

• 分数なしのガウス消去法によっているため, 多変数多項式を成分とする行列に対しては小行列式展開による方法のほうが効率がよい場合もある.

[91] A=newmat(5,5)$
[92] V=[x,y,z,u,v];
[x,y,z,u,v]
[93] for(I=0;I<5;I++)for(J=0,B=A[I],W=V[I];J<5;J++)B[J]=W^J;
[94] A;
[ 1 x x^2 x^3 x^4 ]
[ 1 y y^2 y^3 y^4 ]
[ 1 z z^2 z^3 z^4 ]
[ 1 u u^2 u^3 u^4 ]
[ 1 v v^2 v^3 v^4 ]
[95] fctr(det(A));
[[1,1],[u-v,1],[-z+v,1],[-z+u,1],[-y+u,1],[y-v,1],[-y+z,1],[-x+u,1],[-x+z,1],
[-x+v,1],[-x+y,1]]
参照  newmat

6.5 型を求める函数

6.5.1 type

type(obj) :: obj の型 (整数) を返す.

return 自然数 obj 任意

• obj の型の値は次の通り.

0  0
1  数

2 多項式 (数でない) 3 有理式 (多項式でない) 4 リスト 5 ベクトル 6 行列 7 文字列 8 構造体 9 分散表現多項式

• 数の型を求めるには, ntype を用いる. 不定元の型を求めるには, vtype を用いる.

参照  ntype, vtype

6.5.2 ntype
ntype(num)

:: num (数) の型 (整数) を返す.

return 自然数 obj 数

• 数の型の値は次の通り.

0 有理数 1 倍精度浮動小数 2 代数的数

3 任意精度浮動小数 (bigfloat)

4 複素数

• newalg(x^2+1) で生成した数と, 虚数単位 @i は, 異なるものとして扱われる.

• 代数的数に関しては, 第 8 章 [代数的数に関する演算], 76 ページ参照.

[0] [10/37,ntype(10/37)];
[10/37,0]
[1] [10.0/37.0,ntype(10.0/37.0)];
[0.27027,1]
[2] [newalg(x^2+1)+1,ntype(newalg(x^2+1)+1)];
[(#0+1),2]
[3] [eval(sin(@pi/6)),ntype(eval(sin(@pi/6)))];
[0.49999999999999999991,3]
[4] [@i+1,ntype(@i+1)];
[(1+1*@i),4]
参照  type

6.5.3 vtype
vtype(var)

:: var (不定元) の型 (整数) を返す.

return 自然数 var 不定元

• var (不定元) の型の値は次の通り. 詳細は第 3.3 節 [不定元の型], 13 ページ参照.

0 一般不定元 (a,b,x,afo,bfo,...,etc.) 1 uc() で生成された不定元 (_0, _1, _2, ... etc.)

2  函数形式 (sin(x), log(a+1), acosh(1), @pi, @e, ... etc.)

3 函数子 (組み込み函数子, ユーザ定義函数子, 初等函数子 : sin, log, ... etc.)

• a(); を実行 (通常ではエラー) しただけでも ntype(a) は 3 となる. すなわち a はユーザ定義函数子とみなされる.

• @pi, @e は不定元として扱われるが, eval(), pari() においては数として扱われる.

参照  type, ntype, uc

6.6 函数に対する操作

6.6.1 functor, args, funargs
functor(func)

:: func の函数子を取り出す.

args(func)

:: func の引数リストを取り出す.

funargs(func)
     :: cons(functor(func),args(func)) を返す.
return  functor() : 不定元, args(), funargs() : リスト

func 函数形式を表す不定元

• 函数形式に関しては, vtype() を参照.

• 函数形式 func の函数子, 引数リストを取り出す.

• 逆に, 取り出した函数子を値に持つプログラム変数を F とすれば (*F)(x) で x を引数とする函数呼び出しまたは函数形式が入力できる.

[0] functor(sin(x));
sin
[0] args(sin(x));
[x]
[0] funargs(sin(3*cos(y)));
[sin,3*cos(y)]
[1] for (L=[sin,cos,tan];L!=[];L=cdr(L)) {A=car(L); print(eval((*A)(@pi/3)));}
0.86602540349122136831
0.5000000002
1.7320508058
参照  vtype

6.7 文字列に関する演算

6.7.1 rtostr
rtostr(obj)

:: obj を文字列に変える.

return 文字列 obj 任意

• 任意のオブジェクト obj を文字列に変える.

• 整数などを文字列に変換して変数名と結合することにより, 添字付きの不定元を生成する場合に多く用いられる.

• 逆に, 文字列を不定元に変換する時には, strtov を用いる.

   [0] A=afo;
   afo
   [1] type(A);
   2
   [2] B=rtostr(A);
   afo
   [3] type(B);
   7
   [4] B+"1";
   afo1
参照  strtov, type

6.7.2 strtov
strtov(str)

:: str (文字列) を不定元に変える.

return 不定元

str 不定元として変換可能な文字列

• 不定元として変換可能な文字列を不定元に変える.

• 不定元として変換可能な文字列とは, 英小文字で始まり, 英字, 数字および記号 _で作られる文字列である.

• rtostr() と組合せて, プログラム中で自動的に不定元を生成したい時に用いられる.

   [0] A="afo";
   afo
   [1] for (I=0;I<3;I++) {B=strtov(A+rtostr(I)); print([B,type(B)]);}
   [afo0,2]
   [afo1,2]
   [afo2,2]
参照  rtostr, type, uc

6.8 入出力

6.8.1 end, quit
end, quit

:: 現在読み込み中のファイルを閉じる. トップレベルにおいてはセッションを終了することになる.

• end, quit ともに無引数の函数であるが, ‘()’ なしで呼び出すことができる. いずれも現在読み込み中のファイルを閉じる. これは, トップレベルにおいてはセッションを終了させることになる.

• ファイルの場合, ファイルの終端まで読めば, 自動的にファイルは閉じられるが, トップレベルの場合プロンプトが出ないまま, 入力待ちになるので, ファイルの終端には end$ を書くのが望ましい.

 [6] quit;
 %
参照  load

6.8.2 load

load("filename")

:: filename を読み込む.

return (1|0)

filename ファイル名 (パス名)

• 実際のプログラムの書き方は, 第 4 章 [ユーザ言語 Asir], 15 ページ参照. テキストファイルを読み込む場合, cpp を通すので, C のプログラム同様 #include, #define を使うことができる.

• 指定したファイルが存在した時には 1 を返し, 存在しなかった時は 0 を返す.

• ファイル名が ‘/’ で始まる場合は絶対パス, ‘.’ で始まる場合はカレントディレクトリからの相対パスと見なされる. それ以外の場合, 環境変数 ASIRLOADPATH に設定されているディレクトリを左から順にサーチする. それらに該当するファイルが存在しない場合, 標準ライブラリディレクトリ (あるいは環境変数 ASIR_LIBDIR に設定されているディレクトリ) もサーチする.

• 読み込むファイルの最後に, end$ がないと load() 終了後にプロンプトがでないが, 実際には入力を受け付ける. しかし, 混乱を招くおそれがあるのでファイルの最後に end$ を書いておくことが望ましい. (end; でもよいが, end が返す値 0 が表示されるため, end$ をお勧めする. )

参照  end, which
6.8.3 which
which("filename")

:: 引数 filename に対し, load() が読み込むパス名を返す.

return パス名 filename ファイル名 (パス名) または 0 • load() がファイルをサーチする手順に従ってサーチし, ファイルが存在する場合にはパス名を文字列と

して, 存在しない場合には 0 を返す.

• サーチの手順については load() を参照.

   [0] which("gr");
   ./gb/gr
   [1] which("/usr/local/lib/gr");
   0
   [2] which("/usr/local/lib/asir/gr");
   /usr/local/lib/asir/gr
参照  load

6.8.4 output
output(["filename"])

:: 以降の出力先を filename または標準出力に切替える.

return 1

filename ファイル名

• Asir の出力を標準出力から, ファイルへの出力に切替える. なお, ファイル出力の間は, 標準出力にはキーボードからの入力以外, 出力されない.

• 別のファイル出力に切替える時には, 再び output("filename") を実行する. 又, ファイル出力を終了し標準出力に戻りたい時には, 引数なしで output() を実行する.

• 指定したファイル filename が存在した時は, そのファイルの末尾に追書きされ, 存在しなかった時には, 新たにファイルを作成し, そこに書き込まれる.

• ファイルネームを "" ダブルクォートなしで指定をしたり, ユーザが, 書き込めないファイルを指定したりすると, エラーによりトップレベルに戻る.

• 入力したものも込めてファイルに出力したい場合には, ctrl("echo",1) を実行した後でファイル出力に切替えれば良い.

• 計算時間など, 標準エラー出力に書き出されるものはファイルには書き出されない.

• 函数形式, 未定係数 (vtype() 参照) を含まない数式のファイルへの読み書きは, bload(), bsave() を使うのが, 時間, 空間ともに効率がよい.

   [83] output("afo");
   fctr(x^2-y^2);
   print("afo");
   output();
   1
   [87] quit;
   % cat afo
   1
   [84] [[1,1],[x+y,1],[x-y,1]]
   [85] afo
   0
   [86]
参照  ctrl, bload, bsave

6.8.5 bsave, bload
bsave(obj,"filename")

:: filename に obj をバイナリ形式で書き込む.

bsave("filename")

:: filename から数式をバイナリ形式で読み込む.

return bsave() : 1, bload() : 読み込んだ数式

obj 函数形式, 未定係数を含まない任意の数式 filename ファイル名

• bsave() は内部形式をほぼそのままバイナリ形式でファイルに書き込む. bload() は, bsave() で書き込んだ数式を読み込んで内部形式に変換する. 現在のインプリメンテーションの制限により, 函数形式, 未定係数 (vtype() 参照) を含まないリスト, 配列などを含む任意の数式をファイルに保存することができる.

• output() などで保存した場合, 読み込み時にパーザが起動されるが, bsave() で保存したものを bload() で読む場合, 直接内部形式が構成できるため, 時間的, 空間的に効率がよい.

• 多項式の場合, 書き込み時と読み込み時で変数順序が異なる場合があるが, その場合には, 自動的に現在の変数順序における内部形式に変換される.

   [0] A=(x+y+z+u+v+w)^20$
   [1] bsave(A,"afo");
   1
   [2] B = bload("afo")$
   [3] A == B;
   1
   [4] X=(x+y)^2;
   x^2+2*y*x+y^2
   [5] bsave(X,"afo")$
   [6] quit;
   % asir
   [0] ord([y,x])$
   [1] bload("afo");
   y^2+2*x*y+x^2
参照  output

6.8.6 print
print(obj [,nl])

:: obj を表示する.

return 0

obj 任意 nl フラグ (任意)

• obj を評価して表示する.

• 第 2 引数が 0 の場合改行せず, それ以外は改行する.

• この函数の戻り値は 0 であるから, print(); で実行すると, 出力の後に 0 が返される. print()$ とすれば, 最後の 0 は出力されない.

• 複数の obj を同時に出力したい時は obj をリストにするとよい.

   [8] def cat(L) { while ( L != [] ) { print(car(L),0); L = cdr(L);} print("");
   }
   [9] cat([xyz,123,"gahaha"])$
   xyz123gahaha

6.9 プロセス間通信

6.9.1 tcpinit, tcpdebug, tcpclose

tcpinit(host,command [,display])

:: 遠隔プロセスの起動および通信を開始する.

tcpdebug(host,command [,display])

:: 遠隔プロセスの起動のための shell コマンドを返す.

tcpclose(id)

:: 遠隔プロセスを終了させ, 通信を終了する.

ping(obj) :: 数式を遠隔プロセスに送り, 返された数式を返す.

return  tcpinit() : 整数, tcpdebug() : 文字列, ping() : 任意

host, command, display

文字列

id 整数 obj 函数形式, 未定係数を含まない任意の数式

• tcpinit() は, ホスト host 上でコマンド command を起動し, このプロセスと通信を開始する.

• 返される整数は, 実際にはオープンされた TCP/IP ストリームのソケット番号である.

• UNIX 版においては, グラフィックスは別プロセスで処理される. これらの函数は, グラフィックスに限らず一般に分散計算を行うためのツールとして用いることができる.

• Asir と通信するプロセスは同一のマシン上で動作している必要はない. また, 通信におけるバイトオーダは big-endian に統一してあるため, 相手先のマシンとバイトオーダが異なっていても構わない.

• 以下の準備が必要である. ここで, Asir の動いているホストを A, 通信相手のプロセスが起動されるホストを B とする.

1. ホスト B の csh のサーチパスに起動されるプログラムのあるディレクトリをいれる. プログラムは rsh で起動される. したがって, ホスト B のサーチパスにそのプログラムが入っていない場合には起動できない. この場合絶対パスを与えるか, ‘~/.cshrc’ のサーチパスにそのプログラムのあるディレクトリを追加する必要がある. その際, 相手先ホストにおけるディレクトリであることを忘れないようにすること.

2. ホスト B の ‘~/.rhosts’ に, ホスト A のホスト名を登録する.

3. ‘asir_plot’ など, X とのコネクションも用いられる場合, Xserver に対し, 必要なホストを authorize させる. xhost で必要なホスト名を追加すればよい.

4. command によっては, スタックを大量に使用するものもあるため, ‘.cshrc’ でスタックサイズを大きめ (16MB 程度) に指定しておくのが安全である. スタックサイズは limit stacksize 16m などと指定する.

• command が, X 上にウインドウを開ける場合, display が指定されればその文字列を, 省略時には環境

変数 DISPLAY の値を用いる.

• tcpdebug() は, tcpinit() と全く同じ引数をとり, tcpinit() が rsh により遠隔プロセスを起動す

る際のコマンドラインを返す. 更に, Asir は, tcpinit() と同様遠隔プロセスからの通信開始要求を待つ. この函数は, tcpinit() がうまく遠隔プロセスを起動できない場合に, 返された文字列を, command を起動するマシン上で shell から直接実行してみて, 起動できない理由を調べたり, あるいは command をデバッグする場合に用いる.

• tcpclose() は番号 id の入出力ストリームを閉じる. id は tcpinit() により返された値である. これにより通信は終了し, 遠隔プロセスは終了する.

• Asir が正常した場合には全ての入出力ストリームは自動的に閉じられ, 起動されているプロセスは全て終了するが, 異常終了した場合, 遠隔プロセスが終了しない場合もある. Asir が異常終了した場合, 遠隔プロセスを起動したマシン上で ps などを起動して, もし Asir から起動したプロセスが残っている場合, kill する必要がある.

• ping() は, command として ‘asir_ping’ を用いて tcpinit()を呼び出した後使用可能な函数で, 通

信が正しく行われているかどうかをテストするために用いる.

• ping() は引数をそのまま ‘asir_ping’ に送る. ‘asir_ping’ は送られたデータをそのまま ‘Asir’ に

返送し, ping() はそれをユーザに返す.

[15] tcpinit("localhost","asir_ping");
7
[16] ping(xyz);
xyz
[17] tcpclose(7);
0
[18] tcpdebug("localhost","asir_ping");
rsh localhost -n "asir_ping geisha 1040 otemoyan:0.0>&/dev/null&">/dev/null
------------------------------------
/* マシン localhost 上で */
% asir_ping geisha 1040 otemoyan:0.0
------------------------------------
7
[19] ping((x+y)^10);
x^10+10*y*x^9+45*y^2*x^8+120*y^3*x^7+210*y^4*x^6+252*y^5*x^5+210*y^6*x^4
+120*y^7*x^3+45*y^8*x^2+10*y^9*x+y^10
[20] tcpclose(7);
0
参照  ifplot

6.10 陰函数の描画

6.10.1 ifplot, conplot, plot

ifplot(poly [,geometry] [,xrange] [,yrange] [,id] [,name])

:: 2 変数多項式の実数上での零点を表示する.

conplot(poly [,geometry] [,xrange] [,yrange] [,zrange] [,id] [,name])

:: 2 変数多項式の実数上での等高線を表示する.

plot(poly [,geometry] [,xrange] [,id] [,name])

:: 1 変数多項式で表される函数のグラフを表示する.

plotover(poly,id,number)

:: すでに存在しているウィンドウへ描画する.

return 整数 poly 多項式

geometry, xrange, yrange, zrange

リスト

id, number

整数

name 文字列

• ifplot() は, 2 変数の多項式 poly の実数上での零点, すなわち実代数曲線のグラフの表示を行う. conplot() は, 同様の引数に対し, 等高線の表示を行う. plot() は, 1 変数多項式を 1 変数函数と見なしてそのグラフの表示を行う. UNIX 版 (X11 上), Mac 版で動作する.

• UNIX 版は, 遠隔プロセスにより実現されている. コマンドは ‘asir_plot’ で, tcpinit() により起動しておく必要がある.

• Mac 版では直接これらの函数を起動できる.

• 引数の内, poly は必須である. その他の引数はオプションである. オプションの形式およびそのデフォルト値 (カッコ内) は次の通り. geometry ウィンドウのサイズをドット単位で [x,y] で指定する. (UNIX 版では [400,400], Mac 版

では [200,200].)

xrange, yrange 変数の範囲の指定で, [v,vmin,vmax] で指定する. (いずれの変数も [v,-2,2].) この指定が

ない場合, poly に含まれる変数の内変数順序の上の変数が ‘x’, 下の変数が ‘y’ として扱われる. これを避けるためには xrange, yrange を指定する. また, poly が 1 変数の場合, これらの指定は必須となる.

zrange conplot() の場合のみ指定できる. 形式は [v,vmin,vmax [,step ]] で, step が指定され

た場合には, 等高線の間隔が (vmax-vmin)/step となる. ([z,-2,2,16].)

id 遠隔プロセスの番号, すなわち tcpinit() が返した番号を指定する. (一番最近に作られ,

かつアクティブなプロセスに対応する番号.)

name ウィンドウの名前. (Plot.) 生成されたウィンドウのタイトルは name:n/m となる. これは, プロセス番号 n のプロセスの, m 番のウィンドウを意味する. この番号は, plotover() で用いられる.

• 引数は, bigfloat を含んではいけない. すなわち引数に現れる浮動小数は, 全て倍精度浮動小数でなければならない.

• 一つのプロセス上で描画できるウィンドウの数は最大 128 個である.

• plotover() は, 指定したウィンドウ上に, 引数である 2 変数多項式の零点を上書きする.

• 描画終了後のウィンドウ上で, マウスの左ボタンを押しながらのドラッグで範囲を指定しボタンを離すと新たなウィンドウが生成され, 指定した範囲が拡大して表示される. ドラッグは左上から右下へと行う. ドラッグを始めた後キャンセルする場合は, マウスポインタを始点の上か左に持っていってボタンを離せばよい. 新しいウインドウの形は, 指定領域と相似で, 最大辺が, 元のウィンドウの最大辺と一致するように定められる. 以下で説明する precise が on の場合, 選択した領域が同一 window 上で書き直される.

• ウィンドウ内で右ボタンを押すと, その点の座標がウィンドウの下部に表示される.

• conplot() で生成したウィンドウにおいて, ウィンドウの右側のマーカを中ボタンでドラッグすると, 対応する等高線の色が変わり, 右上のウィンドウに対応するレベルが表示される.

• UNIX 版ではいくつかのボタン, Mac 版ではプルダウンメニューによりいくつかの設定変更, 操作ができる. UNIX 版では次のボタンがある. quit window を破壊する. 計算中の場合, 計算を中断する.

wide (トグル)

現在の表示部分を縦横各 10 倍した領域を表示する. 現在表示されている範囲はこの表示において中央部に長方形で示される. この表示で範囲指定を行うと, その範囲が新しいウィンドウに描画される.

precise (トグル)

選択領域を, 整数演算により, より正確に再描画する. このモードでは Sturm 列と二分法により, 区間内の零点の個数を正確に求めていくもので, デフォルトの計算法よりも正確な描画が期待できる. ただし, 描画時間は余計にかかる場合が多い. この説明から明らかなように, この機能は有理数係数の多項式の描画に対してのみ有効である. ((x^2+y^2-1)^2 の描画で試してみよ.)

formula 対応する式を表示する.

noaxis (トグル)

座標軸を消す.

• ‘asir_plot’ が起動されるマシンによっては, スタックを大量に使用するものもあるため, ‘.cshrc’ でスタックサイズを大きめ (16MB 程度) に指定しておくのが安全である. スタックサイズは limit

stacksize 16m などと指定する.

• X では、ウインドウの各部分について resource により色付けや、ボタンの形を変えることができる。

resource の指定の仕方は以下の通り。（デフォルトを示しておく） plot*form*shapeStyle は、 rect-

angle, oval, ellipse, roundedRectangle が、指定できる。
plot*background:white
plot*form*shapeStyle:rectangle
plot*form*background:white
plot*form*quit*background:white
plot*form*wide*background:white
plot*form*precise*background:white
plot*form*formula*background:white
plot*form*noaxis*background:white
plot*form*xcoord*background:white
plot*form*ycoord*background:white
plot*form*level*background:white
plot*form*xdone*background:white
plot*form*ydone*background:white
[0] tcpinit("geisha","asir_plot");
7
[1] ifplot(x^2+y^2-1)$
[2] ifplot(x^5-2*y*x^2+y^5,[200,200])$
[3] ifplot(x^6+3*y^2*x^4+(3*y^4-4*y^2)*x^2+y^6)$
[4] ifplot(x^4+(2*y^2+3*y)*x^2+y^4-y^3)$
[5] conplot(2*x^4-3*x^2*y+y^2-2*y^3+y^4,[y,-1,3],"Mask")$
[6] conplot(x^6+(43/12*y^2-3)*x^4+(88/27*y^4+46/3*y^2+3)*x^2+64/729*y^6-
    16/27*y^4+4/3*y^2-1,[x,-3,3],[y,-3,3])$
[7] plot(256*x^8-512*x^6+304*x^4-48*x^2+1,[x,-1,1])$
[8] ifplot(364816*x^6+(9214800*y^2+8937600*y-121625)*x^4+(2520000*y^4-
    2250000*y^3-18877500*y^2-12656250*y+1880000)*x^2+4000000*y^6+
    3000000*y^5-8250000*y^4-4437500*y^3+6187500*y^2+1687500*y-1687500)$

参照  tcpinit, tcpclose

6.11 その他

6.11.1 ctrl

ctrl("switch",onoff )

:: 環境設定

return 0 または 1 switch スイッチ名 onoff フラグ (任意)

• Asir の実行環境の設定変更を行う. フラグが 0 ならばスイッチ switch を off にし, それ以外ならば on にする.

• スイッチは文字列として入力する. すなわちダブルクォートで囲む.

• スイッチは次の通り.

cputime on の時 CPU time および GC time を表示, off の時表示しない. cputime() を参照.

            ctrl("cputime",onoff ) は cputime(onoff ) と同じである.

nez EZGCD のアルゴリズムの切替え. デフォルトで 1 であり, とくに切替える必要はない. echo on の時は標準入力を繰り返して出力し, off の時は標準入力を繰り返さない. output コマ

ンドを用いる際に有効である.

bigfloat on の時, 入力された浮動小数は bigfloat に変換され, 浮動小数演算は PARI (第 6.1.10 節 [pari], 31 ページ参照) により行われる. デフォルトの有効桁数は 9 桁である. 有効桁数を増やしたい時には setprec() を用いる. off の時, 入力された浮動小数は, 倍精度浮動小数に変換される.

• 成功した場合には 1 を, 失敗したとき又は用意されたスイッチ以外のものを指定した場合には 0 を返す.

参照  cputime, output, pari, setprec, eval

6.11.2 debug

debug :: デバッグモードに入る.

• debug は無引数の函数であるが, ‘()’ なしで呼び出せる.

• デバッグモードに入るとプロンプトが (debug) となり, コマンド受け付け状態となる. quit を入力するとデバッガから抜ける.

• デバッグモードについての詳細は第 5 章 [デバッガ], 23 ページ参照.

   [1] debug;
   (debug) quit
   0

6.11.3 error

error(message)

:: プログラム中で強制的にエラーを発生させる.

message 文字列

• 一般に, 引数の間違いなど, 続行不可能なエラーが組み込み函数において発生した時, トップレベルに戻る前に, 可能ならばそのエラーの時点でデバッグモードに入る. error() は, ユーザ函数の内部でこの動作と同様の動作を行わせるための函数である.

• 引数は, error() が呼び出される際に表示されるメッセージで, 文字列である.

• ユーザ函数において, 変数をチェックして, あり得ない値の場合に error() を呼び出すようにしておけば, その時点で自動的にデバッグモードに入れる.

% cat mod3
def mod3(A)
        if ( type(A) >= 2 )
                error("invalid argument");
        else
                return A % 3;
end$
% asir
[0] load("mod3");
1
[3] mod3(5);
2
[4] mod3(x);
invalid argument
stopped in mod3 at line 3 in file "./mod3"
3                       error("invalid argument");
(debug) print A
A = x
(debug) quit
return to toplevel
[4]
参照  debug

6.11.4 help

help(["function"])

:: 函数の説明を表示する.

return 0

function 函数名 • 無引数の時, 最小限の説明が表示される. 函数名が引数として与えられたとき, 標準ライブラリディレク

トリにある ‘help’ というディレクトリに同名のファイルがあれば, 環境変数 PAGER に設定されているコマンド, あるいは ‘more’ を呼び出してそのファイルを表示する.

• Mac 版では未対応.

6.11.5 time

time() :: セッション開始から現在までの CPU 時間および GC 時間を表示する

return リスト

• CPU 時間および GC 時間の表示に関するコマンドである.

• GC 時間とは, ガーベジコレクタにより消費されたと見なされる時間, CPU 時間は, 全体の CPU 時間から GC 時間を引いた残りで, 単位は秒である.

• time() は引数なしで, セッション開始から現在までの CPU 時間, GC 時間, および現在までに要求され

たメモリののべ容量の表示をする. すなわち, [CPU 時間 (秒), GC 時間 (秒), メモリ量 (ワード)]

なるリストを返す. 1 ワードは通常 4 バイトである.

• 計算の実行開始時, 終了時の time() から, その計算に対する CPU 時間, GC 時間がわかる.

• メモリ量は多倍長数ではないため, ある値を越えると無意味な値となるためあくまでも目安として用いるべきである.

• ctrl() や cputime() により cputime スイッチが on になっている場合には, トップレベルの文を一つの単位として, その実行時間が表示される. しかし, プログラムの内部などで, 特定の計算に対する計算時間を知りたい時には, time() などを使う必要がある.

• getrusage() が使える UNIX 上では time() は信頼性のある値を返すが, DOS, Mac 上では時刻を用

いるほか方法がないため経過時間そのものが表示される. よって, デバッグモードに入ったり, 割り込みプロンプトでの待ち状態があると, それも経過時間に加算される. 特に, PC98 の場合, 時刻は秒単位で返されるため, 短時間で終る計算に対しては, time() の返す値はほとんど無意味である. また, getrusage() が使えない UNIX (HP-UX など) においては clock() により CPU 時間を得ているが, この函数の性質上ある程度以上の時間 (HP-UX の場合 2147 秒) が経過するとやはり無意味な値となる.

 [72] T0=time();
 [0.24,0.03,22861]
 [73] G=hgrm(katsura(4),[u4,u3,u2,u1,u0])$
 [74] T1=time();
 [2.48,1.37,1934543]
 [75] ["CPU",T1[0]-T0[0],"GC",T1[1]-T0[1]];
 [CPU,2.24,GC,1.34]
参照  cputime, tstart, tstop

6.11.6 cputime, tstart, tstop
cputime(onoff )

:: 引数が 0 ならば cputime の表示を止める. それ以外ならば表示を行う.

tstart() :: CPU time 計測開始. tstop() :: CPU time 計測終了および表示. return 0

onoff フラグ (任意)

• cputime() は, 引数が 0 ならば CPU time の表示を止める. それ以外ならば表示を行う.

• tsart は引数なし, ‘()’ なしで, CPU time 計測を開始する.

• tstop は引数なし, ‘()’ なしで, CPU time 計測を終了, および表示する.

• cputime(onoff ) は ctrl("cputime",onoff ) と同じである.

• tstart, tstop は, 入れ子にして使われることは想定していないため, そのような可能性がある場合には, time() による計測を行う必要がある.

• cputime() による on, off は, 単に表示の on, off であり, トップレベルの一つの文に対する計測は常に行われている. よって, 計算を始めてからでも, 計算終了前にデバッガに入って cputime(1) を実行させれば計算時間は表示される.

[49] tstart$
[50] fctr(x^10-y^10);
[[1,1],[x+y,1],[x^4-y*x^3+y^2*x^2-y^3*x+y^4,1],[x-y,1],
[x^4+y*x^3+y^2*x^2+y^3*x+y^4,1]]
[51] tstop$
80msec + gc : 40msec
[52] grm(katsura(4),[u4,u3,u2,u1,u0])$
^Cinterrupt ?(q/t/c/d/w/?) d
stopped in gbcheck at line 186 in file "./gb/gr"
186                     if ( !ZERO(H) )
(debug) print cputime(1)
cputime(1) = 0
(debug) c
580msec + gc : 320msec
[53]
参照  time, ctrl

6.11.7 heap

heap() :: 現在のヒープの大きさを返す. (単位:バイト)

return 自然数

• 現在のヒープの大きさ (単位 : バイト) を返す. ヒープとは, Asir のさまざまな数式や, ユーザプログラムなどがおかれるメモリの領域で, ガーベジコレクタにより管理されている. プログラムの動作中は, ヒープの大きさは単調非減少であり, 実メモリの量をこえて大きくなった場合には, OS によるスワップエリアへの読み書きがほとんどの計算時間を占めることになる.

• 実メモリが少ない場合には, 起動時の -adj オプションにより, GC 主体の設定を行っておく必要がある.

% asir -adj 16
[0] load("fctrdata")$
0
[97] cputime(1)$
0msec
[98] heap();

524288
0msec
[99] fctr(Wang[8])$
3.190sec + gc : 3.420sec
[100] heap();
1118208
0msec
[101] quit;
% asir
[0] load("fctrdata")$
0
[97] cputime(1)$
0msec
[98] heap();
827392
0msec
[99] fctr(Wang[8])$
3.000sec + gc : 1.180sec
[100] heap();
1626112
0msec
[101] quit;

参照第 2.4 節 [コマンドラインオプション], 7 ページ

6.11.8 version
version()

:: Asir のバージョンを返す.

return 自然数

• Asir のバージョンを 10 進 6 桁の自然数で返す. 最初の 2 桁が西暦の下 2 桁, 次の 2 桁が月, 最後の 2 桁が日を表す.

[0] version();
940216

6.11.9 shell

shell(command)

:: command をシェルコマンドとして実行する.

return 自然数 command 文字列

• command を C の system() 函数によりシェルコマンドとして実行する. シェルの終了ステータスを返す.

[0] shell("ls");
alg             da              katsura         ralg            suit
algt            defs.h          kimura          ratint          test
alpi            edet            kimura3         robot           texput.log
asir.o          fee             mfee            sasa            wang
asir_symtab     gr              mksym           shira           wang_data
base            gr.h            mp              snf1            wt
bgk             help            msubst          solve
chou            hom             p               sp
const           ifplot          proot           strum
cyclic          is              r               sugar
0

第 7 章: グレブナ基底の計算 64

7 グレブナ基底の計算

7.1 分散表現多項式

分散表現多項式とは, 多項式の内部形式の一つである. 通常の多項式 (type が 2) は, 再帰表現と呼ばれる形式で表現されている. すなわち, 特定の変数を主変数とする 1 変数多項式で, その他の変数は, その 1 変数多項式の係数に, 主変数を含まない多項式として現れる. この係数が, また, ある変数を主変数とする多項式となっていることから再帰表現と呼ばれる.

(x + y + z)^{2} = 1 · x^{2} + (2 · y + (2 · z)) · x + ((2 · z) · y + (1 · z^{2}))

これに対し, 多項式を, 変数の冪積と係数の積の和として表現したものを分散表現と呼ぶ.

(x + y + z)^{2} = 1 · x^{2} + 2 · xy + 2 · xz + 1 · y^{2} + 2 · yz + 1 · z^{2}

グレブナ基底計算においては, 単項式に注目して操作を行うため多項式が分散表現されている方がより効率のよい演算が可能になる. このため, 分散表現多項式が, 識別子 9 の型として Asir のトップレベルから利用可能となっている. ここで, 後の説明のために, いくつかの言葉を定義しておく.

項 (term)

変数の冪積. すなわち, 係数 1 の単項式のこと. Asir においては,

               <<0,1,2,3,4>>

という形で表示され, また, この形で入力可能である. この例は, 5 変数の項を示す. 各変数を a,

          b, c, d, e とするとこの項は b*c^2*d^3*e^4 を表す.

単項式 (monomial)

項と係数の積.

               2*<<0,1,2,3,4>>

という形で表示され, また, この形で入力可能である.

頭単項式 (head monomial) 頭項 (head term) 頭係数 (head coefficient)

分散表現多項式における各単項式は, ある全順序により整列される. この時順序最大の単項式を頭単項式, それに現れる項, 係数をそれぞれ頭項, 頭係数と呼ぶ.

7.2 ファイルの読み込み

グレブナ基底を計算するためのツールは, 組み込み函数としてではなく, Asir 言語で書かれたファイル ‘gr’ を load() により読み込むことにより使用可能となる. ‘gr’ は, Asir の標準ライブラリディレクトリに置かれている. よって, 環境変数 ASIR_LIBDIR を特に異なるパスに設定しない限り, ファイル名のみで読み込むことができる.

     [0] load("gr")$

7.3 函数, オプション

7.3.1 函数

‘gr’ では数多くの函数, オプション等が定義されているが, 実際に使用するものはそう多くない. グレブナ基底計算のためのトップレベルは次の 4 つである. 以下で, plist は多項式のリスト, vlist は変数 (不定元) のリストである.

gr(plist,vlist)

Gebauer-Moeller-Sugar アルゴリズムによるグレブナ基底計算函数. 一般にはこの函数を用いる.

grm(plist,vlist)

モジュラ演算を用いて gr() の高速化を図ったもの. 入力イデアルが 0 次元, すなわち入力多項式リストの多項式の共通零点の個数が有限個であると推測される時, gr() と比較して劇的に高速化される場合がある.

hgr(plist,vlist)

斉次化を経由してグレブナ基底を求める函数. Sugar による仮想的な斉次化に比較して, 安定して良いストラテジを与えるが, 不必要対が増加するのが難点であり, 通常は, hgrm() を用いる.

変数順序は, DegRevLex と Lex の場合にのみ有効.

hgrm(plist,vlist)

hgr() の欠点を, モジュラ演算により解消したもの. grm() と同様 0 次元イデアルに対して有効である. 特に, grm() でも計算が行き詰まってしまった場合など, 最後の手段として用いることが多い.

7.3.2 オプション

グレブナ基底の計算においては, さまざまな状況設定が必要となる. それらは具体的にには大域変数の設定として行われる.

Ord

単項式の順序は, 引数の vlist で与えられた変数間の順序を元に, 大域変数 Ord の値により決められる. 詳細は後述する.

PRINT

PRINT が 0 でないとき, グレブナ基底計算の途中におけるさまざまな情報を表示する. 大きな計算を行う場合, 途中経過を知ることで, 中断して他の設定での再計算を行うなどの決定をする場合に便利である.

NOREDUCE

最終的に得られたグレブナ基底は, 相互正規化を行って, 互いに他の基底により簡約できない正規グレブナ基底として出力されるが, NOREDUCE が 0 でない時, この操作を行うことを抑制する.

NOSUGAR

NOSUGAR が 0 でない場合, Sugar ストラテジの代わりに Buchberger の Normal ストラテジ

が用いられる.

NOCRIB

NOCRIB が 0 でない場合, 不必要対検出規準のうち, 規準 B を適用しない.

NOGC

NOGC が 0 でない場合, grm(), hgrm() において結果がグレブナ基底になっているかどうかのチェックを行わない.

NOMC

NOMC が 0 でない場合, grm(), hgrm() において結果が入力イデアルと同等のイデアルであるかどうかのチェックを行わない.

これらの変数の初期値は全て 0 である. また, NOREDUCE 以下は, 通常は変更の必要はない. PRINT は必要に応じて on-off すればよい. 重要なのは, Ord および引数の変数順序の設定である.

7.4 Ord, 変数順序の設定

Ord は, 変数順序の型を設定する. Ord は 0 から 8 までの整数値をとれるが, 通常用いられるのは 0, 1, 2 の 3 つである.

0 (DegRevLex; 全次数逆辞書式順序)

一般に, この順序によるグレブナ基底計算が最も高速である. ただし, 方程式を解くという目的に用いることは, 一般にはできない. この順序によるグレブナ基底は, 解の個数の計算, イデアルのメンバシップや, 他の変数順序への基底変換のためのソースとして用いられる.

1 (DegLex; 全次数辞書式順序)

この順序も, 辞書式順序に比べて高速にグレブナ基底を求めることができるが, DegRevLex と同様直接その結果を用いることは困難である. しかし, 辞書式順序のグレブナ基底を求める際に, 斉次化後にこの順序でグレブナ基底を求めている.

2 (Lex; 辞書式順序)

この順序によるグレブナ基底は, 方程式を解く場合に最適の形の基底を与えるが計算時間がかかり過ぎるのが難点である. 特に, 解が有限個の場合, 結果の係数が極めて長大な多倍長数になる場合が多い. この場合, grm(), hgrm() による計算が極めて有効になる場合が多い.

これらの順序の具体的な定義およびグレブナ基底に関する更に詳しい解説は [Becker,Weispfenning] などを参照のこと.

Ord の設定の他に, 変数の順序自体も計算時間に大きな影響を与える.

[90] B=[x^10-t,x^8-z,x^31-x^6-x-y]$
0msec
[91] Ord=2$
0msec
[92] gr(B,[x,y,z,t])$
[x^2-2*y^7+(-41*t^2-13*t-1)*y^2+(2*t^17-12*t^14+42*t^12+30*t^11-168*t^9
-40*t^8+70*t^7+252*t^6+30*t^5-140*t^4-168*t^3+2*t^2-12*t+16)*z^2*y
+(-12*t^16+72*t^13-28*t^11-180*t^10+112*t^8+240*t^7+28*t^6-127*t^5
-167*t^4-55*t^3+30*t^2+58*t-15)*z^4,
(y+t^2*z^2)*x+y^7+(20*t^2+6*t+1)*y^2+(-t^17+6*t^14-21*t^12-15*t^11+84*t^9
+20*t^8-35*t^7-126*t^6-15*t^5+70*t^4+84*t^3-t^2+5*t-9)*z^2*y+(6*t^16-36*t^13
+14*t^11+90*t^10-56*t^8-120*t^7-14*t^6+64*t^5+84*t^4+27*t^3-16*t^2-30*t+7)*z^4,
(t^3-1)*x-y^6+(-6*t^13+24*t^10-20*t^8-36*t^7+40*t^5+24*t^4-6*t^3-20*t^2-6*t-1)*y
+(t^17-6*t^14+9*t^12+15*t^11-36*t^9-20*t^8-5*t^7+54*t^6+15*t^5+10*t^4-36*t^3
-11*t^2-5*t+9)*z^2,

-y^8-8*t*y^3+16*z^2*y^2+(-8*t^16+48*t^13-56*t^11-120*t^10+224*t^8+160*t^7
-56*t^6-336*t^5-112*t^4+112*t^3+224*t^2+24*t-56)*z^4*y+(t^24-8*t^21+20*t^19
+28*t^18-120*t^16-56*t^15+14*t^14+300*t^13+70*t^12-56*t^11-400*t^10-84*t^9
+84*t^8+268*t^7+84*t^6-56*t^5-63*t^4-36*t^3+46*t^2-12*t+1)*z,
2*t*y^5+z*y^2+(-2*t^11+8*t^8-20*t^6-12*t^5+40*t^3+8*t^2-10*t-20)*z^3*y+8*t^14
-32*t^11+48*t^8-t^7-32*t^5-6*t^4+9*t^2-t,
-z*y^3+(t^7-2*t^4+3*t^2+t)*y+(-2*t^6+4*t^3+2*t-2)*z^2,
2*t^2*y^3+z^2*y^2+(-2*t^5+4*t^2-6)*z^4*y+(4*t^8-t^7-8*t^5+2*t^4-4*t^3+5*t^2-t)*z,
z^3*y^2+2*t^3*y+(-t^7+2*t^4+t^2-t)*z^2,
-t*z*y^2-2*z^3*y+t^8-2*t^5-t^3+t^2,
-t^3*y^2-2*t^2*z^2*y+(t^6-2*t^3-t+1)*z^4,
z^5-t^4]
530msec + gc : 280msec
[93] gr(B,[t,z,y,x]);
[x^10-t,x^8-z,x^31-x^6-x-y]
0msec + gc : 10msec

順序 [x,y,z,t] におけるグレブナ基底は, 基底の数も多く, それぞれの式も大きい. しかし, 順序 [t,z,y,x] にもとでは, B がすでにグレブナ基底となっている. 大雑把にいえば, 辞書式順序でグレブナ基底を求めることは, 左側の (順序の高い) 変数を, 右側の (順序の低い) 変数で書き表すことであり, この例の場合は, t, z, y が既に x で表されていることからこのような極端な結果となったわけである. 実際に現れる計算においては, このように選ぶべき変数順序が明らかであることは少なく, 試行錯誤が必要な場合もある.

7.5 有理式を係数とするグレブナ基底計算

gr() などのトップレベル函数は, いずれも, 入力多項式リストに現れる変数 (不定元) と, 変数リストに現れる変数を比較して, 変数リストにない変数が入力多項式に現れている場合には, 自動的に, その変数を, 係数体の元として扱う.

[63] Ord=2$
[64] gr([a*x+b*y-c,d*x+e*y-f],[x,y]);
[(-e*a+d*b)*x-f*b+e*c,(-e*a+d*b)*y+f*a-d*c]

この例では, a, b, c, d が係数体の元として扱われる. すなわち, 有理函数体 F = Q(a,b,c,d) 上の 2 変数多項式環 F[x,y] におけるグレブナ基底を求めることになる. 注意すべきことは, 係数が体として扱われていることである. すなわち, 係数の間に多項式としての共通因子があった場合には, 結果からその因子は除かれているため, 有理数体上の多項式環上の問題として考えた場合の結果とは一般には異なる.

7.6 グレブナ基底に関する函数

7.6.1 gr, grm, hgr, hgrm

gr(plist,vlist) grm(plist,vlist) hgr(plist,vlist) hgrm(plist,vlist)

:: グレブナ基底の計算 return リスト plist, vlist リスト

• 標準ライブラリの ‘gr’ で定義されている.

• いずれも, 多項式リスト plist の, 変数順序 vlist に関するグレブナ基底を求める.

• vlist は不定元のリスト. vlist に現れない不定元は, 係数体に属すると見なされる.

• grm(), hgrm() はモジュラ演算を用いた高速化, hgr() hgrm() は斉次化を用いた安定化を行う.

• 変数順序型は, 大域変数 Ord の値が用いられる.

• 解が有限個と推測される場合には, grm(), hgrm() が有効.

[0] load("gr")$
[44] Ord=2$
[45] load("cyclic")$
[55] P=cyclic(5);
[c4*c3*c2*c1*c0-1,(((c3+c4)*c2+c4*c3)*c1+c4*c3*c2)*c0+c4*c3*c2*c1,
((c2+c4)*c1+c4*c3)*c0+c3*c2*c1+c4*c3*c2,(c1+c4)*c0+c2*c1+c3*c2+c4*c3,
c0+c1+c2+c3+c4]
[56] G=grm(P,[c0,c1,c2,c3,c4]);
[c0+c1+c2+c3+c4,...]
参照  Ord

7.6.2 dp_ord
dp_ord(order)

:: 変数順序型の設定

return 1

order 整数

• 変数順序型を order に設定する. gr() 等のトップレベル函数は大域変数 Ord の値を dp_ord() の引数として変数順序型を設定している.

• トップレベル函数以外の函数を直接呼び出す場合には, この函数により変数順序型を正しく設定しなければならない.

[19] dp_ord(0)$
[20] <<1,2,3>>+<<3,1,1>>;
(1)*<<1,2,3>>+(1)*<<3,1,1>>
[21] dp_ord(2)$
[22] <<1,2,3>>+<<3,1,1>>;
(1)*<<3,1,1>>+(1)*<<1,2,3>>
参照  Ord

7.6.3 dp_ptod

dp_ptod(poly,vlist)

:: 多項式を分散表現多項式に変換する.

return 分散表現多項式 poly 多項式 vlist リスト

• 変数順序 vlist および現在の変数順序型に従って分散表現多項式に変換する.

• vlist に含まれない不定元は, 係数体に属するとして変換される.

[50] dp_ord(0);
1
[51] dp_ptod((x+y+z)^2,[x,y,z]);
(1)*<<2,0,0>>+(2)*<<1,1,0>>+(1)*<<0,2,0>>+(2)*<<1,0,1>>+(2)*<<0,1,1>>
+(1)*<<0,0,2>>
[52] dp_ptod((x+y+z)^2,[x,y]);
(1)*<<2,0>>+(2)*<<1,1>>+(1)*<<0,2>>+(2*z)*<<1,0>>+(2*z)*<<0,1>>+(z^2)*<<0,0>>
参照  dp_dtop, dp_ord

7.6.4 dp_dtop
dp_dtop(dpoly,vlist)

::

return 多項式 dpoly 分散表現多項式 vlist リスト

• 分散表現多項式を, 与えられた不定元リストを用いて多項式に変換する.

• 不定元リストは, 長さ分散表現多項式の変数の個数と一致していれば何でもよい.

[53] T=dp_ptod((x+y+z)^2,[x,y]);
(1)*<<2,0>>+(2)*<<1,1>>+(1)*<<0,2>>+(2*z)*<<1,0>>+(2*z)*<<0,1>>+(z^2)*<<0,0>>
[54] P=dp_dtop(T,[a,b]);
z^2+(2*a+2*b)*z+a^2+2*b*a+b^2

7.6.5 dp_nf

dp_nf(indexlist,dpoly,dpolyarray,fullreduce)

:: 分散表現多項式の正規形を求める.

return 分散表現多項式 indexlist リスト dpoly 分散表現多項式

dpolyarray

配列

fullreduce フラグ

• 分散表現多項式 dpoly の正規形を求める.

• dpolyarray は分散表現多項式を要素とするベクトル, indexlist は正規化計算に用いる dpolyarray の

要素のインデックスのリスト.

• fullreduce が 0 でないとき全ての項に対して簡約を行う. fullreduce が 0 のとき頭項のみに対して簡約を行う.

• indexlist で指定された多項式は, 前の方のものが優先的に使われる.

• 一般には indexlist の与え方により函数の値は異なる可能性があるが, グレブナ基底に対しては一意的に定まる.

[0] load("gr")$
[45] load("katsura")$
[50] K=katsura(4)$
[51] length(K)$
5
[52] Ord=2$
[53] dp_ord(2)$
[54] DP1=newvect(5)$
[55] V=[u0,u1,u2,u3,u4]$
[56] for(I=0;I<5;I++)DP1[I]=dp_ptod(K[I],V);
[57] G=gr(K,V)$
[58] length(G);
5
[59] DP2=newvect(5)$
[60] for(I=0;I<5;I++)DP2[I]=dp_ptod(G[I],V);
[61] T=dp_ptod((u0-u1+u2-u3+u4)^2,V)$
[62] dp_dtop(dp_nf([0,1,2,3,4],T,DP1,1),V);
u4^2+(6*u3+2*u2+6*u1-2)*u4+9*u3^2+(6*u2+18*u1-6)*u3+u2^2+(6*u1-2)*u2+9*u1^2-6*u1+1
[63] dp_dtop(dp_nf([4,3,2,1,0],T,DP1,1),V);
-5*u4^2+(-4*u3-4*u2-4*u1)*u4-u3^2-3*u3-u2^2+(2*u1-1)*u2-2*u1^2-3*u1+1
[64] dp_dtop(dp_nf([0,1,2,3,4],T,DP2,1),V);
-1138087976845165778088612297273078520347097001020471455633353049221045677593
0005716505560062087150928400876150217079820311439477560587583488*u4^15+...
[65] dp_dtop(dp_nf([4,3,2,1,0],T,DP2,1),V);
-1138087976845165778088612297273078520347097001020471455633353049221045677593
0005716505560062087150928400876150217079820311439477560587583488*u4^15+...
[66] @64==@65;
1
参照  dp_dtop, dp_ord, p_nf

7.6.6 dp_hm, dp_ht, dp_hc, dp_rest
dp_hm(dpoly)

:: 頭単項式を取り出す.

dp_ht(dpoly)

:: 頭項を取り出す.

dp_hc(dpoly)

:: 頭係数を取り出す.

dp_rest(dpoly)

:: 頭単項式を取り除いた残りを返す.

return  dp_hm(), dp_ht(), dp_rest() : 分散表現多項式, dp_hc() : 数または多項式

dpoly 分散表現多項式

• これらは, 分散表現多項式の各部分を取り出すための函数である.

• 分散表現多項式 p に対し次が成り立つ.

  p = dp_hm(p) + dp_rest(p)
  dp_hm(p) = dp_hc(p) dp_ht(p)
   [87] dp_ord(0)$
   [88] X=ptozp((a46^2+7/10*a46+7/48)*u3^4-50/27*a46^2-35/27*a46-49/216)$
   [89] T=dp_ptod(X,[u3,u4,a46])$
   [90] dp_hm(T);
   (2160)*<<4,0,2>>
   [91] dp_ht(T);
   (1)*<<4,0,2>>
   [92] dp_hc(T);
   2160
   [93] dp_rest(T);
   (1512)*<<4,0,1>>+(315)*<<4,0,0>>+(-4000)*<<0,0,2>>+(-2800)*<<0,0,1>>
   +(-490)*<<0,0,0>>

7.6.7 dp_td, dp_sugar, dp_true_sugar
dp_td(dpoly)

:: 頭項の全次数を返す.

dp_sugar(dpoly)

:: 多項式の sugar を返す.

dp_true_sugar([onoff ])

:: dp_sugar() が, 全次数を意味するか, 本来の sugar を意味するかの選択, 表示.

return 自然数 dpoly 分散表現多項式 onoff フラグ

• dp_td() は, 頭項の全次数, すなわち各変数の指数の和を返す.

• 分散表現多項式が生成されると, sugar と呼ばれるある整数が付与される. この値は dp_true_sugar() により設定される値が 0 の時多項式としての全次数, 0 でない時, 仮想的に斉次化して計算した場合に結果が持つ全次数の値となる. デフォルトでは 0 が設定されている. すなわち dp_sugar() は多項式としての全次数を返す.

• dp_true_sugar() は, 引数がある場合, 引数が 0 ならば 0, 引数が 0 でないならば 1 を内部のフラグの値に設定する. 引数のあるなしにかかわらず, 現在 (設定後) の状態を返す.

• sugar は, グレブナ基底計算における正規化対の選択のストラテジを決定するための重要な指針となる.

[87] dp_ord(0)$
[88] X=ptozp((a46^2+7/10*a46+7/48)*u3^4-50/27*a46^2-35/27*a46-49/216)$
[89] T=dp_ptod(X,[u3,u4,a46])$
[90] dp_td(dp_rest(T));
5
[91] dp_true_sugar();
0
[92] dp_sugar(T);
6

7.6.8 dp_lcm

dp_lcm(dpoly1,dpoly2)

:: 最小公倍項を返す.

return 分散表現多項式

dpoly1, dpoly2

分散表現多項式

• それぞれの引数の頭項の最小公倍項を返す. 係数は 1 である.

[100] dp_lcm(<<1,2,3,4,5>>,<<5,4,3,2,1>>);
(1)*<<5,4,3,4,5>>
参照  dp_ht

7.6.9 dp_redble
dp_redble(dpoly1,dpoly2)

:: 頭項どうしが整除可能かどうか調べる.

return 整数

dpoly1, dpoly2

分散表現多項式

• dpoly1 の頭項が dpoly2 の頭項で割り切れれば 1, 割り切れなければ 0 を返す.

• 多項式の簡約を行う際, どの項を簡約できるかを探すのに用いる.

[148] C;
(1)*<<1,1,1,0,0>>+(1)*<<0,1,1,1,0>>+(1)*<<1,1,0,0,1>>+(1)*<<1,0,0,1,1>>
[149] T;
(3)*<<2,1,0,0,0>>+(3)*<<1,2,0,0,0>>+(1)*<<0,3,0,0,0>>+(6)*<<1,1,1,0,0>>
[150] for ( ; T; T = dp_rest(T)) print(dp_redble(T,C));
0
0
0

参照  dp_red

7.6.10 dp_subd

dp_subd(dpoly1,dpoly2)

:: 頭項の商単項式を返す.

return 分散表現多項式

dpoly1, dpoly2

分散表現多項式

• dp_ht(dpoly1)/dp_ht(dpoly2) を求める. 結果の係数は 1 である.

• 割り切れることがあらかじめわかっている必要がある.

[162] dp_subd(<<1,2,3,4,5>>,<<1,1,2,3,4>>);
(1)*<<0,1,1,1,1>>
参照  dp_red

7.6.11 dp_red

dp_red(dpoly1,dpoly2,dpoly3)

:: 一回の簡約操作

return リスト

dpoly1, dpoly2, dpoly3

分散表現多項式

vlist

• dpoly1 + dpoly2 なる分散表現多項式を dpoly3 で 1 回簡約する.

• 簡約される項は dpoly2 の頭項である. 従って, dpoly2 の頭項が dpoly3 の頭項で割り切れることがあらかじめわかっていなければならない.

• 引数が整数係数の時, 簡約は, 分数が現れないよう, 整数 a, b, 項 t により a(dpoly1 + dpoly2)-bt

dpoly3 として計算される.

• 結果は, [a dpoly1,a dpoly2 - bt dpoly3] なるリストである.

[157] D=(3)*<<2,1,0,0,0>>+(3)*<<1,2,0,0,0>>+(1)*<<0,3,0,0,0>>;
(3)*<<2,1,0,0,0>>+(3)*<<1,2,0,0,0>>+(1)*<<0,3,0,0,0>>
[158] R=(6)*<<1,1,1,0,0>>;
(6)*<<1,1,1,0,0>>
[159] C=12*<<1,1,1,0,0>>+(1)*<<0,1,1,1,0>>+(1)*<<1,1,0,0,1>>;
(12)*<<1,1,1,0,0>>+(1)*<<0,1,1,1,0>>+(1)*<<1,1,0,0,1>>
[160] dp_red(D,R,C);
[(6)*<<2,1,0,0,0>>+(6)*<<1,2,0,0,0>>+(2)*<<0,3,0,0,0>>,(-1)*<<0,1,1,1,0>>
+(-1)*<<1,1,0,0,1>>]
参照  dp_nf

7.6.12 p_nf

p_nf(poly,plist,vlist,otype)

:: 多項式の正規形を求める.

return 多項式 poly 多項式 plist,vlist リスト otype 整数

• ‘gr’ で定義されている.

• 多項式の, 多項式リストによる正規形を求める.

• dp_nf() に対する一つのインタフェースである.

• poly および plist は, 変数順序 vlist および変数順序型 otype に従って分散表現多項式に変換され,

  dp_nf() に渡される.

• dp_nf() は fullreduce が 1 で呼び出される.

• 結果は多項式に変換されて出力される.

• 内部で dp_ord(otype) を実行するため, 大域変数 Ord と実際の設定が異なることもあり得る.

   [78] Ord = 2$
   [79] K = katsura(5)$
   [80] V = [u5,u4,u3,u2,u1,u0]$
   [81] NOCRIB = 1$
   [82] G = grm(K,V)$
   [83] p_nf(K[1],G,V,2);
   0
   [84] p_nf(K[1],G,V,1);
   2*u4*u0+(2*u3+2*u5)*u1+u2^2-u4
参照  dp_ptod, dp_dtop, dp_ord, dp_nf

7.6.13 p_terms
p_terms(poly,vlist)

:: 多項式にあらわれる単項をリストにする.

return リスト poly 多項式 vlist リスト

• ‘gr’ で定義されている.

• 多項式を単項に展開した時に現れる項をリストにして返す. 項の順序はその時の変数順序型および vlist の順序による.

• グレブナ基底はしばしば係数が巨大になるため, 実際にどの項が現れているのかを見るためなどに用いる.

   [232] Ord=2$

[233] G=grm(katsura(5),[u5,u4,u3,u2,u1,u0])$
[234] p_terms(G[0],[u5,u4,u3,u2,u1,u0]);
[u5,u0^31,u0^30,u0^29,u0^28,u0^27,u0^26,u0^25,u0^24,u0^23,u0^22,u0^21,u0^20,
u0^19,u0^18,u0^17,u0^16,u0^15,u0^14,u0^13,u0^12,u0^11,u0^10,u0^9,u0^8,u0^7,
u0^6,u0^5,u0^4,u0^3,u0^2,u0,1]

7.6.14 katsura, hkatsura, cyclic, hcyclic
katsura(n)
hkatsura(n)
cyclic(n)
hcyclic(n)

:: 多項式リストの生成

return リスト n 整数

• katsura() は ‘katsura’, cyclic() は ‘cyclic’ で定義されている.

• グレブナ基底計算でしばしばテスト, ベンチマークに用いられる katsura, cyclic およびその斉次化を生成する.

• cyclic は Arnborg, Lazard, Davenport などの名で呼ばれることもある.
[74] load("katsura")$
[79] load("cyclic")$
[89] katsura(5);
[u0+2*u4+2*u3+2*u2+2*u1+2*u5-1,2*u4*u0-u4+2*u1*u3+u2^2+2*u5*u1,
2*u3*u0+2*u1*u4-u3+(2*u1+2*u5)*u2,2*u2*u0+2*u2*u4+(2*u1+2*u5)*u3-u2+u1^2,
2*u1*u0+(2*u3+2*u5)*u4+2*u2*u3+2*u1*u2-u1,
u0^2-u0+2*u4^2+2*u3^2+2*u2^2+2*u1^2+2*u5^2]
[90] hkatsura(5);
[-t+u0+2*u4+2*u3+2*u2+2*u1+2*u5,
-u4*t+2*u4*u0+2*u1*u3+u2^2+2*u5*u1,-u3*t+2*u3*u0+2*u1*u4+(2*u1+2*u5)*u2,
-u2*t+2*u2*u0+2*u2*u4+(2*u1+2*u5)*u3+u1^2,
-u1*t+2*u1*u0+(2*u3+2*u5)*u4+2*u2*u3+2*u1*u2,
-u0*t+u0^2+2*u4^2+2*u3^2+2*u2^2+2*u1^2+2*u5^2]
[91] cyclic(6);
[c5*c4*c3*c2*c1*c0-1,
((((c4+c5)*c3+c5*c4)*c2+c5*c4*c3)*c1+c5*c4*c3*c2)*c0+c5*c4*c3*c2*c1,
(((c3+c5)*c2+c5*c4)*c1+c5*c4*c3)*c0+c4*c3*c2*c1+c5*c4*c3*c2,
((c2+c5)*c1+c5*c4)*c0+c3*c2*c1+c4*c3*c2+c5*c4*c3,
(c1+c5)*c0+c2*c1+c3*c2+c4*c3+c5*c4,c0+c1+c2+c3+c4+c5]
[92] hcyclic(6);
[-c^6+c5*c4*c3*c2*c1*c0,
((((c4+c5)*c3+c5*c4)*c2+c5*c4*c3)*c1+c5*c4*c3*c2)*c0+c5*c4*c3*c2*c1,
(((c3+c5)*c2+c5*c4)*c1+c5*c4*c3)*c0+c4*c3*c2*c1+c5*c4*c3*c2,
((c2+c5)*c1+c5*c4)*c0+c3*c2*c1+c4*c3*c2+c5*c4*c3,
(c1+c5)*c0+c2*c1+c3*c2+c4*c3+c5*c4,c0+c1+c2+c3+c4+c5]
参照  dp_dtop, Ord

第 8 章: 代数的数に関する演算 76

8 代数的数に関する演算

8.1 代数的数の表現

Asir においては, 代数体という対象は定義されない. 独立した対象として定義されるのは, 代数的数である. 代数体は, 有理数体に, 代数的数を有限個順次添加した体として仮想的に定義される. 新たな代数的数は, 有理数およびこれまで定義された代数的数の多項式を係数とする 1 変数多項式を定義多項式として定義される. 以下, ある定義多項式の根として定義された代数的数を, root と呼ぶことにする.

     [0] A0=newalg(x^2+1);
     (#0)
     [1] A1=newalg(x^3+A0*x+A0);
     (#1)
     [2]  [type(A0),ntype(A0)];
     [1,2]

この例では, A0 は x^2+1=0 の根, A1 は, その A0 を係数に含む x^3+A0*x+A0=0 の根として定義されて

いる.

newalg() の引数すなわち定義多項式には次のような制限がある.

1. 定義多項式は 1 変数多項式でなければならない.

2. newalg() の引数である定義多項式は, 代数的数を含む式の簡単化のために用いられる. この簡単化は, 組み込み函数 srem() に相当する内部ルーチンを用いて行われる. このため, 定義多項式の主係数は, 有理数になっている必要がある.

3. 定義多項式の係数はすでに定義されている root の有理数係数多項式でなければならない.

4. 定義多項式は, その係数に含まれる全ての root を有理数に添加した体上で既約でなければならない.

newalg() が行う引数チェックは, 1 および 2 のみである. 特に, 引数の定義多項式の既約性は全くチェックされない. これは既約性のチェックが多大な計算量を必要とするためで, この点に関しては, ユーザの責任に任されている.

一旦 newalg() によって定義された代数的数は, 数としての識別子を持ち, また, 数の中では代数的数としての識別子を持つ. (type(), vtype() 参照.) さらに, 有理数と, root の有理式も同様に代数的数となる.

     [87] N=(A0^2+A1)/(A1^2-A0-1);
     ((#1+#0^2)/(#1^2-#0-1))
     [88] [type(N),ntype(N)];
     [1,2]

例からわかるように, rootは #n と表示される. しかし, ユーザはこの形では入力できない. root は変数に格納して用いるか, あるいは alg(n) により取り出す. また, 効率は落ちるが, 全く同じ引数 (変数は異なっていてもよい) により newalg() を呼べば, 新しい代数的数は定義されずに既に定義されたものが得られる.

     [90] alg(0);
     (#0)
     [91] newalg(t^2+1);

     (#0)

root の定義多項式は, defpoly() により取り出せる.

     [96] defpoly(A0);
     t#0^2+1
     [97] defpoly(A1);
     t#1^3+t#0*t#1+t#0

ここで現れた, t#0, t#1 はそれぞれ #0, #1 に対応する不定元である. これらもユーザが入力することはできない. var() で取り出すか, あるいは algv(n) により取り出す.

     [98] var(@);
     t#1
     [99] algv(0);
     t#0
     [100]

8.2 代数的数の演算

前節で, 代数的数の表現, 定義について述べた. ここでは, 代数的数を用いた演算について述べる. 代数的数に関しては, 組み込み函数として提供されている機能はごく少数で, 大部分はユーザ定義函数により実現されている. ファイルは, ‘sp’ で, ‘gr’ と同様 Asir の標準ライブラリディレクトリにおかれている. なお, ‘sp’ で定義された函数の中には ‘gr’ のグレブナ基底函数を用いるものもあるので, 同時に load() しておくとよい.

     [0] load("gr")$
     [1] load("sp")$

あるいは, 常に用いるならば, ‘$HOME/.asirrc’ に書いておくのもよい.

root はその他の数と同様, 四則演算が可能となる. しかし, 定義多項式による簡単化は自動的には行われないので, ユーザの判断で適宜行わなければならない. 特に, 分母が 0 になる場合に致命的なエラーとなるため, 実際に分母を持つ代数的数を生成する場合には細心の注意が必要となる.

代数的数の, 定義多項式による簡単化は, simpalg() で行う.

     [49] T=A0^2+1;
     (#0^2+1)
     [50] simpalg(T);
     0

simpalg() は有理式の形をした代数的数を, 多項式の形に簡単化する.

     [39] A0=newalg(x^2+1);
     (#0)
     [40] T=(A0^2+A0+1)/(A0+3);
     ((#0^2+#0+1)/(#0+3))
     [41] simpalg(T);
     (3/10*#0+1/10)

[42] T=1/(A0^2+1);
((1)/(#0^2+1))
[43] simpalg(T);
div : division by 0
stopped in invalgp at line 258 in file "/usr/local/lib/asir/sp"
258                     return 1/A;
(debug)

この例では, 分母が 0 の代数的数を簡単化しようとして 0 による除算が生じたため, ユーザ定義函数である simpalg() の中でデバッガが呼ばれたことを示す. simpalg() は, 代数的数を係数とする多項式の各係数を簡単化できる.

[43] simpalg(1/A0*x+1/(A0+1));
(-#0)*x+(-1/2*#0+1/2)

代数的数を係数とする多項式の基本演算は, 適宜 simpalg() を呼ぶことを除けば通常の場合と同様であるが, 因数分解などで頻繁に用いられるノルムの計算などにおいては, root を不定元に置き換える必要が出てくる.

この場合, algptorat() を用いる.
[83] A0=newalg(x^2+1);
(#0)
[84] A1=newalg(x^3+A0*x+A0);
(#1)
[85] T=(2*A0+A1*A0+A1^2)*x+(1+A1)/(2+A0);
(#1^2+#0*#1+2*#0)*x+((#1+1)/(#0+2))
[86] S=algptorat(T);
(((t#0+2)*t#1^2+(t#0^2+2*t#0)*t#1+2*t#0^2+4*t#0)*x+t#1+1)/(t#0+2)
[87] algptorat(coef(T,1));
t#1^2+t#0*t#1+2*t#0

このように, algptorat() は, 多項式, 数に含まれる root を, 対応する不定元, すなわち #n に対する t#n に置き換える. 既に述べたように, この不定元はユーザが入力することはできない. これは, ユーザの入力した不定元と, root に対応する不定元が一致しないようにするためである.

逆に, root に対応する不定元を, 対応する root に置き換えるためには rattoalgp() を用いる.

[88] rattoalgp(S,[alg(0)]);
(((#0+2)/(#0+2))*t#1^2+((#0^2+2*#0)/(#0+2))*t#1+((2*#0^2+4*#0)/(#0+2)))*x
+((1)/(#0+2))*t#1+((1)/(#0+2))
[89] rattoalgp(S,[alg(0),alg(1)]);
(((#0^3+6*#0^2+12*#0+8)*#1^2+(#0^4+6*#0^3+12*#0^2+8*#0)*#1+2*#0^4+12*#0^3
+24*#0^2+16*#0)/(#0^3+6*#0^2+12*#0+8))*x+(((#0+2)*#1+#0+2)/(#0^2+4*#0+4))
[90] rattoalgp(S,[alg(1),alg(0)]);
(((#0+2)*#1^2+(#0^2+2*#0)*#1+2*#0^2+4*#0)/(#0+2))*x+((#1+1)/(#0+2))
[91] simpalg(@89);
(#1^2+#0*#1+2*#0)*x+((-1/5*#0+2/5)*#1-1/5*#0+2/5)
[92] simpalg(@90);
(#1^2+#0*#1+2*#0)*x+((-1/5*#0+2/5)*#1-1/5*#0+2/5)

rattoalgp() は, 置換の対象となる root のリストを第 2 引数にとり, 左から順に, 対応する不定元を置き換えて行く. この例は, 置換する順序を換えると簡単化を行わないことにより結果が一見異なるが, 簡単化により実は一致することを示している. algptorat(), rattoalgp() は, ユーザが独自の簡単化を行いたい場合などにも用いることができる.

8.3 代数体上での 1 変数多項式の演算

‘sp’ では, 1 変数多項式に限り, GCD, 因数分解およびそれらの応用として最小分解体を求める函数を提供している.

8.3.1 GCD

代数体上での GCD は gcda() により計算される. この函数は, gr のグレブナ基底を用いている. モジュラ演算による方法が実用上最も高速とされているが, 現在 Asir 上では実現されていないため, 次善の策としてグレブナ基底を用いている.

[0] X=x^6+3*x^5+6*x^4+x^3-3*x^2+12*x+16;
x^6+3*x^5+6*x^4+x^3-3*x^2+12*x+16
[1] A=newalg(X);
(#0)
[2] S = x^3+(3*A+3)*x^2+(3*A^2+6*A+3)*x+(A^3+3*A^2+3*A+4);
x^3+(3*#0+3)*x^2+(3*#0^2+6*#0+3)*x+(#0^3+3*#0^2+3*#0+4)
[3] load("gr")$
[47] load("sp")$
[86] gcda(X,S);
12*x^2+(-#0^5-#0^4-2*#0^3+7*#0^2+13*#0+8)*x+(-2*#0^5-4*#0^4-8*#0^3+14*#0^2
+16*#0-16)

8.3.2 無平方分解, 因数分解

無平方分解は, 多項式とその微分との GCD の計算から始まるもっとも一般的なアルゴリズムを採用している. このため, 無平方の場合に最も計算時間が多くかかることになる. 函数は asq() である.

[116] A=newalg(x^2+x+1);
(#4)
[117] T=simpalg((x+A+1)*(x^2-2*A-3)^2*(x^3-x-A)^2);
x^11+(#4+1)*x^10+(-4*#4-8)*x^9+(-10*#4-4)*x^8+(16*#4+20)*x^7+(24*#4-6)*x^6
+(-29*#4-31)*x^5+(-15*#4+28)*x^4+(38*#4+29)*x^3+(#4-23)*x^2+(-21*#4-7)*x
+(3*#4+8)
[118] asq(T);
[[x^5+(-2*#4-4)*x^3+(-#4)*x^2+(2*#4+3)*x+(#4-2),2],[x+(#4+1),1]]

結果は通常と同様に, [因子, 重複度] のリストとなるが, 全ての因子の積は, もとの多項式と定数倍の差はあり得る. これは, 因子を整数係数にして見やすくするためで, 因数分解でも同様である.

代数体上での因数分解は, Trager によるノルム法を改良したもので, 特にある多項式に対し, その根を添加した体上でその多項式自身を因数分解する場合に特に有効である.

     [119] af(T,[A]);
     [[x^3-x+(-#4),2],[x^2+(-2*#4-3),2],[x+(#4+1),1]]

引数は 2 つで, 第 2 引数は, root のリストである. 因数分解は有理数体に, それらの root を添加した体上で行われる. root の順序には制限がある. すなわち, 後で定義されたものほど前の方にこなければならない. 並べ換えは, 自動的には行われない. ユーザの責任となる.

     [120] B=newalg(x^2-2*A-3);
     (#5)
     [121] af(T,[B,A]);
     [[x+(#5),2],[x^3-x+(-#4),2],[x+(-#5),2],[x+(#4+1),1]]

8.3.3 最小分解体

やや特殊な演算ではあるが, 前節の因数分解を反復適用することにより, 多項式の最小分解体を求めることができる. 函数は sp() である.

     [103] sp(x^5-2);
     [[x+(-#1),2*x+(#0^3*#1^3+#0^4*#1^2+2*#1+2*#0),2*x+(-#0^4*#1^2),2*x
     +(-#0^3*#1^3),x+(-#0)],[[(#1),t#1^4+t#0*t#1^3+t#0^2*t#1^2+t#0^3*t#1+t#0^4],
     [(#0),t#0^5-2]]]

sp() は 1 引数で, 結果は [1 次因子のリスト, [[root, algptorat(定義多項式)] のリスト] なるリ

ストである. 第 2 要素の [root,algptorat(定義多項式)] のリストは, 右から順に, 最小分解体が得られるまで添加していった root を示す. その定義多項式は, その直前までの root を添加した体上で既約であることが保証されている.

結果の第 1 要素である 1 次因子のリストは, 第 2 要素の root を全て添加した体上での, sp() の引数の多項式の全ての因子を表す. その体は最小分解体となっているので, 因子は全て 1 次となるわけである. af() と同様, 全ての因子の積は, もとの多項式と定数倍の差はあり得る.

8.4 代数的数に関する函数のまとめ

8.4.1 newalg
newalg(defpoly)

:: root を生成する.

return 代数的数 (root)

defpoly 多項式

• defpoly を定義多項式とする代数的数 (root) を生成する.

• defpoly に対する制限に関しては, 第 8.1 節 [代数的数の表現], 76 ページ参照.

     [0] A0=newalg(x^2-2);

参照  defpoly
8.4.2 defpoly
defpoly(alg)

:: root の定義多項式を返す.

return 多項式

alg 代数的数 (root)

• root alg の定義多項式を返す.

• root を #n とすれば, 定義多項式の主変数は t#n となる.

     [1] defpoly(A0);
     t#0^2-2
参照  newalg, alg, algv

8.4.3 alg

alg(i) :: インデックスに対応する root を返す.

return 代数的数 (root)

i 整数

• root #i を返す.

• #i はユーザが直接入力できないため, alg(i) という形で入力する.

     [2] x+#0;
     syntax error
     0
     [3] alg(0);
     (#0)
参照  newalg, algv

8.4.4 algv

algv(i) :: alg(i) に対応する不定元を返す. return 多項式 i 整数

• 多項式 t#i を返す.

• t#i はユーザが直接入力できないため, algv(i) という形で入力する.

[4] var(defpoly(A0));
t#0
[5] t#0;
syntax error
0
[6] algv(0);
t#0
参照  newalg, defpoly, alg

8.4.5 simpalg
simpalg(rat)

:: 有理式に含まれる代数的数を簡単化する.

return 有理式 rat 有理式

• ‘sp’ で定義されている.

• 数, 多項式, 有理式に含まれる代数的数を, 含まれる root の定義多項式により簡単化する.

• 数の場合, 分母があれば有理化され, 結果は root の多項式となる.

• 多項式の場合, 各係数が簡単化される.

• 有理式の場合, 分母分子が多項式として簡単化される.

[7] simpalg((1+A0)/(1-A0));
simpalg undefined
return to toplevel
[7] load("sp")$
[46] simpalg((1+A0)/(1-A0));
(-2*#0-3)
[47] simpalg((2-A0)/(2+A0)*x^2-1/(3+A0));
(-2*#0+3)*x^2+(1/7*#0-3/7)
[48] simpalg((x+1/(A0-1))/(x-1/(A0+1)));
(x+(#0+1))/(x+(-#0+1))

8.4.6 algptorat
algptorat(poly)

:: 多項式に含まれる root を, 対応する不定元に置き換える.

return 多項式 poly 多項式

• ‘sp’ で定義されている.

• 多項式に含まれる root #n を全て t#n に置き換える.

[49] algptorat((-2*alg(0)+3)*x^2+(1/7*alg(0)-3/7));
(-2*t#0+3)*x^2+1/7*t#0-3/7
参照  defpoly, algv
8.4.7 rattoalgp
rattoalgp(poly,alglist)

:: 多項式に含まれる root に対応する不定元を root に置き換える.

return 多項式 poly 多項式 alglist リスト

• ‘sp’ で定義されている.

• 第 2 引数は root のリストである. rattoalgp() は, この root に対応する不定元を, それぞれ root

に置き換える.

[51] rattoalgp((-2*algv(0)+3)*x^2+(1/7*algv(0)-3/7),[alg(0)]);
(-2*#0+3)*x^2+(1/7*#0-3/7)
参照  alg, algv

8.4.8 gcda

gcda(poly1,poly2)

:: 代数体上の 1 変数多項式の GCD

return 多項式

poly1, poly2

多項式

• ‘sp’ で定義されている.

• 2 つの 1 変数多項式の GCD を求める.

• グレブナ基底を用いている. 従って ‘gr’ も読み込んでおく必要がある.

[52] X=simpalg((x-A0-2)^2*(x+A0-1)^3);
x^5+(#0-7)*x^4+(-8*#0+15)*x^3+(17*#0-13)*x^2+(-6*#0+14)*x+(2*#0-2)
[53] Y=simpalg((x-A0-2)^3*(x+A0-1)^2);
x^5+(-#0-8)*x^4+(4*#0+21)*x^3+(#0-14)*x^2+(-12*#0-10)*x+(-2*#0-4)
[54] gcda(X,Y);
grm undefined
stopped in gcda at line 357 in file "/usr/local/lib/asir/sp"
357             L = grm(ML,cons(var(P1),VL));

(debug) quit
return to toplevel
[54] load("gr")$
[98] gcda(X,Y);
-x^4+6*x^3+(2*#0-9)*x^2+(-6*#0)*x-2
参照  gr, asq

8.4.9 sp_norm

sp_norm(alg,var,poly,alglist)

:: 代数体上でのノルムの計算

return 多項式

var poly の主変数

poly 1 変数多項式

alg  root

alglist root のリスト

• ‘sp’ で定義されている.

• poly の, alg に関するノルムをとる. すなわち, K = Q(alglist \ {alg}) とするとき, poly に現れる

alg を, alg の K 上の共役に置き換えたもの全ての積を返す.

• 結果は K 上の多項式となる.

• 計算は, res() および中国剰余定理により行なわれる.

[0] load("sp")$
[39] A0=newalg(x^2+1)$
[40] A1=newalg(x^2+A0)$
[41] sp_norm(A1,x,x^3+A0*x+A1,[A1,A0]);
x^6+(2*#0)*x^4+(#0^2)*x^2+(#0)
[42] sp_norm(A0,x,@@,[A0]);
x^12+2*x^8+5*x^4+1
参照  res, af

8.4.10 asq, af

asq(poly) :: 代数体上の 1 変数多項式の無平方分解

af(poly,alglist)

:: 代数体上の 1 変数多項式の因数分解

return リスト poly 多項式

alglist root のリスト

• いずれも ‘sp’ で定義されている. また ‘gr’ も必要である.

• root を含まない場合は整数上の函数が呼び出され高速であるが, root を含む場合には, gcda() が起動されるためしばしば極めて時間がかかる.

• af() は, 基礎体の指定, すなわち第 2 引数の, root のリストの指定が必要である.

• 第 2 引数が空リストすなわち [] の場合, fctr() が呼び出される.

• alglist で指定される root は, 後で定義されたものほど前の方に来なければならない.

• 結果は, 通常の無平方分解, 因数分解と同様 [因子, 重複度] のリストである.

• 重複度を込めた因子の全ての積は, poly と定数倍の違いがあり得る.

[99] asq(-x^4+6*x^3+(2*alg(0)-9)*x^2+(-6*alg(0))*x-2);
[[-x^2+3*x+(#0),2]]
[100] af(-x^2+3*x+alg(0),[alg(0)]);
[[x+(#0-1),1],[-x+(#0+2),1]]
参照  gcda, sqfr

8.4.11 sp

sp(poly) :: 最小分解体を求める.

return リスト poly 多項式

• ‘sp’ で定義されている. また ‘gr’ も必要である.

• 有理数係数の 1 変数多項式 poly の最小分解体, およびその体上での poly の 1 次因子への分解を求める.

• 結果は, poly の因子のリストと, 最小分解体の, 逐次拡大による表現からなるリストである.

• 最小分解体は, [root,algptorat(defpoly(root))] のリストとして表現されている. すなわち, 求

める最小分解体は, 有理数体に, この root を全て添加した体として得られる. 添加は, 右の方の root から順に行われる.

[101] L=sp(x^9-54);
[[x+(-#2),-54*x+(#1^6*#2^4),54*x+(#1^6*#2^4+54*#2),54*x+(-#1^8*#2^2),
-54*x+(#1^5*#2^5),54*x+(#1^5*#2^5+#1^8*#2^2),-54*x+(-#1^7*#2^3-54*#1),
54*x+(-#1^7*#2^3),x+(-#1)],[[(#2),t#2^6+t#1^3*t#2^3+t#1^6],[(#1),t#1^9-54]]]
[102] for(I=0,M=1;I<9;I++)M*=L[0][I];
[111] M=simpalg(M);
-1338925209984*x^9+72301961339136
[112] ptozp(M);
-x^9+54
参照  af, defpoly, algptorat

付録 A 文法の詳細

<式>: (第 4.2.9 節 [さまざまな式],  20 ページ参照)
`('<式>`)'

<式> <二項演算子> <式>

`+' <式>
`-' <式>

<左辺値> <左辺値> <代入演算子> <式>

<左辺値> `++'
<左辺値> `--'
`++' <左辺値>
`--' <左辺値>
`!' <式>
<式> `?' <式> `:' <式>
<函数> `(' <式並び> `)'

<文字列> <指数ベクトル> <アトム> <リスト>

<左辺値>:
<変数> [`['<式>`]']*

<二項演算子>:

`+' `-' `*' `/' `%' `^'(冪)
`==' `!=' `<' `>' `<=' `>=' `&&' `||'

<代入演算子>:

`=' `+=' `-=' `*=' `/=' `%=' `^='
<式並び>:
<空>
<式> [`,' <式>]*
<リスト>:
`[' <式並び> `]'

<変数>: (第 4.2.2 節 [変数および不定元], 17 ページ参照) 大文字で始まる文字列 (X,Y,Japan など)

<函数>:

小文字で始まる文字列 (fctr,gcd など)

<アトム>:

<不定元>

<数>

<不定元>: (第 4.2.2 節 [変数および不定元], 17 ページ参照)

小文字で始まる文字列 (a,bCD,c1_2 など)

<数>: (第 3.2 節 [数の型],  12 ページ参照)

<有理数> <浮動小数> <代数的数> <複素数>

<有理数>:
0, 1, -2, 3/4

<浮動小数>:

0.0, 1.2e10

<代数的数>: (第 8 章 [代数的数に関する演算], 76 ページ参照)

newalg(x^2+1), alg(0)^2+1
<複素数>:
1+@i, 2.3*@i
<文字列>:

`"' で囲まれた文字列

<指数ベクトル>: (第 7 章 [グレブナ基底の計算], 64 ページ参照)

`<<' <式並び> `>>'
<文>: (第 4.2.5 節 [文],  18 ページ参照)
<式> <終端>
<複文>
`break' <終端>
`continue' <終端>
`return' <終端>
`return' <式> <終端>
`if' `(' <式並び> `)' <文>
`if' `(' <式並び> `)' <文> `else' <文>
`for' `(' <式並び> `;' <式並び> `;' <式並び> `)' <文>
`do' <文> `while' `(' <式並び> `)' <終端>
`while' `(' <式並び> `)' <文>
`def' <函数> `(' <式並び> `)' `{' <変数宣言> <文並び> `}'
`end(quit)' <終端>
<終端>:
`;' `$'

<変数宣言>:

[`extern' <変数> [`,' <変数>]* <終端>]*
<複文>:
`{' <文並び> `}'
<文並び>:
[<文>]*

付録 B: Macintosh 版 Risa/Asir 88

付録 B Macintosh 版 Risa/Asir

B.1 ファイル構成

     dist --- asir    680X0 (X>=2) 用 asir
           |
           |- asir-sc コプロなしの 680X0 (X>=2) 用 asir
           |
           |- asir-00 68000 用 asir
           |

|- params メモリ管理に関するパラメタ

           |

|- lib --- gr グレブナ基底パッケージ

                      |

|- wang 因数分解のテスト

                      |
                      |- defs.h
                      |
                      |- ...

B.2 params

params の内容は次の通り.

     stacksize=xxx adj=xxx paristack=xxx fontsize=xxx rows=xxx cols=xxx

xxx はいずれも 10 進数. 意味は,

stacksize Asir が使用する stack の大きさ. 単位はバイト. adj adj が大きいほど GC の頻度が増す. paristack PARI 用の heap の大きさ. デフォルトは 64 KB. 単位はバイト. fontsize 表示用フォントのサイズ. rows ウィンドウの行数. cols 一行の文字数.

Asir にはデフォルトの partition size が設定されている. この値は command+i で参照, 変更できる. 使用可能なメモリのサイズはこの値により制限されるため, 必要に応じて変更する必要がある. System 7 の仮想記憶が on になっている場合, 実装メモリの量を越えて設定することはできるが, 実際に実装メモリの量を越える計算を行う場合には, 極端に実行速度は低下する.

B.3 使用法

Asir を double click すると, Asir なる window が開く. その後は UNIX 版の Asir と同様である.

付録 B: Macintosh 版 Risa/Asir 89

B.4 UNIX 版との相違点

emacs キーバインディングによるヒストリ置き換えを含むコマンドライン編集が組み込まれている. ‘!’ によるヒストリの参照は ‘!!’ と ‘!string’ のみである. ヒストリが格納されるファイルは ‘asir’ と同じディレクトリの ‘history’ というファイルで, 最大 100 行のコマンドがセーブされる. ファイルの読み込みは,

     [1] load(":dir_a:dir_b:...:filename");

による. カレントディレクトリのファイルの場合は, 先頭の : は省略できる. これはユーザに苦痛を強いるの

で, mini finder による読み込みも可能である. ‘File’ menu の ‘Load’ または, command+’L’ により mini finder が open する. また, 割り込みは, command+’.’ で行う.

付録 C: MS-DOS/DOS-Extender 版 Risa/Asir 90

付録 C MS-DOS/DOS-Extender 版 Risa/Asir

C.1 動作環境

Asir を 80386, 80486 を CPU とする MS-DOS パソコン上で, DOS-Extender を用いて動作させることができる. DOS-Extender は, go32と run386 の 2 種類に対応しているが, ここでは go32 版について述べる.

まず, 使用するパソコン上で動作する go32 を入手する. これは, IBM-PC 互換機, PC98 であれば, anony-

mous ftp, JUNET, パソコン通信ネットワーク (日経 MIX, NIFTY など) で入手できる. FM 用はやや入

手困難の可能性があるが, やはり NIFTY などで入手可能と思われる. 手に入らない場合のために, ver1.10 の ‘go32.exe’ が, 配布バイナリに付属している.

go32 の設定は, それ自身のマニュアルを参照のこと. 特に, 浮動小数点演算プロセッサを持たない機種では, 環境変数 EMU を正しく emulatorを使用するように設定しなければならない. また, asir 実行中に shell を呼び出して中断する場合, かなり大きいファイルが GO32TMPで指定されるディレクトリにできるので, ここはある程度余裕のあるディレクトリを指定しておく必要がある (10MB 程度).

入手方法を含むインストレーションについての詳細は, 第 2.3 節 [インストレーション], 3 ページ参照.

C.2 DOS 版の使用法

起動は次のように行う.

     A> go32 asir
     [0]

或いは, ‘stub.exe’ を先頭に付けた ‘asir.exe’ の場合,

     A> asir
     [0]

でよい. 以後は, UNIX 版とほぼ同様であるが, 実行中の割り込みは, ^X により行う. ^C は, go32 自体を終了させるので使用してはいけない. また, ^Z により, shell (通常 command.com) を呼び出す. この shell を exit で終了させることにより, Asir の実行を継続できる. Mac 版と同様コマンドライン編集が組み込まれて

いる. なお, graphics, dynamic object loading は未サポートである.

既に述べたように, DOS 版は UNIX 版と比較してさまざまな点で欠点, 不安定な点が多い. これらをまとめて述べておく.

• internal error で Asir 自体が終了する. (第 2.8 節 [エラー処理], 9 ページ参照)

• ^C は Asir 自体を終了させるため, 割り込みは ^X を用いる. (第 2.7 節 [割り込み], 8 ページ参照)

• 割り込みの検出は, メモリ管理部で独自に行っているため, PARI が呼び出されている間は割り込みが効かない.

付録 C: MS-DOS/DOS-Extender 版 Risa/Asir 91

• ^Z あるいは help() により他のプログラムが呼び出される場合, go32 は Asir によって使用されているメモリ領域のほとんどをディスクに退避する. このため, 大きな計算の途中では, この操作に多くの時間がかかる場合がある. また, スワップエリアとして指定されているディスクの空き容量が小さいと, 容量不足で Asir あるいは最悪の場合 MS-DOS まで落ちてしまうこともある.

• time() により報告される CPU 時間は, 計算に要した実際の経過時間である. (第 6.11.5 節 [time], 60 ページ参照)

付録 D: C の函数による機能追加 92

付録 D C の函数による機能追加

この節では, 現在の所ソースによる配布を受けた場合にのみ可能なことがらが説明されている.

D.1 インクリメンタルローディング

ソースディレクトリのサブディレクトリ ‘o’ には, C で記述されたインクリメンタルローディング用のいくつかのファイルがある. これらの詳しい説明はライブラリのマニュアルを参照のこと. これらは, ‘o’ で make することによりロード可能な状態になる. 現在, インクリメンタルローディングは Sun, VAX, DECStation, RISC NEWS でのみサポートされている. それ以外の機械については次節参照のこと.

例えば, ‘o/xxx.c’ をコンパイルする場合,

     % cd o
     % make xxx.o

とすることにより ‘xxx.o’ ができる. あとは, load("xxx.o")によりロードできる.

R3000, R4000 を CPU とするマシンの場合, CFLAGS に-G 0 を追加する必要がある. これは, global pointer

register による大域データの参照を避けるための操作である. 更に言えば, 共にリンクするライブラリもすべて -G 0 option つきでコンパイルしたものである必要がある.

D.2 asir.o を用いた機能追加

Asir に, C で記述された函数を追加する方法として, 前節で述べた, インクリメンタルローディングによる方法の他に, ‘asir.o’ を用いて新たなバイナリファイルを生成する方法がある. 特に, インクリメンタルローディングがサポートされていない機種においてはこれが唯一の拡張方法となる. ‘asir.o’ は, 標準ライブラリディレクトリ (デフォルトでは ‘/usr/local/lib/asir’) にインストールされている.

‘asir.o’ は, reg_sysf() というシンボルが未定義になっている他は, ‘asir’ と全く同様の機能を持つ. reg_sysf() をもつ他のオブジェクトファイルとリンクすることにより, 実行可能ファイルが作れるが, reg_sysf() が, 組み込み函数登録用の函数であった場合, そこで登録された函数は, インクリメンタルロードした場合と同様に使用可能となる. ここで述べた, reg_sysf() を持つオブジェクトファイルとして, 前節の ‘o’ で作られた ‘xxx.o’ ファイルを用いることができる.

<R3000, R4000 を CPU とする機械の場合>

     % cc -Wl,-D -Wl,2000000 /.../asir.o xxx.o -o yyy

<上記以外の機械の場合>

     % cc /.../asir.o xxx.o -o yyy

により ‘yyy’ ができ, ‘yyy’ は, ‘xxx.o’ に含まれる函数が組み込まれた Asir となる. ここで, 前者の 2000000

は実際には, インストール時に ‘include/Risa.tmpl’ で HEAP_START_ADDR として指定した値を用いる.

デフォルト値は, ここに示された値である.

付録 E 添付のユーザ定義函数ファイル

標準ライブラリディレクトリ (デフォルトでは ‘/usr/local/lib/asir’) にはいくつかのユーザ定義函数ファイルがおかれている. これらのうちの主なものについて説明する.

‘gr’ グレブナ基底計算パッケージ. (第 7 章 [グレブナ基底の計算], 64 ページ参照) ‘sp’ 代数的数の演算および因数分解, 最小分解体. (第 8 章 [代数的数に関する演算], 76 ページ参照)

‘alpi’
‘bgk’
‘cyclic’
‘katsura’

‘kimura’ グレブナ基底計算において, ベンチマークその他で用いられる例. (第 7.6.14 節 [katsura hkatsura

cyclic hcyclic], 75 ページ参照)

‘defs.h’ いくつかのマクロ定義. (第 4.2.10 節 [プリプロセッサ], 21 ページ参照)

‘fctrtest’

整数上の多項式の因数分解のテスト. REDUCE の ‘factor.tst’ および重複度の大きいいくつかの例を含む. これは, load() すると直ちに計算が始まる. 入手した Asir が正しく動作しているかのテストにも使うことができる.

‘fctrdata’

‘fctrtest’ で使われている例を含む, 因数分解テスト用の例. Alg[] に収められている例は,

af() (第 8.4.10 節 [asq af], 84 ページ参照) 用の例である.

[0] load("gr")$
[45] load("sp")$
[84] load("fctrdata")$
[175] cputime(1)$
0msec
[176] Alg[5];
x^9-15*x^6-87*x^3-125
0msec
[177] af(Alg[5],[newalg(Alg[5])]);
[[1,1],[75*x^2+(10*#0^7-175*#0^4-470*#0)*x+(3*#0^8-45*#0^5-261*#0^2),1],
[75*x^2+(-10*#0^7+175*#0^4+395*#0)*x+(3*#0^8-45*#0^5-261*#0^2),1],
[25*x^2+(25*#0)*x+(#0^8-15*#0^5-87*#0^2),1],[x^2+(#0)*x+(#0^2),1],
[x+(-#0),1]]
3.600sec + gc : 1.040sec

‘ifplot’ 描画 (第 6.10.1 節 [ifplot conplot plot], 55 ページ参照) のための例. IS[] には有名な曲線

の例, 変数 H, D, C, S にはトランプのハート, ダイヤ, クラブ, スペード (らしき) 曲線の例が入っている.

‘num’ 数に関する簡単な演算函数の例. ‘mat’ 行列に関する簡単な演算函数の例. ‘ratint’ 有理函数の不定積分. ‘sp’, ‘gr’ が必要. ratint() という函数が定義されているが, その返す

結果はやや複雑である. 例で説明する.

[0] load("gr")$
[45] load("sp")$
[84] load("ratint")$
[102] ratint(x^6/(x^5+x+1),x);
[1/2*x^2,
[[(#2)*log(-140*x+(-2737*#2^2+552*#2-131)),161*t#2^3-23*t#2^2+15*t#2-

付録 E: 添付のユーザ定義函数ファイル 94

     [(#1)*log(-5*x+(-21*#1-4)),21*t#1^2+3*t#1+1]]]

この例では, x^6/(x^5+x+1) の不定積分の計算を行っている. 結果は 2 つの要素からなるリストで, 第 1 要素は不定積分の有理部分, 第 2 要素は対数部分を表す. 対数部分は更にリストと

なっていて, 各要素は, [root*log(poly),defpoly] という形をしている. これは, 不定積分においては, defpoly の全ての根 root に対して root*log(poly) を作りそれらを足し合わ

せるという意味である. ここで poly は root を含んでいて, root を入れ替える場合には poly に対しても同じ操作を行うものとする. この操作を, 結果の第 2 要素の各成分に対して行って, 全てを足し合わせたものが対数部分となる.

付録 F 文献

[Becker,Weispfenning]

Becker, T., Weispfenning, V., "Groebner Bases", Graduate Texts in Math. 141, Springer-Verlag, 1993.

[Boehm,Weiser]

Boehm, H., Weiser, M., "Garbage Collection in an Uncooperative Environment", Software Practice & Experience, September 1988, 807-820.

[Batut et al.]

Batut, C., Bernardi, D., Cohen, H., Olivier, M., "User’s Guide to PARI-GP", 1993.

[Gebauer,Moeller]

Gebauer, R., Moeller, H. M., "An installation of Buchberger’s algorithm", J. of Symbolic Computation 6, 275-286.

[Giovini et al.]

Giovini, A., Mora, T., Niesi, G., Robbiano, L., Traverso, C., ""One sugar cube, please" OR Selection strategies in the Buchberger algorithm", Proc. ISSAC’91, 49-54.

[Noro,Takeshima]

Noro, M., Takeshima, T., "Risa/Asir – A Computer Algebra System", Proc. ISSAC’92, 387-396.

索引 96

索引

%

% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

A

af. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 alg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 algptorat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 algv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 append . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 args . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 asq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

B

bload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 bsave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

C

car . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 cdr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 coef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 conj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 conplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 cons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 cputime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 ctrl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 cyclic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

D

debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 defpoly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 deg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 det . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 diff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 dn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 dp dtop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 dp hc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 dp hm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 dp ht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 dp lcm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 dp nf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 dp ord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 dp ptod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 dp red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 dp redble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 dp rest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 dp subd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 dp sugar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 dp td . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 dp true sugar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

E

end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 eval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

F

fac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 fctr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 funargs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 functor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

G

gcd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 gcda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 gr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 grm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

H

hcyclic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 hgr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 hgrm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 hkatsura. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

I

idiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 ifplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 igcd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 inv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 irem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

K

katsura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

L

length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 lprime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

M

mindeg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

N

newalg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 newmat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 newvect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 nm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 nmono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 ntype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

索引 97

O

ord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

P

p nf. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 p terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 pari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 prim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 prime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 psubst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 ptozp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Q

quit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

R

random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 rattoalgp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 res . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 reverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 rtostr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

S

sdiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 setprec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 simpalg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 sp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 sp norm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 sqfr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 sqr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 srem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 strtov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 subst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

T

tcpclose. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 tcpdebug. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 tcpinit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 tdiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 tstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 tstop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

U

uc. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 ufctrhint. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

V

var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 vars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 vtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

W

which . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

P_{PARI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30, 31, 32, 58}

目次（抄）

1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 Risa/Asir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 4 ユーザ言語 Asir. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15

5 デバッガ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 6 組み込み函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 7 グレブナ基底の計算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 8 代数的数に関する演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

Appendix A 文法の詳細. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Appendix B Macintosh 版 Risa/Asir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Appendix C MS-DOS/DOS-Extender 版 Risa/Asir . . . . . . . . . . . . . . . . . . 90 Appendix D C の函数による機能追加 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

Appendix E 添付のユーザ定義函数ファイル . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

Appendix F 文献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

目次

1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.1 マニュアルの構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 Risa/Asir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.1 Risa および Asir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2 Asir の特徴 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.3 インストレーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.3.1 UNIX 版 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.3.2 Macintosh 版. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 2.3.3 DOS 版 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.4 コマンドラインオプション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.5 環境変数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7

2.6 起動から終了まで . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.7 割り込み. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8

2.8 エラー処理. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 2.9 計算結果, 特殊な数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.1 Asir で使用可能な型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 3.2 数の型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.3 不定元の型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13

4 ユーザ言語 Asir. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15

4.1 文法 — C 言語との違い . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.2 ユーザ定義函数の書き方. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16

4.2.1 ユーザ定義函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.2.2 変数および不定元 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.2.3 引数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.2.4 コメント . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.2.5 文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.2.6 return 文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.2.7 if 文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.2.8 ループ, break, return, continue . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.2.9 さまざまな式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.2.10 プリプロセッサ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5 デバッガ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.1 デバッガとは. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .23 5.2 コマンドの解説. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .23 5.3 デバッガの使用例. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25 5.4 デバッガの初期化ファイルの例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

6 組み込み函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

6.1 数の演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 6.1.1 idiv, irem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 6.1.2 fac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 6.1.3 igcd. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28 6.1.4 inv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 6.1.5 prime, lprime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 6.1.6 random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 6.1.7 nm, dn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 6.1.8 conj, real, imag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 6.1.9 eval. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30 6.1.10 pari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 6.1.11 setprec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

6.2 多項式, 有理式の演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

6.2.1 var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 6.2.2 vars. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33 6.2.3 uc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 6.2.4 coef. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34 6.2.5 deg, mindeg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 6.2.6 nmono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 6.2.7 ord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 6.2.8 sdiv, srem, sqr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36 6.2.9 tdiv. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37 6.2.10 % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 6.2.11 subst, psubst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 6.2.12 diff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 6.2.13 res. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39 6.2.14 fctr, sqfr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 6.2.15 ufctrhint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 6.2.16 ptozp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 6.2.17 prim, cont . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 6.2.18 gcd, gcdz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 6.2.19 red. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43

6.3 リストの演算. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43

6.3.1 car, cdr, cons, append, reverse, length . . . . . . . . . . . . . . . . 43

6.4 配列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 6.4.1 newvect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 6.4.2 newmat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 6.4.3 size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46 6.4.4 det . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

6.5 型を求める函数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47

6.5.1 type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47 6.5.2 ntype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 6.5.3 vtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

6.6 函数に対する操作. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49

6.6.1 functor, args, funargs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6.7 文字列に関する演算. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49

6.7.1 rtostr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.7.2 strtov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

6.8 入出力 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 6.8.1 end, quit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51 6.8.2 load. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51 6.8.3 which . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 6.8.4 output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.8.5 bsave, bload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 6.8.6 print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.9 プロセス間通信. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .54

6.9.1 tcpinit, tcpdebug, tcpclose . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.10 陰函数の描画 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

6.10.1 ifplot, conplot, plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 6.11 その他 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.11.1 ctrl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.11.2 debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.11.3 error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 6.11.4 help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 6.11.5 time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 6.11.6 cputime, tstart, tstop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 6.11.7 heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 6.11.8 version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 6.11.9 shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

7 グレブナ基底の計算. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .64

7.1 分散表現多項式. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .64 7.2 ファイルの読み込み. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .64 7.3 函数, オプション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

7.3.1 函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 7.3.2 オプション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

7.4 Ord, 変数順序の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

7.5 有理式を係数とするグレブナ基底計算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 7.6 グレブナ基底に関する函数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .67

7.6.1 gr, grm, hgr, hgrm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 7.6.2 dp ord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 7.6.3 dp ptod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 7.6.4 dp dtop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 7.6.5 dp nf. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .69 7.6.6 dp hm, dp ht, dp hc, dp rest . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 7.6.7 dp td, dp sugar, dp true sugar . . . . . . . . . . . . . . . . . . . . . . . . . 71 7.6.8 dp lcm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 7.6.9 dp redble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 7.6.10 dp subd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 7.6.11 dp red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 7.6.12 p nf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 7.6.13 p terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 7.6.14 katsura, hkatsura, cyclic, hcyclic . . . . . . . . . . . . . . . . . . . 75

8 代数的数に関する演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

8.1 代数的数の表現. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .76 8.2 代数的数の演算. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .77 8.3 代数体上での 1 変数多項式の演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

8.3.1 GCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

8.3.2 無平方分解, 因数分解 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

8.3.3 最小分解体 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

8.4 代数的数に関する函数のまとめ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

8.4.1 newalg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 8.4.2 defpoly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 8.4.3 alg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 8.4.4 algv. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .81 8.4.5 simpalg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 8.4.6 algptorat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .82 8.4.7 rattoalgp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .83 8.4.8 gcda. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .83 8.4.9 sp norm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 8.4.10 asq, af . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 8.4.11 sp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Appendix A 文法の詳細 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Appendix B Macintosh 版 Risa/Asir . . . . . . . . . . . . . . . . 88

B.1 ファイル構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

B.2 params . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 B.3 使用法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 B.4 UNIX 版との相違点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

Appendix C MS-DOS/DOS-Extender 版 Risa/Asir90

C.1 動作環境 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 C.2 DOS 版の使用法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90

Appendix D C の函数による機能追加 . . . . . . . . . . . . . . . . . . 92

D.1 インクリメンタルローディング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

D.2 asir.o を用いた機能追加 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

Appendix E 添付のユーザ定義函数ファイル. . . . . . . . . . . . .93 Appendix F 文献. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .95 索引. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96