sf による置換群の数値実験

● 始めに

sf のアプリケーション・ノートの一つとして、置換群への適用を行ってみました。

sf の行列変数の集まりとして置換群を作り上げてやることで、抽象的な群論の教科書を読み進めていくとき、具体的な数値実験を行いながら読んでいくことが可能になります。教科書での抽象的な定義と証明ばかりではなく、それらの具体例を作ってコンピュータ上で実際に計算できます。定理や公理の意味を、具体例を使って確認できます。

群論の教科書を読むとき、ここで提示した S3,S4,S5,D4 群を使って数値実験をしながら読み進んでもらえることを希望しています。抽象的過ぎて、定理の意味が解らないままに証明を追ってしまうことになりやすい群論が、具体例の計算により抽象度を下げられます。より群論を面白くできます。

なお、ここでの置換群モデルの sf 変数による構築は「Galois 理論の数値実験」に繋がるものです。


● 1 置換群の行列/ベクタ表現

置換群を sf の行列ファイル変数、ベクタ・ファイル変数として表現できます。sf のファイル変数として表現することで、演算操作も可能な変数にできます。置換群要素の集合を sf のインデックス・ファイル行列変数として表現することで、共役類を計算するなど S3,S4,A4,V4,S5,D4 などにおける様々の群要素の一括操作が可能になります。群の性質の確認計算が可能になります。

△ 置換の基本表現、ベクタ表現

置換群 Sn は 0,1, ... n-1 の自然数を置き換える操作であり下のような基本表現がよく使われます。
      │0, 1, 2, ., m, ... , n-1│  ---------------- (1.1)
      │i, j, k, .. p, ... ,  q │

        0 を i に, 1 を j に,  ..., n-1 を q に置換することを表現します。
        そのため 0<= i, j, k, .. p, ...q <= n-1 であり、重複がないものとします。
(1.1) 式で上側は常に 0,1,2, ... , n-1 に固定されているので、省略できます。(1.1) 式を下のような、下側だけの sf ベクタ変数として表現することができます。(多くの数学の教科書でのように巡回置換ではありません)
      < i, j, k, .. p, ... ,  q >   ----------------- (1.2)

△ 置換の行列表現

置換のベクトル表現を使えば、sf のベクタ変数として置換をコンパクトに表現できます。でも置換どうしの演算操作を行えません。置換の演算操作を可能にするために、sf の行列変数による置換表現も使います。たとえば S3 の <0,2,1> の置換に下の sf ファイル行列変数を対応させます。

//@@
    Mat = [[3]]
    Mat[<0,9,1>] = <1,0,0
                    0,0,1
                    0,1,0>
//@@@

置換と行列表現の対応のさせかたは、上の例だけで検討がつくと思います。また置換の積が行列の積に対応していることも分るとおもいます。

上の sf プロック実行を行わせることで Mat.val と名前のついた下のような sf ファイル変数ができています。

    type Mat.val
    % BaseDoubleMatrix 3,  3
    < 1, 0, 0 >
    < 0, 0, 1 >
    < 0, 1, 0 >

このような置換を表示する sf ファイル変数 Mat を複数作ってやり、その sf 行列の積を置換の積に対応させます。また、sf 置換行列と <0,1,2> 単位置換の sf ベクタ表現を掛けてやれば、置換の行列表現 Mat に対応するベクタ表現を sf に計算させられます。下のような具合です。

    Mat<0,1,2>
     sf command argment: Mat<0,1,2>
    < 0, 2, 1 >

置換群として複数の置換を纏めて扱うためには sf のインデックス・ファイル変数を使います。まず単純な S3 と呼ばれる置換群を見てみましょう。


● 2 S3 置換群

S3 置換群に対応する sf 行列ファイル変数を作ります。この行列ファイル変数は {number} のようなインデックスを付けた変数にすることができます。こうすることで、共役類を計算するときのような複数操作を、一行で記述できるようになります。

△ S3 P3{..} sf インデックス・ファイル変数の作成

下の sf プロック実行により S3 に相当する P3{0}, P3{1}, ... P3{5} の sf ファイル変数を作成できます。
//@@
    # 整数 [0,1,2] 全ての順列を Mat の行データで表現する
    Mat = [[6,3]]
    Mat[<0,6*3,1>] = <\
    0, 1, 2 # 0 -- e 単位置換
    1, 2, 0 # 1 --- 偶置換
    2, 0, 1 # 2 --- 偶置換偶

    0, 2, 1 # 3
    1, 0, 2 # 4
    2, 1, 0># 5

    MatE @= [[3]]
    MatE[*,*] = <1,1,1>

    <<0,6,1 @ j |                      # 24 = 4*3*2 個の P{k,l,m,n} 行列を誠意背
        k@ = Mat[j,0]
        l@ = Mat[j,1]
        m@ = Mat[j,2]
        P3{j}=[[3]]

        P3{j}[*,0] = MatE[*,k]
        P3{j}[*,1] = MatE[*,l]
        P3{j}[*,2] = MatE[*,m]
    >>
//@@@
 --------------------------------------  (2.1)
