Resuelve un Eigensystem 2x2

11

Para aquellos con un poco de fondo de álgebra lineal, el desafío es tan simple como esto: determinar los valores propios y los vectores propios de una matriz compleja de 2x2 dada. Puede pasar al Reto para obtener detalles de E / S, etc. Para aquellos que necesitan un poco de actualización sobre eigensystems, siga leyendo.

Antecedentes

La ecuación característica de una matriz A se define por

det| A - λI | = 0

donde λ es un parámetro complejo (escalar), I es la matriz de identidad y det | ... | Es el determinante . El lado izquierdo se evalúa como un polinomio en λ , el polinomio característico , que es cuadrático en el caso de matrices de 2x2. Las soluciones de esta ecuación característica son los valores propios de A , que denotaremos como λ 1 y λ 2 .

Ahora los vectores propios v i de A satisfacen

A vi = λi vi

Para cada λ i , esto le proporciona un sistema de dos ecuaciones en dos incógnitas (los componentes de v i ), que se pueden resolver con bastante facilidad. Notará que el sistema está realmente subespecificado, y la magnitud de los vectores propios no está determinada por las ecuaciones. Por lo general, queremos que los vectores propios se normalicen, es decir √ (| x | 2 + | y ​​| 2 ) = 1 , donde x e y son los componentes del vector, | x | 2 es x multiplicado por su complejo conjugado.

Tenga en cuenta que los valores propios pueden ser degenerados, es decir, λ 1 = λ 2 . En este caso, puede o no ser capaz de satisfacer el único sistema de ecuaciones con dos vectores propios linealmente independientes.

El reto

Dada una matriz de 2x2 con elementos complejos, determine sus dos valores propios (posiblemente idénticos) y un vector propio normalizado para cada valor propio. Los números resultantes deben tener una precisión de al menos 3 dígitos (decimales) significativos. Puede suponer que las partes reales e imaginarias de cualquier elemento de la matriz están en el rango [-1,1] .

Puede escribir una función o un programa, tomando datos a través de STDIN, argumento de línea de comando, indicador de solicitud o argumento de función. Puede enviar el resultado a STDOUT, un cuadro de diálogo o como el valor de retorno de la función.

Puede usar cualquier cadena conveniente (pero no ambigua) o formato de lista para entrada y salida. También puede elegir entre pares de flotadores o tipos complejos para representar los números individuales.

No debe usar funciones integradas para resolver sistemas propios (como Mathematica Eigenvectorso Eigensystem) o solucionadores de ecuaciones.

Este es el código de golf, por lo que gana la respuesta más corta (en bytes).

Ejemplos

Cada ejemplo tiene tres líneas: la entrada, los valores propios y los vectores propios correspondientes en el mismo orden. Tenga en cuenta que los vectores propios solo se determinan hasta su fase, y que en el caso de valores propios degenerados, los vectores propios pueden ser realmente arbitrarios (como en el primer ejemplo).

[[1.0, 0.0], [0.0, 1.0]]
[1.0, 1.0]
[[1.0, 0.0], [0.0, 1.0]]

[[0.0, 0.4], [-0.1, -0.4]]
[-0.2, -0.2]
[[0.894427, -0.447214], [0.894427, -0.447214]]

[[0.3, 0.1], [0.4, -0.9]]
[-0.932456, 0.332456]
[[-0.0808731, 0.996724], [0.951158, 0.308703]]

[[0.5, -1.0], [0.8, -0.5]]
[0.74162i, - 0.74162i]
[[0.745356, 0.372678 - 0.552771i], [0.745356, 0.372678 + 0.552771i]]

[[-0.0539222 + 0.654836i, -0.016102 + 0.221334i], [0.739514 - 0.17735i, -0.0849216 + 0.77977i]]
[0.238781 + 0.984333i, -0.377625 + 0.450273i]
[[0.313668 + 0.322289i, 0.893164], [-0.236405 - 0.442194i, 0.865204]]

[[-0.703107 - 0.331792i, 0.286719 - 0.587305i], [-0.418476 + 0.396347i, -0.885934 + 0.50534i]]
[-1.13654 - 0.32678i, -0.4525 + 0.500329i]
[[0.833367, -0.248208 - 0.493855i], [-0.441133 - 0.408236i, 0.799215]]

