Solve a 2x2 Eigensystem
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]]
Input is a flat list of 4 complex numbers via STDIN, e.g.
[0.0+0j, 0.4+0j, -0.1+0j, -0.4+0j]
Note that Python uses j
instead of i
for complex numbers.
Output is two lists, the first containing the eigenvalues and the second containing the eigenvectors, e.g.
[(-0.2+0j), (-0.2+0j)]
[[(0.8944271909999159+0j), (-0.4472135954999579+0j)], [(0.8944271909999159+0j), (-0.4472135954999579+0j)]]
(newline inserted for clarity)
MATLAB, 91
A standard technique to obtain a normalized vector and remove the useless degree of freedom is representing the elements of the vector as the cosine and sine of some angle.
I originally tried to code in Python, but its math handling proved to be too brain-damaged. Its math functions refused to accept complex values, and it does not understand that floating-point division by zero is OK.
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)]
First the two eigenvalues are printed under the heading L =
. Then two column vectors are printed under the corresponding values of L, under v =
. The code may fail to give linearly independent vectors in cases where it is possible to do so (such a program normally would be considered broken), but Martin said it is not required.
Lua, 462 455 431 427 bytes
There is no built-in complex math in Lua. No vector operations either. All had to be rolled by hand.
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
Run from the command-line with the following arguments:
lua eigen.lua Re(a) Im(a) Re(b) Im(b) Re(c) Im(c) Re(d) Im(d)
Produces the following output:
Re(lambda1) Im(lambda1) Re(lambda2) Im(lambda2)
Re(v11) Im(v11) Re(v12) Im(v12) Re(v21) Im(v21) Re(v22) Im(v22)
...for a,b,c,d the 4 components of the input matrix, lambda1 and lambda2 the two eigenvalues, v11,v21 the first unit eigenvector, and v12,v22 the second unit eigenvector. For example,
lua eigen.lua 1 0 1 0 1 0 0 0
...produces...
1.6180339887499 0 -0.61803398874989 0
0.85065080835204 0 -0.52573111211913 0 0.52573111211913 0 0.85065080835204 0