Google ClassroomGoogleクラスルーム
GeoGebraGeoGebra Classroom

多項式体で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を各成分で実行してみよう。
1 61116
1215 2 5
14 9 8 3
7 41310
これで、(0+1+2+3)*(4+1)+1*4=34 の和一定の魔方陣ができたね。

ラテン方陣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を入れ替えればいいですね。

演算表から魔方陣まで一気に計算する