2025年02月21日更新

 SageMath で, Galois群を求める

[1] SageMathは無料の数学ソフトで,微分積分,線形代数,代数学といった広い範囲をカバーしています.Magma と異なり,対象は個人なので,マニュアルも少しは読みやすくPDFによる解説も多いです.しかし Mathematica などの有料ソフトとは比較になりません.こちらも日本語の本は無いですが,英語の本は数冊出版されています.どなたか日本語で代数学の初歩を書いて下さるとよいのですが...

SageMathは ver9 をインストールすることも,web上でインストール無しで使える SageMathCellを使うことも,はたまたスマホで SageMathアプリを使うことも出来ますが,私としてはインストールがおすすめです.理由は[3]に書いてあります.インストールの方法などは 上の「PythonとSageMath」などに詳しいです.このあたりは Google すれば簡単なので省略します.

[2]私はSageMathは時々しか使っていないので,入門未満ですが,上記のサイトの助けを借りて,ガロア群を求めるプログラムを作成することができました.(「作成」というより「見つけた」というべきですが)
例えば f1(x)=x5x+15x+12 のガロア群を求めるには次の様に SageMathCellあるいは Jupyter notebook の入力欄に入力します.このとき,文末の「;」は不要ですが,Python と同じくインデントセンシティブです.さらに SageMathはオブジェクト指向なので,多くのメソッドはインスタンスメソッドです.Galois群を求めるにも galois_group(f) などとは出来ません.インスタンスメソッドとして f.galois_group() としないと駄目です.なおMagmaと同様に,最初の1行で「xを有理数係数多項式の変数と定める」というおまじないが必要です.なおxの多項式に名前をつけることもできます.(R_.<x> などとします. ここで"-"と<x>の間にピリオドが必要です) またMagmaでは入力文の出力コマンドは全て出力されましたが,SageMathでは一番最後のコマンドの答えのみが出力されます.複数個出力したいときは,リストにして[ ]の中に入れる必要があります.さらに既約多項式でないとGalois群は求められません.

_.<x>= PolynomialRing (QQ)
f1 = x^5+15*x+12
G1=f1. galois_group ()
[G1.order(), G1.gens(), G1.list()]

位数は order , 生成元は gensを, リストは list を使います.出力は以下の様になります.

[20,,
 [(1,2,3,4,5), (1,2,4,3)],,
 [(),
  (1,5,4,3,2),
  (1,4,2,5,3),
  (1,3,5,2,4),
  (1,2,3,4,5),
  (2,5)(3,4),
  (1,5)(2,4),
  (1,4)(2,3),
  (1,3)(4,5),
  (1,2)(3,5),
  (2,4,5,3),
  (1,5,2,3),
  (1,4,3,5),
  (1,3,4,2),
  (1,2,5,4),
  (2,3,5,4),
  (1,5,3,4),
  (1,4,5,2),
  (1,3,2,5),
  (1,2,4,3)]]

[3]SageMathは for文, if文などの制御文も非常に豊富に持っています.それを使って f(x)=x5+ax3+bx2+cx+d (-11<a,b,c<11 ,0<d<11 a,b,c,d整数)のGalois群(213*10=92610個!)を一度に計算させます.Magmaでも同様の計算をしましたが,その時は -1<a,b,c<4 ,0<d<6 でしたから,今度は約300倍の量です.(d>0の時しか考えていないのは f(x)=x5+ax3+bx2+cx+dとg(x)=x5+ax3-bx2+cx-dのGalois群が一致するからです.)

今度はインデントが必須です.

_.<x>= PolynomialRing (QQ)

for i in range(-10,11):
 for j in range(-10,11):
  for k in range(-10,11):
   for m in range(1,11):
     f=x^5+ i*x^3+j*x^2+k*x+m
     if f is_irreducible():
       g=f.galois_group()
       if g.order()<60:
        print([f,g.order(),g.gens()])

結果は次の様になります.位数が60より小さい場合に限って,f (x)の係数[a,b,c,d] と位数と生成元を出力させました.ご覧の様に C5 は1つしかなく,D5 が最も多く,F20 は固まって点在していることが分かります.なお掛かった時間は私のPCで約2分( 腕時計で測りました).私は SageMath ver.9 をインストールしているので CPU の速度が直接効いてきます.最近のPCならもっと速いのではないでしょうか?

同じ計算を SageMathCell でもやらせてみました.なんと一分経つと途中で「時間切れ」となってしまいました.最初の6つが表示されただけです.もしかすると1分以上は計算できない仕様かもしれません.SageMathで長い計算をやらせたい方は ver9でも良いので ちゃんとインストールしたほうが良いみたいです.さらにインストールした場合は「TAB による入力補完」と「ファイル保存」が使えます.この違いは大きいです.

