3x3 행렬의 역함수를 구합니다


22

도전

a, b, c, d, e, f, g, h, i제곱 행렬에 해당하는 입력으로 9 개의 숫자가 주어집니다 .

M=(abcdefghi)

행렬의 역수 M−1 찾아 성분을 출력합니다.

역행렬

행렬 3의 3에 대한 역은 다음 방정식을 따릅니다.

MM−1=M−1M=I=(100010001)

다음과 같이 계산할 수 있습니다.

M−1=1det(M)CT

여기서 C 는 보조 인자의 행렬입니다.

C=(ei−fhfg−didh−egch−biai−cgbg−ahbf−cecd−afae−bd)

그리고 의 전치 C :CTC

CT=(ei−fhch−bibf−cefg−diai−cgcd−afdh−egbg−ahae−bd)

그리고 의 결정이다 M :det(M)M

det(M)=a(ei−fh)−b(di−fg)+c(dh−eg)

작동 예

예를 들어 입력이이라고 가정 해 봅시다 0, -3, -2, 1, -4, -2, -3, 4, 1. 이것은 매트릭스에 해당합니다.

M=(0−3−21−4−2−341)

먼저 위의 공식을 사용하여 결정 요인을 계산해 보겠습니다.

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)

=(45−8−5−69−2−23)

그런 다음 C 를 바꿉니다.C 얻기 위해 (행과 열을 플립) :CT

CT=(4−525−6−2−893)

마지막으로 다음과 같이 역을 찾을 수 있습니다.

M−1=1det(M)CT=11(4−525−6−2−893)=(4−525−6−2−893)

따라서 출력은입니다 4, -5, -2, 5, -6, -2, -8, 9, 3.

규칙

  • 주어진 행렬은 항상 역수 (즉, 비단 수)입니다. 행렬은 자기 역수 일 수 있습니다

  • 주어진 행렬은 항상 9 개의 정수를 가진 3x3 행렬입니다.

  • 입력의 숫자는 항상 범위의 정수가 될 것이다 −1000≤n≤1000

  • 행렬의 정수가 아닌 성분은 소수 또는 분수로 주어질 수 있습니다

예

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 규칙을 사용하여 결정자를 계산합니다 .

Rule of Sarrus demonstration

그리고 Cayley–Hamilton 공식을 사용하여 어쥬 게이트 (전이 된 보조 인자 행렬) .

조정⁡(에이)=12((tr⁡에이)2−tr⁡에이2)나는삼−에이tr⁡에이+에이2.

주석이 달린 코드 :

% 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

우리는 행해진 행렬 곱셈을 대체함으로써 훨씬 더 순수하게 갈 수 있습니다.GtY*에이2같은 뭔가 3:"Gt!@qYS*!s] 3$v t&v 3:K-&Xd( MATL 온라인에보십시오 ).

더 직접적이고 명백한 방법 :

4 바이트

-1Y^

온라인으로 사용해보십시오!

(@Luis Mendo 덕분에 1 바이트)

-1 -리터럴 푸시 -1

Y^ -입력을 해당 전력으로 올립니다 (암시 적 입력, 암시 적 출력)


Interesting, I never knew it was called the “Rule of Sarrus”. My teacher taught us it, but he had made it up himself while at uni.
— Beta Decay

@LuisMendo Thanks, replaced the short version (tbh the previous version was just a blind implementation of the MATL manual's suggestion for inverse, no actual thinking went into that one :) ). For the long version, I think it's a tiny bit clearer to leave it as such, enough to be worth taking a 1 byte hit.
— sundar - Reinstate Monica

1
@ sundar Heh, 나는 그 제안을 기억조차하지 못했습니다. 매트릭스 파워에 대한 제안도 추가하겠습니다
— Luis Mendo


9

R, 51 35 27 8 5 바이트

solve

온라인으로 사용해보십시오!

먼저 이러한 골프 도전 중 하나를 수행하십시오. 내 서식이 잘못되어 죄송합니다.

주세페 덕분에 총 11 바이트를 추가로 절약했습니다! JAD 덕분에 추가로 19 바이트를 절약했습니다!


5
PPCG에 오신 것을 환영합니다!
— Beta Decay

16 바이트를 뺀 행렬 함수에서 매개 변수 변수 이름을 제거했습니다!
— Robert S.

1
좋은! 실제로 작업을 연결하기 때문에 대부분의 변수를 제거하여 바이트를 절약 할 수 있습니다. 온라인으로 시도하십시오!
— 주세페

1
을 (를) 사용 solve하려는 경우 솔루션은 solve질문의 모든 요구 사항을 충족 하므로 솔루션은 단지 입니다. 행렬을 입력으로 받아서 행렬을 반환합니다.
— JAD


4

젤리 , 3 바이트

æ*-

온라인으로 사용해보십시오!

입력을 받아서 2D 정수 목록으로 제공 할 수 있다고 가정합니다. 정수의 단순 목록이 정말 입력과 출력 모두에 대해 필요한 경우, 다음 이 6 바이트 작동합니다.


Explanation (I don't think it's worth including in the answer): æ* - matrix exponentiation, - - exponent, which equals −1. - is a syntax character for negative literals but it defaults to −1 when there is no number right after it.
— Mr. Xcoder

12
Comments aren't necessarily meant to be long lived. If you're including an explanation in the comments, you should move it to the answer instead.
— Poke

4

JavaScript (ES6), 123 bytes

Saved 2 bytes thanks to @Mr.Xcoder
Saved 1 byte thanks to @ETHproductions

Takes input as 9 distinct values.

(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)

Try it online!


Hey, i've allowed built-in matrix functions now. That is, if JS has any
— Beta Decay

@BetaDecay JS has none. :-)
— Arnauld

Are those brackets really needed?
— Mr. Xcoder




1

파이썬 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

Perl, 226 + 4 ( -plF,플래그) = 230 바이트

$_=join', ',map$_/($a*$x+$b*$y+$c*$z),$x=($e=$F[4])*($i=$F[8])-($f=$F[5])*($h=$F[7]),($c=$F[2])*$h-($b=$F[1])*$i,$b*$f-$c*$e,$y=$f*($g=$F[6])-($d=$F[3])*$i,($a=$F[0])*$i-$c*$g,$c*$d-$a*$f,$z=$d*$h-$e*$g,$b*$g-$a*$h,$a*$e-$b*$d

온라인으로 사용해보십시오 .






0

클로저, 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.