3次の行列式:サラスの方法

3次の行列式を求めるのに,サラスの方法というものがあります。

式で覚えるというより,図で覚えるのが一般的でしょう。

まず下図の左側のようにとりこれが+,次に右側のようにとり−をつけて一つの式にします。


この図を描きます。

なお,「KeTCindyによる図入り教材の作成」のページ https://www65.atwiki.jp/ketcindy/pages/131.html

を参考にしています。

この図では,矢線の位置が問題です。始点と終点の位置にすべて点を置くのは面倒ですし,調整も大変。

点はまず成分を描くための9つをとります。それと,行列式の縦線,迂回する線の中継点です。

これで,たとえば,点Aと点Eを結ぶ矢線を描くのですが,そのままではだめで,短くしたいですね。

そこで,線分の両端をカットして,カットした線分の両端の座標を返す関数を,ユーザ定義関数として定義します。

// 2点を結ぶ線分の両端を短くした端点の座標リストを返す

// plist 2点のリスト dlist : 切り落とす長さのリスト

cutseg(plist,dlist):=(

regional(uv,p1,p2,d1,d2);

p1=plist_1;

p2=plist_2;

d1=dlist_1;

d2=dlist_2;

uv=(p2-p1)/|p2-p1|;

[p1+uv*d1,p2-uv*d2];

);

たとえば,cutest([A,B],[0,0.5]) とすると,Aの方はカットせず,Bの方だけ0.5短くした線分の両端の座標が返ります。

では,9つの点に対し,成分を表示し,行列式の縦線をまず描きましょう。

Expr([A,"c","a_{11}"]);

Expr([B,"c","a_{12}"]);

Expr([C,"c","a_{13}"]);

Expr([D,"c","a_{21}"]);

Expr([E,"c","a_{22}"]);

Expr([F,"c","a_{23}"]);

Expr([G,"c","a_{31}"]);

Expr([H,"c","a_{32}"]);

Expr([K,"c","a_{33}"]);

Listplot("11",[A.xy+[-0.8,0.8],G.xy+[-0.8,-0.8]],["dr,0.5"]);

Listplot("12",[C.xy+[0.8,0.8],K.xy+[0.8,-0.8]],["dr,0.5"]);

次に矢線です。

まず左側の図から。

sz=0.7; // 矢線の前後の空白サイズ

Listplot("1",cutseg([C,L],[sz,0]));

Listplot("2",[L,M]);

Arrowdata("3",cutseg([M,D],[0,sz]));

Listplot("4",cutseg([F,N],[sz,0]));

Listplot("5",[N,O]);

Arrowdata("6",cutseg([O,G],[0,sz]));

Arrowdata("7",cutseg([A,E],[sz,sz]));

Arrowdata("8",cutseg([B,F],[sz,sz]));

Arrowdata("9",cutseg([D,H],[sz,sz]));

Arrowdata("10",cutseg([E,K],[sz,sz]));

Expr([[0,-6],"c","a_{11}a_{22}a_{33}+a_{12}a_{23}a_{31}+a_{13}a_{21}a_{32}"]);

矢線の前後の空白は sz で調整します。

次に右側ですが,これをあらためて右に作るのは面倒なので,同じ点を使って右の図を作り,左右2つの図ファイルを作ることにしましょう。

Setcolor("red");

Listplot("1",cutseg([A,P],[sz,0]));

Listplot("2",[P,Q]);

Arrowdata("3",cutseg([Q,F],[0,sz]));

Listplot("4",cutseg([D,S],[sz,0]));

Listplot("5",[S,R]);

Arrowdata("6",cutseg([R,K],[0,sz]));

Arrowdata("7",cutseg([C,E],[sz,sz]));

Arrowdata("8",cutseg([B,D],[sz,sz]));

Arrowdata("9",cutseg([F,H],[sz,sz]));

Arrowdata("10",cutseg([E,G],[sz,sz]));

Expr([[0,-6],"c","-a_{11}a_{23}a_{32}-a_{12}a_{21}a_{33}-a_{13}a_{22}a_{31}"]);

この2つをif文で切り換えられるようにすれば便利です。

前後の設定も含めた全体のスクリプトは次のようになります。

Setunitlen() や Fontsize()などは適当に。

Ketinit();

Addax(0);

Fontsize("La");

// 2点を結ぶ線分の両端を短くした端点の座標リストを返す

// plist 2点のリスト dlist : 切り落とす長さのリスト

cutseg(plist,dlist):=(

regional(uv,p1,p2,d1,d2);

p1=plist_1;

p2=plist_2;

d1=dlist_1;

d2=dlist_2;

uv=(p2-p1)/|p2-p1|;

[p1+uv*d1,p2-uv*d2];

);

Setunitlen("7mm");

Expr([A,"c","a_{11}"]);

Expr([B,"c","a_{12}"]);

Expr([C,"c","a_{13}"]);

Expr([D,"c","a_{21}"]);

Expr([E,"c","a_{22}"]);

Expr([F,"c","a_{23}"]);

Expr([G,"c","a_{31}"]);

Expr([H,"c","a_{32}"]);

Expr([K,"c","a_{33}"]);

Listplot("11",[A.xy+[-0.8,0.8],G.xy+[-0.8,-0.8]],["dr,0.5"]);

Listplot("12",[C.xy+[0.8,0.8],K.xy+[0.8,-0.8]],["dr,0.5"]);

sz=0.7; // 矢線の前後の空白サイズ

leftdraw=1;

if(leftdraw==1,

Listplot("1",cutseg([C,L],[sz,0]));

Listplot("2",[L,M]);

Arrowdata("3",cutseg([M,D],[0,sz]));

Listplot("4",cutseg([F,N],[sz,0]));

Listplot("5",[N,O]);

Arrowdata("6",cutseg([O,G],[0,sz]));

Arrowdata("7",cutseg([A,E],[sz,sz]));

Arrowdata("8",cutseg([B,F],[sz,sz]));

Arrowdata("9",cutseg([D,H],[sz,sz]));

Arrowdata("10",cutseg([E,K],[sz,sz]));

Expr([[0,-6],"c","a_{11}a_{22}a_{33}+a_{12}a_{23}a_{31}+a_{13}a_{21}a_{32}"]);

, // 右の図

Setcolor("red");

Listplot("1",cutseg([A,P],[sz,0]));

Listplot("2",[P,Q]);

Arrowdata("3",cutseg([Q,F],[0,sz]));

Listplot("4",cutseg([D,S],[sz,0]));

Listplot("5",[S,R]);

Arrowdata("6",cutseg([R,K],[0,sz]));

Arrowdata("7",cutseg([C,E],[sz,sz]));

Arrowdata("8",cutseg([B,D],[sz,sz]));

Arrowdata("9",cutseg([F,H],[sz,sz]));

Arrowdata("10",cutseg([E,G],[sz,sz]));

Expr([[0,-6],"c","-a_{11}a_{23}a_{32}-a_{12}a_{21}a_{33}-a_{13}a_{22}a_{31}"]);

);

Windispg();

< 戻る >