Encontre o inverso de uma matriz 3 por 3

22

Desafio

Dados nove números,, a, b, c, d, e, f, g, h, icomo entrada que corresponde à matriz quadrada:

M=(abcdefghi)

Encontre o inverso da matriz, M1 e produza seus componentes.

Matriz Inversa

O inverso de uma matriz 3 por 3 obedece à seguinte equação:

MM1=M1M=I=(100010001)

E pode ser calculado como:

M1=1det(M)CT

Onde é a matriz dos cofatores:C

C=(eifhfgdidhegchbiaicgbgahbfcecdafaebd)

E é a transposta de C :CTC

CT=(eifhchbibfcefgdiaicgcdafdhegbgahaebd)

E é o determinante de M :det(M)M

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

Exemplo Trabalhado

Por exemplo, digamos que a entrada seja 0, -3, -2, 1, -4, -2, -3, 4, 1. Isso corresponde à matriz:

M=(032142341)

Primeiro, vamos calcular o que é conhecido como determinante usando a fórmula acima:

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

A seguir, vamos calcular a matriz dos cofatores:

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)

Em seguida, precisamos transpor (inverter as linhas e colunas) para obter C T :CCT

CT=(452562893)

Finalmente, podemos encontrar o inverso como:

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

Então a saída seria 4, -5, -2, 5, -6, -2, -8, 9, 3.

Regras

  • A matriz dada sempre terá um inverso (ou seja, não singular). A matriz pode ser auto-inversa

  • A matriz fornecida sempre será uma matriz 3 por 3 com 9 números inteiros

  • Os números na entrada sempre serão números inteiros no intervalo 1000n1000

  • Componentes não inteiros da matriz podem ser dados como um decimal ou uma fração

Exemplos

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

Ganhando

O código mais curto em bytes vence.

Beta Decay
fonte

Respostas:

18

MATL , 54 bytes

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

Experimente online!

Apenas para mantê-lo interessante, não usa a divisão da matriz embutida ou funções determinantes para fazê-lo.

Em vez disso, calcula o determinante usando a Regra de Sarrus .

Demonstração da regra de Sarrus

E o adjugado (matriz de cofatores transpostos) usando a fórmula de Cayley-Hamilton .

adj(UMA)=12((trUMA)2-trUMA2)Eu3-UMAtrUMA+UMA2.

Código comentado:

% 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

Poderíamos ficar ainda mais insanos , substituindo a multiplicação de matrizes GtY*feita porUMA2, com algo como 3:"Gt!@qYS*!s] 3$v t&v 3:K-&Xd( Experimente no MATL Online ).

A maneira mais direta e óbvia:

4 bytes

-1Y^

Experimente online!

(-1 byte graças a @Luis Mendo.)

-1 - Pressione o literal -1

Y^ - Aumentar a entrada para essa potência (entrada implícita, saída implícita)

sundar - Restabelecer Monica
fonte
Interessante, eu nunca soube que era chamado de "Regra de Sarrus". Meu professor nos ensinou, mas ele próprio inventara enquanto estava na universidade.
Beta Decay
@LuisMendo Obrigado, substituiu a versão curta (a versão anterior era apenas uma implementação cega da sugestão de inversão do manual MATL, nenhum pensamento real entrou nessa :)). Para a versão longa, acho que é um pouco mais claro deixá-lo como tal, o suficiente para valer a pena dar um golpe de 1 byte.
sundar - Restabelece Monica
1
@ Sundar Heh, eu nem me lembrava dessa sugestão. Vou acrescentar a sugestão do poder matriz também
Luis Mendo
13

APL (Dyalog Classic), 1 byte

Experimente online!

se for necessário um lis plano, isso significa 8 bytes

,∘⌹3 3∘⍴

Experimente online!

jslip
fonte
9
Bem-vindo ao PPCG!
Beta Decay
9

R, 51 35 27 8 5 bytes

solve

Experimente online!

Primeiro, faça um desses desafios de golfe. Desculpe se minha formatação está errada!

Economizou um total de 11 bytes adicionais graças a Giuseppe! Economizou 19 bytes adicionais graças ao JAD!