[[-0.156312 + 0.788441i, 0.045056 - 0.579167i], [0.130741 - 0.97017i, 0.049183 - 0.590768i]]
[-0.181759 + 1.11738i, 0.0746298 - 0.919707i]
[[0.86955, -0.493846 + 0.000213145i], [0.318856 - 0.0181135i, 0.94763]]
Martin Ender
fuente

Respuestas:

6

MATLAB, 91

Una técnica estándar para obtener un vector normalizado y eliminar el grado inútil de libertad es representar los elementos del vector como el coseno y el seno de algún ángulo.

Originalmente intenté codificar en Python, pero su manejo matemático resultó ser demasiado dañino para el cerebro. Sus funciones matemáticas se negaron a aceptar valores complejos, y no comprende que la división de coma flotante por cero esté bien.

function[]=f(a,b,c,d)
L=(a+d+[1,-1]*((a-d)^2+4*b*c)^.5)/2
t=atan((L-a)/b);v=[cos(t);sin(t)]

Primero se imprimen los dos valores propios debajo del encabezado L =. Luego se imprimen dos vectores de columna bajo los valores correspondientes de L, debajo v =. Es posible que el código no proporcione vectores linealmente independientes en los casos en que sea posible hacerlo (dicho programa normalmente se consideraría roto), pero Martin dijo que no es obligatorio.

Feersum
fuente
8

Python 2, 198 bytes

a,b,c,d=input()
H=(a+d)/2
D=(H*H-a*d+b*c)**.5
X,Y=H+D,H-D
p,q,r,s=[[1,0,0,1],[b,X-a,b,Y-a],[X-d,c,Y-d,c]][2*(c!=0)or(b!=0)]
A=abs
V=A(A(p)+A(q)*1j)
W=A(A(r)+A(s)*1j)
print[X,Y],[[p/V,q/V],[r/W,s/W]]

La entrada es una lista plana de 4 números complejos a través de STDIN, p. Ej.

[0.0+0j, 0.4+0j, -0.1+0j, -0.4+0j]

Tenga en cuenta que Python usa en jlugar de inúmeros complejos.

La salida es dos listas, la primera que contiene los valores propios y la segunda que contiene los vectores propios, p. Ej.

[(-0.2+0j), (-0.2+0j)]
[[(0.8944271909999159+0j), (-0.4472135954999579+0j)], [(0.8944271909999159+0j), (-0.4472135954999579+0j)]]

(nueva línea insertada para mayor claridad)

Sp3000
fuente
3

Lua, 462 455 431 427 bytes

No hay matemáticas complejas integradas en Lua. No hay operaciones de vectores tampoco. Todo tuvo que ser rodado a mano.

a,b,c,d,e,f,g,h=...x=math.sqrt z=print i=a-g j=b-h
k=(i^2-j^2)/2+2*(c*e-d*f)m=x(k^2+(i*j+2*(c*f+d*e))^2)n=x(m+k)o=x(m-k)i=(a+g+n)/2
j=(b+h+o)/2 k=(a+g-n)/2 l=(b+h-o)/2 z(i,j,k,l)q=c^2+d^2 r=e^2+f^2 s=q+r if s==0
then z(1,0,0,0,0,0,1,0)else if r==0 then m,n,o,p=c,d,c,d c,d=i-a,j-b e,f=k-a,l-b
u=x(q+c^2+d^2)v=x(q+e^2+f^2)else m,n=i-g,j-h o,p=k-g,l-h c,d=e,f
u=x(r+m^2+n^2)v=x(r+o^2+p^2)end z(m/u,n/u,o/v,p/v,c/u,d/u,e/v,f/v)end

Ejecute desde la línea de comandos con los siguientes argumentos:

lua eigen.lua Re(a) Im(a) Re(b) Im(b) Re(c) Im(c) Re(d) Im(d)

Produce el siguiente resultado:

Re(lambda1) Im(lambda1) Re(lambda2) Im(lambda2)
Re(v11) Im(v11) Re(v12) Im(v12) Re(v21) Im(v21) Re(v22) Im(v22)

... para a, b, c, d los 4 componentes de la matriz de entrada, lambda1 y lambda2 los dos valores propios, v11, v21 el vector propio de la primera unidad, y v12, v22 el vector propio de la segunda unidad. Por ejemplo,

lua eigen.lua 1 0  1 0  1 0  0 0

... produce ...

1.6180339887499 0   -0.61803398874989   0
0.85065080835204    0   -0.52573111211913   0   0.52573111211913    0   0.85065080835204    0
thenumbernine
fuente