Résoudre un Eigensystem 2x2

11

Pour ceux qui ont un petit fond d'algèbre linéaire, le défi est aussi simple que cela: déterminer les valeurs propres et les vecteurs propres d'une matrice 2x2 complexe donnée. Vous pouvez passer directement au défi pour les détails des E / S, etc.

Contexte

L' équation caractéristique d'une matrice A est définie par

det| A - λI | = 0

λ est un paramètre complexe (scalaire), I est la matrice d'identité et det | ... | est le déterminant . Le côté gauche correspond à un polynôme en λ , le polynôme caractéristique , qui est quadratique dans le cas de matrices 2x2. Les solutions de cette équation caractéristique sont les valeurs propres de A , que nous désignerons comme λ 1 et λ 2 .

Maintenant, les vecteurs propres v i de A satisfont

A vi = λi vi

Pour chaque λ i , cela vous donne un système de deux équations à deux inconnues (les composantes de v i ), qui peuvent être résolues assez facilement. Vous remarquerez que le système est en fait sous-spécifié et que la magnitude des vecteurs propres n'est pas déterminée par les équations. Nous voulons généralement que les vecteurs propres soient normalisés, c'est-à-dire √ (| x | 2 + | y ​​| 2 ) = 1 , où x et y sont les composantes vectorielles, | x | 2 est x multiplié par son conjugué complexe.

Notez que les valeurs propres peuvent être dégénérées, c'est-à-dire λ 1 = λ 2 . Dans ce cas, vous pouvez ou non être en mesure de satisfaire le système unique d'équations avec deux vecteurs propres linéairement indépendants.

Le défi

Étant donné une matrice 2x2 avec des éléments complexes, déterminez ses deux valeurs propres (éventuellement identiques) et un vecteur propre normalisé pour chaque valeur propre. Les nombres résultants doivent être précis à au moins 3 chiffres décimaux (décimaux). Vous pouvez supposer que les parties réelles et imaginaires de n'importe quel élément de matrice sont dans la plage [-1,1] .

Vous pouvez écrire une fonction ou un programme, en prenant une entrée via STDIN, un argument de ligne de commande, une invite ou un argument de fonction. Vous pouvez exporter le résultat vers STDOUT, une boîte de dialogue ou comme valeur de retour de fonction.

Vous pouvez utiliser n'importe quelle chaîne ou format de liste pratique (mais sans ambiguïté) pour l'entrée et la sortie. Vous pouvez également choisir entre des paires de flotteurs ou des types complexes pour représenter les nombres individuels.

Vous ne devez pas utiliser de fonctions intégrées pour résoudre des systèmes électroniques (comme Mathematica Eigenvectorsou Eigensystem) ou des solveurs d'équations.

Il s'agit du code golf, donc la réponse la plus courte (en octets) l'emporte.

Exemples

Chaque exemple est composé de trois lignes: l'entrée, les valeurs propres et les vecteurs propres correspondants dans le même ordre. Notez que les vecteurs propres ne sont déterminés que jusqu'à leur phase, et que dans le cas de valeurs propres dégénérées, les vecteurs propres peuvent en fait être arbitraires (comme dans le premier exemple).

[[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
la source

Réponses:

6

MATLAB, 91

Une technique standard pour obtenir un vecteur normalisé et supprimer le degré de liberté inutile consiste à représenter les éléments du vecteur comme le cosinus et le sinus d'un certain angle.

J'ai d'abord essayé de coder en Python, mais sa gestion mathématique s'est avérée trop endommagée au cerveau. Ses fonctions mathématiques ont refusé d'accepter des valeurs complexes et il ne comprend pas que la division en virgule flottante par zéro soit 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)]

Les deux valeurs propres sont d'abord imprimées sous le titre L =. Ensuite, deux vecteurs de colonne sont imprimés sous les valeurs correspondantes de L, sous v =. Le code peut ne pas donner de vecteurs linéairement indépendants dans les cas où il est possible de le faire (un tel programme serait normalement considéré comme défectueux), mais Martin a déclaré qu'il n'était pas requis.

feersum
la source
8

Python 2, 198 octets

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]]

L'entrée est une liste plate de 4 nombres complexes via STDIN, par exemple

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

Notez que Python utilise jau lieu de ipour les nombres complexes.

La sortie est deux listes, la première contenant les valeurs propres et la seconde contenant les vecteurs propres, par exemple

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

(nouvelle ligne insérée pour plus de clarté)

Sp3000
la source
3

Lua, 462 455 431 427 octets

Il n'y a pas de mathématiques complexes intégrées dans Lua. Aucune opération vectorielle non plus. Tout devait être roulé à la main.

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

Exécutez à partir de la ligne de commande avec les arguments suivants:

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

Produit la sortie suivante:

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

... pour a, b, c, d les 4 composantes de la matrice d'entrée, lambda1 et lambda2 les deux valeurs propres, v11, v21 le premier vecteur propre d'unité et v12, v22 le deuxième vecteur propre d'unité. Par exemple,

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

... produit ...

1.6180339887499 0   -0.61803398874989   0
0.85065080835204    0   -0.52573111211913   0   0.52573111211913    0   0.85065080835204    0
l'umbumbine
la source