多項式体で4次の魔方陣を作る
このページはマス旅の一部です。
前回はアフィン平面で素数次の魔方陣を作りました。
今回は次数が素数でない魔方陣、4次の魔方陣を作ってみよう。
1.思い起こし
<素数次の魔方陣の作り方のまとめ>
pが素数のときは、体Fpの直積を点にして直線群を作った。
そして、傾きmの直線群y-mx=cで1つのラテン方陣ができた。
i行j列をc_m(i,j)=j-m i(mod p)がセルの数値になる。
直交して、しかも1対角線の和も0からp-1までの和になる2つのラテン方陣があると魔方陣が作れたね。
0からp-1までの和は(0+p-1)*p/2=p(p-1)/2
平均はp(p-1)/2/p=(p-1)/2
ラテン方陣c_1(i,j)=j-i(mod p)はj=iのセル値が0になるからすべて(p-1)/2を加算して、
c_A(i,j)=j-i +(p-1)/2(mod p)
とする。
ラテン方陣c_p-1(i,j)=j-(p-1)i(mod p)=j+i(mod p)はj+i=p-1のセル値がp-1になるからすべて(p-1)/2を減算して、
c_B(i,j)=j+i -(p-1)/2(mod p)
とする。
この2つの方陣値からi行j列を
M(i,j)=p*c_A+c_B+1
とすれば、完全魔方陣ができる。
最小値がp*0+0+1,最大値がp*(p-1)+(p-1)+1=p^2。
たてよこ斜めの和が
p*p(p-1)/2+p(p-1)/2+1*p=(p+1)p(p-1)/2+p
=(p^3+p)/2
で一定になる。
<素数次でない体の作り方の例>
前回は使わなかったが、
素数次でない有限体の作り方を簡単に振り返ろう。
pが素数のとき、q=p^nは素数でないが、体Fqが作れる。
多項式環Fを作る。x^q-xを素因数分解して、既約多項式fxを見つける。
そして、多項式の集合を多項式fxで割った剰余で分類すると、それが剰余類になる。
これで体Fp/fFpができる。
たとえば、F4では、x^4-x=x(x^3-1)=x(x-1)(x^2+x+1)から、f=x^2+x+1が既約多項式。
2次の多項式環F2をfF2で分類した商体を作ればいいね。
F4=F2[x]/fF2[x]={[0],[1],[x],[x+1]}
の4元になる。
2.4次の魔方陣を作る
F4はF2[x]/fF2[x]={[0],[1],[x],[x+1]}で、F4の直積でアフィン空間を作ろう。
ただし、F4とはいっても、もとの多項式環はF2だった。
F2なので係数の剰余計算は、mod4 ではなくてmod2になることに注意しよう。
たとえば、
x+x=2x=0x=0
x*x=x^2≡x^2+x^2+x+1=x+1(mod x^2+x+1)
のように、多項式としては、x^2+x+1を法にして、
係数はmod 2にして、演算結果が4元のどれかになることを確認しよう。
加法表と乗法表を作る。
+ 0、 1、 x、x+1
0 0、 1、 x、x+1
1 1、 0、x+1、 x
x x、x+1、 0、 1
x+1、x+1、x、 1、 0
× 0、 1、 x、x+1
0 0、 0、 0、 0
1 0、 1、 x、x+1
x 0、 x、x+1、 1
x+1 0、x+1、 1、 x
ここで、平面の軸としてのx、yとの混同をさけるために、
x=a,x+1=b
と置き換えましょう。
ここからは、多項式の体という意味も捨てます。
F4={0,1,a,b}(mod2)の直積をアフィン平面の4×4=16点とする。
加法 0 1 a b
0 0 1 a b
1 1 0 b a
a a b 0 1
b b a 1 0
乗法 0 1 a b
0 0 0 0 0
1 0 1 a b
a 0 a b 1
b 0 b 1 a
a=2,b=3
と読み替えて、
原点を通るy軸以外の4直線
L0 0x+y=0 (0,0),(0,1),(0,2),(0,3)
L1 1x+y=0 (0,0),(1,1),(2,2),(3,3)
L2 2x+y=0 (0,0),(1,2),(2,3),(3,1)
L3 3x+y=0 (0,0),(1,3),(2,1),(3,2)
これらの切片を0,1,2,3と平行移動した直線群はそれぞれラテン方陣になるはず。
L1群は
1x+y=0 (0,0),(1,1),(2,2),(3,3)
1x+y=1 (0,1),(1,0),(2,3),(3,2)
1x+y=2 (0,2),(1,3),(2,0),(3,1)
1x+y=3 (0,3),(1,2),(2,1),(3,0)
L2群は
2x+y=0 (0,0),(1,2),(2,3),(3,1)
2x+y=1 (0,1),(1,3),(2,2),(3,0)
2x+y=2 (0,2),(1,0),(2,1),(3,3)
2x+y=3 (0,3),(1,1),(2,0),(3,2)
L3群は
3x+y=0 (0,0),(1,3),(2,1),(3,2)
3x+y=1 (0,1),(1,2),(2,0),(3,3)
3x+y=2 (0,2),(1,1),(2,3),(3,0)
3x+y=3 (0,3),(1,0),(2,2),(3,1)
各直線は4セルを通り、そのセルに切片値を入れると、
L1からのラテン方陣Aは
0 1 2 3
1 0 3 2
2 3 0 1
3 2 1 0
L2からのラテン方陣Bは
0 1 2 3
2 3 0 1
3 2 1 0
1 0 3 2
L3からのラテン方陣Cは
0 1 2 3
3 2 1 0
1 0 3 2
2 3 0 1
方陣は0だけ対角線と3だけの対角線があるので使えないが、
方陣B、Cは対角線も他と同じく0,1,2,3がすべてそろう。
だから、たとえば、
4B+C+1を各成分で実行してみよう。
これで、(0+1+2+3)*(4+1)+1*4=34
の和一定の魔方陣ができたね。
| 1 | 6 | 11 | 16 |
| 12 | 15 | 2 | 5 |
| 14 | 9 | 8 | 3 |
| 7 | 4 | 13 | 10 |
ラテン方陣A,Bから魔方陣を求める
3.振り返り
<振り返り>
手作業で演算表を作り、それを目でみて直線群を作り、
その点位置を読み取って、切片を行列のセルに入れていくという、
なんとも手間のかかる作業でした。
試行錯誤はしてませんが、あまりスマートではないですね。
最後の4A+B+1にいたっては、暗算大会でした。
加法 0 1 a b
0 0 1 a b
1 1 0 b a
a a b 0 1
b b a 1 0
加法 0 1 2 3
0 0 1 2 3
1 1 0 3 2
2 2 3 0 1
3 3 3 1 0
この加法はXORで実現できます。2進数に直して、
ビットが片方だけ立っていると1になるのが排他的ORです。
これを⊕マークであらわそう。
乗法 0 1 a b
0 0 0 0 0
1 0 1 a b
a 0 a b 1
b 0 b 1 a
ここで、a=2,b=3におきかえましょう。
乗法 0 1 2 3
0 0 0 0 0
1 0 1 2 3
2 0 2 3 1
3 0 3 1 2
これはガロア体演算(GF4)a^2=b+1
この演算を⊗マークで表そう。
すると、
L2はc2(i,j)=(2⊗i)⊕jででき、
L3はc3(i,j)=(3⊗i)⊕jでできる。
これから、対応する成分の和で4次の魔方陣が作れるはずだね。
課題:4次の魔方陣をgeogebraの機能で表示するにはどうしたらいいですか。
geogebraにはビット演算の⊕はなく、論理値だけしか対応してません。
また、ガロア体演算もありません。
あきらめて、ラテン方陣A、Bをべた打ちしてMを計算で出すこともできます。
タイトルは「ラテン方陣A,Bから魔方陣を求める」
A={{0, 1, 2, 3},{2, 3, 0, 1},{3, 2, 1, 0},{1, 0, 3, 2}}
B={{0, 1, 2, 3},{3, 2, 1, 0},{1, 0, 3, 2},{2, 3, 0, 1}}
M=Sequence(Sequence(4*A(p,q)+B(p,q)+1, p,1,4),q,1,4)
text1="ラテン方陣A"
TableText(A(1),A(2),A(3),A(4),"c|_")
text2="ラテン方陣B"
TableText(B(1),B(2),B(3),B(4),"c|_")
text3="4A+B+1=魔方陣M"
TableText(M(1),M(2),M(3),M(4),"c|_")
このまま数式ビューに貼り付けると、")が繰り返して、行列の最後に右かっこが自動でつくバグがありますので、貼り付けるときに、謎に追加される")を削ってから確定してください。
しかし、これでは、つまらないですね。
関数がなければ、演算表を行列で作ってそれを読み取ってみましょう。
課題:4次の魔方陣を演算表からgeogebraで実現するにはどうしたらいいですか。
#演算表を作って、行と列から行列値を読み取ることで実現できそうです。
#タイトルは「演算表から魔方陣まで一気に計算する」
ADD = {{0, 1, 2, 3}, {1, 0, 3, 2}, {2, 3, 0, 1}, {3, 2, 1, 0}}
MUL = {{0, 0, 0, 0}, {0, 1, 2, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}}
#しかし、Elementは数値として呼び出したときだけ作動するので
#Add(x,y)=Element(ADD,x,y)は作れません。
#そこで、Elementを使った関数を作るのではなく、Sequenceコマンドの中で使いましょう。
#geogebraのマニュアルでは、Element( <行列>, <行>, <列> )形式で、
#行と列の位置を指定して要素を取り出せるとあります。
#また、
#Sequenceを入れ子にすると、for文の入れ子と同じ効果があります。
#すると、
#Sequence(Sequence(Element(ADD,p,q)+1, p, 1, 4), q, 1, 4)
#で、ADD+1の行列ができます。
#これを
For_pq[ Element(ADD,p,q)+1 ]
と略記します。
#もし、2⊗iをしたかったら、2は3行目だから、Element(MUL,3,p)で値を得ます。
#さらに、(2⊗i)⊕jをしたかったら、Element(MUL,3,p)の値から行を読み、
#jの分を列にしてADD行列を見ます。
#ここで、
#For_pq[ Element(ADD, (Element(MUL, 3, p) ), q) ]
#にすると、?がでます。
#なぜでしょうか。
#Element(MUL,3,p)の値は0~3ですが、これをADDの行位置に渡してしまうと0行を読もうとする
#からです。
#そこで、
#For_pq[ Element(ADD, (Element(MUL, 3, p)+1 ), q) ]
#でAが作れることがわかりますね。
#具体的には
A = Sequence(Sequence(Element(ADD, (Element(MUL, 3, p) +1 ), q), p, 1, 4), q, 1, 4)
B = Sequence(Sequence(Element(ADD, (Element(MUL, 4, p) +1 ), q), p, 1, 4), q, 1, 4)
M=Sequence(Sequence(4*A(p,q)+B(p,q)+1, p,1,4),q,1,4)
text1="ラテン方陣A"
text2="ラテン方陣B"
text3="4A+B+1=魔方陣M"
TableText(A,"c|_")
TableText(B,"c|_")
TableText(M,"c|_")
さっきの比べるとあれっとなります。
ちがってみえます。
でもよくみると、行列が転置しているだけだと気づきますね。
まあ、全部転置すれば、何も問題はないです。
シーケンスループの外変数がqで内変数がpだから、q行p列という行列を読みかきするんですね。
だから、気にいらなければ、#For_pq[ ]の中だけ、pとqを入れ替えればいいですね。