[[-10, 5, 10, 1], 5, [(1,2,3,4,5)]]
[[-10, 10, 5, 2], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-9, -4, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-9, 9, 4, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-8, -3, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-8, 8, 3, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-7, 7, 2, 5], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-7, 10, -5, 2], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-6, -1, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-6, 6, 1, 6], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-5, 0, 5, 3], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 5, 4], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 5, 5], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 5, 6], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 5, 7], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 5, 8], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 5, 9], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 5, 10], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-5, 0, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-5, 0, 10, 9], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-5, 5, 0, 7], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-5, 7, 8, 5], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-5, 10, -10, 8], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-4, 1, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-4, 4, -1, 8], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-3, -4, 8, 1], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-3, 1, 7, 5], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-3, 2, 6, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-3, 2, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-3, 3, -2, 9], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-2, 2, -3, 10], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-2, 3, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-2, 9, -2, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-1, -10, 8, 9], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-1, -4, 7, 2], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[-1, -2, 3, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-1, 2, -2, 1], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-1, 4, 4, 1], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-1, 4, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[-1, 7, -1, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[0, -10, 10, 2], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, -3, 2, 1], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[0, 0, 0, 2], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 3], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 4], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 5], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 6], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 7], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 8], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 9], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 0, 0, 10], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 5, -5, 8], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[0, 5, -4, 1], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[0, 5, 0, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[0, 5, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[0, 10, -10, 6], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[1, 3, 1, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[1, 6, 4, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[1, 6, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[2, 1, 2, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[2, 4, -1, 4], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[2, 5, -4, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[2, 7, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[2, 8, 9, 8], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[3, -1, 3, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[3, 6, -1, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[3, 8, 6, 9], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[3, 8, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[4, -3, 4, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[4, 4, 8, 8], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[4, 9, 10, 1], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[4, 9, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[5, -5, 5, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[5, 0, 5, 1], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 2], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 3], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 4], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 5], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 6], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 7], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 8], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 9], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 0, 5, 10], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 1, 9, 5], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 10, 0, 5], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[5, 10, 5, 4], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[5, 10, 10, 4], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[6, -7, 6, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[6, 4, -9, 4], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[7, -9, 7, 3], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[7, 3, 5, 5], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[7, 5, 5, 1], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[7, 5, 9, 5], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[7, 10, -6, 5], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[8, 2, 2, 2], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[8, 5, 6, 7], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[9, 5, 3, 9], 10, [(1,2,3,4,5), (1,4)(2,3)]]
[[10, 0, 0, 5], 20, [(1,2,3,4,5), (1,2,4,3)]]
[[10, 10, 10, 3], 20, [(1,2,3,4,5), (1,2,4,3)]]

[4]SageMathの利点は Galois群の計算だけではありません.様々な群論や代数学の演算が可能です.これは Mathematica の苦手な点なので重宝しています.例えば,Magmaで(x5 + 15x + 12)のGalois群を求めた時,Gal=<(2, 4, 5, 3),(2, 5)(3, 4),(1, 3, 5, 2, 4)>となりました.これからリストを作るのはまず PermutationGroup を作ってそのリストを表示させます.

G=PermutationGroup(['(2, 4, 5, 3)','(2, 5)(3, 4)','(1, 3, 5, 2, 4)'])
G.list()

出力は以下の通りです.

[(),
 (1,4,2,5,3),
 (1,2,3,4,5),
 (1,5,4,3,2),
 (1,3,5,2,4),
 (2,5)(3,4),
 (1,4)(2,3),
 (1,2)(3,5),
 (1,5)(2,4),
 (1,3)(4,5),
 (2,3,5,4),
 (1,4,5,2),
 (1,2,4,3),
 (1,5,3,4),
 (1,3,2,5),
 (2,4,5,3),
 (1,4,3,5),
 (1,2,5,4),
 (1,5,2,3),
 (1,3,4,2)]

次にF20 を生成元から作り,Gと同型か調べます.

F20=PermutationGroup(['(1,2,3,4,5)','(2,3,5,4)'])
G.is_isomorphic(F20)

True


確かに同型となります.これで確信が持てました.また Mathematica でガロア群を計算すると置換の表現(Galois流のGalois群)しか求まりません.しかし20個も要素があると手と頭で直すのは大変です.これらを現代の表記に直すことも出来ます.「PermutationGroupElement()」というクラスメソッドを使います.

例えば,解の置換K=[[1, 2, 3, 4, 5],[5, 1, 2, 3, 4],[4, 5, 1, 2, 3],[3, 4, 5, 1, 2],[2, 3, 4, 5, 1],[1, 5, 4, 3, 2],[5, 4, 3, 2, 1],[4, 3, 2, 1, 5],[3, 2, 1, 5, 4],[2, 1, 5, 4, 3],[1, 4, 2, 5, 3],[5, 3, 1, 4, 2],[4, 2, 5, 3, 1],[3, 1, 4, 2, 5],[2, 5, 3, 1, 4],[1, 3, 5, 2, 4],[5, 2, 4, 1, 3],[4, 1, 3, 5, 2],[3, 5, 2, 4, 1],[2, 4, 1, 3, 5]]が与えられた時,これを現代の書き方に直すには次の様にします.([ ]は Pythonの内包表記に当たります. またFは「リスト」になるので,それをPermutaionGroupを使って「置換群」に直しています.)

F=[PermutationGroupElement(K[i]) for i in range(0,len(K))]
G=PermutationGroup(F)
G.list()

出力は次の様になります.これが F20 と同型なことも容易に確かめることが出来ます.

[(),
 (1,5,4,3,2),
 (1,4,2,5,3),
 (1,3,5,2,4),
 (1,2,3,4,5),
 (2,5)(3,4),
 (1,5)(2,4),
 (1,4)(2,3),
 (1,3)(4,5),
 (1,2)(3,5),
 (2,4,5,3),
 (1,5,2,3),
 (1,4,3,5),
 (1,3,4,2),
 (1,2,5,4),
 (2,3,5,4),
 (1,5,3,4),
 (1,4,5,2),
 (1,3,2,5),
 (1,2,4,3)]

SageMathでは他にも群論の計算や,剰余類の作成,共役部分群の発見など色々な事ができます.今までに使用したコマンドと合わせて, ここ にtextファイルで,まとめておきました.


Mathematica で 高次方程式へ Top pageへ

生越 茂樹 (Ogose Shigeki) All rights reserved