A matriz é positiva-definitiva?

19

Introdução

Hoje nós vamos cuidar da desgraça dos alunos do primeiro ano de álgebra linear: definição de matriz! Aparentemente, isso ainda não tem um desafio, então vamos lá:

Entrada

  • Uma Matriz n×n simétrica A em qualquer formato conveniente (você também pode, naturalmente, pegar apenas a parte superior ou a parte inferior da matriz)
  • Opcionalmente: o tamanho da matriz n

O que fazer?

O desafio é simples: dada uma matriz com valor real n×n Matriz decide se é definida positivamente emitindo um valor verdadeiro, se for o caso, e um valor falsey, se não.

Você pode supor que seus internos realmente funcionem com precisão e, portanto, não sejam responsáveis ​​por problemas numéricos que podem levar ao comportamento errado se a estratégia / código "provável" produzir o resultado correto.

Quem ganha?

Isso é , então o código mais curto em bytes (por idioma) vence!


O que é uma matriz positiva definida de qualquer maneira?

Aparentemente, existem 6 formulações equivalentes de quando uma matriz simétrica é definida positivamente. Vou reproduzir os três mais fáceis e referenciá-lo à Wikipedia para os mais complexos.

  • Se vRn{0}:vTAv>0 então A é positivo-definido.
    Isto pode ser formulado como re-:
    Se para cada diferente de zero vetor v o (padrão) dot produto de v e Av for positivo, então A será positivo.
  • Seja λii{1,,n} são osautovaloresdeA , se agorai{1,,n}:λi>0 (ou seja, todos os autovalores são positivos), entãoA é positivo-definido.
    Se você não sabe quais são os autovalores, sugiro que você use seu mecanismo de pesquisa favorito para descobrir, porque a explicação (e as estratégias de computação necessárias) é muito longa para ser contida neste post.
  • Se a decomposição de Cholesky de A existe, isto é, existe uma matriz triangular inferior L tal que LLT=A então A é definida positiva. Observe que isso é equivalente a "false" de retorno antecipado se a qualquer momento o cálculo da raiz durante o algoritmo falhar devido a um argumento negativo.

Exemplos

Para saída de verdade

(100010001)

(1000020000300004)

(521211113)

(1222502030)

(7.152.452.459.37)

Para saída falsey

(pelo menos um valor próprio é 0 / semi-definido positivo)

(322240202)

(valores próprios têm sinais diferentes / indefinidos)

(100010001)

(todos os autovalores menores que 0 / negativo definido)

(100010001)

(todos os autovalores menores que 0 / definido negativo)

(230350001)

(todos os autovalores menores que 0 / definido negativo)

(7.152.452.459.37)

(três positivos, um autovalor negativo / indefinido)

(7.152.451.233.52.459.372.713.141.232.7106.23.53.146.20.56)

SEJPM
fonte
Você precisa fornecer uma definição melhor do que devemos procurar, em vez de assumir que todos podemos ler notação matemática (ou todos sabem o que é um "valor próprio"). Um exemplo trabalhado também seria útil.
Shaggy
9
@ Shagy Acho que o desafio é melhor sem todo o pano de fundo para entupi-lo. Existem muitas explicações existentes sobre o que é um autovalor em outro lugar, e este post já é realmente grande.
Assistente de trigo
1
O desafio teria sido melhor se você não restringisse a entrada a matrizes simétricas .
polfosol ఠ_ఠ
1
Eu quis dizer que apenas verificar o sinal de autovalores também é chato. Gostos diferentes Eu sei;)
polfosol ఠ_ఠ

Respostas:

11

C, 108 bytes

-1 byte graças ao Logern
-3 bytes graças ao ceilingcat

f(M,n,i)double**M;{for(i=n*n;i--;)M[i/n][i%n]-=M[n][i%n]*M[i/n][n]/M[n][n];return M[n][n]>0&(!n||f(M,n-1));}

Experimente online!

Executa a eliminação gaussiana e verifica se todos os elementos diagonais são positivos (critério de Sylvester). Argumento né o tamanho da matriz menos um.

Nwellnhof
fonte
Talvez salvar um personagem com float em vez de duplo?
Jens
Você pode raspar outro caractere se soltar i=0o loop for, efetuar a chamada recursiva f(M,n-1,0)e a chamada inicial com 0 como o terceiro argumento.
Jens
@ Jens 1. O uso de floats em vez de duplas pode levar rapidamente a erros de arredondamento perceptíveis, então não acho que o byte salvo economize. 2. Inicializar uma variável por meio de um argumento adicional parece trapaça para mim.
Nwellnhof # 24/18
@ Logern Recuso-me a usar o truque "omitir a declaração de retorno" nas minhas respostas em C. Mas obrigado pelo outro byte salvo.
Nwellnhof # 24/18
9

MATLAB / Oitava , 19 17 12 bytes

@(A)eig(A)>0

Experimente online!

A função eig fornece os autovalores em ordem crescente, portanto, se o primeiro autovalor for maior que zero, os outros também.

Daniel Turizo
fonte
Você pode largar f=no início - funções anônimas geralmente são aceitas como respostas.
Delfad0r 23/09/18
Obrigado pela dica!
Daniel Turizo 23/09
Mesmo que seja um vetor? Interessante
Daniel Turizo
1
+1. Adicionei um link para experimentá-lo online. Espero que você não se importe. Observe que também está provando que os valores de saída, apesar de serem matrizes, contam como os valores "verdade" ou "falsey" corretos, conforme o link @ Delfad0r publicado.
Tom Carpenter
2
Dito isto, falha no primeiro caso de teste "falsey" no TIO. Eu estou supondo que devido a um problema de precisão - um dos valores Eigen sai como 8.9219e-17ao invés de 0.
Tom Carpenter
7

