Решить 2x2 Eigensystem

11

Для тех, у кого небольшой фон линейной алгебры, задача настолько проста: определить собственные значения и собственные векторы заданной сложной матрицы 2x2. Вы можете перейти к разделу The Challenge, чтобы узнать подробности ввода / вывода и т. Д. Если вам нужно немного освежить в eigensystems, читайте дальше.

Фон

Характеристическое уравнение матричного А определяется

det| A - λI | = 0

где λ - комплексный (скалярный) параметр, I - единичная матрица, а det | ... | это определитель . В левой части вычисляется многочлен от λ , характеристический многочлен , который является квадратичным в случае матриц 2x2. Решения этого характеристического уравнения на собственные значения из А , который мы будем обозначать λ 1 и λ 2 .

Теперь собственные векторы v i из A удовлетворяют

A vi = λi vi

Для каждого λ i это дает систему из двух уравнений с двумя неизвестными (составляющими v i ), которая может быть решена довольно легко. Вы заметите, что система на самом деле не указана, и величина собственных векторов не определяется уравнениями. Обычно мы хотим, чтобы собственные векторы были нормализованы, то есть √ (| x | 2 + | y ​​| 2 ) = 1 , где x и y - компоненты вектора, | x | 2 является х , умноженные на комплексно сопряженное.

Обратите внимание, что собственные значения могут быть вырожденными, то есть λ 1 = λ 2 . В этом случае вы можете или не сможете удовлетворить единую систему уравнений с двумя линейно независимыми собственными векторами.

Соревнование

Учитывая матрицу 2x2 со сложными элементами, определите ее два (возможно, идентичных) собственных значения и нормализованный собственный вектор для каждого собственного значения. Результирующие числа должны быть с точностью не менее 3 (десятичных) значащих цифр. Можно предположить, что действительная и мнимая части любого матричного элемента находятся в диапазоне [-1,1] .

Вы можете написать функцию или программу, используя ввод через STDIN, аргумент командной строки, приглашение или аргумент функции. Вы можете вывести результат в STDOUT, в диалоговое окно или в качестве возвращаемого значения функции.

Вы можете использовать любую удобную (но однозначную) строку или формат списка для ввода и вывода. Вы также можете выбирать между парами чисел с плавающей точкой или сложных типов для представления отдельных чисел.

Вы не должны использовать встроенные функции для решения собственных систем (таких как Mathematica Eigenvectorsили Eigensystem) или решения уравнений.

Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.

Примеры

Каждый пример состоит из трех строк: входные данные, собственные значения и соответствующие собственные векторы в одинаковом порядке. Отметим, что собственные векторы определяются только до их фазы, и что в случае вырожденных собственных значений собственные векторы могут фактически быть произвольными (как в первом примере).

[[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]]
Мартин Эндер
источник

Ответы:

6

МАТЛАБ, 91

Стандартная методика получения нормализованного вектора и удаления бесполезной степени свободы представляет элементы вектора как косинус и синус некоторого угла.

Первоначально я пытался писать код на Python, но его математическая обработка оказалась слишком поврежденной. Его математические функции отказались принимать комплексные значения, и он не понимает, что деление с плавающей точкой на ноль в порядке.

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

Сначала два собственных значения печатаются под заголовком L =. Затем два вектора столбцов печатаются под соответствующими значениями L, под v =. Код может не дать линейно независимые векторы в тех случаях, когда это возможно (такая программа обычно считается неработающей), но Мартин сказал, что это не требуется.

feersum
источник
8

Python 2, 198 байт

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

Ввод представляет собой простой список из 4 комплексных чисел через STDIN, например,

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

Обратите внимание, что Python использует jвместо iкомплексных чисел.

Выходными данными являются два списка, первый из которых содержит собственные значения, а второй - из собственных векторов, например

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

(новая строка вставлена ​​для ясности)

Sp3000
источник
3

Lua, 462 455 431 427 байт

В Lua нет встроенной сложной математики. Никаких векторных операций тоже нет. Все пришлось катить вручную.

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

Запустите из командной строки со следующими аргументами:

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

Производит следующий вывод:

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

... для a, b, c, d 4 компонента входной матрицы, лямбда1 и лямбда2, два собственных значения, v11, v21, собственный вектор первого блока, и v12, v22, собственный вектор второго блока. Например,

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

... производит ...

1.6180339887499 0   -0.61803398874989   0
0.85065080835204    0   -0.52573111211913   0   0.52573111211913    0   0.85065080835204    0
thenumbernine
источник