実際に下のように位数 6 の S3 を表現する P3{number}.val ファイルが作られています。
    dir /W P3{*.val
    P3{0}.val   P3{1}.val   P3{2}.val   P3{3}.val   P3{4}.val   P3{5}.val
なお、インデックスは P3{0} が単位行列になるように、また P3{1}, P3{2} までが隅置換群 A3 になるように配置してあります。

このように S3, P3{..} sf インデックス・ファイルを作り上げると、P3{4} の行列表示の参照は、下の sf コマンドを実行するだけで可能です。

>sf "P3{4}"
     sf command argment: P3{4}
    < 0, 1, 0 >
    < 1, 0, 0 >
    < 0, 0, 1 >

△ 置換S3 P3{..} のベクタ表現と一括操作

置換群の全体 P3{0}, ... P3{5} に対応するベクタ表現は、下の sf ループ・コマンドを使って作れます。
>sf "<<0,6,1@j|P3{j}<0,1,2> >>"
     ・
     ・
< 2, 1, 0 >
< 0, 1, 2 >
< 2, 0, 1 >
< 1, 2, 0 >
< 0, 2, 1 >
< 1, 0, 2 >
< 2, 1, 0 >

結果のベクタ・データだけを集めてコメントをつけてやり、下のような置換群のベクタ表現のテキストを作っておき、置換の行列演算結果がどんな置換になったかを判定しやすくしておきます。

    # S3 置換群のベクタ表現
    # 下の前半は A3 交代群です
    0:< 0, 1, 2 >
    1:< 2, 0, 1 >
    2:< 1, 2, 0 >

    # 下は A3 交代群ではない
    3:< 0, 2, 1 >
    4:< 1, 0, 2 >
    5:< 2, 1, 0 >
 --------------------------------------  (2.2)

S3 置換群を sf のファイル変数として表現したことにより、置換の積を行列の積として sf を使って計算できるようになります。下のような具合です。

    # P3{2} と P3{5} の積
>sf "P3{2}P3{5}"
    < 0, 1, 0 >
    < 1, 0, 0 >
    < 0, 0, 1 >

    # P3{2}P3{5} 計算結果のベクタ表現
>sf "P3{2}P3{5}<0,1,2>"
    < 1, 0, 2 >
    # (2.2) 式の一覧から、P3{2}P3{5}<0,1,2> == <1,0,2> は P3{4} と解ります

    # 下の行列計算が 0 であることでも P3{2}P3{5} == P3{4} を確認できる
>sf "P3{2}P3{5} - P3{4}"
    < 0, 0, 0 >
    < 0, 0, 0 >
    < 0, 0, 0 >

<1,0,2> のベクトルは式(2.2) のテキストより P3{3} に対応するので P3{2}P3{5}== P3{4} であると分ります。エディタのサーチ操作で確認できます。

このような sf 置換群行列の計算を繰り返すことで、下のような演算表も容易に作れます。

    A3 の演算表

         |     e,   P3{1},  P3{2}
    -----+-----------------------
    e,   |     e,   P3{1},  P3{2}
    P3{1}| P3{1},   P2{2},     e
    P3{2}| P3{2},       e,  P3{1}
この演算表を眺めていると A3 は { P3{1}^0, P3{1}^1, P3{1}^2} の巡回群であることが分ります。このことは後の Galois 理論で、3 次の多項式が可解であることの証明に使います。

上の演算表の各要素が正しいことは、下の sf 計算の結果が 0 行列になることからも確認できます。

>sf "P3{1}P3{1}-P3{2}"
     sf command argment: P3{1}P3{1}-P3{2}
    < 0, 0, 0 >
    < 0, 0, 0 >
    < 0, 0, 0 >
    # 以下 sf 式の計算結果は全て 0 行列になります
    P3{1}P3{2}-P3{0}
    P3{2}P3{1}-P3{0}
    P3{2}P3{2}-P3{1}

GPL 条件で公開されている WZ エディタのkShell マクロを使えば、計算したい行にカーソルを持っていき ctrl+ O, N の操作をするだけ上の計算を行わせられます。ホームポジションだけの操作で全ての計算処理ができます。知的作業を集中して持続できます。WZ エディタ使いの方はお試しください。

置換の偶奇は置換群を表示する行列式の値が +1 か -1 かで判別できます。ですから下のような sf ループ・コマンドで P3{..} インデックスごとの行列式の値を計算させることにより、置換群の偶奇を調べられます。

>sf "<<0,6,1@t|!det(P3{t})>>"
     sf command argment: <<0,6,1@t|!det(P3{t})>>
    <  1,  1,  1, -1, -1, -1 >
この sf 計算によっても、P3{..} 置換群の前半に A3 を固めてあることが確認できます。

このように S3 置換群を P3{..} sf インデックス・ファイル変数として表現してやったことで、複数の置換行列の積の操作を一つの sf ループ・コマンドで行わせられます。まず手始めに共役類を計算してみましょう。


△ 置換S3 P3{..} の共役類

s ∈ S3 が s1 と共役であるとは、s1 ==sx s sx^-1 for ∃sx ∈ S3 とできることを意味します。部分群の全要素の共役類類が、元の部分群であるときに、その部分群は正規部分群であるとされます。正規部分群は、その商群による分解を巡回群にできるので、ガロア理論で重要な役目を持ちます。

手始めに P3{1} の共役類全てを下の様に計算させられます

>sf "<< 0,6,1@j|P3{_n} P3{1} P3{_n}^-1 <0,1,2> >>"
< 2, 0, 1 >  #P3{1}
< 2, 0, 1 >
< 2, 0, 1 >
< 1, 2, 0 >  #P3{2}
< 1, 2, 0 >
< 1, 2, 0 >

P3{1} の共役類は P3{2} だけであることより A3 == { P3{0},P3{1},P3{2} } は正規部分群であることが分ります。

参考のために P3(4} の共役類全てを計算してみます。

>sf "<< 0,6,1@j|P3{_n} P3{4} P3{_n}^-1 <0,1,2> >>"
 sf command argment: <<0,6,1@j|P3{_n} P3{4} P3{_n}^-1 <0,1,2> >>
< 1, 0, 2 >  #P3{4}
< 0, 2, 1 >  #P3{3}
< 2, 1, 0 >  #P3{5}
< 2, 1, 0 >
< 1, 0, 2 >
< 0, 2, 1 >
P3{3},P3{4},P4{5} の共役類は A3 には全く属さないことが確認できます。

このような共役類の計算を手計算で行おうとすると、 S3 のような単純な場合でも面倒です。群論の教科書を読んでいくとき、S3 のような単純例でも、その具体例を計算する気にはなれません。どっかで一回でも計算ミスが入り込むと、その後の計算全てが狂い、なかなか正しい計算結果が得られません。でも sf を使えば、この共役類の計算のように誤りなく、手早く計算できます。群論の教科書を読んでいくとき、具体例を作って計算し、定理の具体的な意味を確認していけます。



● 3 S4 置換群

△ S4 P4{..} sf インデックス・ファイル変数の作成

こんどは、もう少し複雑な S4 置換群での数値実験を行います。ただし 4 次ともなると「整数 [0,1,2,3] 全ての順列をデータを誤りなく表現する」ことが難しくなるので、次のような C program によって順列データを生成して利用することにします。
//@@
#include
using namespace std;
#define dfSize 4
int exchangeInAccendingOrder(int arInAg[5] )
{
    int inSignAt=1;

    for(int i=0;i< dfSize-1;++i ){
        if ( arInAg[i] > arInAg[i+1]){
            swap(arInAg[i+1],arInAg[i]);
            inSignAt *= -1;
            i=-1;   // ++i == 0
            continue;
        }
    }   
    return inSignAt;
}

void printPermutation(int inSignAt)
{
    for (int i0=0; i0< dfSize; ++i0){
        for (int i1=0; i1< dfSize; ++i1){
            if( i1 == i0 ){
                continue;
            }
            for (int i2=0; i2< dfSize; ++i2){
                if( (i2 == i1) || (i2==i0) ){
                    continue;
                }
                for (int i3=0; i3< dfSize; ++i3){
                    if( (i3 == i2) || (i3==i1) || (i3==i0) ){
                        continue;
                    }
                    int inArAt[dfSize]={i0,i1,i2,i3};
                    if ( exchangeInAccendingOrder(inArAt) == inSignAt){
                        cout 
                         <<         i0
                         << ", " << i1
                         << ", " << i2
                         << ", " << i3
                         << endl;
                    }
                }
            }
        }
    }
}

int main(void)
{
    printPermutation(1);
    printPermutation(-1);
}
//@@@
>copy c:\#####.### a.cpp /y
>cl a.cpp /MDd /W3 /Od /D"DfVC_" /D"DfVrfy" /D"_CONSOLE" /YX /GX -I.\
このプログラムをコンパイルして実行させると下の文字列を出力してくれます。
a.exe
0, 1, 2, 3
0, 2, 3, 1
0, 3, 1, 2
1, 0, 3, 2
1, 2, 0, 3
1, 3, 2, 0
2, 0, 1, 3
2, 1, 3, 0
2, 3, 0, 1
3, 0, 2, 1
3, 1, 0, 2
3, 2, 1, 0
0, 1, 3, 2
0, 2, 1, 3
0, 3, 2, 1
1, 0, 2, 3
1, 2, 3, 0
1, 3, 0, 2
2, 0, 3, 1
2, 1, 0, 3
2, 3, 1, 0
3, 0, 1, 2
3, 1, 2, 0
3, 2, 0, 1
 --------------------------------------  (3.1)

この文字列を使って S4: P4{..} sf インデックス・ファイル変数群を、下の sf プロック・コマンドを使って作ります。

//@@
# 整数 [0,1,2,3] 全ての順列を Mat の行データで表現する
Mat = [[24,4]]
Mat[<0,24*4,1>] = <\
# 下の順列組み合わせの数値は、上の C プログラムで作成したのち
# Klein の 4 元群:P{0,1,2,3},P{1,0,3,2},P{2,3,0,1},P{3,2,1,0}
# だけを index 0,1,2,3 に配置する
0, 1, 2, 3
1, 0, 3, 2
2, 3, 0, 1
3, 2, 1, 0
0, 2, 3, 1
0, 3, 1, 2
1, 2, 0, 3
1, 3, 2, 0
2, 0, 1, 3
2, 1, 3, 0
3, 0, 2, 1
3, 1, 0, 2
0, 1, 3, 2
0, 2, 1, 3
0, 3, 2, 1
1, 0, 2, 3
1, 2, 3, 0
1, 3, 0, 2
2, 0, 3, 1
2, 1, 0, 3
2, 3, 1, 0
3, 0, 1, 2
3, 1, 2, 0
3, 2, 0, 1>

MatE @= [[4]]
MatE[*,*] = <1,1,1,1>

<<0,24,1 @ j |                      # 24 = 4*3*2 個の P{k,l,m,n} 行列を誠意背
    k@ = Mat[j,0]
    l@ = Mat[j,1]
    m@ = Mat[j,2]
    n@ = Mat[j,3]
    P4{j}=[[4]]

    P4{j}[*,0] = MatE[*,k]
    P4{j}[*,1] = MatE[*,l]
    P4{j}[*,2] = MatE[*,m]
    P4{j}[*,3] = MatE[*,n]
>>
//@@@
上の sf ブロック式の計算で最後に表示する行列は無意味な行列です。 P4{j} への値の設定の繰り返し操作の副作用として作られた行列です。無視して下さい。

△ 置換S4 P4{..} のベクタ表現

S3 のときと同様に P4{..} 置換群のベクタ表現も下のように作っておきます。
>sf "<<0,24,1@j|P4{j}<0,1,2,3> >>"
    # 下の 11 までは A4 交代群です
     0:< 0, 1, 2, 3 >
     1:< 1, 0, 3, 2 >
     2:< 2, 3, 0, 1 >
     3:< 3, 2, 1, 0 >
     4:< 0, 3, 1, 2 >
     5:< 0, 2, 3, 1 >
     6:< 2, 0, 1, 3 >
     7:< 3, 0, 2, 1 >
     8:< 1, 2, 0, 3 >
     9:< 3, 1, 0, 2 >
    10:< 1, 3, 2, 0 >
    11:< 2, 1, 3, 0 >

    # ここから下は A4 交代群ではありません
    12:< 0, 1, 3, 2 >
    13:< 0, 2, 1, 3 >
    14:< 0, 3, 2, 1 >
    15:< 1, 0, 2, 3 >
    16:< 3, 0, 1, 2 >
    17:< 2, 0, 3, 1 >
    18:< 1, 3, 0, 2 >
    19:< 2, 1, 0, 3 >
    20:< 3, 2, 0, 1 >
    21:< 1, 2, 3, 0 >
    22:< 3, 1, 2, 0 >
    23:< 2, 3, 1, 0 >
 --------------------------------------  (3.2)
P4{..} 置換群の前半に A4 を固めてあることが、下の sf による計算でも確認できます。
>sf "<<0,24,1@t|!det(P4{t})>>"
    <  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 >

△ 置換群 S4 P4{..} の演算表

A4 の演算表は下の様になります。
      A4 演算表

      | P4{0}e  P4{1}   P4{2}   P4{3}     P4{4}   P4{5}   P4{6}   P4{7}     P4{8}   P4{9}   P4{10]  P4{11}
------+---------------------------------------------------------------------------------------------------
P4{0}e| e       P4{1}   P4{2}   P4{3}     P4{4}   P4{5}   P4{6}   P4{7}     P4{8}   P4{9}   P4{10]  P4{11}
P4{1} | P4{1}   e       P4{3}   P4{2}     P4{7}   P4{6}   P4{5}   P4{4}     P4{11}  P4{10}  P4{8}   P4{8}
P4{2} | P4{2}   P4{3}   e       P4{1}     P4{8}   P4{9}   P4{10}  P4{11}    P4{4}   P4{5}   P4{6}   P4{3}
P4{3} | P4{3}   P4{2}   P4{1}   e         P4{11}  P4{10}  P4{9}   P4{8}     P4{7}   P4{6}   P4{5}   P4{4} 
      |
P4{4} | P4{4}   P4{8}   P4{11}  P4{7}     P4{5}   e       P4{2}   P4{9}     P4{10}  P4{3}   P4{1}   P4{6} 
P4{5} | P4{5}   P4{1}   P4{6}   P4{9}     e       P4{4}   P4{11}  P4{3}     P4{1}   P4{7}   P4{8}   P4{2} 
P4{6} | P4{6}   P4{9}   P4{5}   P4{10}    P4{1}   P4{7}   P4{8}   P4{2}     e       P4{4}   P4{11]  P4{3} 
P4{7} | P4{7}   P4{11}  P4{8}   P4{4}     P4{6}   P4{1}   P4{3}   P4{10}    P4{9}   P4{2}   e       P4{5} 
      |
P4{8} | P4{8}   P4{4}   P4{7}   P4{11}    P4{9}   P4{2}   e       P4{5}     P4{6}   P4{1}   P4{3}   P4{10}
P4{9} | P4{9}   P4{6}   P4{10}  P4{5}     P4{2}   P4{8}   P4{7}   P4{1}     P4{3}   P4{11}  P4{4}   e     
P4{10]| P4{10]  P4{5}   P4{9}   P4{6}     P4{3}   P4{11}  P4{4}   e         P4{2}   P4{8}   P4{7}   P4{1} 
P4{1} | P4{11}  P4{7}   P4{4}   P4{8}     P4{10}  P4{3}   P4{1}   P4{6}     P4{5}   e       P4{2}   P4{9} 
 --------------------------------------  (3.3)

この演算表は 40 分かけて、テレビの野球中継を見ながら作りました。それでもミスは入り込んでいません。エディタのマクロとサーチを活用しても、これは A4 の演算表を作るのは単純作業です。神経を集中させる価値はありません。一方で sf を使って A4 演算表を作る過程は無意味な単純作業でもありません。左上 P4{0},...P4{3} の部分群は対角線に対して対称であること、すなわち可換であることは否が応でも知らされます。この意味で、sf を使っての計算作業は整数の四則演算の手計算に近いものがあります。



△ 群 V4

P4{0},...P4{3} は V4 という名前がついている群でもあります。(3.3)式 演算表から、左上の P4{0},...P4{3} のみを下に抜き出します

          V4 演算表

          | P4{0}e  P4{1}   P4{2}   P4{3}
    ------+------------------------------
    P4{0}e| e       P4{1}   P4{2}   P4{3}
    P4{1} | P4{1}   e       P4{3}   P4{2}
    P4{2} | P4{2}   P4{3}   e       P4{1}
    P4{3} | P4{3}   P4{2}   P4{1}   e    
 --------------------------------------  (3.4)
V4 で閉じていること、可換群であること、巡回群ではないことが解かります。


△ 置換S4 P4{..} の共役類

S4 すなわち P4{3} の共役類を計算してみます。

>sf "<<0,24,1@j|P4{j} P4{3} P4{j}^-1 <0,1,2,3> >>"
< 3, 2, 1, 0 >  #P4{3}
< 3, 2, 1, 0 >  #P4{3}
< 3, 2, 1, 0 >  #P4{3}
< 3, 2, 1, 0 >  #P4{3}
< 1, 0, 3, 2 >  #P4{1}
< 2, 3, 0, 1 >  #P4{2}
< 2, 3, 0, 1 >  #P4{2}
< 1, 0, 3, 2 >  #P4{1}
< 1, 0, 3, 2 >  #P4{1}
< 2, 3, 0, 1 >  #P4{2}
< 2, 3, 0, 1 >  #P4{2}
< 1, 0, 3, 2 >  #P4{1}
< 2, 3, 0, 1 >  # 以下 P4{1},P4{2},P4{3}, だけが出てくる
< 3, 2, 1, 0 >
< 1, 0, 3, 2 >
< 2, 3, 0, 1 >
< 1, 0, 3, 2 >
< 3, 2, 1, 0 >
< 3, 2, 1, 0 >
< 1, 0, 3, 2 >
< 2, 3, 0, 1 >
< 1, 0, 3, 2 >
< 3, 2, 1, 0 >
< 2, 3, 0, 1 >

共役類の連鎖が V4 の中にとどまり、また単位元を除く V4の要素全てを訪れるように動いているのが分ります。V4 が S4, A4 に対して正規部分群であることが分ります。

下の様に P4{1} の交換子を A4 の範囲でスキャンすることもできます。

>sf "<<0,12,1@j|P4{1}P4{j}P4{1}^-1P4{j}^-1 <0,1,2,3> >>"
    < 0, 1, 2, 3 >  # P4{0}
    < 0, 1, 2, 3 >
    < 0, 1, 2, 3 >
    < 0, 1, 2, 3 >
    < 3, 2, 1, 0 >  # P4{3]
    < 2, 3, 0, 1 >  # P4{2}
    < 2, 3, 0, 1 >
    < 3, 2, 1, 0 >
    < 3, 2, 1, 0 >
    < 2, 3, 0, 1 >
    < 2, 3, 0, 1 >
    < 3, 2, 1, 0 >
でも、まだ私は交換子群について、自分でも数学的に、もう一つ納得できていないので、交換子をスキャンできることの指摘だけで済ませます。

△ 商群 S4/V4

S4/V4 == (e, P4{4}, P4{5}, P4{12}, P4{13}, P4{14} ) であることは、下の五つの sf 繰り返しコマンドが、重複しないグループを示すことから確認できます。

>sf "<<0,4,1@j|P4{0}P4{j}<0,1,2,3> >>
>sf "<<0,4,1@j|P4{4}P4{j}<0,1,2,3> >>"
>sf "<<0,4,1@j|P4{5}P4{j}<0,1,2,3> >>"
>sf "<<0,4,1@j|P4{13}P4{j}<0,1,2,3> >>"
>sf "<<0,4,1@j|P4{14}P4{j}<0,1,2,3> >>"
その演算表が下のようになることも、個別に sf 計算を繰り返すことで確認できます。
    S4/V4 == (e, P4{4}, P4{5}, P4{12}, P4{13}, P4{14} ) 演算表

          | (e,     P4{4},  P4{5},  P4{12}, P4{13}, P4{14}
    ------+------------------------------------------------
    e,    | e,      P4{4},  P4{5},  P4{12}, P4{13}, P4{14}
    P4{4} | P4{4}   P4{5}   e,      P4{13}, P4{14}, P4{12}
    P4{5} | P4{5}   e,      P4{4}   P4{14}, P4{12}, P4{13}
    P4{12}| P4{12}  P4{14}  P4{13}, e,      P4{5},  P4{4}
    P4{13}| P4{13}, P4{12}, P4{14}, P4{4},  e,      P4{5}
    P4{14}| P4{14}, P4{13}, P4{12}, P4{5}   P4{4}   e
     --------------------------------------  (3.5)
表を (3.5) 眺めていると、S4/V4 は可換群ではないが、可換群の傾向があることが見られます。

△ 商群 A4/V4

表 (3.5) の左上 1/4 を抜き出すと A4/V4 の商群となります。
    A4/V4 の演算表 S4/V4 の一部

          | e,      P4{4),  P4{5}
    ------+----------------------
    e,    | e       P4{4),  P4{5}
    P4{4),| P4{4}   P4{5}   e,   
    P4{5} | P4{5}   e,      P4{4}
     --------------------------------------  (3.6)
表 (3.6) より A4/V4 は可換群であり、また巡回群であることが分ります。



● 4 二面体群

置換群ではありませんが、D4 と呼ばれる二面体群について考えてみます。「ガロア理論の数値実験」で、x^4-2 によるガロア拡大のガロア群が D4 であることを使います。

二面体群 とは、xy平面上の4点(1,1)(−1,1)(−1,−1)(1,−1)を頂点とする正方形の、頂点同士を重ね合わせる合同変換の集合です。以下のような変換があります。

    A : なにもしない 
    B : 原点を中心に90度回転 
    C : 原点を中心に180度回転 
    D : 原点を中心に270度回転 
    E : x軸に関して折り返す 
    F : y軸に関して折り返す 
    G : 直線y=xに関して折り返す 
    H : 直線y=-xに関して折り返す 
     --------------------------------------  (4.1)



△ 二面体群を sf 変数で表す

二面体群の操作は、平面の対称操作であり、2 x 2 の実数行列で表せます。この二面体群に対応する sf のインデックス・ファイル変数 D4{..} を作ります。

まず二次元での回転を表すの 回転パラメータ θ をグローバル変数とする sf のサブルーチン rotate.sf を下のように作っておきます。

//@@
@@subFile rotate
    # _prm1 は回転角度を Radian で表記したもの
    _rt =[[2]]
    _rt[<0,4,1>]=< !cos(_prm{1}), -!sin(_prm{1})
                   !sin(_prm{1}),  !cos(_prm{1})>
@@endSubFile
//@@@
rotate.sf を使い、また反転などは直接にパラメータを設定することで、下の様に D4{...} を作ります。
>sf "D4{0} =[[2]], D4{0}[*,*]=<1,1>                  # A"
>sf "D4{1} = @rotate(π/2)                           # B"
>sf "D4{2} = @rotate(π)                             # c"
>sf "D4{3} = @rotate(3π/2)                          # D"
# <== B,C,D の計算では 1e-17 のオーダーの小さな誤差が入り込むので、できあがった
#     D4{1}.val, D4{2}.val, D4{3}.val をエディタテーで開いて誤差分を 0 にします。

>sf "D4{4} =[[2]], D4{4}[<0,4,1>]=<1,0,  0, -1>      # E"
>sf "D4{5} =[[2]], D4{5}[<0,4,1>]=<-1,0,  0, 1>      # F"
>sf "D4{6} =[[2]], D4{6}[<0,4,1>]=<0,1,  1,0>        # G"
>sf "D4{7} =[[2]], D4{7}[<0,4,1>]=<0,-1,  -1,0>      # H"
以下のように D4{0}, ..., D4{8} が出来上がります。
>sf "<<0,8,1@j|D4{j}>>"
        loop count:_n  0 sf command argment: D4{j}
    < 1, 0 >
    < 0, 1 >
    
        loop count:_n  1 sf command argment: D4{j}
    <  0, -1 >
    <  1,  0 >
    
        loop count:_n  2 sf command argment: D4{j}
    < -1,  0 >
    <  0, -1 >
    
        loop count:_n  3 sf command argment: D4{j}
    <  0,  1 >
    < -1,  0 >
    
        loop count:_n  4 sf command argment: D4{j}
    <  1,  0 >
    <  0, -1 >
    
        loop count:_n  5 sf command argment: D4{j}
    < -1,  0 >
    <  0,  1 >
    
        loop count:_n  6 sf command argment: D4{j}
    < 0, 1 >
    < 1, 0 >
    
        loop count:_n  7 sf command argment: D4{j}
    <  0, -1 >
    < -1,  0 >



△ D4{..} のベクタ・インデックス表現

D4{..} は置換群のときのように置換操作に直接対応した意味をもつベクタ表現はできません。でも下のように、D4{..} 二面体群と一対一に対応するベクタ表現を作ることはできます。

    # <1,2> の変換結果は重複しないので、群のベクトル・インデックスとして使える
>sf "<<0,8,1@j|D4{j}<1,2>>>"
    < 1, 2 >      A:0:
    < -2,  1 >    B:1:
    < -1, -2 >    C:2:
    <  2, -1 >    D:3:
    <  1, -2 >    E:4:
    < -1,  2 >    F:5:
    < 2, 1 >      G:6:
    < -2, -1 >    H:7:
     --------------------------------------  (4.2)


△ 二面体群 D4{..} 演算表

(4.2) 式のような D4{..} に対応するインデックス・ベクタを作っておけば、D4{..} 行列同士の演算が何に対応するか簡単に判定できます。下のような D4{..} の演算表が簡単に作れます。

    二面体群 A,B,.., H D4{..} の演算表
                A:D4{0} B:D4{1} C:D4{2} D:D4{3}         E:D4{4} F:D4{5} G:D4{6} H:D4{7}
    A:D4{0}     e       D4{1}   D4{2}   D4{3}           D4{4}   D4{5}   D4{6}   D4{7}
    B:D4{1}     D4{1}   D4{2}   D4{3}   e               D4{6}   D4{7}   D4{5}   D4{4}
    C:D4{2}     D4{2}   D4{3}   e       D4{1}           D4{5}   D4{4}   D4{7}   D4{6}
    D:D4{3}     D4{3}   e       D4{1}   D4{2}           D4{7}   D4{6}   D4{4}   D4{5}
    
    E:D4{4}     D4{4}   D4{7}   D4{5}   D4{6}           e       D4{2}   D4{3}   D4{1}
    F:D4{5}     D4{5}   D4{6}   D4{4}   D4{7}           D4{2}   e       D4{1}   D4{3}
    G:D4{6}     D4{6}   D4{4}   D4{7}   D4{5}           D4{1}   D4{3}   e       D4{2}
    H:D4{7}     D4{7}   D4{5}   D4{6}   D4{4}           D4{3}   D4{1}   D4{2}   e    
    #20 分程度でできあがりました
     --------------------------------------  (4.3)

A,C,E,F の項のみをエディタを使って切り出す。下の様に積演算に対して閉じている部分群となることが分ります。V4 とはことなり、この部分群は巡回群になっていることも分ります。D4 は S4 の部分群とも見なせるのですが、でも S4 とはかなり雰囲気の異なる群に思えます。

    A,C,E,F の演算表
                A:D4{0} C:D4{2} E:D4{4} F:D4{5} 
    A:D4{0}     D4{0}   D4{2}   D4{4}   D4{5}   
    C:D4{2}     D4{2}   D4{0}   D4{5}   D4{4}   
    E:D4{4}     D4{4}   D4{5}   D4{0}   D4{2}   
    F:D4{5}     D4{5}   D4{4}   D4{2}   D4{0}   

△ D4{..} の正規部分群

下のように A,C,E,F を示すインデックス・ベクタ id.val を作って、対応するインデックス・ベクタを作っておきます。

>sf "id=<0,2,6,7>    # {A,C,G,H} 部分群"
>sf "<<0,4,1@j|D4{id[j]}<1,2> >>"
    <  1,  2 >      A:0:
    < -1, -2 >      C:2:
    <  2,  1 >      G:6:
    < -2, -1 >      H:7:
     --------------------------------------  (4.4)

{A,C,G,H} が部分群として閉じていることは、(4,3) の演算表を目視確認する以外にに、下のように全ての組み合わせ直接計算して確認することもできます。

>sf "<<1,3,1@j|D4{id[1]}D4{id[j]}<1,2> >>"
    <  1,  2 >
    < -2, -1 >
    <  2,  1 >

    <<1,3,1@j|D4{id[2]}D4{id[j]}<1,2> >>
    <<1,3,1@j|D4{id[3]}D4{id[j]}<1,2> >>
     --------------------------------------  (4.5)

id=<0,2,6,7> としてやれば (4,4), (4,5) の式が {A,C,G,H} に対しても使えて、やはり閉じた群 になっていることが分ります。

C についての共役類を下のように計算できます。{A,C} のみであることがわかります。

>sf "<<0,8,1@j|D4{j}D4{2}D4{j}^1<1,2> >> # C の共役類類は A,C のみ"
    < -1, -2 >
    <  1,  2 >
    < -1, -2 >
    <  1,  2 >
    < -1, -2 >
    < -1, -2 >
    < -1, -2 >
    < -1, -2 >

>sf "<<0,8,1@j|D4{j}D4{4}D4{j}^1<1,2> >> # E の共役類類は E,F のみ"
>sf "<<0,8,1@j|D4{j}D4{5}D4{j}^1<1,2> >> # F の共役類類は E,F のみ"

また E,F の共役類類が {E,F} であることから {A,C,E,F} が正規部分群であることが分ります。G,H の共役類は {G,H} であることも分ります。{A,C,G,H} も正規部分群であることが分ります

>sf "<<0,8,1@j|D4{j}D4{6}D4{j}^1<1,2> >> # G の共役類類は G,H のみ"
    <  2,  1 >
    <  2,  1 >
    <  2,  1 >
    <  2,  1 >
    < -2, -1 >
    < -2, -1 >
    <  2,  1 >
    <  2,  1 >
    
>sf "<<0,8,1@j|D4{j}D4{7}D4{j}^1<1,2> >> # H の共役類類は G,H  のみ"
    < -2, -1 >
    < -2, -1 >
    < -2, -1 >
    < -2, -1 >
    <  2,  1 >
    <  2,  1 >
    < -2, -1 >
    < -2, -1 >

● 5 S5 置換群

S5 置換群に対応する sf インデックス・ファイル変数 P5{..} を S4 のときと同様に作ります。S5 ではA5 が単純群になってしまいます。共役類を回す範囲が広くなってくるため、全体の絡み合いが強くなるからです。(このことと 5 次の代数方程式を代数的に解けないことと同値であることが Galois 理論で証明されます。)

△ S5 順列組み合わせインデックスの作成

S4 の時と同様に、P5 の置換に対応する 0,.. 4 の変数文字列の組み合わせを下の C 言語プログラムで作ります。これを手作業では行うのは止めるべきです。タイプ・ミスなどによるバグの混入の危険度が大きい高いからです。
//@@
#include
using namespace std;
#define dfSize 5
int exchangeInAccendingOrder(int arInAg[5] )
{
    int inSignAt=1;

    for(int i=0;i< dfSize-1;++i ){
        if ( arInAg[i] > arInAg[i+1]){
            swap(arInAg[i+1],arInAg[i]);
            inSignAt *= -1;
            i=-1;   // ++i == 0
            continue;
        }
    }   
    return inSignAt;
}

void printPermutation(int inSignAt)
{
    int N=5;
    for (int i0=0; i0< N; ++i0){
        for (int i1=0; i1< N; ++i1){
            if( i1 == i0 ){
                continue;
            }
            for (int i2=0; i2< N; ++i2){
                if( (i2 == i1) || (i2==i0) ){
                    continue;
                }
                for (int i3=0; i3< N; ++i3){
                    if( (i3 == i2) || (i3==i1) || (i3==i0) ){
                        continue;
                    }
                    for (int i4=0; i4< N; ++i4){
                        if( (i4 == i3) || (i4==i2) || (i4==i1) || (i4==i0) ){
                            continue;
                        }
                        int inArAt[dfSize]={i0,i1,i2,i3,i4};
                        if ( exchangeInAccendingOrder(inArAt) == inSignAt){
                            cout 
                             <<         i0
                             << ", " << i1
                             << ", " << i2
                             << ", " << i3
                             << ", " << i4
                             << endl;
                        }
                    }
                }
            }
        }
    }
}

int main(void)
{
    printPermutation(1);
    printPermutation(-1);
}
//@@@
>copy c:\#####.### a.cpp /y
>cl a.cpp /MDd /W3 /Od /D"DfVC_" /D"DfVrfy" /D"_CONSOLE" /YX /GX -I.\

>a.ex
    0, 1, 2, 3, 4
    0, 1, 3, 4, 2
    0, 1, 4, 2, 3
    0, 2, 1, 4, 3
    0, 2, 3, 1, 4
    0, 2, 4, 3, 1
    0, 3, 1, 2, 4
    0, 3, 2, 4, 1
    0, 3, 4, 1, 2
    0, 4, 1, 3, 2
    0, 4, 2, 1, 3
    0, 4, 3, 2, 1
    1, 0, 2, 4, 3
    1, 0, 3, 2, 4
    1, 0, 4, 3, 2
    1, 2, 0, 3, 4
    1, 2, 3, 4, 0
    1, 2, 4, 0, 3
    1, 3, 0, 4, 2
    1, 3, 2, 0, 4
    1, 3, 4, 2, 0
    1, 4, 0, 2, 3
    1, 4, 2, 3, 0
    1, 4, 3, 0, 2
    2, 0, 1, 3, 4
    2, 0, 3, 4, 1
    2, 0, 4, 1, 3
    2, 1, 0, 4, 3
    2, 1, 3, 0, 4
    2, 1, 4, 3, 0
    2, 3, 0, 1, 4
    2, 3, 1, 4, 0
    2, 3, 4, 0, 1
    2, 4, 0, 3, 1
    2, 4, 1, 0, 3
    2, 4, 3, 1, 0
    3, 0, 1, 4, 2
    3, 0, 2, 1, 4
    3, 0, 4, 2, 1
    3, 1, 0, 2, 4
    3, 1, 2, 4, 0
    3, 1, 4, 0, 2
    3, 2, 0, 4, 1
    3, 2, 1, 0, 4
    3, 2, 4, 1, 0
    3, 4, 0, 1, 2
    3, 4, 1, 2, 0
    3, 4, 2, 0, 1
    4, 0, 1, 2, 3
    4, 0, 2, 3, 1
    4, 0, 3, 1, 2
    4, 1, 0, 3, 2
    4, 1, 2, 0, 3
    4, 1, 3, 2, 0
    4, 2, 0, 1, 3
    4, 2, 1, 3, 0
    4, 2, 3, 0, 1
    4, 3, 0, 2, 1
    4, 3, 1, 0, 2
    4, 3, 2, 1, 0
    0, 1, 2, 4, 3
    0, 1, 3, 2, 4
    0, 1, 4, 3, 2
    0, 2, 1, 3, 4
    0, 2, 3, 4, 1
    0, 2, 4, 1, 3
    0, 3, 1, 4, 2
    0, 3, 2, 1, 4
    0, 3, 4, 2, 1
    0, 4, 1, 2, 3
    0, 4, 2, 3, 1
    0, 4, 3, 1, 2
    1, 0, 2, 3, 4
    1, 0, 3, 4, 2
    1, 0, 4, 2, 3
    1, 2, 0, 4, 3
    1, 2, 3, 0, 4
    1, 2, 4, 3, 0
    1, 3, 0, 2, 4
    1, 3, 2, 4, 0
    1, 3, 4, 0, 2
    1, 4, 0, 3, 2
    1, 4, 2, 0, 3
    1, 4, 3, 2, 0
    2, 0, 1, 4, 3
    2, 0, 3, 1, 4
    2, 0, 4, 3, 1
    2, 1, 0, 3, 4
    2, 1, 3, 4, 0
    2, 1, 4, 0, 3
    2, 3, 0, 4, 1
    2, 3, 1, 0, 4
    2, 3, 4, 1, 0
    2, 4, 0, 1, 3
    2, 4, 1, 3, 0
    2, 4, 3, 0, 1
    3, 0, 1, 2, 4
    3, 0, 2, 4, 1
    3, 0, 4, 1, 2
    3, 1, 0, 4, 2
    3, 1, 2, 0, 4
    3, 1, 4, 2, 0
    3, 2, 0, 1, 4
    3, 2, 1, 4, 0
    3, 2, 4, 0, 1
    3, 4, 0, 2, 1
    3, 4, 1, 0, 2
    3, 4, 2, 1, 0
    4, 0, 1, 3, 2
    4, 0, 2, 1, 3
    4, 0, 3, 2, 1
    4, 1, 0, 2, 3
    4, 1, 2, 3, 0
    4, 1, 3, 0, 2
    4, 2, 0, 3, 1
    4, 2, 1, 0, 3
    4, 2, 3, 1, 0
    4, 3, 0, 1, 2
    4, 3, 1, 2, 0
    4, 3, 2, 0, 1


△ S5 P5{..} sf インデックス・ファイル変数の作成

上で出力させた置換の文字列を使って下の様に P5{..} を作ります
//@@
    # 整数 [0,1,2,3,4] 全ての順列を Mat の行データで表現する
    Mat = [[5*4*3*2,5]]
    Mat[<0,5*4*3*2*5,1>] = <\
    # 下の順列組み合わせの数値は、上の C プログラムで作成する
    0, 1, 2, 3, 4
    0, 1, 3, 4, 2
    0, 1, 4, 2, 3
    0, 2, 1, 4, 3
    0, 2, 3, 1, 4
    0, 2, 4, 3, 1
    0, 3, 1, 2, 4
    0, 3, 2, 4, 1
    0, 3, 4, 1, 2
    0, 4, 1, 3, 2
    0, 4, 2, 1, 3
    0, 4, 3, 2, 1
    1, 0, 2, 4, 3
    1, 0, 3, 2, 4
    1, 0, 4, 3, 2
    1, 2, 0, 3, 4
    1, 2, 3, 4, 0
    1, 2, 4, 0, 3
    1, 3, 0, 4, 2
    1, 3, 2, 0, 4
    1, 3, 4, 2, 0
    1, 4, 0, 2, 3
    1, 4, 2, 3, 0
    1, 4, 3, 0, 2
    2, 0, 1, 3, 4
    2, 0, 3, 4, 1
    2, 0, 4, 1, 3
    2, 1, 0, 4, 3
    2, 1, 3, 0, 4
    2, 1, 4, 3, 0
    2, 3, 0, 1, 4
    2, 3, 1, 4, 0
    2, 3, 4, 0, 1
    2, 4, 0, 3, 1
    2, 4, 1, 0, 3
    2, 4, 3, 1, 0
    3, 0, 1, 4, 2
    3, 0, 2, 1, 4
    3, 0, 4, 2, 1
    3, 1, 0, 2, 4
    3, 1, 2, 4, 0
    3, 1, 4, 0, 2
    3, 2, 0, 4, 1
    3, 2, 1, 0, 4
    3, 2, 4, 1, 0
    3, 4, 0, 1, 2
    3, 4, 1, 2, 0
    3, 4, 2, 0, 1
    4, 0, 1, 2, 3
    4, 0, 2, 3, 1
    4, 0, 3, 1, 2
    4, 1, 0, 3, 2
    4, 1, 2, 0, 3
    4, 1, 3, 2, 0
    4, 2, 0, 1, 3
    4, 2, 1, 3, 0
    4, 2, 3, 0, 1
    4, 3, 0, 2, 1
    4, 3, 1, 0, 2
    4, 3, 2, 1, 0
    0, 1, 2, 4, 3
    0, 1, 3, 2, 4
    0, 1, 4, 3, 2
    0, 2, 1, 3, 4
    0, 2, 3, 4, 1
    0, 2, 4, 1, 3
    0, 3, 1, 4, 2
    0, 3, 2, 1, 4
    0, 3, 4, 2, 1
    0, 4, 1, 2, 3
    0, 4, 2, 3, 1
    0, 4, 3, 1, 2
    1, 0, 2, 3, 4
    1, 0, 3, 4, 2
    1, 0, 4, 2, 3
    1, 2, 0, 4, 3
    1, 2, 3, 0, 4
    1, 2, 4, 3, 0
    1, 3, 0, 2, 4
    1, 3, 2, 4, 0
    1, 3, 4, 0, 2
    1, 4, 0, 3, 2
    1, 4, 2, 0, 3
    1, 4, 3, 2, 0
    2, 0, 1, 4, 3
    2, 0, 3, 1, 4
    2, 0, 4, 3, 1
    2, 1, 0, 3, 4
    2, 1, 3, 4, 0
    2, 1, 4, 0, 3
    2, 3, 0, 4, 1
    2, 3, 1, 0, 4
    2, 3, 4, 1, 0
    2, 4, 0, 1, 3
    2, 4, 1, 3, 0
    2, 4, 3, 0, 1
    3, 0, 1, 2, 4
    3, 0, 2, 4, 1
    3, 0, 4, 1, 2
    3, 1, 0, 4, 2
    3, 1, 2, 0, 4
    3, 1, 4, 2, 0
    3, 2, 0, 1, 4
    3, 2, 1, 4, 0
    3, 2, 4, 0, 1
    3, 4, 0, 2, 1
    3, 4, 1, 0, 2
    3, 4, 2, 1, 0
    4, 0, 1, 3, 2
    4, 0, 2, 1, 3
    4, 0, 3, 2, 1
    4, 1, 0, 2, 3
    4, 1, 2, 3, 0
    4, 1, 3, 0, 2
    4, 2, 0, 3, 1
    4, 2, 1, 0, 3
    4, 2, 3, 1, 0
    4, 3, 0, 1, 2
    4, 3, 1, 2, 0
    4, 3, 2, 0, 1>
    
    MatE @= [[5]]
    MatE[*,*] = <1,1,1,1,1>
    
    <<0,24*5,1 @ j |                      # 24 = 4*3*2 個の P{k,l,m,n} 行列を誠意背
        k@ = Mat[j,0]
        l@ = Mat[j,1]
        m@ = Mat[j,2]
        n@ = Mat[j,3]
        p@ = Mat[j,4]
        P5{j}=[[5]]
    
        P5{j}[*,0] = MatE[*,k]
        P5{j}[*,1] = MatE[*,l]
        P5{j}[*,2] = MatE[*,m]
        P5{j}[*,3] = MatE[*,n]
        P5{j}[*,4] = MatE[*,p]
    >>
//@@@
>xcopy \#####.### temp.se /y
>sf @@temp

前半に隅置換が並んでいることは、下の計算で確認できます。

>sf "<<0,120,1@t|!det(P5{t})>>"
<  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 >


△ 置換S5 P5{..} のベクタ表現

P5{..} 置換群のベクタ表示は下の様になります。P5{..} を作ったときの sf ブロック・コマンドでつかった順列組み合わせの数値と同じですが、sf での計算結果としてのベクタ表現文字列の一覧表を作っておいたほうが、計算結果をエディタのサーチ・コマンドで調べるときに便利です。

    # P5{0}....P5{129} のベクトル表示
>sf "<<0,120,1@t|P5{t}<0,1,2,3,4>> >"
    # 前半は交代群です
    < 0, 1, 2, 3, 4 > #P5{0}
    < 0, 1, 4, 2, 3 > #P5{1}
    < 0, 1, 3, 4, 2 > #P5{2}
    < 0, 2, 1, 4, 3 > #P5{3}
    < 0, 3, 1, 2, 4 > #P5{4}
    < 0, 4, 1, 3, 2 > #P5{5}
    < 0, 2, 3, 1, 4 > #P5{6}
    < 0, 4, 2, 1, 3 > #P5{7}
    < 0, 3, 4, 1, 2 > #P5{8}
    < 0, 2, 4, 3, 1 > #P5{9}
    < 0, 3, 2, 4, 1 > #P5{10}
    < 0, 4, 3, 2, 1 > #P5{11}
    < 1, 0, 2, 4, 3 > #P5{12}
    < 1, 0, 3, 2, 4 > #P5{13}
    < 1, 0, 4, 3, 2 > #P5{14}
    < 2, 0, 1, 3, 4 > #P5{15}
    < 4, 0, 1, 2, 3 > #P5{16}
    < 3, 0, 1, 4, 2 > #P5{17}
    < 2, 0, 4, 1, 3 > #P5{18}
    < 3, 0, 2, 1, 4 > #P5{19}
    < 4, 0, 3, 1, 2 > #P5{20}
    < 2, 0, 3, 4, 1 > #P5{21}
    < 4, 0, 2, 3, 1 > #P5{22}
    < 3, 0, 4, 2, 1 > #P5{23}
    < 1, 2, 0, 3, 4 > #P5{24}
    < 1, 4, 0, 2, 3 > #P5{25}
    < 1, 3, 0, 4, 2 > #P5{26}
    < 2, 1, 0, 4, 3 > #P5{27}
    < 3, 1, 0, 2, 4 > #P5{28}
    < 4, 1, 0, 3, 2 > #P5{29}
    < 2, 3, 0, 1, 4 > #P5{30}
    < 4, 2, 0, 1, 3 > #P5{31}
    < 3, 4, 0, 1, 2 > #P5{32}
    < 2, 4, 0, 3, 1 > #P5{33}
    < 3, 2, 0, 4, 1 > #P5{34}
    < 4, 3, 0, 2, 1 > #P5{35}
    < 1, 2, 4, 0, 3 > #P5{36}
    < 1, 3, 2, 0, 4 > #P5{37}
    < 1, 4, 3, 0, 2 > #P5{38}
    < 2, 1, 3, 0, 4 > #P5{39}
    < 4, 1, 2, 0, 3 > #P5{40}
    < 3, 1, 4, 0, 2 > #P5{41}
    < 2, 4, 1, 0, 3 > #P5{42}
    < 3, 2, 1, 0, 4 > #P5{43}
    < 4, 3, 1, 0, 2 > #P5{44}
    < 2, 3, 4, 0, 1 > #P5{45}
    < 4, 2, 3, 0, 1 > #P5{46}
    < 3, 4, 2, 0, 1 > #P5{47}
    < 1, 2, 3, 4, 0 > #P5{48}
    < 1, 4, 2, 3, 0 > #P5{49}
    < 1, 3, 4, 2, 0 > #P5{50}
    < 2, 1, 4, 3, 0 > #P5{51}
    < 3, 1, 2, 4, 0 > #P5{52}
    < 4, 1, 3, 2, 0 > #P5{53}
    < 2, 3, 1, 4, 0 > #P5{54}
    < 4, 2, 1, 3, 0 > #P5{55}
    < 3, 4, 1, 2, 0 > #P5{56}
    < 2, 4, 3, 1, 0 > #P5{57}
    < 3, 2, 4, 1, 0 > #P5{58}
    < 4, 3, 2, 1, 0 > #P5{59}
    
    # 交代群ではない
    < 0, 1, 2, 4, 3 > #P5{60}
    < 0, 1, 3, 2, 4 > #P5{61}
    < 0, 1, 4, 3, 2 > #P5{62}
    < 0, 2, 1, 3, 4 > #P5{63}
    < 0, 4, 1, 2, 3 > #P5{64}
    < 0, 3, 1, 4, 2 > #P5{65}
    < 0, 2, 4, 1, 3 > #P5{66}
    < 0, 3, 2, 1, 4 > #P5{67}
    < 0, 4, 3, 1, 2 > #P5{68}
    < 0, 2, 3, 4, 1 > #P5{69}
    < 0, 4, 2, 3, 1 > #P5{70}
    < 0, 3, 4, 2, 1 > #P5{71}
    < 1, 0, 2, 3, 4 > #P5{72}
    < 1, 0, 4, 2, 3 > #P5{73}
    < 1, 0, 3, 4, 2 > #P5{74}
    < 2, 0, 1, 4, 3 > #P5{75}
    < 3, 0, 1, 2, 4 > #P5{76}
    < 4, 0, 1, 3, 2 > #P5{77}
    < 2, 0, 3, 1, 4 > #P5{78}
    < 4, 0, 2, 1, 3 > #P5{79}
    < 3, 0, 4, 1, 2 > #P5{80}
    < 2, 0, 4, 3, 1 > #P5{81}
    < 3, 0, 2, 4, 1 > #P5{82}
    < 4, 0, 3, 2, 1 > #P5{83}
    < 1, 2, 0, 4, 3 > #P5{84}
    < 1, 3, 0, 2, 4 > #P5{85}
    < 1, 4, 0, 3, 2 > #P5{86}
    < 2, 1, 0, 3, 4 > #P5{87}
    < 4, 1, 0, 2, 3 > #P5{88}
    < 3, 1, 0, 4, 2 > #P5{89}
    < 2, 4, 0, 1, 3 > #P5{90}
    < 3, 2, 0, 1, 4 > #P5{91}
    < 4, 3, 0, 1, 2 > #P5{92}
    < 2, 3, 0, 4, 1 > #P5{93}
    < 4, 2, 0, 3, 1 > #P5{94}
    < 3, 4, 0, 2, 1 > #P5{95}
    < 1, 2, 3, 0, 4 > #P5{96}
    < 1, 4, 2, 0, 3 > #P5{97}
    < 1, 3, 4, 0, 2 > #P5{98}
    < 2, 1, 4, 0, 3 > #P5{99}
    < 3, 1, 2, 0, 4 > #P5{100}
    < 4, 1, 3, 0, 2 > #P5{10}
    < 2, 3, 1, 0, 4 > #P5{102}
    < 4, 2, 1, 0, 3 > #P5{103}
    < 3, 4, 1, 0, 2 > #P5{104}
    < 2, 4, 3, 0, 1 > #P5{105}
    < 3, 2, 4, 0, 1 > #P5{106}
    < 4, 3, 2, 0, 1 > #P5{107}
    < 1, 2, 4, 3, 0 > #P5{108}
    < 1, 3, 2, 4, 0 > #P5{109}
    < 1, 4, 3, 2, 0 > #P5{110}
    < 2, 1, 3, 4, 0 > #P5{111}
    < 4, 1, 2, 3, 0 > #P5{112}
    < 3, 1, 4, 2, 0 > #P5{113}
    < 2, 4, 1, 3, 0 > #P5{114}
    < 3, 2, 1, 4, 0 > #P5{115}
    < 4, 3, 1, 2, 0 > #P5{116}
    < 2, 3, 4, 1, 0 > #P5{117}
    < 4, 2, 3, 1, 0 > #P5{118}
    < 3, 4, 2, 1, 0 > #P5{119}
     --------------------------------------  (5.1)


△ 置換S4 P4{..} の共役類

P5(1} の共役類全てを計算します。S5 ともなると計算量は多くなります。でも sf のコマンド記述では S4 のときと同じです。20 個の S5 要素が共役類として繋がっていることが分ります

>sf "<<0,120,1@j|P5{j} P5{1} P5{j}^-1 <0,1,2,3,4> >>"
    < 0, 1, 4, 2, 3 >
    < 0, 1, 4, 2, 3 >
    < 0, 1, 4, 2, 3 >
    < 0, 3, 2, 4, 1 >
    < 0, 3, 2, 4, 1 >
    < 0, 3, 2, 4, 1 >
    < 0, 4, 1, 3, 2 >
    < 0, 4, 1, 3, 2 >
    < 0, 4, 1, 3, 2 >
    < 0, 2, 3, 1, 4 >
    < 0, 2, 3, 1, 4 >
    < 0, 2, 3, 1, 4 >
    < 0, 1, 3, 4, 2 >
    < 0, 1, 3, 4, 2 >
    < 0, 1, 3, 4, 2 >
    < 4, 1, 2, 0, 3 >
    < 4, 1, 2, 0, 3 >
    < 4, 1, 2, 0, 3 >
    < 2, 1, 4, 3, 0 >
    < 2, 1, 4, 3, 0 >
    < 2, 1, 4, 3, 0 >
    < 3, 1, 0, 2, 4 >
    < 3, 1, 0, 2, 4 >
    < 3, 1, 0, 2, 4 >
    < 0, 4, 2, 1, 3 >
    < 0, 4, 2, 1, 3 >
    < 0, 4, 2, 1, 3 >
    < 3, 1, 2, 4, 0 >
    < 3, 1, 2, 4, 0 >
    < 3, 1, 2, 4, 0 >
    < 4, 0, 2, 3, 1 >
    < 4, 0, 2, 3, 1 >
    < 4, 0, 2, 3, 1 >
    < 1, 3, 2, 0, 4 >
    < 1, 3, 2, 0, 4 >
    < 1, 3, 2, 0, 4 >
    < 0, 2, 4, 3, 1 >
    < 0, 2, 4, 3, 1 >
    < 0, 2, 4, 3, 1 >
    < 4, 1, 0, 3, 2 >
    < 4, 1, 0, 3, 2 >
    < 4, 1, 0, 3, 2 >
    < 1, 4, 2, 3, 0 >
    < 1, 4, 2, 3, 0 >
    < 1, 4, 2, 3, 0 >
    < 2, 0, 1, 3, 4 >
    < 2, 0, 1, 3, 4 >
    < 2, 0, 1, 3, 4 >
    < 0, 3, 1, 2, 4 >
    < 0, 3, 1, 2, 4 >
    < 0, 3, 1, 2, 4 >
    < 2, 1, 3, 0, 4 >
    < 2, 1, 3, 0, 4 >
    < 2, 1, 3, 0, 4 >
    < 3, 0, 2, 1, 4 >
    < 3, 0, 2, 1, 4 >
    < 3, 0, 2, 1, 4 >
    < 1, 2, 0, 3, 4 >
    < 1, 2, 0, 3, 4 >
    < 1, 2, 0, 3, 4 >
    
    < 0, 1, 3, 4, 2 >
    < 0, 1, 3, 4, 2 >
    < 0, 1, 3, 4, 2 >
    < 0, 4, 2, 1, 3 >
    < 0, 4, 2, 1, 3 >
    < 0, 4, 2, 1, 3 >
    < 0, 2, 4, 3, 1 >
    < 0, 2, 4, 3, 1 >
    < 0, 2, 4, 3, 1 >
    < 0, 3, 1, 2, 4 >
    < 0, 3, 1, 2, 4 >
    < 0, 3, 1, 2, 4 >
    < 0, 1, 4, 2, 3 >
    < 0, 1, 4, 2, 3 >
    < 0, 1, 4, 2, 3 >
    < 3, 1, 2, 4, 0 >
    < 3, 1, 2, 4, 0 >
    < 3, 1, 2, 4, 0 >
    < 4, 1, 0, 3, 2 >
    < 4, 1, 0, 3, 2 >
    < 4, 1, 0, 3, 2 >
    < 2, 1, 3, 0, 4 >
    < 2, 1, 3, 0, 4 >
    < 2, 1, 3, 0, 4 >
    < 0, 3, 2, 4, 1 >
    < 0, 3, 2, 4, 1 >
    < 0, 3, 2, 4, 1 >
    < 4, 1, 2, 0, 3 >
    < 4, 1, 2, 0, 3 >
    < 4, 1, 2, 0, 3 >
    < 1, 4, 2, 3, 0 >
    < 1, 4, 2, 3, 0 >
    < 1, 4, 2, 3, 0 >
    < 3, 0, 2, 1, 4 >
    < 3, 0, 2, 1, 4 >
    < 3, 0, 2, 1, 4 >
    < 0, 4, 1, 3, 2 >
    < 0, 4, 1, 3, 2 >
    < 0, 4, 1, 3, 2 >
    < 2, 1, 4, 3, 0 >
    < 2, 1, 4, 3, 0 >
    < 2, 1, 4, 3, 0 >
    < 4, 0, 2, 3, 1 >
    < 4, 0, 2, 3, 1 >
    < 4, 0, 2, 3, 1 >
    < 1, 2, 0, 3, 4 >
    < 1, 2, 0, 3, 4 >
    < 1, 2, 0, 3, 4 >
    < 0, 2, 3, 1, 4 >
    < 0, 2, 3, 1, 4 >
    < 0, 2, 3, 1, 4 >
    < 3, 1, 0, 2, 4 >
    < 3, 1, 0, 2, 4 >
    < 3, 1, 0, 2, 4 >
    < 1, 3, 2, 0, 4 >
    < 1, 3, 2, 0, 4 >
    < 1, 3, 2, 0, 4 >
    < 2, 0, 1, 3, 4 >
    < 2, 0, 1, 3, 4 >
    < 2, 0, 1, 3, 4 >
     --------------------------------------  (5.2)

P5{2} が P5{1} の共役類に属すことは、エディタのサーチ機能を使って簡単に判定できます。

P5{3} の共役類としては 15 個が繋がっていることは下の計算より分ります

>sf "<<0,60,1@j|P5{j} P5{3} P5{j}^-1 <0,1,2,3,4> >>"
    < 0, 2, 1, 4, 3 >
    < 0, 3, 4, 1, 2 >
    < 0, 4, 3, 2, 1 >
    < 0, 2, 1, 4, 3 >
    < 0, 4, 3, 2, 1 >
    < 0, 3, 4, 1, 2 >
    < 0, 3, 4, 1, 2 >
    < 0, 4, 3, 2, 1 >
    < 0, 2, 1, 4, 3 >
    < 0, 4, 3, 2, 1 >
    < 0, 3, 4, 1, 2 >
    < 0, 2, 1, 4, 3 >
    
    
    < 2, 1, 0, 4, 3 >
    < 3, 1, 4, 0, 2 >
    < 4, 1, 3, 2, 0 >
    < 2, 1, 0, 4, 3 >
    < 4, 1, 3, 2, 0 >
    < 3, 1, 4, 0, 2 >
    < 3, 1, 4, 0, 2 >
    < 4, 1, 3, 2, 0 >
    < 2, 1, 0, 4, 3 >
    < 4, 1, 3, 2, 0 >
    < 3, 1, 4, 0, 2 >
    < 2, 1, 0, 4, 3 >
    
    < 1, 0, 2, 4, 3 >
    < 3, 4, 2, 0, 1 >
    < 4, 3, 2, 1, 0 >
    < 1, 0, 2, 4, 3 >
    < 4, 3, 2, 1, 0 >
    < 3, 4, 2, 0, 1 >
    < 3, 4, 2, 0, 1 >
    < 4, 3, 2, 1, 0 >
    < 1, 0, 2, 4, 3 >
    < 4, 3, 2, 1, 0 >
    < 3, 4, 2, 0, 1 >
    < 1, 0, 2, 4, 3 >
    
    < 1, 0, 4, 3, 2 >
    < 2, 4, 0, 3, 1 >
    < 4, 2, 1, 3, 0 >
    < 1, 0, 4, 3, 2 >
    < 4, 2, 1, 3, 0 >
    < 2, 4, 0, 3, 1 >
    < 2, 4, 0, 3, 1 >
    < 4, 2, 1, 3, 0 >
    < 1, 0, 4, 3, 2 >
    < 4, 2, 1, 3, 0 >
    < 2, 4, 0, 3, 1 >
    < 1, 0, 4, 3, 2 >
    
    < 1, 0, 3, 2, 4 >
    < 2, 3, 0, 1, 4 >
    < 3, 2, 1, 0, 4 >
    < 1, 0, 3, 2, 4 >
    < 3, 2, 1, 0, 4 >
    < 2, 3, 0, 1, 4 >
    < 2, 3, 0, 1, 4 >
    < 3, 2, 1, 0, 4 >
    < 1, 0, 3, 2, 4 >
    < 3, 2, 1, 0, 4 >
    < 2, 3, 0, 1, 4 >
    < 1, 0, 3, 2, 4 >

P5{16} の共役類が 12 個あることは下の計算をすることで確認できます

<<0,60,1@j|P5{j} P5{16} P5{j}^-1 <0,1,2,3,4> >>

△ P5 交換子と正規部分群

P5{1} の交換子をスキャンしてやると下のようになります。
>sf "<<0,60,1@j|P5{1}P5{j}P5{1}^-1P5{j}^-1 <0,1,2,3,4> >>"
    < 0, 1, 2, 3, 4 >
    < 0, 1, 2, 3, 4 >
    < 0, 1, 2, 3, 4 >
    < 0, 4, 3, 2, 1 >   #P5{3}
    < 0, 4, 3, 2, 1 >
    < 0, 4, 3, 2, 1 >
    < 0, 2, 1, 4, 3 >   #P5{3}
    < 0, 2, 1, 4, 3 >
    < 0, 2, 1, 4, 3 >
    < 0, 3, 4, 1, 2 >   #P5{3} と共役
    < 0, 3, 4, 1, 2 >
    < 0, 3, 4, 1, 2 >
    < 0, 1, 3, 4, 2 >   #P5{1} と共役
    < 0, 1, 3, 4, 2 >
    < 0, 1, 3, 4, 2 >
    < 3, 1, 0, 2, 4 >   #P5{1} と共役
    < 3, 1, 0, 2, 4 >
    < 3, 1, 0, 2, 4 >
    < 4, 1, 2, 0, 3 >
    < 4, 1, 2, 0, 3 >
    < 4, 1, 2, 0, 3 >
    < 2, 1, 4, 3, 0 >
    < 2, 1, 4, 3, 0 >
    < 2, 1, 4, 3, 0 >
    < 0, 3, 1, 2, 4 >
    < 0, 3, 1, 2, 4 >
    < 0, 3, 1, 2, 4 >
    < 4, 1, 3, 2, 0 >
    < 4, 1, 3, 2, 0 >
    < 4, 1, 3, 2, 0 >
    < 1, 4, 0, 2, 3 >
    < 1, 4, 0, 2, 3 >
    < 1, 4, 0, 2, 3 >
    < 3, 0, 4, 2, 1 >
    < 3, 0, 4, 2, 1 >
    < 3, 0, 4, 2, 1 >
    < 0, 4, 2, 1, 3 >
    < 0, 4, 2, 1, 3 >
    < 0, 4, 2, 1, 3 >
    < 2, 1, 0, 4, 3 >
    < 2, 1, 0, 4, 3 >
    < 2, 1, 0, 4, 3 >
    < 4, 0, 1, 2, 3 >
    < 4, 0, 1, 2, 3 >
    < 4, 0, 1, 2, 3 >
    < 1, 2, 4, 0, 3 >
    < 1, 2, 4, 0, 3 >
    < 1, 2, 4, 0, 3 >
    < 0, 2, 4, 3, 1 >
    < 0, 2, 4, 3, 1 >
    < 0, 2, 4, 3, 1 >
    < 3, 1, 4, 0, 2 >
    < 3, 1, 4, 0, 2 >
    < 3, 1, 4, 0, 2 >
    < 1, 3, 4, 2, 0 >
    < 1, 3, 4, 2, 0 >
    < 1, 3, 4, 2, 0 >
    < 2, 0, 4, 1, 3 >
    < 2, 0, 4, 1, 3 >
    < 2, 0, 4, 1, 3 >

S4 のときより共役類が長くなっていることと交換子の個数が多いことから、S5 全体が強く絡み合っていることがわかります。この絡み合いが強いことにより A5 自身がが正規部分群となります。A5 は単純群となります。


● 6 sf による S3,S4,S5,D4 の実現

sf のファイル変数として S3,S4,S5,D4 の行列を P3{..}, P4{..}, P5{..} D4{..} を作ってきました。これらはプログラム・コードの途中でコンピュータ内のメモリ上に作られる変数ではありません。下のようにハードディクス上にテキスト・ファイルとして残されています。

これらの sf ファイル変数は sf 計算式の対象となるところが、既存の Maxima, Mathematica, Matlab などの数式処理系と大きく異なるところです。sf で成果として残すのはプログラム・コードではなく結果としてつくられた行列テキスト・ファイル・データです。それらが、どのように作られたかは関係ありません。残された行列変数が S3,S4,S5,D5 の機能を持ちさえすればよいのですから。

ここまで行ってきたな S4,S5,D4 群の行列表現をつくって共役類による分類を計算するようなことは Mathematica や Matlab のような高価なソフトでもやる気にならない計算です。ここで行った計算は sf のインデックス ファイル変数の強力さを示していると自負しています。


● 最後に

sf は元々工学や、物理での計算を楽にしたくて開発しました。特に群論への応用を想定していたわけではありません。実際の話 P4{..} などの行列計算は整数ではなく、浮動小数点演算として行っています。

このような sf が置換群や二面体群での群演算も可能なコンピュータ行列モデルの構築に使えることは、sf の機能の優れた所だと自負しています。

Maxima, Mathematica, Matlab など、既存の数学ソフトでは、ここで行ったような単純さでは群の行列モデルを構築できないと思います。配布している評価版でも機能制限はありません。是非とも sf をお試しになってみてください。 そして sf の価値を認めていただけましたら、是非とも登録ください。登録は \5000円と有償ですが、それ以上の価値があると自負しています。


ホーム・ページに戻ります