Geléia , 11 10 bytes

ṖṖ€$ƬÆḊṂ>0

Usa o critério de Sylvester .

Experimente online!

Como funciona

ṖṖ€$ƬÆḊṂ>0  Main link. Argument: M (matrix)

   $Ƭ       Do the following until a fixed point is encountered.
Ṗ             Pop; remove the last row of the matrix.
 Ṗ€           Pop each; remove the last entry of each row.
     ÆḊ     Take the determinants of the resulting minors.
       Ṃ    Take the minimum.
        >0  Test if the least determinant is positive, i.e., if all determinants are.
Dennis
fonte
6

R , 29 bytes

function(m)all(eigen(m)$va>0)

Experimente online!


Alternativa usando cholesky:

R , 34 33 bytes

function(m)is.array(try(chol(m)))

Experimente online!

-1 byte graças a @ Giuseppe

digEmAll
fonte
6

Haskell , 56 bytes

f((x:y):z)=x>0&&f[zipWith(-)v$map(u/x*)y|u:v<-z]
f[]=1>0

Experimente online!

Basicamente, um porto de resposta do nwellnhof . Executa a eliminação gaussiana e verifica se os elementos na diagonal principal são positivos.

Falha na primeira saída falsey devido a erros de arredondamento, mas teoricamente funcionaria com precisão infinita. Graças à sugestão de Curtis Bechtel , agora os resultados estão todos corretos.

Delfad0r
fonte
2
você pode adicionar inputs :: [[[Rational]]]para obter respostas corretas
Curtis Bechtel
4

Wolfram Language (Mathematica) , 20 bytes

0<Min@Eigenvalues@#&

Experimente online!

Mr. Xcoder
fonte
O 4º caso de teste deve ser falso?
tsh
@tsh Fixed, eu sou burro!
Sr. Xcoder 23/09/18
8
Engraçado como o Mathematica tem um builtin para isso , mas seu nome é mais longo que a sua solução.
Federico Poloni
@FedericoPoloni: Uma solução usando o NullSpace ou o MatrixRank seria ainda mais curta? Se o espaço nulo for zero, a matriz é positiva definida.
Phil H
@ Phil Não, receio que isso não funcione por si só. Por exemplo, o segundo exemplo de falsey (matriz diagonal com (1, -1,1)) tem classificação 3, mas não é positivo definido.
Federico Poloni 24/09
3

MATL , 4 bytes

Yv0>

Experimente online!

Percebi que, para o [3 -2 2; -2 4 0; 2 0 2]caso de teste, o MATL calcula o 0autovalor com uma imprecisão muito pequena, calculando algo tão baixo quanto10-18. Portanto, isso falha no primeiro caso de teste falso devido a problemas de precisão. Agradecemos a Luis Mendo por apontar que uma matriz não vazia é verdadeira se todas as suas entradas diferirem de 0, economizando 1 byte.

Mr. Xcoder
fonte
1
@LuisMendo Obrigado, eu aprendi algo novo sobre o MATL hoje!
Sr. Xcoder 26/09/18
O prazer é meu :-) Aqui está uma explicação melhor de Suever. Esqueci de dizer que, para matrizes de valor complexo, apenas a parte real é comparada com zero. O que [1 2 3j]é o falsey
Luis Mendo
2

Mathematica, 29 28 bytes

AllTrue[Eigenvalues@#,#>0&]&

Definição 2.

Shieru Asakoto
fonte
2

MATL , 6 bytes

É possível fazer isso usando ainda menos bytes, @Mr. O Xcoder conseguiu encontrar uma resposta MATL de 5 bytes !

YvX<0>

Explicação

Yv     compute eigenvalues
  X<   take the minimum
    0> check whether it is greather than zero

Experimente online!

flawr
fonte
Falha no primeiro caso de teste falso. Veja minha resposta excluída .
Sr. Xcoder 25/09/18
1
@ Mr.Xcoder Oh, você até enviou uma resposta antes de mim. Acho que você deve recuperar sua resposta, pois depende apenas de questões de arredondamento. (Eu acho que você pode esperar respostas para usar aritmética de precisão limitada -. Eu acho que só as línguas CAS aqui usam cálculos exatos)
flawr
Seguindo o seu conselho, eu o cancelei .
Sr. Xcoder 25/09
1

Bordo , 33 bytes

(ou seja, meus 2 centavos)

with(LinearAlgebra):
IsDefinite(A)
polfosol ఠ_ఠ
fonte
Olá e bem-vindo ao PPCG; Não estou familiarizado com o Maple, mas a nova linha é necessária?
Jonathan Frech 24/09
@JonathanFrech Olá e obrigado. Não, não é. Eu não contei isso.
polfosol ఠ_ఠ
Para mim, sua contagem atual de bytes parece refletir o caractere de nova linha.
Jonathan Frech 24/09
@JonathanFrech Duh, my bad
polfosol ఠ_ఠ
1
Bem ... agora seu código e contagem de bytes discordam.
Jonathan Frech 24/09
0

JavaScript (ES6),  99 95  88 bytes

O mesmo método da resposta de nwellnhof . Devoluções0 0 ou 1.

f=(m,n=0,R=m[n])=>R?f(m,n+1)&R[m.map((r,y)=>y<n&&R.map((v,x)=>r[x]-=v*r[n]/R[n])),n]>0:1

Experimente online!

Arnauld
fonte