Verificar pares próprios


21

Nesse desafio, você receberá uma matriz quadrada A, um vetor ve um escalar λ. Você será solicitado a determinar se (λ, v)um par próprio corresponde a A; isto é, seja ou não Av = λv.

Produto Dot

O produto escalar de dois vetores é a soma da multiplicação por elementos. Por exemplo, o produto escalar dos dois vetores a seguir é:

(1, 2, 3) * (4, 5, 6) = 1*4 + 2*5 + 3*6 = 32

Observe que o produto escalar é definido apenas entre dois vetores do mesmo comprimento.

Multiplicação matriz-vetor

Uma matriz é uma grade de valores 2D. Uma matriz mx ntem mlinhas e ncolunas. Podemos imaginar uma matriz mx ncomo mvetores de comprimento n(se pegarmos as linhas).

A multiplicação de vetor de matriz é definida entre uma matriz mx ne um nvetor de tamanho . Se multiplicarmos uma matriz mx ne um nvetor de tamanho , obteremos um mvetor de tamanho . O i-ésimo valor no vetor de resultado é o produto escalar da i-a linha da matriz e o vetor original.

Exemplo

        1 2 3 4 5
Let A = 3 4 5 6 7
        5 6 7 8 9

        1
        3
Let v = 5
        7
        9

Se multiplicarmos a matriz e o vetor Av = x, obtemos o seguinte:

x 1 = A T 1 * v /* AT1 means the first row of A; A1 would be the first column */= (1,2,3,4,5) * (1,3,5,7,9) = 1 * 1 + 2 * 3 + 3 * 5 + 4 * 7 + 5 * 9 = 1 + 6 + 15 + 28 + 45 = 95

x 2 = A T 2 * v = (3,4,5,6,7) * (1,3,5,7,9) = 3 * 1 + 4 * 3 + 5 * 5 + 6 * 7 + 7 * 9 = 3 + 12 + 25 + 42 + 63 = 145

x 3 = A T 3 * v = (5,6,7,8,9) * (1,3,5,7,9) = 5 * 1 + 6 * 3 + 7 * 5 + 8 * 7 + 9 * 9 = 5 + 18 + 35 + 56 + 81 = 195

Então, nós chegamos Av = x = (95, 145, 195).

Multiplicação escalar

A multiplicação de um escalar (um único número) e um vetor é simplesmente multiplicação por elementos. Por exemplo 3 * (1, 2, 3) = (3, 6, 9),. É bastante direto.

Autovalores e autovetores

Dada a matriz A, dizemos que λé um valor próprio correspondente ao ve vé um autovetor correspondente a λ se e somente se Av = λv . (Onde Avé a multiplicação de vetores matriciais e multiplicação λvescalar).

(λ, v) é um par próprio.

Especificações do Desafio

Entrada

A entrada consistirá em uma matriz, um vetor e um escalar. Elas podem ser obtidas em qualquer ordem, em qualquer formato razoável.

Saída

A saída será um valor verdadeiro / falso; na verdade, se e somente se o escalar e o vetor forem um par próprio com a matriz especificada.

Regras

  • Aplicam-se brechas padrão
  • Se houver um built-in para verificar um par próprio no seu idioma, você não poderá usá-lo.
  • Você pode assumir que todos os números são inteiros

Casos de teste

 MATRIX  VECTOR  EIGENVALUE
 2 -3 -1    3
 1 -2 -1    1    1    ->    TRUE
 1 -3  0    0

 2 -3 -1    1
 1 -2 -1    1    -2   ->    TRUE
 1 -3  0    1

 1  6  3    1
 0 -2  0    0    4    ->    TRUE
 3  6  1    1

 1  0 -1    2
-1  1  1    1    7    ->    FALSE
 1  0  0    0

-4 3    1    
 2 1    2    2    ->    TRUE

2    1    2    ->    TRUE

Vou adicionar um 4x4 mais tarde.

Casos de teste ilegíveis que são mais fáceis para testar



@MartinEnder Thanks. Originalmente, eu tinha um desafio semelhante para matrizes de tamanho arbitrário, nas quais você deveria calcular uma base para cada espaço próprio, mas isso ainda está na caixa de areia porque parece muito confuso.
HyperNeutrino

Se as entradas puderem ter outras dimensões além de 3x3, você deve cobrir parte delas em seus casos de teste.
Martin Ender

11
@HyperNeutrino, sim, isso não ajuda ... Não tente me explicar: eu estou no ensino médio estudando matemática para o GCSE, então está perdido para mim.
você precisa saber é o seguinte

11
@ user00001 Se precisar de ajuda, refine-o e emparelhe-o automaticamente . : P
mbomb007

Respostas:


11

Geléia , 5 bytes

æ.⁵⁼×

