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


22

도전

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

M=(abcdefghi)

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

역행렬

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

MM1=M1M=I=(100010001)

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

M1=1det(M)CT

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

C=(eifhfgdidhegchbiaicgbgahbfcecdafaebd)

그리고 의 전치 C :CTC

CT=(eifhchbibfcefgdiaicgcdafdhegbgahaebd)

그리고 의 결정이다 M :det(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 를 바꿉니다.C 얻기 위해 (행과 열을 플립) :CT

CT=(452562893)

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

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

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

규칙

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

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

  • 입력의 숫자는 항상 범위의 정수가 될 것이다 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 규칙을 사용하여 결정자를 계산합니다 .

Rule of Sarrus demonstration

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

조정(에이)=12((tr에이)2tr에이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.