python sf による群論:群電卓

python sf は、普段のメモ書き数式そのままを計算させてたくて作りました。その python sf は 群論での数式にも使えます。

例えば対称群 Sn(4) における S4(3,0,2,1) 要素の共役類を下のように、エディタでメモ書きする数式に近い python sf 式で計算できます。

{g S4(3,0,2,1) g^-1 for g in SS4}  # SS4 is a set of Sn(4)
===============================
set([Sn(4)(3, 0, 2, 1), Sn(4)(1, 2, 0, 3), Sn(4)(1, 3, 2, 0), Sn(4)(2, 0, 1, 3), 
     Sn(4)(0, 2, 3, 1), Sn(4)(3, 1, 0, 2), Sn(4)(0, 3, 1, 2), Sn(4)(2, 1, 3, 0)])

これは、下の数学でのメモと殆ど同じでしょう。

{g S4(3,0,2,1) g^-1 for g ∈ SS4}  # SS4 is a set of Sn(4)

python sf により、記号の羅列に埋没しがちな抽象群での考察を、手間をかけずに具体例を交えたものにできます。誤りの入りやすい具体的な群論計算はコンピュータに押し付け、群論での多様な考察に専念できます。群論の具体例の計算は python sf 数式を書いていくだけです。プログラム開発をするわけではないので、デバッグ作業に手間をとられることもありません。

以下、通常の群論の教科書を呼んでいくときに行われる、 python sf を使った具体例での検討・考察の様子を見ていきます。

群論向けの記号定義

python sf では分野ごとに異なる 変数/関数名を、カレント・ディレクトリに設ける sfCrrntIni.py ファイルに記述しておきます。sfCrrntIni.py ファイルに宣言・定義しある変数は import することなく python sf 式で記述できます。

この群論での議論は、下の sfCrrntIni.py がカレント・ディレクトリに置かれていることを前提としています。これにより対称群 Sn(3),Sn(4),Sn(5) インスタンスを生成するクラスを S3,S4, S5, S6 の名前で扱えるようにしています。SS3,SS4,SS5 により、これらの対称群の集合を表しています。それらの交代群の集合は SA3,SA4,SA5 で表せます。また Sn(4) の部分具でもある正四面体群の辞書コンテナを dctP4 で扱えるようにしています。

type sfCrrntIni.py
import pysf.octn as oc

S5 = oc.Sn(5)
SS5= S5.setStt
SA5=set([S5(x) for x in S5.m_tplIdxStt[:5*4*3*2//2] ])

S4 = oc.Sn(4)
SS4= S4.setStt
SA4=set([S4(x) for x in S4.m_tplIdxStt[:5*4*3*2//2] ])

S3 = oc.Sn(3)
SS3= S3.setStt
SA3=set([S3(x) for x in S3.m_tplIdxStt[:3*2//2] ])


S6 = oc.Sn(6)

dctP4 = { 'e':S4(0,1,2,3)
       , 'a1':S4(0,2,3,1),'b1':S4(0,3,1,2)
       , 'a2':S4(3,1,0,2),'b2':S4(2,1,3,0)
       , 'a3':S4(1,3,2,0),'b3':S4(3,0,2,1)
       , 'a4':S4(2,0,1,3),'b4':S4(1,2,0,3)
       , 'hx':S4(2,3,0,1),'hy':S4(1,0,3,2),'hz':S4(3,2,1,0)}

dctP4I = dict(zip(dctP4.values(), dctP4.keys()))

もっと高度な群論計算をさせたい方は、それに対応するモジュールを持ってくるなり作るなりして sfCrrntIni.py の中で import してやれば python sf から使えるようになります。下の一行を sfCrrntIni.py の中に挿入するだけで、虹鱒の名で配布されている python 群論モジュールを使えるようになります。

import nzmath as nz

半群

まず半群についての python sf を使った具体的な検討・考察例を見ていきましょう。

半群であるとは推移律: (x y) z == x (y z) が成り立つことです。これは部分的に演算を定めると、それが別の演算まで定めてしまうことを意味します。演算規則の定まり方に粘着性があることを意味します。

python の辞書データ型を使えば、この半群の性質を記述できます。実際に推移律演算を実行させられます。以下では具体的に a b c d 四文字の集合の半群構造を python の辞書を使って記述・実行していきます。

python 辞書による半群演算

集合 G が半群であるとは、下のような関数を定義できることです。

f:G x G --> G
f(f(x,y),z) == f(x, f(y,z) ) for ∀ x,y,z ∈ G
{(g0,g1):g3, .... }  where g0,g1,g3, ... ∈ G

具体例で考えましょう。キャラクタ a b c d を要素とする集合 G に対して、python 辞書を使って下のように半群の演算を含んだ辞書 f を構築できます。

f={('a','a'):'b', ('a','b'):'d', ('a','c'):'a', ('a','d'):'c'}
===============================
{('a', 'b'): 'd', ('a', 'a'): 'b', ('a', 'd'): 'c', ('a', 'c'): 'a'}

この辞書では f['a','a'] は 'b' の値を持ちます。これは f('a','a') == 'b' と同じ意味だと解釈できます。この関数ともみなせる辞書は実際に f GxG --> G を計算可能です。

f={('a','a'):'b', ('a','b'):'d', ('a','c'):'a', ('a','d'):'c'}; f['a','a']
===============================
b
Python sf での 計算結果のデフォルト出力

Python sf では複数の Python sf 式を「;」で区切って記述します。ユーザーが知りたい計算結果は、最後の Python sf 式の値であることが大部分です。ですから最後の Python sf 式の値は print 命令が無くても自動的にコンソールに出力します。

上の f GxG --> G を計算する Python sf 式では「f={('a','a'):'b', ('a','b'):'d', ('a','c'):'a', ('a','d'):'c'}」の辞書コンテナ f を定義する Python sf 式に続けて、この 辞書コンテナ f を使った計算「f['a','a']」の Python sf 式を二つ目・最後に書いています。この計算結果は自動的にコンソールに「===============================\nb」文字列として打ち出されます。

なお、最後の Python sf 式の値は、カレント・ディレクトリの _dt.pvl ファイルにも出力されています。

type _dt.pvl
# python object printed out by pprint
'b'

「:=」記号を使えば、明示的にカレント・ディレクトリへの出力先ファイル名を指定できます。例えば、f 辞書コンテナを下のように f.pvl ファイルに出力できます。これらのカレント・ディレクトリに出力された値はファイル変数と読んでいます。

f:={('a','a'):'b', ('a','b'):'d', ('a','c'):'a', ('a','d'):'c'}
===============================
d

「=:」記号を使えば、カレント・ディレクトリにファイル変数として残っている計算結果を再利用できます。

=:_dt,f;(f['a','b'],f['a','b'])
===============================
('d', 'd')

この辞書は演算表の a に対応する横一列を定めています。

\    'a', 'b', 'c', 'd' 
a    ['b', 'd', 'a', 'c']

実際に、この横一行全部を、Python のリスト内包表記構文を使った下の python コードで計算できます。

f={('a','a'):'b', ('a','b'):'d', ('a','c'):'a', ('a','d'):'c'}; [f['a', y]  for x,y in sorted(f)]
===============================
['b', 'd', 'a', 'c']