Este é um programa triádico e completo.

Experimente online!

Como funciona

æ.⁵⁼×  Main link
       Left argument:  v (eigenvector)
       Right argument: λ (eigenvalue)
       Third argument: A (matrix)

  ⁵    Third; yield A.
æ.     Take the dot product of v and A, yielding Av.
    ×  Multiply v and λ component by component, yielding λv.
   ⁼   Test the results to the left and to the right for equality.

> _> isso é muito curto: P Resposta agradável
HyperNeutrino 13/04

6
Isso é conversa maluca! : P
Dennis

Você escreve algo e pensa "nada poderia ser mais curto!". Então o MATL aparece e reduz pela metade o tamanho do seu código. Então Jelly vem e metades que> _>
HyperNeutrino

@HyperNeutrino Não compare maçãs com laranjas. Os idiomas de golfe têm apenas um byte por operação, algo que os idiomas normais raramente têm. A especificação possui três operações (duas multiplicações e uma igualdade), e permitir que um byte extra duplique vum poderia esperar apenas quatro bytes.
Sanchises

2
Eu gosto de como Jelly e MATL usam dois bytes para multiplicação de matrizes, o que significa que essa resposta realmente mostra o quão bom Jelly é em receber informações, sendo o resto igual.
Sanchises


11

MATL, 7 bytes

*i2GY*=

Entradas na ordem: l, v, A.

Explicação:

*  % implicitly get l and v, multiply.
i  % get A
2G % get second input, i.e., v again
Y* % perform matrix multiplication
=  % test equality of both multiplications

Resposta surpreendentemente longa, se você me perguntar, principalmente porque eu precisava de uma maneira de obter todas as informações corretamente. Eu não acho que menos de 5 bytes seja possível, mas seria legal se alguém encontrasse uma solução de 5 ou 6 bytes.

Basicamente, isso calcula l*v==A*v.


"Surpreendentemente longo" Eu estava esperando pelo menos 20 bytes> _> resposta agradável, porém: P
HyperNeutrino 13/17/17

2
Bem, considerando que a resposta do MATLAB chegaria a 16 bytes @(A,v,l)A*v==v*l, isso parece bastante detalhado, e tenho a sensação de que 6 deve ser suficiente se eu conseguir a entrada um pouco mais inteligente.
Sanchises

Aparentemente, ele chegou a 38 bytes, mas tenho certeza de que pode ser jogado para baixo.
HyperNeutrino 13/04

3
@HyperNeutrino Adicionei o meu para tornar o comentário anterior verdadeiro. (ou truthy ...?)
Sanchises

6

CJam , 15 bytes

q~W$f.*::+@@f*=

Recebe entrada no formulário vector scalar matrix.

Experimente online!

Explicação

q~               e# Read and eval the input
  W$             e# Copy the bottom most value (the vector)
    f.*::+       e# Perform element-wise multiplication with each row of the matrix, then
                 e#   sum the results of each (ie dot product with each row) 
          @@     e# Move the resulting vector to the bottom of the stack
            f*   e# Element-wise multiplication of the scalar and the vector
              =  e# Check if the two vectors are equal

5

MATLAB, 16 bytes

@(A,v,l)A*v==v*l

Resposta bastante trivial. Define uma função anônima que recebe as entradas e calcula a igualdade entre elementos dos vetores resultantes. Um único zero em uma matriz lógica faz com que uma matriz falsey no MATLAB.


Não estava ciente da falseyness de, por exemplo [true,false], obrigado por me ensinar =)
flawr

11
@flawr Veja esta resposta de Suever (que também é aplicável ao MATLAB). Basicamente, um quase-but-não-bastante (matriz vazia []é diferente) implícita all()é chamado na entrada de if, whileetc
Sanchises

2

MATLAB, 38 bytes

function r=f(m,v,s);r=isequal(m*v,s*v)

Retorna 1 ou 0.

MATLAB, 30 bytes

function r=f(m,v,s);r=m*v==s*v

Devoluções

1
1
1

como um valor verdadeiro. Um valor falso é um vetor semelhante com qualquer ou todos os valores 0 em vez de 1.


Não conheço o MATLAB, mas a isequalfunção pode ser reduzida para ==?
HyperNeutrino 13/04

11
@HyperNeutrino isequalseria necessário se a saída exigida trueou falsemelhor que um valor de verdade ou falsey. Como o desafio está, ==é realmente suficiente.
Sanchises

@HyperNeutrino Ele retornaria um vetor contendo os resultados da comparação entre elementos dos dois vetores.
Steadybox

Oh está bem. Boa resposta embora!
HyperNeutrino 13/04

uma função anônima não seria mais curta?
Batman

2

C ++, 225 203 bytes

Agradecemos a @Cort Ammon e @Julian Wolf por salvar 22 bytes!