Robert S.
fonte
5
Bem-vindo ao PPCG!
Beta Decay
Removidos os nomes de variáveis ​​de parâmetros da função matriz que subtraíram 16 bytes!
Robert S.
1
Agradável! Você pode remover a maioria das variáveis ​​para salvar bytes, uma vez que está realmente encadeando as operações: experimente online!
Giuseppe
1
Se você for usar solve, a solução é justa solve, pois atende a todos os requisitos da pergunta. Ele pega uma matriz como entrada e retorna uma matriz.
21318 JAD
1
como este
Giuseppe
4

Geléia , 3 bytes

æ*-

Experimente online!

Supondo que possamos receber informações e fornecer como uma lista 2D de números inteiros. Se uma lista simples de números inteiros é realmente necessária para entrada e saída, isso funciona para 6 bytes.

Mr. Xcoder
fonte
Explicação (acho que não vale a pena incluir na resposta): æ*- exponenciação da matriz, -- expoente, que é igual a-1. -é um caractere de sintaxe para literais negativos, mas o padrão é-1quando não houver número logo após.
Mr. Xcoder
12
Comentários não são necessariamente feitos para durar muito. Se você estiver incluindo uma explicação nos comentários, mova-a para a resposta.
puxão
4

JavaScript (ES6), 123 bytes

Economizou 2 bytes graças a @ Mr.Xcoder
Economizou 1 byte graças a @ETHproductions

Aceita entrada como 9 valores distintos.

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

Experimente online!

Arnauld
fonte
Ei, eu permiti funções de matriz incorporadas agora. Ou seja, se JS tiver algum
Decay Beta
@BetaDecay JS não tem nenhum. :-)
Arnauld
Esses suportes são realmente necessários?
Sr. Xcoder 18/07/19
4

J , 2 bytes

%.

Apenas um primitivo embutido

Experimente online!

Galen Ivanov
fonte
3

Python 2 , 139 bytes

def F(a,b,c,d,e,f,g,h,i):x=e*i-f*h;y=f*g-d*i;z=d*h-e*g;print[j/(a*x+b*y+c*z)for j in x,c*h-b*i,b*f-c*e,y,a*i-c*g,c*d-a*f,z,b*g-a*h,a*e-b*d]

Experimente online! (Em returnvez de printpara facilitar o teste.)

Lynn
fonte
1

Limpo , 143 bytes

import StdEnv
$a b c d e f g h i#p=e*i-h*f
#q=f*g-d*i
#r=d*h-g*e
=[v/(a*p+b*q+c*r)\\v<-[p,c*h-b*i,b*f-c*e,q,a*i-c*g,d*c-a*f,r,g*b-a*h,a*e-d*b]]

Experimente online!

Furioso
fonte
1

Python 3, 77 bytes

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

Aceita entrada como uma lista simples.

São 63 bytes se a entrada for aceita como uma matriz 2D:

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

Perl, 226 + 4 ( -plF,sinalizador) = 230 bytes

$_=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

Experimente online .

Denis Ibaev
fonte
0

Perl 5, 179 bytes

sub{($a,$b,$c,$d,$e,$f,$g,$h,$i)=@_;map$_/($a*$x+$b*$y+$c*$z),$x=$e*$i-$f*$h,$c*$h-$b*$i,$b*$f-$c*$e,$y=$f*$g-$d*$i,$a*$i-$c*$g,$c*$d-$a*$f,$z=$d*$h-$e*$g,$b*$g-$a*$h,$a*$e-$b*$d}

Experimente online .

Denis Ibaev
fonte
0

Noether, 168 bytes

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

Experimente online

Beta Decay
fonte
0

Planilhas Google , 16 bytes

=MINVERSE(A1:C3)

A entrada está no intervalo A1:C3

Built-ins são chatos

Engenheiro Toast
fonte
0

Pari / GP , 6 bytes

m->1/m

Toma inversa multiplicativa no anel da matriz Mn.

Experimente online!

alefalpha
fonte
0

Clojure, 165 bytes

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

Sinto muito, isso gera C na transposição e estou com preguiça de refazer essas longas sequências de caracteres para corrigi-lo no momento.

NikoNyrh
fonte
0

APL (Dyalog), 7 bytes

,⌹3 3⍴⎕

Recebe entrada como uma lista simples e gera como uma lista simples

Experimente online!

Beta Decay
fonte