Trouver l'inverse d'une matrice 3 x 3

22

Défi

Étant donné neuf nombres a, b, c, d, e, f, g, h, i,, en entrée qui correspondent à la matrice carrée:

M=(unebceFghje)

Trouvez l'inverse de la matrice, et sortez ses composants.M-1

Matrice inverse

L'inverse d'une matrice 3 par 3 obéit à l'équation suivante:

MM-1=M-1M=je=(100010001)

Et peut être calculé comme:

M-1=1det(M)CT

est la matrice des cofacteurs:C

C=(eifhfgdidhegchbiaicgbgahbfcecdafaebd)

Et est la transposition de C :CTC

CT=(eifhchbibfcefgdiaicgcdafdhegbgahaebd)

Et est le déterminant de M :det(M)M

det(M)=une(eje-Fh)-b(je-Fg)+c(h-eg)

Exemple travaillé

Par exemple, disons que l'entrée est 0, -3, -2, 1, -4, -2, -3, 4, 1. Cela correspond à la matrice:

M=(032142341)

Tout d'abord, calculons ce que l'on appelle le déterminant à l'aide de la formule ci-dessus:

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

Calculons ensuite la matrice des cofacteurs:

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)

Nous devons ensuite transposer (retourner les lignes et les colonnes) pour obtenirC :CT

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

Enfin, nous pouvons trouver l'inverse comme:

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

Ainsi, la sortie serait 4, -5, -2, 5, -6, -2, -8, 9, 3.

Règles

  • La matrice donnée aura toujours un inverse (c'est-à-dire non singulier). La matrice peut être auto-inverse

  • La matrice donnée sera toujours une matrice 3 x 3 avec 9 entiers

  • Les nombres en entrée seront toujours des entiers dans la plage -1000n1000

  • Les composants non entiers de la matrice peuvent être donnés sous forme décimale ou fractionnelle

Exemples

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

Gagnant

Le code le plus court en octets gagne.

Beta Decay
la source

Réponses:

18

MATL , 54 octets

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

Essayez-le en ligne!

Juste pour le garder intéressant, n'utilise pas la division matricielle intégrée ou les fonctions déterminantes pour le faire.

Au lieu de cela, calcule le déterminant à l'aide de la règle de Sarrus .

Rule of Sarrus demonstration

Et l'adjugate (matrice de cofacteurs transposée) utilisant la formule de Cayley-Hamilton .

adj(UNE)=12((trUNE)2-trUNE2)je3-UNEtrUNE+UNE2.

Code commenté:

% 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

Nous pourrions aller encore plus purement fou en remplaçant la multiplication matricielle GtY*effectuée pourUNE2, avec quelque chose comme 3:"Gt!@qYS*!s] 3$v t&v 3:K-&Xd( Essayez-le sur MATL en ligne ).

La manière la plus directe et la plus évidente:

4 octets

-1Y^

Essayez-le en ligne!

(-1 octet grâce à @Luis Mendo.)

-1 - Poussez le littéral -1

Y^ - Raise input to that power (implicit input, implicit output)

sundar - Reinstate Monica
la source
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 Merci, a remplacé la version courte (tbh la version précédente n'était qu'une implémentation aveugle de la suggestion du manuel MATL pour l'inverse, aucune réflexion réelle n'est entrée dans celle-là :)). Pour la version longue, je pense qu'il est un peu plus clair de le laisser tel quel, suffisamment pour valoir la peine de prendre un hit de 1 octet.
sundar
1
@sundar Heh, je ne me souvenais même pas de cette suggestion. J'ajouterai aussi la suggestion de puissance matricielle
Luis Mendo
9

R, 51 35 27 8 5 octets

solve

Essayez-le en ligne!

Commencez par relever l'un de ces défis de golf. Désolé si ma mise en forme est incorrecte!

Un total de 11 octets supplémentaires enregistrés grâce à Giuseppe! 19 octets supplémentaires grâce à JAD!

Robert S.
la source
5
Bienvenue chez PPCG!
Beta Decay
Suppression des noms de variables de paramètre de la fonction de matrice qui a soustrait 16 octets!
Robert S.
1
Agréable! Vous pouvez supprimer la plupart des variables pour économiser des octets car vous enchaînez vraiment les opérations ensemble: essayez-le en ligne!
Giuseppe
1
Si vous allez utiliser solve, la solution est juste solve, car elle répond à toutes les exigences de la question. Il prend une matrice en entrée et renvoie une matrice.
JAD
1
comme ça
Giuseppe
4

Gelée , 3 octets

æ*-

Essayez-le en ligne!

En supposant que nous pouvons prendre des données et fournir une liste 2D d'entiers. Si une liste plate d'entiers est vraiment requise pour l'entrée et la sortie, alors cela fonctionne pour 6 octets.

M. Xcoder
la source
Explication (je ne pense pas que cela vaille la peine d'être inclus dans la réponse): æ*- exponentiation matricielle, -- exposant, ce qui équivaut à-1. -est un caractère de syntaxe pour les littéraux négatifs, mais il est par défaut-1quand il n'y a pas de numéro juste après.
M. Xcoder
12
Les commentaires ne sont pas nécessairement destinés à durer longtemps. Si vous incluez une explication dans les commentaires, vous devez plutôt la déplacer vers la réponse.
Poke
4

JavaScript (ES6), 123 octets

Enregistré 2 octets grâce à @ Mr.Xcoder
Enregistré 1 octet grâce à @ETHproductions

Prend l'entrée comme 9 valeurs distinctes.

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

Essayez-le en ligne!

Arnauld
la source
Hé, j'ai autorisé les fonctions matricielles intégrées maintenant. Autrement dit, si JS en a
Beta Decay
@BetaDecay JS n'en a pas. :-)
Arnauld
Ces supports sont-ils vraiment nécessaires?
M. Xcoder
3

Python 2 , 139 octets

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]

Essayez-le en ligne! (A la returnplace de printpour faciliter les tests.)

Lynn
la source
1

Nettoyer , 143 octets

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

Essayez-le en ligne!

Οurous
la source
1

Python 3, 77 octets

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

Prend la saisie sous forme de liste plate.

C'est 63 octets si l'entrée est prise comme un tableau 2D:

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

Perl, 226 + 4 ( -plF,indicateur) = 230 octets

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

Essayez-le en ligne .

Denis Ibaev
la source
0

Perl 5, 179 octets

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}

Essayez-le en ligne .

Denis Ibaev
la source
0

Noether, 168 octets

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

Essayez-le en ligne

Beta Decay
la source
0

Google Sheets , 16 octets

=MINVERSE(A1:C3)

L'entrée est dans la plage A1:C3

Les intégrés sont ennuyeux

Ingénieur Toast
la source
0

Pari / GP , 6 octets

m->1/m

Prend l'inverse multiplicatif dans l'anneau de la matrice Mn.

Essayez-le en ligne!

alephalpha
la source
0

Clojure, 165 octets

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

Je suis désolé que cela génère C en transposition, et je me sens paresseux pour refaire ces longues séquences de caractères pour le corriger pour le moment.

NikoNyrh
la source
0

APL (Dyalog), 7 octets

,⌹3 3⍴⎕

Prend les entrées sous forme de liste plate et les sorties sous forme de liste plate

Essayez-le en ligne!

Beta Decay
la source