#import<vector>
#define F(v,i)for(i=0;i<v.size();++i)
using V=std::vector<float>;int f(std::vector<V>m,V v,float s){V p;int i,j;F(m,i){p.push_back(0);F(v,j)p[i]+=v[j]*m[i][j];}F(v,i)v[i]*=s;return v==p;}

Experimente online!


11
using std::vector;poderia tirar dois bytes disso. Custa 18 bytes, mas pode remover 4 std::s, poupando 20.
Cort Amon - Restabeleça Monica

2
melhor ainda, using V=std::vector<float>;ou similar #
Julian Wolf


2

Python 2.7, 33 bytes

f=lambda m,s,e:all(m.dot(s)==e*s)

entrada: m = matriz, s = escalar, e = valor próprio. M e s são matrizes numpy


2
Isso parece bom, mas acho que você precisa incluir a contagem de bytes import nppara que seja válida
DJMcMayhem

11
O seu anterior print(m,s,e)declaração não teria funcionado porque as variáveis m, se enão foram ainda atribuídos / definido. Além disso, você pode remover o espaço após os dois pontos. Além disso, você pode remover a parte `as n` e usar numpymais tarde; Como você o usa apenas uma vez, usar o nome completo na verdade salva um byte.
HyperNeutrino 13/04

11
OK, eu entendo agora. Obrigado pelas sugestões, espremendo cada bit :)
HonzaB

2
Não deveria ser em allvez de any? E eu acho que sé o vetor, e não o escalar, a menos que eu estou faltando alguma coisa
Luis Mendo

11
Seria ainda mais curto comparar representações de string. tio.run/nexus/python2#jZDPCoMwDIfP@hQ9tiOV/hEHgk/...
Dennis



1

R, 30 25 bytes

s=pryr::f(all(a%*%v==λ*v))

Função anônima, bastante direta. Retorna TRUEou FALSE.


0

OK, 12 bytes

{y~z%+/y*+x}

Esta é uma função que absorve [matrix;vector;scalar].

Isso não funciona em k pelas mesmas razões que 3.0~30como resultado.


O seguinte funciona em k , com 14 bytes :

{(y*z)~+/y*+x}

0

Axioma, 27 bytes

f(a,b,c)==(a*b=c*b)@Boolean

exercícios

(17) -> m:=matrix[[2,-3,-1],[1,-2,-1],[1,-3,0] ]; v:=matrix[[3],[1],[0]];
(18) -> f(m,v,1)
   (18)  true

(19) -> m:=matrix[[2,-3,-1],[1,-2,-1],[1,-3,0] ]; v:=matrix[[1],[1],[1]];
(20) -> f(m,v,-2)
   (20)  true

(21) -> m:=matrix[[1,6,3],[0,-2,0],[3,6,1] ]; v:=matrix[[1],[0],[1]];
(22) -> f(m,v,4)
   (22)  true

(23) -> m:=matrix[[1,0,-1],[-1,1,1],[1,0,0] ]; v:=matrix[[2],[1],[0]];
(24) -> f(m,v,7)
   (24)  false

(25) -> m:=matrix[[-4,3],[2,1] ]; v:=matrix[[1],[2]];
(26) -> f(m,v,2)
   (26)  true

(27) -> f(2,1,2)
   (27)  true

Eu não vi esse idioma antes, boa resposta! O que @Booleanfaz?
HyperNeutrino

(a = b) @Boolean significaria "escolher entre o operador = permitido (tipo1, tipo2) aquele cujo resultado é booleano"; em poucas palavras "a = b" tem que ser booleano
RosLuP 14/04

0

Python, 26 bytes

lambda a,b,c:c*b==a.dot(b)

ae bsão matrizes numpy, cé um número inteiro.

Experimente online!


2
As parênteses são c*brealmente necessárias?
Xnor

@xnor obrigado, corrigido.
Rɪᴋᴇʀ

Isso funciona apenas para matrizes pequenas, pois o NumPy abriga representações grandes de cadeias de caracteres da matriz.
User2357112 suporta Monica

@ user2357112 exemplo? Não sei bem o que você quer dizer.
Rɪᴋᴇʀ

Se c*btiver mais de 1000 elementos, o NumPy substituirá a maioria dos elementos por .... Demo.
User2357112 suporta Monica

0

Clojure, 60 bytes

#(=(set(map(fn[a v](apply -(* v %3)(map * a %2)))% %2))#{0})

Isso verifica se todos os deltas são zero, colapsando no conjunto de zero. Exemplo de chamada:

(def f #(=(set(map(fn[a v](apply -(* v %3)(map * a %2)))% %2))#{0}))
(f [[1 6 3][0 -2 0][3 6 1]] [1 0 1] 4)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.