エクセル、グーグルドライブ、リブレオフィスにて行列式と余因子行列と逆行列をmdeterm関数やminverse関数に頼らずに組み立ててみる。
最初は実数版を作ってみたが複素数版も手間は大差なく手順もほぼ同じなので前者は省略。(虚部を0にすれば実数の結果を見ることは可能にした。)
2x2 元行列= AC15:AD16
AC22= =IMSUB(improduct(AC15,AD16),improduct(AC16,AD15))
3x3 元行列= AC15:AE17
AC24= =imsum(
IMPRODUCT(AC15,IMSUB(improduct(AD16,AE17),improduct(AD17,AE16))),
IMPRODUCT(AC16,IMSUB(improduct(AD17,AE15),improduct(AD15,AE17))),
IMPRODUCT(AC17,IMSUB(improduct(AD15,AE16),improduct(AD16,AE15))))
4x4 元行列= AC15:AF18 (「+1,」はエクセルでは「1,」にされる)
AC26= =imsum(
IMPRODUCT(+1,AC15,imsum(
IMPRODUCT(AD16,IMSUB(improduct(AE17,AF18),improduct(AE18,AF17))),
IMPRODUCT(AD17,IMSUB(improduct(AE18,AF16),improduct(AE16,AF18))),
IMPRODUCT(AD18,IMSUB(improduct(AE16,AF17),improduct(AE17,AF16))))),
IMPRODUCT(-1,AC16,imsum(
IMPRODUCT(AD17,IMSUB(improduct(AE18,AF15),improduct(AE15,AF18))),
IMPRODUCT(AD18,IMSUB(improduct(AE15,AF17),improduct(AE17,AF15))),
IMPRODUCT(AD15,IMSUB(improduct(AE17,AF18),improduct(AE18,AF17))))),
IMPRODUCT(+1,AC17,imsum(
IMPRODUCT(AD18,IMSUB(improduct(AE15,AF16),improduct(AE16,AF15))),
IMPRODUCT(AD15,IMSUB(improduct(AE16,AF18),improduct(AE18,AF16))),
IMPRODUCT(AD16,IMSUB(improduct(AE18,AF15),improduct(AE15,AF18))))),
IMPRODUCT(-1,AC18,imsum(
IMPRODUCT(AD15,IMSUB(improduct(AE16,AF17),improduct(AE17,AF16))),
IMPRODUCT(AD16,IMSUB(improduct(AE17,AF15),improduct(AE15,AF17))),
IMPRODUCT(AD17,IMSUB(improduct(AE15,AF16),improduct(AE16,AF15))))))
5x5 元行列= AC15:AG19
AC28= =imsum(
IMPRODUCT(AC15,imsum(
IMPRODUCT(+1,AD16,imsum(
IMPRODUCT(AE17,IMSUB(improduct(AF18,AG19),improduct(AF19,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF19,AG17),improduct(AF17,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF17,AG18),improduct(AF18,AG17))))),
IMPRODUCT(-1,AD17,imsum(
IMPRODUCT(AE18,IMSUB(improduct(AF19,AG16),improduct(AF16,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF16,AG18),improduct(AF18,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF18,AG19),improduct(AF19,AG18))))),
IMPRODUCT(+1,AD18,imsum(
IMPRODUCT(AE19,IMSUB(improduct(AF16,AG17),improduct(AF17,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF17,AG19),improduct(AF19,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF19,AG16),improduct(AF16,AG19))))),
IMPRODUCT(-1,AD19,imsum(
IMPRODUCT(AE16,IMSUB(improduct(AF17,AG18),improduct(AF18,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF18,AG16),improduct(AF16,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF16,AG17),improduct(AF17,AG16))))))),
IMPRODUCT(AC16,imsum(
IMPRODUCT(+1,AD17,imsum(
IMPRODUCT(AE18,IMSUB(improduct(AF19,AG15),improduct(AF15,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF15,AG18),improduct(AF18,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF18,AG19),improduct(AF19,AG18))))),
IMPRODUCT(-1,AD18,imsum(
IMPRODUCT(AE19,IMSUB(improduct(AF15,AG17),improduct(AF17,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF17,AG19),improduct(AF19,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF19,AG15),improduct(AF15,AG19))))),
IMPRODUCT(+1,AD19,imsum(
IMPRODUCT(AE15,IMSUB(improduct(AF17,AG18),improduct(AF18,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF18,AG15),improduct(AF15,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF15,AG17),improduct(AF17,AG15))))),
IMPRODUCT(-1,AD15,imsum(
IMPRODUCT(AE17,IMSUB(improduct(AF18,AG19),improduct(AF19,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF19,AG17),improduct(AF17,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF17,AG18),improduct(AF18,AG17))))))),
IMPRODUCT(AC17,imsum(
IMPRODUCT(+1,AD18,imsum(
IMPRODUCT(AE19,IMSUB(improduct(AF15,AG16),improduct(AF16,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF16,AG19),improduct(AF19,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF19,AG15),improduct(AF15,AG19))))),
IMPRODUCT(-1,AD19,imsum(
IMPRODUCT(AE15,IMSUB(improduct(AF16,AG18),improduct(AF18,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF18,AG15),improduct(AF15,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF15,AG16),improduct(AF16,AG15))))),
IMPRODUCT(+1,AD15,imsum(
IMPRODUCT(AE16,IMSUB(improduct(AF18,AG19),improduct(AF19,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF19,AG16),improduct(AF16,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF16,AG18),improduct(AF18,AG16))))),
IMPRODUCT(-1,AD16,imsum(
IMPRODUCT(AE18,IMSUB(improduct(AF19,AG15),improduct(AF15,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF15,AG18),improduct(AF18,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF18,AG19),improduct(AF19,AG18))))))),
IMPRODUCT(AC18,imsum(
IMPRODUCT(+1,AD19,imsum(
IMPRODUCT(AE15,IMSUB(improduct(AF16,AG17),improduct(AF17,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF17,AG15),improduct(AF15,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF15,AG16),improduct(AF16,AG15))))),
IMPRODUCT(-1,AD15,imsum(
IMPRODUCT(AE16,IMSUB(improduct(AF17,AG19),improduct(AF19,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF19,AG16),improduct(AF16,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF16,AG17),improduct(AF17,AG16))))),
IMPRODUCT(+1,AD16,imsum(
IMPRODUCT(AE17,IMSUB(improduct(AF19,AG15),improduct(AF15,AG19))),
IMPRODUCT(AE19,IMSUB(improduct(AF15,AG17),improduct(AF17,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF17,AG19),improduct(AF19,AG17))))),
IMPRODUCT(-1,AD17,imsum(
IMPRODUCT(AE19,IMSUB(improduct(AF15,AG16),improduct(AF16,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF16,AG19),improduct(AF19,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF19,AG15),improduct(AF15,AG19))))))),
IMPRODUCT(AC19,imsum(
IMPRODUCT(+1,AD15,imsum(
IMPRODUCT(AE16,IMSUB(improduct(AF17,AG18),improduct(AF18,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF18,AG16),improduct(AF16,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF16,AG17),improduct(AF17,AG16))))),
IMPRODUCT(-1,AD16,imsum(
IMPRODUCT(AE17,IMSUB(improduct(AF18,AG15),improduct(AF15,AG18))),
IMPRODUCT(AE18,IMSUB(improduct(AF15,AG17),improduct(AF17,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF17,AG18),improduct(AF18,AG17))))),
IMPRODUCT(+1,AD17,imsum(
IMPRODUCT(AE18,IMSUB(improduct(AF15,AG16),improduct(AF16,AG15))),
IMPRODUCT(AE15,IMSUB(improduct(AF16,AG18),improduct(AF18,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF18,AG15),improduct(AF15,AG18))))),
IMPRODUCT(-1,AD18,imsum(
IMPRODUCT(AE15,IMSUB(improduct(AF16,AG17),improduct(AF17,AG16))),
IMPRODUCT(AE16,IMSUB(improduct(AF17,AG15),improduct(AF15,AG17))),
IMPRODUCT(AE17,IMSUB(improduct(AF15,AG16),improduct(AF16,AG15))))))))
6x6以降は省略
リブレオフィスカルクにて
2x2
(リブレオフィスでも複素数のmdeterm関数はエラーのはずだが0になっているのは自動計算をオフにしてあるからかも知れない)
下準備 元行列は乱数
AB11:AD13は乱数用。元行列は乱数で変化する。
下準備 はみ出し部分
AC17= =AC15 AC17:AD18= AC17をコピペ (以前は配列数式で元行列の範囲丸ごと参照していたが(AC17:AD18= {元行列}等)行挿入列挿入時に不便だったので不採用。配列数式大好きなのに今回は珍しく1か所も使ってない。)
AE15= =AC15 AE15:AF18= AE15をコピペ
小行列式はみ出しシフト(仮)
AD21= =AD16 (これは元行列の1行1列の小行列式)
AG21= AD21をカトペ (「カトペ」はカット&ペーストの意味)
再度 AD21= =AD16 (AD21を数式コピペでも良い。ただ作業セルが増えると面倒になる)
AG21:AH22= AG21をコピペ
余因子行列転置前(仮)
小行列式はみ出しシフト(仮)を符号調整する
AJ21= =IMPRODUCT(AG21,-1^(ROW(A1)+COLUMN(A1)))
AJ21:AK22= AJ21をコピペ
余因子行列
余因子行列転置前(仮)を転置する
AJ18= =OFFSET($AJ$21,COLUMN(A1)-1,ROW(A1)-1)
AJ18:AK19= AJ18をコピペ (元々はtranspose関数を使っていたが行挿入列挿入時に不便だったので代替手段を考えてみた。)
検算
元行列と余因子行列の行列積を求める
AJ15= =IMSUM(IMPRODUCT($AC15,AJ$18),IMPRODUCT($AD15,AJ$19))
AJ15:AK16= AJ15をコピペ
左上から右下の対角線が行列式になって他が0になるととりあえずひと安心。
小行列式循環シフト(仮)
AD22= AD21をコピペ
AD22を選択して「メニュー」「編集」「検索と置換」
検索=17 置換=15 現在の選択範囲のみにチェック 検索場所は「数式」 で「すべて置換」
(検索の17は下はみ出し部分の1行目の行番号)
AE21:AE22= AD21:AD22をコピペ
AE21:AE22を選択して「メニュー」「編集」「検索と置換」
検索=AE 置換=AC 現在の選択範囲のみにチェック 検索場所は「数式」 で「すべて置換」
(検索のAEは右はみ出し部分の1列目の列名)
sag1 行列式前準備1
符号調整と元行列の1列目と小行列式はみ出しシフト(仮)の1列目の積の和(内積)を求める
AA20= =IMSUM(AA21:AA22)
AA21= =IMPRODUCT(+1,AC15,AG21)
AA22= =IMPRODUCT(-1,AC16,AG22)
sag2 行列式前準備2
sag1の数式の最後の項を元行列のセルだけの数式に変更する
AB20= AA20をコピペ
AB21= AA21の数式をコピペ(セルのコピペではなくセル内容のコピペ)
AD21の数式をコピー(「=」を除外)、AB21「=IMPRODUCT(AC15,AG21)」の「AG21」を選択してペースト
AD22の数式をコピー(「=」を除外)、AB22「=IMPRODUCT(AC16,AG22)」の「AG22」を選択してペースト
sag2の全体を1つのセルにまとめる
AC22= =IMSUM(0,0)
AB21の数式をコピー(「=」を除外)、AC22の1つ目の0を選択してペースト
AB22の数式をコピー(「=」を除外)、AC22の2つ目の0を選択してペースト
AC22= =IMSUM(IMPRODUCT(+1,AC15,AD16),IMPRODUCT(-1,AC16,AD15))
この説明では-1倍を使ったが実際には2x2のみ「行列式」ではIMSUBを使った。4x4以上では前者の方が()のネストが少ないし順番変更も不要なのでシンプルかと思う。
AC22= =IMSUB(IMPRODUCT(AC15,AD16),IMPRODUCT(AC16,AD15))
作業で乱れた罫線は必要に応じて書き直す。
下準備 シートのコピーと3x3化
現シート「2x2」のタブを右クリックして「シートを移動またはコピー」
「コピー」「- 末尾に挿入 -」新しい名前を「3x3」等としてコピー
22行を選択して行番号の所で右クリック「上に行を挿入」
19行の上と16行の上にも行挿入 AK列、AH列、AD列の左に列挿入
下準備 その他
元行列は乱数が必要なら同じ数式をコピペすればよい。はみ出し部分も空白部分を埋めるだけ。
小行列式循環シフト(仮)と小行列式はみ出しシフト(仮)の内容とsag2の内容を消去する
小行列式はみ出しシフト(仮)
「3x3」シートのAD23= 「2x2」シートのAC22をコピペ
「3x3」シートのAH23= AD23をカトペ
「3x3」シートのAD23= 「2x2」シートのAC22を再度コピペ
(以下「3x3」シート)
AH23:AJ25= AH23をコピペ
余因子行列転置前(仮)
小行列式はみ出しシフト(仮)を符号調整する(奇数行列では調整不要)
AL23= =IMPRODUCT(AH23,1^(ROW(A1)+COLUMN(A1))) (奇数行列の場合「=AH23」だけで良いがこの形で残しておけば偶数行列での手間が軽減する)
AL23:AN25= AL23をコピペ
余因子行列
余因子行列転置前(仮)を転置する
AL19:AN21= AL19をコピペ
検算
元行列と余因子行列の行列積を求める
AL15= =IMSUM(IMPRODUCT($AC15,AL$19),IMPRODUCT($AD15,AL$20),IMPRODUCT($AE15,AL$21))
(元の数式の最後の「,improduct(~,~)」を数式コピー、文末の「)」の前にカーソルを置いてペーストしてから修正するのが楽)
AL15:AN17= AL15をコピペ
小行列式循環シフト(仮)
AD24= AD23をコピペ
AD24を選択して「メニュー」「編集」「検索と置換」
検索=18 置換=15 現在の選択範囲のみにチェック 検索場所は「数式」 で「すべて置換」
AD25= AD24をコピペ
AD25を選択して「メニュー」「編集」「検索と置換」
検索=18 置換=15 現在の選択範囲のみにチェック 検索場所は「数式」 で「すべて置換」
(4x4以降もこの作業を1行ずつ一番下まで行う)
AE23:AE25= AD23:AD25をコピペ
AE23:AE25を選択して「メニュー」「編集」「検索と置換」
検索=AF 置換=AC 現在の選択範囲のみにチェック 検索場所は「数式」 で「すべて置換」
AF23:AF25= AE23:AE25をコピペ
AF23:AF25を選択して「メニュー」「編集」「検索と置換」
検索=AF 置換=AC 現在の選択範囲のみにチェック 検索場所は「数式」 で「すべて置換」
(4x4以降もこの作業を1列ずつ一番右まで行う)
sag1 行列式前準備1
元行列の1列目と小行列式はみ出しシフト(仮)の1列目の積の和(内積)を求める(奇数行列では符号調整なし)
AA22= =IMSUM(AA23:AA25) (変更なしで使えると思う)
AA23= =IMPRODUCT(AC15,AH23) (変更なしで使えると思う)
AA24:AA25= AA23をコピペ (AA24を埋めるだけで使えると思う)
sag2 行列式前準備2
sag1の数式の最後の項を元行列のセルだけの数式に変更する
AB22= AA22をコピペ
AB23= AA23の数式をコピペ(セルのコピペではなくセル内容のコピペ)
AD23の数式をコピー(「=」を除外)、AB23「=IMPRODUCT(AC15,AH23)」の「AH23」を選択してペースト
AD24の数式をコピー(「=」を除外)、AB24「=IMPRODUCT(AC16,AH24)」の「AH24」を選択してペースト
AD25の数式をコピー(「=」を除外)、AB25「=IMPRODUCT(AC17,AH25)」の「AH25」を選択してペースト
sag2の全体を1つのセルにまとめる
AC24= =IMSUM(0,0,0)
AB23の数式をコピー(「=」を除外)、AC24の1つ目の0を選択してペースト
AB24の数式をコピー(「=」を除外)、AC24の2つ目の0を選択してペースト
AB25の数式をコピー(「=」を除外)、AC24の3つ目の0を選択してペースト
AC24=
=IMSUM(
IMPRODUCT(AC15,IMSUB(IMPRODUCT(AD16,AE17),IMPRODUCT(AD17,AE16))),
IMPRODUCT(AC16,IMSUB(IMPRODUCT(AD17,AE15),IMPRODUCT(AD15,AE17))),
IMPRODUCT(AC17,IMSUB(IMPRODUCT(AD15,AE16),IMPRODUCT(AD16,AE15))))
4x4以降
2x2を元に3x3を作ったのと同様、3x3を元に4x4を作る。偶数の場合は行列式の直前のsag1作成で符号が「+」「-」交互になるが奇数の場合は全て「+」となる。
「8x8」まで作ってみた。行列式を求めるために集計セルの他に作業セルが2*7*8=112セル必要だった。
小行列式はみ出しシフト(仮) (作業セルがある場合)
集計セル群と各作業セル間は1セル開けるようにした。
下方向には作業セルがあるので簡単にコピペできない。
まず1つ小さい行列(5x5なら4x4)の行列式を持ってきたら作業セルを枠外下方向に分離(カトペ)。集計セルを右1下1にコピペしてから作業セルも右1下1にコピペ。そのまま真下に隣接するようにカトペ。そのまま左1にコピペ。集計セルも左1にコピペ。この作業を一番下までやる。
右方向へは集計セルも作業セルも最初の列をそのままコピペ。
小行列式循環シフト(仮) (作業セルがある場合)
はみ出しシフトとほぼ同様だが下に1つコピペするごとに検索と置換で1マスはみ出した行を「15」行に変えていく。
右に1つコピペするごとに検索と置換で1マスはみ出した列を「AC」列に変えていく。
次で使う訳ではないので2列目以降は作らなくても支障はない。
行列式 (作業セルがある場合)
集計セルと各作業セル間は間をあけないように移動した。次で利用するときのために。
エクセルにて 余談2や余談4の後に配置を変更して逆行列も求めてからスクショした。逆行列は手作業で約分する必要があるようだ。
2x2
9x9
グーグルドライブにて 余談2や余談4の後に配置を変更して逆行列も求めてからスクショした。逆行列は手作業で約分する必要があるようだ。
2x2
9x9
余談1 IMSUBを使う?
IMSUBかマイナス1倍かの問題でどちらかに統一した方が良いかと悩んだが、2x2のみIMSUBで4x4・6x6・8x8~は-1倍にするのが良さそうだ。
余談2 実数行列用のmdeterm関数等
2x2のAI14、3x3のAK14には「=mdeterm(value(元行列))」が入っている。行列が大きくなると隠れてしまうので「AF11= =AI14」等と入れたがそこにmdeterm式を入れても良い。複素数の場合はエラー値が表示される。
AB14は元々はsumproductで元行列の1列目と余因子行列転置前(仮)の1列目の積の合計を求めていたが、複素数では機能しないので個別の積を合計した。
3x3の例 AB14= =IMSUM(IMPRODUCT(AC15,AL23),IMPRODUCT(AC16,AL24),IMPRODUCT(AC17,AL25))
余談3 乱数作成
AC15= =complex(round(rand()*($AC$12-$AC$13),0)+$AC$13,round(rand()*($AD$12-$AD$13),0)+$AD$13)
余談4 逆行列
imdiv関数を使って余因子行列を行列式で割れば良い。自分は小数になるのが嫌なので次のようにする。
2x2の場合の逆行列の分子
AJ24= =IMPRODUCT(AJ18,IMCONJUGATE($AC$22)) (IMCONJUGATE関数は共役複素数を求める関数)
AJ24:AK25= AJ24をコピペ
逆行列の分母
AG24= =IMABS(AC22)^2 (IMABS関数は複素数の絶対値を求める関数)
余談5
カトペ(移動)やコピペ(コピー)を多用したため、たとえば小行列式循環シフト(仮)なのに小行列式はみ出しシフト(仮)の数式が残ってしまう等のミスがあるかもしれない。しかし結果の行列式や検算が乱数変化で異常なしなので大きな問題はないと思う。ただ「行列式」にミスが混入すると次で確実に困る事になる。
余談6
はみ出し部分は最後の1行1列は無駄なので削っても良い。
小行列式はみ出しシフト(仮)は残さなくても良いがそうすると小行列式循環シフト(仮)作成中は「検算」等が乱れるためミスが分かりにくくなる。
余談7
エクセルの9x9の行列式を求める際、集計セルが1つに入りきらなかったためその集計セルを作業セルとして更に上位の集計セルが必要になった。「作業セル 3033=6*7*8*9+9」以前作った時は作業セルに数式を追加していったからそんな事態にはなりにくかったと思うが、今回は簡略化のため集計セルに数式を追加していった。あとたとえば作業セル3つを2つに詰め込む事も可能かも知れないがあまりにも手間が大きいのでそれは考えない事にした。
作業セル数 | エクセル | リブレオフィス | グーグルドライブ |
6x6 | 6 | 2 | 0 |
7x7 | 6*7=42 | 2*7=14 | 7 |
8x8 | 6*7*8=336 | 2*7*8=112 | 7*8=56 |
9x9 | 6*7*8*9+9 =3033 |
未作成 | 7*8*9 =504 |
エクセルでは1つしか入らなかった。
リブレオフィスでは3つ入った。4つ入ったかどうかは忘れたが6つを2セルに分けた。
グーグルドライブでは全部(6つ)入った。
余談8
今回の行列式は配列・ベクトル・行列(6)の順列列挙で言うと「2.頭固定小行列循環シフト型(仮)」で作った形になる。「123 132」ではなく因数分解されて「1(23 32)」のようになっているから同じではないが。「4.尾固定小行列循環シフト型(仮)」で作るとどうなるのか、ちょっと気になる。
余談9
試運転版(数日間は凡ミス等を修正する予定。) r070509試運転版解除。だが以後修正しないという意味ではない。