Encuentre el inverso de una matriz de 3 por 3

22

Reto

Dados nueve números, a, b, c, d, e, f, g, h, icomo entrada que corresponden a la matriz cuadrada:

METRO=(unasidoremiFsolhyo)

Encuentre el inverso de la matriz, y genere sus componentes.M1

Matriz inversa

El inverso de una matriz 3 por 3 obedece a la siguiente ecuación:

MM1=M1M=I=(100010001)

Y se puede calcular como:

M1=1det(M)CT

Donde es la matriz de cofactores:C

do=(miyo-FhFsol-reyoreh-misoldoh-siyounayo-dosolsisol-unahsiF-domidore-unaFunami-sire)

Y es la transposición de C :doTdo

doT=(miyo-Fhdoh-siyosiF-domiFsol-reyounayo-dosoldore-unaFreh-misolsisol-unahunami-sire)

Y es el determinante de M :det(METRO)METRO

det(METRO)=una(miyo-Fh)-si(reyo-Fsol)+do(reh-misol)

Ejemplo trabajado

Por ejemplo, digamos que la entrada es 0, -3, -2, 1, -4, -2, -3, 4, 1. Esto corresponde a la matriz:

M=(032142341)

En primer lugar, calculemos lo que se conoce como determinante utilizando la fórmula anterior:

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

A continuación, calculemos la matriz de cofactores:

do=(-4 4×1-(-2)×4 4-(1×1-(-2)×-3)1×4 4-(-4 4)×-3-(-3×1-(-2)×4 4)0 0×1-(-2)×-3-(0 0×4 4-(-3)×-3)-3×-2-(-2)×-4 4-(0 0×-2-(-2)×1)0 0×-4 4-(-3)×1)

=(4 45 5-8-5 5-6 69 9-2-23)

Entonces necesitamos transponer do (voltear las filas y columnas) para obtener :doT

doT=(4 4-5 525 5-6 6-2-89 93)

Finalmente, podemos encontrar el inverso como:

METRO-1=1det(METRO)doT=11(4 4-5 525 5-6 6-2-89 93)=(4 4-5 525 5-6 6-2-89 93)

Entonces la salida sería 4, -5, -2, 5, -6, -2, -8, 9, 3.

Reglas

  • La matriz dada siempre tendrá un inverso (es decir, no singular). La matriz puede ser autoinversa

  • La matriz dada siempre será una matriz de 3 por 3 con 9 enteros.

  • Los números en la entrada siempre serán enteros en el rango -1000norte1000

  • Los componentes no enteros de la matriz se pueden dar como un decimal o una fracción

Ejemplos

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

Victorioso

El código más corto en bytes gana.

Decaimiento Beta
fuente

Respuestas:

18

MATL , 54 bytes

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

Pruébalo en línea!

Solo para mantenerlo interesante, no utiliza la división de matriz incorporada o las funciones determinantes para hacerlo.

En cambio, calcula el determinante usando la Regla de Sarrus .

Demostración de la regla de Sarrus

Y el adyuvante (matriz de cofactor transpuesta) usando la fórmula Cayley-Hamilton .

adj(UNA)=12((trUNA)2-trUNA2)yo3-UNAtrUNA+UNA2.

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

Podríamos volvernos aún más locos al reemplazar la multiplicación matricial GtY*realizada porUNA2, con algo como 3:"Gt!@qYS*!s] 3$v t&v 3:K-&Xd( Pruébalo en MATL Online ).

La forma más directa y obvia:

4 bytes

-1Y^

Pruébalo en línea!

(-1 byte gracias a @Luis Mendo.)

-1 - Empuje el literal -1

Y^ - Elevar la entrada a esa potencia (entrada implícita, salida implícita)

sundar - Restablecer a Monica
fuente
Interesante, nunca supe que se llamaba la "Regla de Sarrus". Mi maestro nos lo enseñó, pero él mismo lo había inventado mientras estaba en la universidad.
Beta Decay
@LuisMendo Gracias, reemplazó la versión corta (por cierto, la versión anterior era solo una implementación ciega de la sugerencia del manual de MATL para la inversa, no se pensó en eso :)). Para la versión larga, creo que es un poco más claro dejarlo como tal, lo suficiente como para que valga la pena recibir un hit de 1 byte.
sundar - Restablecer Monica
1
@sundar Heh, ni siquiera recordaba esa sugerencia. Agregaré también la sugerencia de poder matricial
Luis Mendo
9

R, 51 35 27 8 5 bytes

solve

Pruébalo en línea!

Primero ve a hacer uno de estos desafíos de golf. Lo siento si mi formato es incorrecto!

¡Ahorré un total de 11 bytes adicionales gracias a Giuseppe! ¡Ahorró 19 bytes adicionales gracias a JAD!

Robert S.
fuente
55
Bienvenido a PPCG!
Beta Decay
¡Se eliminaron los nombres de las variables de parámetro de la función de matriz que resta 16 bytes!
Robert S.
1
¡Agradable! Puede eliminar la mayoría de las variables para guardar bytes, ya que realmente solo está encadenando las operaciones juntas: ¡ pruébelo en línea!
Giuseppe
1
Si va a usar solve, la solución es justa solve, ya que cumple con todos los requisitos de la pregunta. Toma una matriz como entrada y devuelve una matriz.
JAD
1
así
Giuseppe
4

Jalea , 3 bytes

æ*-

Pruébalo en línea!

Suponiendo que podamos tomar datos y proporcionar una lista 2D de enteros. Si realmente se requiere una lista plana de enteros tanto para entrada como para salida, entonces esto funciona para 6 bytes.

Sr. Xcoder
fuente
Explicación (no creo que valga la pena incluirla en la respuesta): æ*- exponenciación matricial, -- exponente, que es igual a-1. -es un carácter de sintaxis para literales negativos pero su valor predeterminado es-1cuando no hay un número justo después.
Sr. Xcoder
12
Los comentarios no necesariamente tienen una larga vida. Si incluye una explicación en los comentarios, debe pasarla a la respuesta.
Poke
4

JavaScript (ES6), 123 bytes

Guardado 2 bytes gracias a @ Mr.Xcoder
Guardado 1 byte gracias a @ETHproductions

Toma la 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)

Pruébalo en línea!

Arnauld
fuente
Hola, ahora he permitido funciones de matriz incorporadas. Es decir, si JS tiene alguno
Beta Decay
@BetaDecay JS no tiene ninguno. :-)
Arnauld
¿Son realmente necesarios
Sr. Xcoder
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]

Pruébalo en línea! (Tiene en returnlugar de printfacilitar la prueba).

Lynn
fuente
1

Limpio , 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]]

Pruébalo en línea!

Οurous
fuente
1

Python 3, 77 bytes

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

Toma la entrada como una lista plana.

Son 63 bytes si la entrada se toma como una matriz 2D:

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

Perl, 226 + 4 ( -plF,bandera) = 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

Pruébalo en línea .

Denis Ibaev
fuente
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}

Pruébalo en línea .

Denis Ibaev
fuente
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

Pruébalo en línea

Decaimiento Beta
fuente
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))))))

Lamento que esto transmita C en transposición, y me siento perezoso para rehacer esas secuencias de caracteres largas para solucionarlo en este momento.

NikoNyrh
fuente
0

APL (Dyalog), 7 bytes

,⌹3 3⍴⎕

Toma la entrada como una lista plana y las salidas como una lista plana

Pruébalo en línea!

Decaimiento Beta
fuente