Oblicz odwrotność macierzy
Jakoś nie mamy jeszcze wyzwania, aby znaleźć odwrotność macierzy kwadratowej o dowolnym rozmiarze, pomimo posiadania macierzy dla 3x3 i 4x4 , a także bardziej złożonej wersji .
Twoim zadaniem jest, biorąc pod uwagę kwadrat \$n\times n\$niejednolita macierz \$M\$, wypisz macierz \$M^{-1}\$ to satysfakcjonuje
$$MM^{-1} = I_n$$
Istnieje wiele metod i wzorów obliczania \$M^{-1}\$, ale jednym z najbardziej znanych jest
$$M^{-1} = \frac1{\det(M)}\text{ adj}(M)$$
gdzie \$\det\$reprezentuje wyznacznik i \$\newcommand{\adj}{\text{adj}}\adj\$ adiutant
Niektóre definicje:
- \$I_n\$: \$n\times n\$ macierz tożsamości, czyli \$n\times n\$macierz, w której wiodąca przekątna składa się w całości z \$1\$s i reszta \$0\$s
- Liczba pojedyncza: wyznacznik \$M\$ na pewno jest niezerowa
- Wyznacznik : określona liczba, którą można obliczyć dla dowolnej macierzy kwadratowej. Dokładne metody można znaleźć w artykule w Wikipedii
- Adiugat : Formalnie transpozycja macierzy kofaktora \$M\$. Nieformalnie jest to operacja na \$M\$który w określony sposób przyjmuje wyznaczniki podmacierzy, aby skonstruować powiązaną macierz. Dokładne szczegóły można znaleźć w powiązanym artykule.
Dla uproszczenia możesz założyć:
- Elementy \$M\$ wszystkie będą liczbami całkowitymi w rodzimych granicach twojego języka
- \$n\$, ani \$n^2\$, nigdy nie przekroczy maksymalnej wartości w Twoim języku i zawsze będzie większa lub równa \$1\$
- Elementy \$M^{-1}\$ nigdy nie przekroczy maksymalnej wartości w Twoim języku (lub minimum dla wartości ujemnych)
- \$M\$ nigdy nie będzie pojedyncza
Żadne polecenia wbudowane nie są zbanowane i możesz użyć dowolnej (prawidłowej) metody obliczania \$M^{-1}\$. Dopuszczalne jest, jeśli program zawiedzie w przypadku niektórych danych wejściowych z powodu problemów z liczbami zmiennoprzecinkowymi, o ile bazowy algorytm lub metoda działa dla dowolnych macierzy.
Jest to oczywiście całkowicie opcjonalne, ale jeśli twoja odpowiedź składa się wyłącznie z wbudowanej metody, rozważ włączenie metody niewbudowanej, po prostu ze względu na ogólny interes.
Obowiązują standardowe zasady dotyczące code-golfa . Oznacza to, że możesz wprowadzać lub wyprowadzać dane w dowolnym dogodnym formacie , a standardowe luki są zabronione. Wygrywa najkrótszy kod w bajtach.
Ten skrypt pobierze dane wejściowe \$n\$i wygeneruj \$n\times n\$macierz z losowymi liczbami całkowitymi między \$-10\$i \$10\$, wraz z odwrotnością. Możesz tego użyć w przypadkach testowych.
Przykład praktyczny
Weźmy \$3\times3\$macierz \$M\$ tak jak:
$$M = \left[\begin{matrix} 4 & -3 & 0 \\ -4 & -7 & 6 \\ 5 & 7 & 6 \end{matrix}\right]$$
Użyjemy powyższego wzoru, \$M^{-1} = \frac{\adj(M)}{\det(M)}\$ w tym przykładzie.
Najpierw obliczymy \$\det(M)\$ rozszerzając wzdłuż trzeciej kolumny:
$$\begin{align} \det(M) & = \left|\begin{matrix} 4 & -3 & 0 \\ -4 & -7 & 6 \\ 5 & 7 & 6 \end{matrix}\right| \\ & = 0\left|\begin{matrix} -4 & -7 \\ 5 & 7 \end{matrix}\right| - 6\left|\begin{matrix} 4 & -3 \\ 5 & 7 \end{matrix}\right| + 6\left|\begin{matrix} 4 & -3 \\ -4 & -7 \end{matrix}\right| \\ & = 0 - 6(4\cdot7 - -3\cdot5) + 6(4\cdot-7 - -3\cdot-4) \\ & = -6(28 + 15) + 6(-28 - 12) \\ & = -6\cdot43 + 6\cdot-40 \\ & = -498 \\ \therefore det(M) & = -498 \end{align}$$
Następnie musimy obliczyć \$\adj(M)\$. Jak \$\adj(\cdot)\$macierzy jest transpozycją macierzy kofaktorów, co w zasadzie sprowadza się do obliczenia macierzy kofaktora \$M\$, \$C_M\$:
$$\begin{align} \adj(M) & = C_M^T \\ & = \left[\begin{matrix} \left|\begin{matrix} -7 & 6 \\ 7 & 6 \end{matrix}\right| & \left|\begin{matrix} -4 & 6 \\ 5 & 6 \end{matrix}\right| & \left|\begin{matrix} -4 & -7 \\ 5 & 7 \end{matrix}\right| \\ \left|\begin{matrix} -3 & 0 \\ 7 & 6 \end{matrix}\right| & \left|\begin{matrix} 4 & 0 \\ 5 & 6 \end{matrix}\right| & \left|\begin{matrix} 4 & -3 \\ 5 & 7 \end{matrix}\right| \\ \left|\begin{matrix} -3 & 0 \\ -7 & 6 \end{matrix}\right| & \left|\begin{matrix} 4 & 0 \\ -4 & 6 \end{matrix}\right| & \left|\begin{matrix} 4 & -3 \\ -4 & -7 \end{matrix}\right| \end{matrix}\right]^T \\ & = \left[\begin{matrix} -84 & 54 & 7 \\ 18 & 24 & -43 \\ -18 & -24 & -40 \end{matrix}\right]^T \\ & =\left[\begin{matrix} -84 & 18 & -18 \\ 54 & 24 & -24 \\ 7 & -43 & -40 \end{matrix}\right] \end{align}$$
Wreszcie, po obliczeniu obu \$\det(M)\$i \$\adj(M)\$, dzielimy każdy element \$\adj(M)\$przez \$\det(M)\$do obliczenia ostatecznego wyniku, \$M^{-1}\$:
$$\begin{align} M^{-1} & = \frac{\adj(M)}{\det(M)} \\ & = \left[\begin{matrix} \frac{-84}{-498} & \frac{ 18}{-498} & \frac{-18}{-498} \\ \frac{ 54}{-498} & \frac{ 24}{-498} & \frac{-24}{-498} \\ \frac{ 7}{-498} & \frac{-43}{-498} & \frac{-40}{-498} \end{matrix}\right] \\ & = \left[\begin{matrix} \frac{ 14}{ 83} & \frac{-3}{ 83} & \frac{ 3}{ 83} \\ \frac{ -9}{ 83} & \frac{-4}{ 83} & \frac{ 4}{ 83} \\ \frac{ -7}{498} & \frac{43}{498} & \frac{20}{249} \end{matrix}\right] \end{align}$$
Alternatywnie, jako ułamki dziesiętne, \$M^{-1}\$ jest
[[ 0.1686746987951807, -0.03614457831325301, 0.03614457831325303],
[-0.10843373493975902, -0.04819277108433735, 0.04819277108433734]
[-0.014056224899598388, 0.08634538152610442, 0.08032128514056225]]
Odpowiedzi
Oktawa , 57 bajtów
A=input('');V=A'/trace(A*A');for i=1:1e4V=2*V-V*A*V;end
V
Wypróbuj online!
Nie jest to szczególnie dobre do golfa, ale chciałem zareklamować podejście, które mogłoby być przydatne w przypadku innych, niewbudowanych odpowiedzi.
Wykorzystuje to schemat Hotelling-Bodewig:
$$ V_{i+1} = V_i\left(2I - AV_i\right)$$
Który iteracyjnie oblicza odwrotność macierzy innej niż osobliwa. To gwarantuje zbieżność dla \$\left\lVert I - AV_0\right\rVert < 1\$(zgodnie z odpowiednią normą macierzową). Wybierając \$V_0\$jest trudne, ale Soleymani F. pokazuje w „A New Method For Solving Ill-Conditioned Linear Systems”, że początkowe przypuszczenie \$V_0 = \frac{A^T}{\text{tr}(AA^T)}\$ zawsze spełni ten warunek, więc system jest stabilny numerycznie.
To, co sprawia, że jest to szczególnie atrakcyjne podejście do innych potencjalnych odpowiedzi, to fakt, że nie wymagamy żadnych wbudowanych funkcji wyznaczających ani funkcji odwrotnych. Najbardziej złożoną częścią jest po prostu mnożenie macierzy, ponieważ transpozycja i śledzenie są łatwe do obliczenia.
Wybrałem 1e4tutaj iteracje, aby środowisko wykonawcze było nieco rozsądne, chociaż można je oczywiście przesunąć 1e9bez utraty liczby bajtów.
-10 dzięki xnor za zauważenie, że nie musimy konstruować macierzy tożsamości.
R , 5 bajtów
solve
Wypróbuj online!
Nie ma tu nic nowego ... Zasadniczo kod solve(A, B)rozwiązuje \$AX = B\$, ale kiedy \$B\$ nie jest podana, jest traktowana jako macierz tożsamości, dając nam w rezultacie odwrotność.
APL (Dyalog Unicode) , 1 bajt SBCS
⌹
Wypróbuj online!
Prymityw domina jest bardzo interesującym „wbudowanym” APL-em. Wystąpił już w innej 1-bajtowej odpowiedzi, w której został użyty do rozwiązania problemu najmniejszych kwadratów. Po zastosowaniu do macierzy kwadratowej, ⌹próbuje znaleźć macierz odwrotną do jej argumentu.
Wiele języków golfowych ma również wbudowaną funkcję do tego ... Ale pamiętajcie, APL nie jest językiem golfowym, chociaż jest wystarczająco zwięzły, aby być bardzo konkurencyjnym i, w takich przypadkach, wygrywać.
R , 72 61 bajtów
function(A,V=t(A/sum(diag(A%*%t(A))))){for(i in 1:1e4)V=2*V-V%*%A%*%V;V}
Wypróbuj online!
Przeniesienie odpowiedzi Syzyfa wcale nie jest daremne ... i dzięki Syzyfowi za -11 bajtów.
Zauważa, że \$Tr(AA^T)=\sum\limits_{i,j}a_{ij}^2\$.
R , 94 bajty
function(M)outer(k<-1:dim(M),k,Vectorize(function(j,i)det(M[-i,-j,drop=F])*(-1)^(i+j)))/det(M)
Wypróbuj online!
Podziękowania dla Robin Ryder za naprawienie błędu i sprawienie, by to faktycznie działało.
Oblicza \$A^{-1}\$ przy użyciu metody dopasowanej / wyznaczającej.
Python 2 , 228 bajtów
from random import*
a=input()
exec"""$:j,J=i,I;J+=[j==i $]
while~-all(I[i]$):shuffle(a) $:
j,J=i,I
$: if j-i:I[:]=[y-I[j]*x/J[j]for x,y in zip(J,I)] $:print[x/I[i]for x in I][len(a):]""".replace("$","for i,I in enumerate(a)")
Wypróbuj online!
Wzbogać macierz o macierz tożsamości, a następnie zastosuj eliminację Gaussa-Jordana. Nie wiem, czy to najkrótsze podejście, ale chciałem spróbować gry w golfa.
Używam while not all(a[i][i]for i in r):shuffle(a)do usuwania zera z przekątnej. Ta pętla na pewno się zakończy, ponieważ jeśli nie ma permutacji wierszy \ $ A \ $, która sprawia, że przekątna jest wolna od zer, to \ $ \ det (A) = 0 \ $ , co gwarantujemy, nie ma miejsca . Można to zobaczyć ze wzoru Leibniza na \ $ \ det (A) \ $ :
$$ \ det (A) = \ sum _ {\ sigma \ in S_n} \ text {sgn} (\ sigma) \ prod_ {i = 1} ^ n a _ {\ sigma (i), i} $$
„Nie ma permutacji \ $ \ sigma \ $ wierszy, które sprawiają, że przekątna jest wolna od zer” można równoważnie przeformułować jako „ \ $ \ prod_ {i = 1} ^ n a _ {\ sigma (i), i} \ $ jest zawsze 0, for all \ $ \ sigma \ $ ”, co powoduje, że cała formuła ma wartość 0.
JavaScript (ES6), 169 bajtów
To oblicza \$M^{-1} = \dfrac{\operatorname{adj}(M)}{\det(M)}\$
M=>M.map((r,y)=>r.map((_,x)=>D(h(M,x).map(r=>h(r,y)))*(x+y&1?-1:1)/D(M)),h=(a,n)=>a.filter(_=>n--),D=M=>+M||M.reduce((s,[v],i)=>s+(i&1?-v:v)*D(h(M,i).map(r=>h(r,0))),0))
Wypróbuj online!
05AB1E , 38 22 21 20 bajtów
˜nO/øтF©I2Føδ*O®}·s-
Port of @Sisyphus 'Octave odpowiedzi , więc pamiętaj, aby go zagłosować !!
-16 bajtów dzięki @ovs .
Spróbuj tego online.
Objaśnienie kodu:
˜ # Flatten the (implicit) input-matrix to a single list
n # Square each value in this list
O # Take the sum (this is the trace of M*M')
/ # Divide each value in the (implicit) input-matrix by this trace
ø # Zip/transpose this matrix; swapping rows/columns
тF # Loop 100 times:
© # Store the current matrix in variable `®` (without popping)
I # Push the input-matrix
2F # Loop 2 times:
ø # Zip/transpose the top matrix; swapping rows/columns
δ # Apply double-vectorized with the top two matrices:
* # Multiply
O # Sum each inner row
® # Push the matrix from variable `®` again
}· # After the inner loop: double all values in matrix `®`
s # Swap so the calculated matrix VMV is at the top again
- # Subtract this VMV from the 2V
# (after the outer loop, the resulting matrix is output implicitly)
Oryginalna odpowiedź (38 bajtów ) i szczegółowe wyjaśnienie:
εUεX*O]Å\OIøs/тFxs©εUIøεX*O}U®øεX*O}}-
Wypróbuj online.
05AB1E prawie nie ma użytecznych wbudowanych funkcji macierzy, nawet manipulacji macierzami. Więc prawie wszystko trzeba zrobić ręcznie.
Ponieważ jestem absolutnym noobem w matematyce, wyjaśnię wszystko szczegółowo, aby pomóc innym takim jak ja, którzy chcą wykonać to wyzwanie bez żadnych wbudowanych elementów, a także aby ta odpowiedź była niezależna.
Krok 1) Manipulowanie macierzą macierzy wejściowej \$M\$z jego transpozycją: \$M\times M'\$:
Jeśli mamy macierz \$A\$i \$B\$i chcesz zrobić manipulację matrycą \$AB\$, bierzemy iloczyn skalarny każdego \$i^{th}\$rząd \$A\$i \$j^{th}\$kolumna B dla każdej współrzędnej \$i,j\$ w dwóch macierzach.
Na przykład, jeśli używamy macierzy w opisie wyzwania:
\$M = \left[\begin{matrix} 4 & -3 & 0 \\ -4 & -7 & 6 \\ 5 & 7 & 6 \end{matrix}\right]\$
Możemy na przykład obliczyć wartości w górnym wierszu wynikowego \$M\times M'\$ macierz z:
W lewym górnym rogu: \$4\times4+-3\times-3+0\times0 = 25\$
U góry pośrodku: \$4\times-4+-3\times-7+0\times6=5\$
W prawym górnym rogu: \$4\times5+-3\times7+0\times6 = -1\$
Zrobiłem manipulacji Matrix w 05AB1E wcześniej w tej odpowiedzi kopalni , więc użyłem że kod snippet również tutaj. Ponieważ chcemy pomnożyć macierz wejściową przez jej transpozycję, w rzeczywistości nie będziemy potrzebować wbudowanej transpozycji.
ε # Map over each row of the (implicit) input-matrix
U # Pop and store the current row in variable `X`
ε # Map over each row of the (implicit) input-matrix again
X* # Multiply the values of the current row by the values at the same
# positions in row `X`
O # And take the sum of this row
] # Close both maps
Spróbuj tylko tego kroku online.
Krok 2) Sprawdź ślad tej nowej macierzy: \$(M\times M')^T\$
Ślad macierzy kwadratowej jest w zasadzie sumą jej głównej przekątnej (wartości od lewego górnego rogu do prawego dolnego).
Å\ # Take the main diagonal of the matrix of step 1
O # And sum the values in this list together
Wypróbuj pierwsze dwa kroki online.
Krok 3) Podzielić wszystkie wartości w transponowanej macierzy przez ten wykres, który obliczyliśmy:
I # Push the input-matrix
ø # Zip/transpose it; swapping rows/columns
s # Swap so the trace we calculated it at the top of the stack
/ # And divide each value in the transposed matrix by this trace
Wypróbuj pierwsze trzy kroki online.
Krok 4) Powtórz następujące kroki (od 5 do 8) wystarczająco dużo razy, aby odpowiedź już się nie zmieniła:
Ponieważ program ten nie jest bardzo szybki w 05AB1E, Zdecydowałem się pętli zaledwie 100 razy, ale to może być zwiększona w celu poprawy dokładności wyników po przecinku (I zostały zweryfikowane z @Sisyphus 'Octave odpowiedź , że zmieniając 1e4się 1e2nadal zawiera ten sam wynik dla większości macierzy).
тF # Loop 100 times:
Nie jestem pewien, czy wartości w końcu się już nie zmienią, jeśli wykonamy pętlę wystarczająco dużo razy. Jeśli tak jest, moglibyśmy (teoretycznie) zaoszczędzić bajt, zmieniając to тFna Δ(pętla, aż wynik nie będzie się już zmieniać).
(Nazwijmy pośrednią macierz wewnątrz tej pętli \$V\$ aby uzyskać wyjaśnienia dotyczące kolejnych kroków.)
Krok 5) Podwój każdą wartość w bieżącej macierzy: \$2V\$:
x # Double each value in the current matrix V (without popping)
Wypróbuj pierwsze pięć kroków online, z wyłączeniem pętli z kroku 4.
Krok 6) Wykonaj ponownie manipulację matrycą dla \$VM\$(gdzie \$M\$ jest macierzą wejściową):
s # Swap to take the non-doubled matrix V at the top again
© # Store this matrix V in variable `®` (without popping)
ε # Map over each row of matrix V:
U # Pop the current row, and store it in variable `X`
I # Push the input-matrix M
ø # Zip/transpose; swapping rows/columns
ε # Map over each row of this transposed matrix M':
X* # Multiply the values in the current row by row `X`
O # And take the sum
Wypróbuj pierwsze sześć kroków w trybie online, z wyjątkiem pętli z kroku 4.
Krok 7) I wykonaj ponownie manipulację matrycą zaraz po: \$VMV\$:
} # Close the inner map
U # Pop and store this as new `X`
® # Push the matrix V from variable `®`
ø # Zip/transpose; swapping rows/columns
ε # Map over each row of this transposed matrix V':
X* # Multiply the values in the current row by row `X`
O # And take the sum
}} # Close both the inner and outer maps
Wypróbuj pierwsze siedem kroków w trybie online, z wyjątkiem pętli z kroku 4.
Krok 8) Odejmij od siebie wartości w tych samych pozycjach tych dwóch macierzy: \$2V-VMV\$:
- # Subtract matrix VMV from 2V
Wypróbuj pierwsze osiem kroków w trybie online, z wyjątkiem pętli z kroku 4.
A po wykonaniu pętli wynikowa macierz jest niejawnie wyprowadzana.
Scala , 237232 bajty
Stosuje metodę z odpowiedzi Syzyfa . Głosuj na to!
m=>{val h=m.indices
Seq.iterate(m.transpose.map(_.map(_/m.flatten.map(x=>x*x).sum)),9999){v=>h.map(i=>h.map{j=>2*v(i)(j)-(h.map(k=>v(i).zip(m.transpose.apply(k))map(t=>t._1*t._2)sum),v.transpose.apply(j)).zipped.map(_*_).sum})}last}
Wypróbuj online!
hto tylko zakres od 0 do n do ponownego użycia później (głównie dlatego, że Scala nie ma wbudowanych funkcji mnożenia macierzy). Funkcja tworzy sekwencję 9999 elementów i przyjmuje ostatni element. Pierwszym elementem jest transpozycja mpodzielonego przez ślad mczasu jego transpozycji. Kolejne elementy są obliczane z 2*v-v*m*v, gdzie vbył poprzedni element.
Aby obliczyć \$V_0\$(Okazuje się, że ślad mczasu jego transpozycji jest po prostu sumą kwadratów wszystkich mkomórek '):
m.transpose.map( //For every row in m's transpose
_.map( //For every cell in that row
_ / //Divide it by (trace(M * M's transpose))
m.flatten //Turn m into a 1D list
.map(x=>x*x) //Square each cell
.sum)) //Add them up
Do wyliczenia kolejnych elementów używamy \$2V - (VA)V\$, ale musisz mapować hzamiast nad vsobą:
h.map(i => //For every i in [0, n)
h.map{j => //For every j in [0, n)
2*v(i)(j) - //2V at these coordinates minus
<(v * m * v)[i][j]> }) //v*m*v at these coordinates (see explanation below)
Aby obliczyć (v*m)[i]:
h.map(k => //k is the index of a row in [0, n)
v(i).zip( //Zip column i of v with
m.transpose.apply(k) //Row k of m (apply is used for indexing here)
) map(t=>t._1*t._2) //Multiply v(i)(j) with m(k)(i)
sum //Add then up
)
I coraz iloczynu że z rzędu jz vzastosowań prawie to samo podejście.
Scala, 346342 bajty
Zapisano 4 bajty dzięki @ corvus_192 !
type M=Seq[Seq[Double]]
def c(m:M)={val I=m.indices;I.map(i=>I.map(j=>m(i)(j)*math.pow(-1,i+j)))}
def d(m:M):(M,Double)=if(m.size<2)m->m(0)(0)else{val I=m.indices
val M=I.map(i=>I.map{j=>d(I.filter(i!=_)map(k=>I.filter(j!=_)map(m(k))))._2})
c(M)->c(m).head.zip(M.head).map(t=>t._1*t._2).sum}
def i(m:M)=d(m)._1.transpose.map(_.map(_/d(m)._2))
Wypróbuj w Scastie!
Jak widać, nie jestem zbyt dobry z matematyki.
Język Wolfram (Mathematica) , 7 bajtów
Inverse
Wypróbuj online!
Julia 1.0 , 3 bajty
inv
Wypróbuj online!
Jeszcze jedno krótkie wbudowane rozwiązanie.
J , 2 bajty
%.
Wypróbuj online!
To samo co APL, ale mocniejsze, ponieważ J może generować dokładną macierz wymierną, gdy jako dane wejściowe ma macierz rozszerzonych liczb całkowitych.
Galaretka , 3 bajty
æ*-
Wypróbuj online.
Wyjaśnienie:
# Full program taking a single integer-matrix as argument
æ* # Matrix exponentiation
- # with -1
# (after which the result is output implicitly)
Python 2 , 188 bajtów
lambda a:[[c(a,j,i)/d(a)for j,_ in e(a)]for i,_ in e(a)]
c=lambda a,i,j:(-1)**(i+j)*d([b[:j]+b[j+1:]for I,b in e(a)if i-I])
d=lambda a:a==[]or sum(b[0]*c(a,i,0)for i,b in e(a))
e=enumerate
Wypróbuj online!
Najlepsze obliczenia lambda \$A^{-1} = \frac{1}{\det(A)}\text{adj}(A)\$.
d(a)oblicza wyznacznik i c(a,i,j)oblicza kofaktory.
MATL , 4 bajty
-1Y^
Wypróbuj online!
Wyjaśnienie
-1Y^
-1 : Push -1 onto the stack
Y^ : Raise implicit input to -1 power
Węgiel , 48 bajtów
≔Eθ∕Eθ§λκΣEXθ²ΣληFφUMηEκ⁻⊗μΣEθ×ΣEθ×§κς§ρπ§§ηπνIη
Wypróbuj online! Link prowadzi do pełnej wersji kodu. Zauważ, że tryb gadatliwy ma si został vwymieniony przez pomyłkę. Wyjaśnienie: Kolejna porcja odpowiedzi @ Syzyf.
≔Eθ∕Eθ§λκΣEXθ²Σλη
Przenieś dane wejściowe i podziel je przez sumę kwadratów wszystkich elementów. Niestety, nie sumuj ani nie dziel w pełni wektoryzacji, więc muszę dzielić wiersz na raz i obliczać sumę za pomocą zagnieżdżonej pętli.
Fφ
Powtórz 1000 razy, co powinno wystarczyć dla precyzji zmiennoprzecinkowej.
UMηEκ⁻⊗μΣEθ×ΣEθ×§κς§ρπ§§ηπν
Oblicz mnożenie i odejmowanie macierzy w miejscu. Węgiel nie ma żadnych operacji na wektorach ani na macierzach, więc musimy ręcznie zapętlić wiersze i kolumny, ale jest kilka miejsc, w których możemy udostępniać zmienne, które oszczędzają nam po kilka bajtów.
Iη
Wyprowadź tablicę. (Zauważ, że każdy element jest wyprowadzany w osobnym wierszu, a każdy wiersz jest podwójnie oddzielony od poprzedniego).
Excel, 29 bajtów
=MINVERSE(OFFSET(A2,,,A1,A1))
Proste zastosowanie funkcji MINVERSE () . To nudne, ale byłem podekscytowany tym, że Excel ma coś wbudowanego. Wejście \$n\$in A1, macierz zaczyna się w A2i formuła wszędzie tam, gdzie wyciek nie będzie przeszkadzał.
Matlab 6 3 bajty
inv
Oblicza i drukuje odwrotność macierzy kwadratowej. Dość nudne wbudowane rozwiązanie. Dzięki @Bubbler za wyjaśnienie i -3 bajty.
SageMath , 14 13 11 bajtów
Zapisano bajt dzięki FryAmTheEggman !!!
Zapisano 2 bajty dzięki Syzyfowi !!!
lambda M:~M
Wypróbuj online!
Wprowadza dowolny kwadrat matrixi zwraca jego odwrotność.
APL (Dyalog Unicode) , 27 bajtów
To implementuje metodę reklamowaną przez Syzyfa .
(⊢+⊢-⊢+.×+.×)⍣≡∘(⍉÷1⊥2*⍨,)⍨
Wypróbuj online!
Funkcja, która przyjmuje macierz jako prawy argument.
⍨dojeżdża do pracy całą funkcję. Ponieważ funkcja nie może mieć tylko lewego argumentu, powoduje to, że macierz jest używana jako lewy i prawy argument.
⍉÷1⊥2*⍨,oblicza \$A^T \div \text{tr}(AA^T)\$, używając \$\text{tr}(AA^T) = \sum a_{ij}^2\$:
,spłaszcza macierz do postaci wektora.
2*⍨podnosi każdą wartość do drugiej potęgi.
1⊥konwertuje wynikowy wektor z podstawy 1, co jest tym samym, co sumowanie go.
⍉÷dzieli transponowaną macierz przez ślad.
⊢+⊢-⊢+.×+.×pobiera aktualną macierz \$V\$po jego prawej stronie i macierz wejściowa \$A\$po jego lewej stronie i wykonuje jeden krok iteracji:
+.×jest iloczynem wewnętrznym +i ×. Biorąc pod uwagę dwie macierze, oblicza to ich iloczyn. W tym przypadku \$ A \times V \$.
⊢jest właściwym argumentem \$V\$, ⊢+.×Produkt \$V \times (A \times V)\$.
⊢-odejmuje to od prawego argumentu: \$V-V \times A \times V\$.
⊢+dodaje to do właściwego argumentu: \$V+V-V \times A \times V\$.
⍣≡stosuje funkcję po lewej stronie, aż wynik się nie zmieni. Ze względu na sposób, w jaki testowanie równości działa w Dyalog APL, to faktycznie się kończy.
Ruby -rmatrix , 23 19 bajtów
->a{Matrix[*a].inv}
Wypróbuj online!
Zwraca wynik jako obiekt macierzy Ruby.
-4 bajty z Dingus.