3行3列の行列の逆行列を見つける


22

チャレンジ

a, b, c, d, e, f, g, h, i入力として、正方行列に対応する9つの数値を与えます。

M=(abcdefghi)

行列の逆行列M1を見つけて、その成分を出力します。

逆行列

3 x 3の逆行列は、次の式に従います。

MM1=M1M=I=(100010001)

そして、次のように計算できます:

M1=1det(M)CT

ここで、は補因子の行列です。C

C=(eifhfgdidhegchbiaicgbgahbfcecdafaebd)

そして、は転置です。CCTC

CT=(eifhchbibfcefgdiaicgcdafdhegbgahaebd

そしての決定要因である。Mdet(M)M

det(M)=a(eifh)b(difg)+c(dheg)

実施例

たとえば、入力がであるとしましょう0, -3, -2, 1, -4, -2, -3, 4, 1。これはマトリックスに対応します:

M=(032142341)

まず、上記の式を使用して、行列式と呼ばれるものを計算します。

det(M)=0(4×1(2)×4)(3)(1×1(2)×3)+(2)(1×4(4)×3)=1

次に、補因子の行列を計算しましょう:

C=(4×1(2)×4(1×1(2)×3)1×4(4)×3(3×1(2)×4)0×1(2)×3(0×4(3)×3)3×2(2)×4(0×2(2)×1)0×4(3)×1)

=(458569223)

次に、(行と列を反転)を転置してを取得する必要があります。C TCCT

CT=(452562893)

最後に、逆関数を次のように見つけることができます。

M1=1det(M)CT=11(452562893)=(452562893

したがって、出力はになります4, -5, -2, 5, -6, -2, -8, 9, 3

ルール

  • 指定された行列は常に逆行列(つまり、非特異行列)を持ちます。行列は自己反転する場合があります

  • 指定された行列は、常に9つの整数を持つ3行3列の行列になります

  • 入力の数値は常に範囲の整数になります1000n1000

  • 行列の非整数成分は、小数または小数として指定できます

Input > Output
1, 0, 0, 0, 1, 0, 0, 0, 1 > 1, 0, 0, 0, 1, 0, 0, 0, 1
0, -3, -2, 1, -4, -2, -3, 4, 1 > 4, -5, -2, 5, -6, -2, -8, 9, 3
1, 2, 3, 3, 1, 2, 2, 1, 3 > -1/6, 1/2, -1/6, 5/6, 1/2, -7/6, -1/6, -1/2, 5/6
7, 9, 4, 2, 7, 9, 3, 4, 5 > -1/94, -29/94, 53/94, 17/94, 23/94, -55/94, -13/94, -1/94, 31/94

勝ち

バイト単位の最短コードが優先されます。

回答:


18

MATL、54バイト

th3LZ)t,3:q&XdpswP]w-lw/GtY*tXdsGXdsUw-IXy*2/+GtXds*-*

オンラインでお試しください!

面白くするために、組み込みの行列除算または行列式関数を使用してそれを実行しないでください。

代わりに、Sarrusルールを使用して行列式を計算します。

Sarrusデモンストレーションのルール

そして、Cayley–Hamilton公式を使用したアジュバント(転置補因子行列)。

adj(A)=12((trA)2trA2)I3AtrA+A2.

コメントされたコード:

% Finding determinant
th    % concatenate the matrix to itself sideways
3LZ)  % chop off the last column (since the Rule of Sarrus doesn't need it)
t     % duplicate this matrix (say S)
,     % do this twice:
  3:q&Xd  % get the first three diagonals of S
  ps      % multiply each diagonal's values and add the results
  wP      % switch and flip the matrix (to get the popposing diagonals next time)
]w    % close loop, switch to have correct order of sums
-     % subtract - we now have the determinant
lw/   % invert that

% Finding adjugate using Cayley–Hamilton formula
GtY*  % A^2 term (last term of the formula)
tXds  % trace(A^2) for term 1 of formula
GXdsU % (trace(A))^2 for term1 of formula
w-    % (trace(A))^2 - trace(A^2)
IXy*  % multiply that by the identity matrix
2/    % divide that by 2 - term 1 complete
+
GtXds* % A*trA for term 2 of formula
-      % subtract to get adj(A)

*      % multiply by the inverse of determinant we found earlier
       % implicit output

