Dada uma matriz inteira quadrada como entrada, produza o determinante da matriz.
Regras
- Você pode supor que todos os elementos da matriz, o determinante da matriz e o número total de elementos na matriz estejam dentro do intervalo representável de números inteiros para o seu idioma.
- É permitido emitir um valor decimal / flutuante com uma parte fracionária de 0 (por exemplo, em
42.0
vez de42
). - Builtins são permitidos, mas você deve incluir uma solução que não use os builtins.
Casos de teste
[[42]] -> 42
[[2, 3], [1, 4]] -> 5
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 0
[[13, 17, 24], [19, 1, 3], [-5, 4, 0]] -> 1533
[[372, -152, 244], [-97, -191, 185], [-53, -397, -126]] -> 46548380
[[100, -200, 58, 4], [1, -90, -55, -165], [-67, -83, 239, 182], [238, -283, 384, 392]] -> 571026450
[[432, 45, 330, 284, 276], [-492, 497, 133, -289, -28], [-443, -400, 56, 150, -316], [-344, 316, 92, 205, 104], [277, 307, -464, 244, -422]] -> -51446016699154
[[416, 66, 340, 250, -436, -146], [-464, 68, 104, 471, -335, -442], [159, -407, 310, -489, -248, 370], [62, 277, 446, -325, 47, -193], [460, 460, -418, -28, 234, -374], [249, 375, 489, 172, -423, 125]] -> 39153009069988024
[[-246, -142, 378, -156, -373, 444], [186, 186, -23, 50, 349, -413], [216, 1, -418, 38, 47, -192], [109, 345, -356, -296, -47, -498], [-283, 91, 258, 66, -127, 79], [218, 465, -420, -326, -445, 19]] -> -925012040475554
[[-192, 141, -349, 447, -403, -21, 34], [260, -307, -333, -373, -324, 144, -190], [301, 277, 25, 8, -177, 180, 405], [-406, -9, -318, 337, -118, 44, -123], [-207, 33, -189, -229, -196, 58, -491], [-426, 48, -24, 72, -250, 160, 359], [-208, 120, -385, 251, 322, -349, -448]] -> -4248003140052269106
[[80, 159, 362, -30, -24, -493, 410, 249, -11, -109], [-110, -123, -461, -34, -266, 199, -437, 445, 498, 96], [175, -405, 432, -7, 157, 169, 336, -276, 337, -200], [-106, -379, -157, -199, 123, -172, 141, 329, 158, 309], [-316, -239, 327, -29, -482, 294, -86, -326, 490, -295], [64, -201, -155, 238, 131, 182, -487, -462, -312, 196], [-297, -75, -206, 471, -94, -46, -378, 334, 407, -97], [-140, -137, 297, -372, 228, 318, 251, -93, 117, 286], [-95, -300, -419, 41, -140, -205, 29, -481, -372, -49], [-140, -281, -88, -13, -128, -264, 165, 261, -469, -62]] -> 297434936630444226910432057
You may assume that all elements in the matrix, the determinant of the matrix, and the total number of elements in the matrix are within the representable range of integers for your language.
Respostas:
Gelatina , 15 bytes
Experimente online!
Como funciona
Por que funciona - versão mathy
O operador det pega uma matriz e retorna um escalar. Um n -by- n matriz pode ser pensado como um conjunto de n vetores de tamanho n , então det é realmente uma função que toma n vetores de ℤ n e retorna um escalar.
Portanto, escrevo det ( v 1 , v 2 , v 3 , ..., v n ) para det [ v 1 v 2 v 3 ... v n ].
Observe que det é linear em cada argumento, ou seja, det ( v 1 + λ w 1 , v 2 , v 3 , ..., v n ) = det ( v 1 , v 2 , v 3 , ..., v n ) + λ det ( w 1 , v 2 , v 3 , ..., v n ). Portanto, é um mapa linear de (ℤ n ) ⊗ n para ℤ.
Basta determinar a imagem da base no mapa linear. A base de (ℤ n ) ⊗ n consiste em produtos tensores n vezes os elementos base de ℤ n , ieeg 5 e 3 e 3 e 1 e 5 e 1 . Os produtos tensores que incluem tensores idênticos devem ser enviados a zero, pois o determinante de uma matriz na qual duas colunas são idênticas é zero. Resta verificar para onde são enviados os produtos tensores de elementos básicos distintos. Os índices dos vetores no produto tensorial formam uma bijeção, isto é, uma permutação, na qual permutações pares são enviadas para 1 e permutações ímpares são enviadas para -1.
Por exemplo, para encontrar o determinante de [[1, 2], [3, 4]]: observe que as colunas são [1, 3] e [2, 4]. Nós decompomos [1, 3] para dar (1 e 1 + 3 e 2 ) e (2 e 1 + 4 e 2 ). O elemento correspondente no produto tensorial é (1 e 1 ⊗ 2 e 1 + 1 e 1 ⊗ 4 e 2 + 3 e 2 ⊗ 2 e 1 + 3 e 2 ⊗ 4 e 2 ), que simplificamos para (2 e 1 ⊗ e 1 + 4 e 1 ⊗ e 2 + 6 e 2 ⊗ e 1 + 12 e 2 ⊗ e dois) Assim sendo:
det [[1, 2], [3, 4]]
= det (1 e 1 + 3 e 2 , 2 e 1 + 4 e 2 )
= det (2 e 1 e 1 + 4 e 1 e 2 + 6 e 2 1 e 1 + 12 e 2 ⊗ e 2 )
= det (2 e 1 ⊗ e 1 ) + det (4 e 1 ⊗ e 2 ) + det (6 e 2 ⊗ e 1 ) + det (12 e2 e 2 )
= 2 det (e 1 e 1 ) + 4 det (e 1 e 2 ) + 6 det (e 2 e 1 ) + 12 det (e 2 e 2 )
= 2 (0) + 4 (1) + 6 (-1) + 12 (0)
= 4-6
= -2
Agora resta provar que a fórmula para encontrar a paridade da permutação é válida. O que meu código faz é encontrar essencialmente o número de inversões, ou seja, os lugares onde um elemento à esquerda é maior que um elemento à direita (não necessariamente consecutivamente).
Por exemplo, na permutação 3614572, existem 9 inversões (31, 32, 61, 64, 65, 62, 42, 52, 72), portanto a permutação é ímpar.
A justificativa é que cada transposição (troca de dois elementos) adiciona uma inversão ou retira uma inversão, trocando a paridade do número de inversões, e a paridade da permutação é a paridade do número de transposições necessárias para obter a permutação.
Portanto, em conclusão, nossa fórmula é dada por:
Por que funciona - versão não matemática
onde σ é uma permutação de 𝕊 n o grupo de todas as permutações de n letras, e SGN é o sinal da permutação, AKA (-1) levantada para a paridade da permutação, e um i j é o ( ij ) th entrada em a matriz ( i abaixo, j transversalmente).
fonte
R , 3 bytes
Solução trivial
Experimente online!
R ,
9492 bytessolução reimplementada
superado por Jarko Dubbeldam
Experimente online!
Recursivamente usa a expansão por menores na primeira coluna da matriz.
fonte
Gelatina ,
16151210 bytesUsa a expansão Laplace . Graças a @miles por jogar fora
35 bytes!Experimente online!
Como funciona
fonte
Wolfram Language (Mathematica) , entre 14 e 42 bytes
Tivemos uma solução integrada de 3 bytes e uma solução de 53 bytes que evitam completamente os embutidos; portanto, aqui estão algumas soluções mais estranhas em algum lugar.
A Wolfram Language possui muitas funções muito intensas para decompor matrizes em produtos de outras matrizes com estrutura mais simples. Um dos mais simples (ou seja, eu já ouvi isso antes) é a decomposição da Jordânia. Toda matriz é semelhante a uma matriz triangular superior (possivelmente com valor complexo) feita de blocos diagonais com uma estrutura específica, chamada decomposição de Jordan dessa matriz. A similaridade preserva os determinantes, e o determinante de uma matriz triangular é o produto dos elementos diagonais, para que possamos calcular o determinante com os seguintes 42 bytes :
O determinante também é igual ao produto dos autovalores de uma matriz, com multiplicidade. Felizmente, a função de autovalor do Wolfram controla a multiplicidade (mesmo para matrizes não diagonalizáveis), para obter a seguinte solução de 20 bytes :
A próxima solução é meio que trapacear e não sei ao certo por que funciona. O Wronskiano de uma lista de n funções é o determinante da matriz das primeiras derivadas n -1 das funções. Se atribuirmos à
Wronskian
função uma matriz de números inteiros e dissermos que a variável de diferenciação é 1, de alguma forma ela cospe o determinante da matriz. É estranho, mas não envolve as letras "Det
" e tem apenas 14 bytes …(O determinante Casoratian funciona tão bem, para mais um byte:
#~Casoratian~1&
)No domínio da álgebra resumo, o determinante de um n x n matriz (pensado como o mapa k → k que é a multiplicação pelo determinante) é o n ° de energia exterior da matriz (após a colheita um isomorfismo k → ⋀ n k n ) Na linguagem Wolfram, podemos fazer isso com os seguintes 26 bytes :
E aqui está uma solução que funciona apenas para determinantes positivos. Se pegarmos um hipercubo de unidade n- dimensional e aplicarmos uma transformação linear a ele, o "volume" n- dimensional da região resultante é o valor absoluto do determinante da transformação. A aplicação de uma transformação linear a um cubo fornece um paralelepípedo, e podemos obter seu volume com os seguintes 39 bytes de código:
fonte
Exp@*Tr@*MatrixLog
, mas infelizmente isso não funciona para matrizes singulares.Check[E^Tr@MatrixLog@#,0]&
.Check
antes.Haskell , 71 bytes
-3 bytes graças a Lynn. Outro bytes a poeira, graças a Craig Roy.
Experimente online! Adicionado
-O
sinalizador para fins de otimização. Não é necessário.Explicação (desatualizada)
f
implementa recursivamente a expansão do cofator.Esta linha abrange o caso de uma base de 1 x 1 matriz, no caso em que o determinante é
mat[0, 0]
.Isso usa a correspondência de padrões de Haskell para quebrar a matriz em uma cabeça (a primeira linha) e uma cauda (o resto da matriz).
Enumere a cabeça da matriz (fechando a lista infinita de números inteiros e a cabeça) e itere sobre ela.
Negue o resultado com base no fato de seu índice ser uniforme, pois o cálculo do determinante envolve adição e subtração alternadas.
Isso essencialmente remove a i - ésima coluna da cauda, pegando elementos i e concatenando-a com a linha com os primeiros (i + 1) th elementos descartados para cada linha na cauda.
Calcule o determinante do resultado acima e multiplique pelo resultado de
(-1)*i*v
.Soma o resultado da lista acima e devolva-o.
fonte
sum[(-1)^i*...
comfoldr(-)0[...
Próton , 99 bytes
Experimente online!
-3 bytes graças ao Sr. Xcoder
-3 bytes graças a Erik, o Outgolfer
Expansão na primeira linha
fonte
((~i%2)*2-1)
->((-i%2)|1)
j!=i
porj-i
oui-j
.Oitava , 28 bytes
Experimente online!
Isto usa a decomposição de QR de uma matriz X em uma matriz orthgonal Q e uma matriz triangular superior R . O determinante de X é o produto de aqueles de Q e R . Uma matriz ortogonal tem determinante de unidade e, para uma matriz triangular, o determinante é o produto de suas entradas diagonais. De Octave
qr
função chamada com uma única saída dá R .O resultado é arredondado para o número inteiro mais próximo. Para matrizes de entrada grandes, imprecisões de ponto flutuante podem produzir um erro excedente
0.5
e, portanto, produzir um resultado errado.fonte
det
embutido. ;)Haskell , 59 bytes
Experimente online!
fonte
C,
176125 bytesObrigado a @ceilingcat por jogar 42 bytes de golfe e obrigado a @Lynn e @Jonathan Frech por salvar um byte cada!
Calcula o determinante usando a expansão Laplace ao longo da primeira linha.
Experimente online!
Desenrolado:
fonte
(i%2*-2+1)
→(1-i%2*2)
salva mais um byte.n+1+c
pode sern-~c
.i=s
vez dereturn s
Gelatina , 43 bytes
Finalmente, escrevi minha solução não integrada em um idioma de golfe!
Agradecemos ao HyperNeutrino por salvar um byte!
Experimente online! (código espaçado para maior clareza)
terrivelmente longo para remover os enésimos elementos de uma lista, melhorará mais tarde
Essa resposta foi superada pelas respostas de HyperNeutrino, Dennis e Leaky Nun. A geléia é muito popular como idioma de golfe.
Explicação rápida:
fonte
Gelatina , 24 bytes
Experimente online!
Explicação
-2 bytes graças à solução de user202729
fonte
MATL , 3 bytes / 5 bytes
Com função embutida
Experimente online!
Sem embutido
Obrigado a Misha Lavrov por apontar um erro, agora corrigido
Experimente online!
Isso calcula o determinante como o produto dos autovalores, arredondado para o número inteiro mais próximo para evitar imprecisões de ponto flutuante.
fonte
R , 32 bytes
Não utiliza o algoritmo de uma árvore para obter os autovalores da matriz e a parte real de seu produto.
Experimente online!
fonte
Oitava , 30 bytes
Experimente online!
ou, a chata solução de 4 bytes (economizou 6 bytes graças a Luis Mendo (esqueceu as regras relativas às funções internas)):
Explicação:
Chegando! :)
fonte
TI-Basic, 2 bytes
Ah bem.
Por favor, não vote em respostas triviais.
Como um estudante do ensino médio (que é forçado a possuir uma dessas calculadoras), essa função é muito útil, então ...
fonte
Haskell, 62 bytes
Experimente online! (Rodapé com casos de teste retirados da solução do totallyhuman.)
d
calcula o determinante usando uma expansão de Laplace ao longo da primeira coluna. Precisa de três bytes a mais que o permanente .fonte
Python 2 , 95 bytes
-12 bytes graças a Lynn.
Porto da minha resposta Haskell .
Experimente online!
fonte
[]
como caso base:f=lambda m:sum((-1)**i*v*f([j[:i]+j[i+1:]for j in m[1:]])for i,v in enumerate(m[0]))if m else 1
para 95 bytes!m==[]or sum(...)
dá 92 bytes.Wolfram Language (Mathematica) ,
5352 bytesExperimente online!
Infelizmente, computar o determinante de um n por n matriz desta forma usos O ( N n ) de memória, o que coloca grandes casos de teste fora do alcance.
Como funciona
A primeira parte
1##&@@@(t=Tuples)@#
,, calcula todos os produtos possíveis de um termo de cada linha da matriz especificada.t[Range@Tr[1^#]&/@#]
dá uma lista do mesmo comprimento cujos elementos são coisas como{3,2,1}
ou{2,2,3}
dizendo que a entrada de cada linha que escolheu para o produto correspondente.Aplicamos
Signature
a segunda lista, que mapeia permutações pares para1
, permutações ímpares para-1
e não permutações para0
. Este é precisamente o coeficiente com o qual o produto correspondente aparece no determinante.Finalmente, pegamos o produto escalar das duas listas.
Se even
Signature
for muito embutido, com 73 bytes , podemos obtersubstituindo-o por
1##&@@Order@@@#~Subsets~{2}&
. Isso calculaSignature
uma permutação possível, tomando o produto deOrder
aplicado a todos os pares de elementos da permutação.Order
dará1
se o par estiver em ordem crescente,-1
se estiver em ordem decrescente e0
se forem iguais.-1 byte graças a @ user202729
fonte
Python 3 ,
238 bytes,227 bytes,224 bytes, 216 bytesExperimente online!
Minha solução usa a definição de um determinante para cálculos. Infelizmente, a complexidade desse algoritmo é
n!
e não posso mostrar a passagem do último teste, mas, em teoria, isso é possível.fonte
CJam (
5045 bytes)Este é um bloco anônimo (função) que pega uma matriz 2D na pilha e deixa um número inteiro na pilha.
Conjunto de testes online
Dissecação
Isso implementa o algoritmo de Faddeev-LeVerrier , e acho que é a primeira resposta para essa abordagem.
fonte
Wolfram Language (Mathematica) , 3 bytes
Experimente online!
De acordo com o meta consenso , principalmente as soluções não triviais aprovadas com esforço para escrever.
fonte
Python 2 , 75 bytes
Experimente online!
fonte
SageMath , vários
Aqui estão alguns métodos para calcular o determinante que achei interessante, todos programados no SageMath. Todos eles podem ser experimentados aqui .
Incorporado, 3 bytes
Este não é muito interessante. O Sage fornece aliases em nível global para muitas operações comuns que normalmente seriam métodos de objeto, então isso é mais curto que
lambda m:m.det()
.Parte real do produto de valores próprios, 36 bytes
Infelizmente,
eigenvalues
não é um desses aliases em nível global. Isso, combinado com o fato de o Sage não ter uma maneira elegante de compor funções, significa que estamos presos a um custo altolambda
. Os valores simbólicos desta função que são convertidos automaticamente em valores numéricos quando impressos, portanto, algumas imprecisões de ponto flutuante podem estar presentes em algumas saídas.Produto da Diagonal na Forma Normal da Jordânia, 60 bytes
Na forma Jordan Normal, uma matriz NxN é representada como uma matriz de blocos, com N blocos na diagonal. Cada bloco consiste em um único valor próprio ou em uma matriz MxM com um valor próprio repetido na diagonal
1
es na super diagonal (a diagonal acima e à direita da diagonal "principal"). Isso resulta em uma matriz com todos os autovalores (com multiplicidade) na diagonal principal e alguns1
s na super diagonal correspondendo a autovalores repetidos. Isso retorna o produto da diagonal da forma normal de Jordan, que é o produto dos autovalores (com multiplicidade), portanto, essa é uma maneira mais indireta de executar o mesmo cálculo da solução anterior.Como Sage deseja que a forma normal de Jordan esteja no mesmo anel que a matriz original, isso só funciona se todos os autovalores forem racionais. Autovalores complexos resultam em um erro (a menos que a matriz original esteja acima do anel
CDF
(flutuadores duplos complexos) ouSR
). No entanto, isso significa que não é necessário assumir a parte real, em comparação com a solução acima.Produto da Diagonal na Decomposição de Smith
Diferentemente da forma normal da Jordan, é garantido que a forma normal de Smith esteja no mesmo campo da matriz original. Em vez de calcular os autovalores e representá-los com uma matriz diagonal de bloco, a decomposição de Smith calcula os divisores elementares da matriz (que é um tópico um pouco complicado demais para este post), os coloca em uma matriz diagonal
D
e calcula duas matrizes com unidade determinanteU
eV
tal queD = U*A*V
(ondeA
está a matriz original). Como o determinante do produto de matrizes é igual ao produto dos determinantes das matrizes (det(A*B*...) = det(A)*det(B)*...
)U
eV
é definido como tendo determinantes de unidadedet(D) = det(A)
,. O determinante de uma matriz diagonal é simplesmente o produto dos elementos na diagonal.Expansão de Laplace, 109 bytes
Isso realiza a expansão de Laplace ao longo da primeira linha, usando uma abordagem recursiva.
det([[a]]) = a
é usado para o caso base. Deve ser mais curto para usardet([[]]) = 1
no caso base, mas minha tentativa nessa implementação teve um erro que ainda não consegui rastrear.Fórmula de Leibniz, 100 bytes
Isso implementa diretamente a fórmula de Leibniz. Para uma explicação muito melhor da fórmula e por que ela funciona do que eu poderia escrever, veja esta excelente resposta .
Parte real de
e^(Tr(ln(M)))
, 48 bytesEsta função retorna expressões simbólicas. Para obter uma aproximação numérica, ligue
n(result)
antes da impressão.Essa é uma abordagem que ainda não vi ninguém usar. Vou dar uma explicação mais longa e detalhada para este.
Seja
A
uma matriz quadrada sobre os reais. Por definição, o determinante deA
é igual ao produto dos valores próprios deA
. O traço deA
é igual à soma dosA
autovalores de s. Para números reaisr_1
er_2
,exp(r_1) * exp(r_2) = exp(r_1 + r_2)
. Como a função exponencial da matriz é definida como análoga à função exponencial escalar (especialmente na identidade anterior), e a exponencial da matriz pode ser calculada diagonalizando a matriz e aplicando a função exponencial escalar aos valores próprios na diagonal, podemos dizerdet(exp(A)) = exp(trace(A))
(o produto deexp(λ)
para cada valor próprioλ
deA
é igual à soma dos valores próprios deexp(A)
). Assim, se pudermos encontrar uma matrizL
tal queexp(L) = A
, podemos calculardet(A) = exp(trace(L))
.Podemos encontrar essa matriz
L
através da computaçãolog(A)
. O logaritmo da matriz pode ser calculado da mesma maneira que o exponencial da matriz: forme uma matriz diagonal quadrada aplicando a função de logaritmo escalar a cada autovalor deA
(é por isso que restringimosA
os reais). Como nos preocupamos apenas com o rastreio deL
, podemos pular a construção e somar diretamente os exponenciais dos valores próprios. Os valores próprios podem ser complexos, mesmo que a matriz não esteja acima do anel complexo, portanto, pegamos a parte real da soma.fonte
real(prod(m.eigenvalues()))
destruído.Java 8,
266261259258 bytesOlha mãe, sem build-ins .. porque o Java não tem ..>.>
-7 bytes graças a @ceilingcat .
Explicação:
Experimente aqui. (Apenas o último caso de teste é muito grande para caber em um
long
tamanho 2 63 -1.)fonte
JavaScript (ES6), 91
Laplace recursivo
Menos golfe
Teste
fonte
Python 2 + numpy , 29 bytes
Experimente online!
fonte
Julia , 3 bytes
Experimente online!
fonte
Pari / GP , 6 bytes
Experimente online!
fonte
Java (OpenJDK 8) ,
195 192177 bytesExperimente online!
Como muitas outras respostas, isso também usa a fórmula de Laplace. Uma versão um pouco menos golfe:
fonte
J , 5 bytes
Experimente online!
fonte