群のイニシャルを散歩しよう
4次の対称群S4
1.G、H、N、S、A、D、C、V、Q、GLはよくある群の名
このワークシートはMath by Codeの一部です。
英語でも日本語でも最初の文字をとって
名前を縮めるのはよくやるね。
群論の導入では、
あみだくじをつかうこともあるけれど、
対称性に着目したり、
いろいろな群表をかいて群の要素の関係性を目と手で実感したり、さまざまだ。
いろんな群の書籍にスムーズに入ったり、先に進むときに、
あみだくじだけではイメージが乏しい。
イメージを豊かにするという目的で、
今回は、群の中身を正面からさぐるのではなく、群の事例を増やすために、
群のサンプルと戯れる、群の周辺お散歩をしてみよう。
<Gは群GroupのG>
そのまんま、ストレートな名前だ。
だから、とてもよく登場する。
群といえばG。
一般名だから、群であればいつでも使われる。
一番カンタンな群は、かけ算で要素が1だけの集合G({1},×)
1×1=1。1をかけてもかわらないから、単位元は1だ。
1×1=1。だから、1の反対は1だ。1の逆元は1だ。
1×1は閉じているし、1×1×1は結合法則が成り立つ。
1だけしかないが、立派な群といえるね。
もう少しおもしろいのは、
偶数の代表元0と奇数の代表元1のたし算の集合G({0,1},+)
1+0=1 , 0+0=0。0をたしても偶数、奇数は変えないから0が無変化にする要素。単位元だ。
1+1=0, 0+0=0。1の反対は1,0の反対は0だ。自分自身が逆元になるね。
奇数と偶数の代表のたし算は閉じているし、たし算は結合法則が成り立つ。
だから、これは群だ。
<H、Nは部分群向け>
HはGの部分群になっているものによく使われる。
NはNormalな部分群、正規部分群向けによく使われる。
偶置換が交代群A
<Sは対称SymmetryのS>
対称群Snというのは番号の順列の群だ。
あみだくじとか、席替えのイメージだね。
S1,S2,S3,.....,Snとnを変えると、いくらでも対称群は作れる。
3本あみだの群はS3ということになるね。
要素の数が4つの対称群とはたとえば、
1,2,3,4の座席があって、
1は2に、2は3に、3は4に、4は1にと順送りに移動する
など、4つの番号の変更(無変更も含む)の仕方は
順列になるね。4!=24通りの移動がある。
これが対称群S4だ。
S4は4本あみだだから、S3と同様に分類してみよう。
互換の数が0ならeの1個。
互換が1つなら4C2=6個。(1 2),(1 3),(1 4),(2 3),(2 4),(3 4)だね。
互換が2つなら共通要素がない積で4-1=3個。(1 2)(3 4), (1 3)(2 4),(1 4)(2 3)
互換が2つで3次巡回置換は4×2=8個。 (1 2 3),(1 3 2), (1 2 4),(1 4 2), (1 3 4),(1 4 3), (2 3 4),(2 4 3)
互換が3つで4次巡回置換は3×2×1=6個。(1 2 3 4),(1 2 4 3),(1 3 2 4),(1 3 4 2),(1 4 2 3),(1 4 3 2)
1+6+3+8+6=24個
<Aは交代AlternatingのA>
対称群Snは置換として区分すると、偶置換と奇置換に2種類に区分できる。
偶置換というのは2要素の交換(互換)が偶数個のものだ。
偶置換になる対称群を、特別に交代群という。
S3の正規部分群N={e, (1 2 3), (1 3 2)}は偶置換の集まりだったから、A3ということになるね。
<Dは2面体DihedralのD>
2面体という名前は、初めて聞くとあれっと思う人もいるでしょう。
2面の立体はないよね?と感じるでしょう。
正n角形を空間の中で移動すると、回転や裏返して自分に重ねると
頂点が入れ替わるの。これをDnと呼ぶ。
二面体群Dnは位数ではなく、正n角形のnからきているので注意しよう。
・D6は正六角形の6個の番号の移動と考えることもできるから、対称群S6の部分群になる。
・例えば正三角形の移動して自分に重ねる群はD3ということになる。
D3はR0,R1,R3(反時計回りに60*0,1,2回転)、
S0,S1,S2(x軸と作る角が60*0,1,2度の軸で裏返し)の3*2=6要素。
・例えば正方形を自分に重ねる群はD4ということになるね。
D4はR0,R1,R3,R4(反時計回りに45*0,1,2,3回転)、
S0,S1,S2,S4(x軸と作る角が45*0,1,2,3度の軸で裏返し)の4*2=8要素
二面体群D4
巡回群Cn
<Cには巡回CyclicのC>
アナログ時計の長針は5分ごとに、12から1,2,3,…と1つの数字を進む。
1回で30度進み、12回でもとにもどる。
このように、1回で円のn等分進む動きを1として、これを繰り返して1周の動きになるとき
スタートから動いたメモリ数は{0,1,2,.....,n-1}になる。
このように動きを繰り返して周期ができる群が巡回群のイメージだ。
足し算以外での回転を表すことができるね。
たとえば、{i0,i1,i2,i3}={1,i,-1,-i}は
かけ算の繰り返しで、座標平面での90度回転の繰り返しを表しているね。
要素数が4だから、C4とかく。
・群の位数と同じ位数になる元を巡回群の生成元と呼びます。
iは4乗して1(単位元)になりますが、
-1は2乗しただけで1(単位元)になるので、生成元にはなれません。
・巡回群は可換群。
巡回群のかけ算の結果は、生成元のn乗で表したかけ算は指数の和で表せるから。
・巡回群の部分群は巡回群
巡回群の位数が合成数ならば、位数の約数をdとして、生成元のd乗を新たな生成元とすると、
同じ指数にするともとにもどり、巡回群となり、要素は部分集合だから、部分群になるね。
<V4はクラインの4元群>
クラインの4元群V4は至る所に出てくるやつだ。
x軸対称移動、y軸対称移動、原点対称移動、無移動の4つ。
G={e,a,b,c}とすると、a2=e,b2=e,c2=e となる。abがaでもbでもeでもないとすると、
ab=c。原点対称はx軸対称とy軸対称の結合になっている。
生成する元がa,bの2つある。
同じ4個の元でも、巡回群とはちがう。
aは生成元なのにaは2乗で戻るのに群のサイズは4だから。
<GLは一般線形群generalLinerのGL>
n次の正則(逆行列がある)な正方行列のあつまりをGLnとかきます。
成分が実数Rのときは、GLn(R), 成分が複素数のときはGLn(C)とかきます。
行列の積は可換とはかぎらないけれど、閉性、結合法則、単位元、逆元があれば
群になることはすぐにわかるね。
(ちなみに、GLnのうち、行列式が1のものを特殊線形群SLn、成分が整数で行列式の絶対値が1のものをモジュラー群、転置行列との積が単位行列になる群を直交群O(n)、複素共役行列との積が単位行列になるものをユニタリー群U(n)と読んだり書いたりすることがあります。)
<Qは4元数quaternionクォータニオンのQ>
もともと、4元数というのは、
虚数単位i,j,kを使って4つの元a,b,c,dの組み合わせで
x=a + bi + cj + dk
と表す数です。
ここで、a, b, c, d は実数であり、虚数単位 i, j, k は以下の関係を満たす。
これが、4元数。交換法則は成り立たない。
1も含めて、単位に±をつけた8要素の集合は群をなします。
これを、4元数群Q8といいます。
Q8 = {±1, ±i, ±j, ±k}
また、i=x, j=y, k=xyとおくことによって、
x4=y4=1なので、xとyの位数は4です。
x2=y2 は他の元と可換(群の中心)です。
y-1xy=x-1とxとyの交換関係があります。
Q8={1, x, x2, x3, y, xy, x2y, x3y}
とおくこともあります。この場合はx,yが群の生成元になりますね。
4元数の行列は、ゲームソフト開発や航空機での姿勢や運動の制御には役立つようです。
クラインの4元群
あみだの群(対称群S3)から始まって、
前回までに巡回群C6、交代群A3(S3の正規部分群であり、巡回群C3でもあった)
はあつかってきたことになるね。
質問:置換を利用して、クラインの4元群の群表を作るコードはどうやってつくれますか。
座標平面にある4つの象限を代表する4点を1:(1,1)、2:(-1,1)、3:(-1,-1)、4:(1,-1)
としてみよう。
x軸対称移動はX={1:4, 2:3,3:2,4:1}という辞書
y軸対称移動はY={1:2, 2:1,3:4,4:3}という辞書
原点対称移動はO={1:3, 3:1,2:4,4:2}という辞書
無移動はE={1:1}という辞書にして、V4の群表を作ってみよう。
同じ位数4でも、巡回群C4とどうちがうのかを群表を作って比べてみよう。
[IN]Python
#=================================================
def ami2dic(ami):
return dict(zip(ami , ami[1:] + [ami[0]]))
def amis2dics(amis):
return [dict(zip(ami , ami[1:] + [ami[0]])) for ami in amis]
# kの辞書dic_aによる行先を返す。辞書にないなら行先はk。
def ami_go(k,dic_a):
return dic_a[k] if k in dic_a.keys() else k
#あみだの辞書a,bの連結をする。
def conL(a,b):#a,bの順に演算する。
keys = list(set(list(a.keys()) + list(b.keys())))
dic ={key:ami_go(ami_go(key,a),b) for key in keys if key !=ami_go(ami_go(key,a),b)}
if len(dic)==0:
dic={1:1}
return dic
def conR(a,b):#b,aの順に演算する。
return conL(b,a)
#アミダを、(辞書,名)のタプルのリストにする。
def rotdic(S,SN):
dic=[ami2dic(x) for x in S]
return list(zip(dic,SN))
# あみだ辞書dic_aを名で返す。
def name(dic_a):
global Nlist
return [item[1] for item in Nlist if item[0]==dic_a][0]
# あみだ辞書集dicsを名のリストで返す。
def names(dics):
global Nlist
return [item[1] for item in Nlist for b in dics if item[0]==b]
# あみだ辞書の集合Hと辞書aを演算した結果リストを返す。
def Ha(H,a):
global Nlist
res=[]
for b in H:
res +=[item[1] for item in Nlist if item[0]==conR(b,a)]
return res
def aH(a,H):
global Nlist
res=[]
for b in H:
res +=[item[1] for item in Nlist if item[0]==conR(a,b)]
return res
#辞書リストS,名リストSNから(辞書、名)のタプルのリストにする。
def Ndic(S,SN):
return list(zip(S,SN))
def pow(G,n):
return polymultiR([ G for x in range(1,n+1)]) if n>0 else {1:1}
#群表を作る
def maketable():
global Nlist
G = [x[0] for x in Nlist]
print("* ",names(G))
for item in G:
print(name(item),aH(item,G))
return True
#==================================以下がクラインの4元群====
#x軸対称移動はX={1:4, 2:3,3:2,4:1}という辞書
#y軸対称移動はY={1:2, 2:1,3:4,4:3}という辞書
#原点対称移動はO={1:3, 3:1,2:4,4:2}という辞書
#無移動はE={1:1}という辞書にして、群表を作ってみよう。
E={1:1}
X={1:4,2:3,3:2,4:1}
Y={1:2,2:1,3:4,4:3}
O={1:3,3:1,2:4,4:2}
S=[E,X,Y,O]
SN=["E","X","Y","O"]
Nlist=Ndic(S,SN)
print("クラインの4元群V4の群表")
maketable()
#=================================以下が4次の巡回群=====
g=[1,2,3,4]
S=[pow(ami2dic(g),index) for index in range(4)]
SN=["g" + str(x) for x in range(4)]
SN[0]='E '
Nlist=Ndic(S,SN)
print("4次の巡回群C4の群表")
maketable()
#===================================================
[OUT]
クラインの4元群V4の群表
* ['E', 'X', 'Y', 'O']
E ['E', 'X', 'Y', 'O']
X ['X', 'E', 'O', 'Y']
Y ['Y', 'O', 'E', 'X']
O ['O', 'Y', 'X', 'E']
4次の巡回群C4の群表
* ['E ', 'g1', 'g2', 'g3']
E ['E ', 'g1', 'g2', 'g3']
g1 ['g1', 'g2', 'g3', 'E ']
g2 ['g2', 'g3', 'E ', 'g1']
g3 ['g3', 'E ', 'g1', 'g2']
質問:置換を利用して、2面体群D3,D4の群表を作るにはどんなコードで実現できますか。
(D3)
正3角形の頂点1,2,3の移動は回転と裏返しによって、3*2=6個の状態に移動できる。
回転は3次の巡回群と同じで、{e, r, s=r^2}が要素となるね。
裏返しは固定する頂点が1,2,3のどれかなので、残りの互換になるから、{(1,2),(2,3),(3,1)}が要素になる。
(D4)
正4角形の頂点1,2,3,4の移動は回転と裏返しによって、4*2=6個の状態に移動できる。
回転は4次の巡回群と同じで、{e, r, s=r^2,t=r^3}が要素となるね。
裏返しは軸が向かい合う辺の中点の連結線か対角線かで互換の積か互換になるので、
{(1,2)(3,4),(1,4)(2,3),(1,3),(2,4)}が要素になる。
コードは基本関数以外の部分だけ作ろう。
#(D3)===============================================
e={1:1}
r=ami2dic([1,2,3])
s=ami2dic([1,3,2])
a=ami2dic([1,2])
b=ami2dic([2,3])
c=ami2dic([3,1])
S=[e,r,s,a,b,c]
SN=['E','R','S','a','b','c']
Nlist=Ndic(S,SN)
print("2面体群D3の群表")
maketable()
#(D4)===============================================
e={1:1}
r=ami2dic([1,2,3,4])
s=pow(r,2)
t=pow(r,3)
a=conR(ami2dic([1,2]),ami2dic([3,4]))
b=conR(ami2dic([1,4]),ami2dic([2,3]))
c=ami2dic([1,3])
d=ami2dic([2,4])
S=[e,r,s,t,a,b,p,q]
SN=['E','R','S','T','a','b','c','d']
Nlist=Ndic(S,SN)
print("2面体群D4の群表")
maketable()
#===================================
[OUT]
2面体群D3の群表
* ['E', 'R', 'S', 'a', 'b', 'c']
E ['E', 'R', 'S', 'a', 'b', 'c']
R ['R', 'S', 'E', 'c', 'a', 'b']
S ['S', 'E', 'R', 'b', 'c', 'a']
a ['a', 'b', 'c', 'E', 'R', 'S']
b ['b', 'c', 'a', 'S', 'E', 'R']
c ['c', 'a', 'b', 'R', 'S', 'E']
2面体群D4の群表
* ['E', 'R', 'S', 'T', 'a', 'b', 'c', 'd']
E ['E', 'R', 'S', 'T', 'a', 'b', 'c', 'd']
R ['R', 'S', 'T', 'E', 'c', 'd', 'b', 'a']
S ['S', 'T', 'E', 'R', 'b', 'a', 'd', 'c']
T ['T', 'E', 'R', 'S', 'd', 'c', 'a', 'b']
a ['a', 'd', 'b', 'c', 'E', 'S', 'T', 'R']
b ['b', 'c', 'a', 'd', 'S', 'E', 'R', 'T']
c ['c', 'a', 'd', 'b', 'R', 'T', 'E', 'S']
d ['d', 'b', 'c', 'a', 'T', 'R', 'S', 'E']
2面体群の群表は回転系と裏返し系に行列を2分割してみると、群表が4等分される。
回転系同士は閉じていて、裏返し系同士は回転系になり、両方系は裏返し系になる
という傾向が、D3,D4の両方でみられるね。
質問:行列を使って4元数群Q8を作り、非可換であることをコードで確かめるにはどうしたらようですか。
今まで辞書で作った群の要素の演算をする関数たちを、
行列を群の要素にしたものに作りかえましょう。
行列の2項演算は右から左へかけるので、conをconR,conLと区別する必要はありませんね。
その上で、8要素の行列の要素をmaketable()で演算して名前を表示してみよう。
行列の計算では、パッケージnumpyをnpの名でimportします。
また、
行列AとBのかけ算はA@Bでできます。
行列A==Bの確認はnp.all(A==B)というように,np.all()でくるみましょう。
行列で作る4元数群Q8は、一般線形群GL2(C)の部分群で正則です。
Aの逆行列はpythonでは、np.linalg.inv(A)のようにかいて求められます。
虚数単位はpythonではiではなくて、jになるので、注意しよう。
#[IN]Python
#=====================================================
import numpy as np
#行列mat_aの名を返す
def name(ma):
global Nlist
return [item[1] for item in Nlist if np.all(item[0]==ma)][0]
# 行列集mdicsを名のリストで返す。
def names(mdics):
global Nlist
return [item[1] for item in Nlist for b in mdics if np.all(item[0]==b)]
#行列リストS,名リストSNから(行列、名)のタプルのリストにする。
def Nmat(S,SN):
return list(zip(S,SN))
def con(a,b): #行列a,bの積する。
return a@b
def polymulti(mat_Lst):
global e
listsize=len(mat_Lst)
a = mat_Lst[0]
for num in range(1,listsize):
b = mat_Lst[num]
a = con(a,b)
mat = a
#空の行列は形式的に単位元とする。
if len(mat)==0:
mat = e
return mat
# あみだ辞書の集合Hと辞書aを演算した結果リストを返す。
def Ha(H,a):
global Nlist
res=[]
for b in H:
res +=[item[1] for item in Nlist if np.all(item[0]==con(b,a))]
return res
def aH(a,H):
global Nlist
res=[]
for b in H:
res +=[item[1] for item in Nlist if np.all(item[0]==con(a,b))]
return res
def powM(M,n): #行列aのn乗
return polymulti([M for x in range(1,n+1)] )
#群表を作る
def maketable():
global Nlist
G = [x[0] for x in Nlist]
print(" @ ",names(G))
for item in G:
print(name(item),aH(item,G))
return True
e = np.array([[1,0],[0,1]])
x = np.array([[0,1j],[1j,0]])
y = np.array([[0,1],[-1,0]])
x2=x@x
x3=x2@x
x4=x3@x
xy=x@y
x2y=x2@y
x3y=x3@y
S=[e,x,x2,x3,y,xy,x2y,x3y]
SN=['e ','x ','x^2 ','x^3 ','y ','xy ','x^2y','x^3y']
Nlist=Nmat(S,SN)
print("x^4=y^4=1==============")
print(f"{powM(x,4)}\n={powM(y,4)}\n={name(e)}")
print("x^2=y^2================")
print(f"{powM(x,2)}\n={powM(y,2)}")
print("y^(-1)xy=x^(-1)========")
print(f"{np.linalg.inv(y)@x@y}\n={np.linalg.inv(x)}")
print(" Q8の要素===============")
Q8=list(zip(S,SN))
for item in Q8:
print(f"{item[0]}={item[1]}")
print(" Q8@Q8の群表=============")
maketable()
#=====================================================
[OUT]
x^4=y^4=1==============
[[1.+0.j 0.+0.j]
[0.+0.j 1.+0.j]]
=[[1 0]
[0 1]]
=e
x^2=y^2================
[[-1.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j]]
=[[-1 0]
[ 0 -1]]
y^(-1)xy=x^(-1)========
[[0.+0.j 0.-1.j]
[0.-1.j 0.+0.j]]
=[[0.+0.j 0.-1.j]
[0.-1.j 0.+0.j]]
Q8の要素===============
[[1 0]
[0 1]]=e
[[0.+0.j 0.+1.j]
[0.+1.j 0.+0.j]]=x
[[-1.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j]]=x^2
[[0.+0.j 0.-1.j]
[0.-1.j 0.+0.j]]=x^3
[[ 0 1]
[-1 0]]=y
[[0.-1.j 0.+0.j]
[0.+0.j 0.+1.j]]=xy
[[ 0.+0.j -1.+0.j]
[ 1.+0.j 0.+0.j]]=x^2y
[[0.+1.j 0.+0.j]
[0.+0.j 0.-1.j]]=x^3y
Q8@Q8の群表=============
@ ['e ', 'x ', 'x^2 ', 'x^3 ', 'y ', 'xy ', 'x^2y', 'x^3y']
e ['e ', 'x ', 'x^2 ', 'x^3 ', 'y ', 'xy ', 'x^2y', 'x^3y']
x ['x ', 'x^2 ', 'x^3 ', 'e ', 'xy ', 'x^2y', 'x^3y', 'y ']
x^2 ['x^2 ', 'x^3 ', 'e ', 'x ', 'x^2y', 'x^3y', 'y ', 'xy ']
x^3 ['x^3 ', 'e ', 'x ', 'x^2 ', 'x^3y', 'y ', 'xy ', 'x^2y']
y ['y ', 'x^3y', 'x^2y', 'xy ', 'x^2 ', 'x ', 'e ', 'x^3 ']
xy ['xy ', 'y ', 'x^3y', 'x^2y', 'x^3 ', 'x^2 ', 'x ', 'e ']
x^2y ['x^2y', 'xy ', 'y ', 'x^3y', 'e ', 'x^3 ', 'x^2 ', 'x ']
x^3y ['x^3y', 'x^2y', 'xy ', 'y ', 'x ', 'e ', 'x^3 ', 'x^2 ']
群表をながめてみましょう。
x@y=xyになりますが、
y@x=x^3yになってますね。
xy@x=yですが、
x@xy=x^2yです。
1つでも非可換があれば非可換群なので
4元数群が非可換であることが、この表でも確認できますね。