A 2に対して行われた行列乗算を(MATL Onlineで試してみてください)のようなもので置き換えることにより、さらに非常に純粋になります。GtY*A23:"Gt!@qYS*!s] 3$v t&v 3:K-&Xd

より直接的で明白な方法:

4バイト

-1Y^

オンラインでお試しください!

(@Luis Mendoのおかげで1バイト。)

-1 -リテラル-1をプッシュする

Y^ -入力をその累乗に上げる(暗黙的な入力、暗黙的な出力)


興味深いことに、「Rule of Sarrus」と呼ばれることは知りませんでした。私の先生は教えてくれましたが、彼は大学の間に自分で作り上げました。
ベータ崩壊

@LuisMendoありがとう、ショートバージョンを置き換えました(以前のバージョンはMATLマニュアルの逆の提案の盲目的な実装でしたが、実際の考えはその中にありませんでした:))。長いバージョンの場合、1バイトのヒットを取るだけの価値があるので、そのままにしておくほうが少しわかりやすいと思います。
スンダ

1
@sundarへん、私もその提案を覚えていませんでした。マトリックスパワーの提案も追加します
ルイスメンドー


9

R、51 35 27 8 5バイト

solve

オンラインでお試しください!

まず、これらのゴルフチャレンジの1つを行います。書式設定が間違っている場合は申し訳ありません!

ジュゼッペのおかげで、合計でさらに11バイト節約できました!JADのおかげでさらに19バイト節約できました!


5
PPCGへようこそ!
ベータ崩壊

16バイトを減算したマトリックス関数からパラメーター変数名を削除しました!
ロバートS.

1
いいね!実際に操作を連鎖させているだけなので、ほとんどの変数を削除してバイトを節約できます
ジュゼッペ

1
を使用するsolve場合、ソリューションはsolve質問のすべての要件を満たしているため、まさにです。入力として行列を取り、行列を返します。
JAD


4

ゼリー、3 バイト

æ*-

オンラインでお試しください!

入力を受け取り、整数の2Dリストとして提供できると仮定します。入力と出力の両方に整数のフラットリストが本当に必要な場合、これは6バイトで機能します。


æ*-1-1

12
コメントは必ずしも長続きするものではありません。コメントに説明を含める場合は、代わりに答えに移動する必要があります。
ポケ

4

JavaScript(ES6)、123バイト

@ Mr.Xcoderのおかげで2バイト
節約@ETHproductionsのおかげで1バイト節約

入力を9つの異なる値として受け取ります。

(a,b,c,d,e,f,g,h,i)=>[x=e*i-h*f,c*h-b*i,b*f-c*e,y=f*g-d*i,a*i-c*g,d*c-a*f,z=d*h-g*e,g*b-a*h,a*e-d*b].map(v=>v/=a*x+b*y+c*z)

オンラインでお試しください!


ねえ、組み込みの行列関数を許可しました。JSは、いずれかを持っている場合つまり、
ベータ崩壊

@BetaDecay JSには何もありません。:-)
アーナウド

これらのブラケットは本当に必要ですか?
Mr Xcoder




1

Python 3、77バイト

import numpy
lambda l:(numpy.matrix(l).reshape(-1,3)**-1).ravel().tolist()[0]

入力をフラットリストとして受け取ります。

入力が2D配列として取得される場合、63バイトです。

import numpy
lambda l:(numpy.matrix(l)**-1).ravel().tolist()[0]



0

ネーター、168バイト

I~aI~bI~cI~dI~eI~fI~gI~hI~iei*fh*-a*di*fg*-b*-dh*eg*-c*+~zei*fh*-z/P","~nPch*bi*-z/PnPbf*ce*-z/PnPfg*di*-z/PnPai*cg*-z/PnPcd*af*-z/PnPdh*eg*-z/PnPbg*ah*-z/PnPae*bd*-z/P

オンラインで試す




0

Clojure、165バイト

(fn[a b c d e f g h i](let[M map C(M -(M *[e f d c a b b c a][i g h h i g f d e])(M *[f d e b c a c a b][h i g i g h e f d]))](for[i C](/ i(apply +(M *[a b c]C))))))

申し訳ありませんが、これはCを転置で出力しますが、現時点で修正するためにこれらの長い文字シーケンスを再実行するのが面倒です。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.