행렬의 고유 값


11

정사각 행렬이 주어지면 행렬의 고유 값을 출력합니다. 각 고유 값은 대수 다중 성과 같은 횟수만큼 반복되어야합니다.

행렬의 고유 값은 일부 열 벡터의 경우 A스칼라 값 입니다. 또한의 특성 다항식의 해결책은 : ( 동일한 크기와 같이 단위 행렬이다 ).λvA*v = λ*vAdet(A - λ*I) = 0IA

출력은 유효 숫자 3 자리로 정확해야합니다. 모든 입력 및 출력은 선택한 언어의 표현 가능한 숫자 값 범위 내에 있습니다.

내장은 허용되지만 내장을 사용하지 않는 솔루션을 포함하는 것이 좋습니다.

테스트 사례

이 테스트 사례에서는 I허수 단위를 나타냅니다. 복소수는 양식으로 작성 a + b*I됩니다. 모든 출력의 유효 자릿수는 3 자리입니다.

[[42.0]] -> [42.0]
[[1.0, 0.0], [0.0, 1.0]] -> [1.00, 1.00]
[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]] -> [16.1, -1.12, -1.24e-15]
[[1.2, 3.4, 5.6, 7.8], [6.3, 0.9, -5.4, -2.3], [-12.0, -9.7, 7.3, 5.9], [-2.5, 7.9, 5.3, 4.4]] -> [7.20 + 5.54*I, 7.20 - 5.54*I, -4.35, 3.75]
[[-3.22 - 9.07*I, 0.193 + 9.11*I, 5.59 + 1.33*I, -3.0 - 6.51*I, -3.73 - 6.42*I], [8.49 - 3.46*I, -1.12 + 6.39*I, -8.25 - 0.455*I, 9.37 - 6.43*I, -6.82 + 8.34*I], [-5.26 + 8.07*I, -6.68 + 3.72*I, -3.21 - 5.63*I, 9.31 + 3.86*I, 4.11 - 8.82*I], [-1.24 + 9.04*I, 8.87 - 0.0352*I, 8.35 + 4.5*I, -9.62 - 2.21*I, 1.76 - 5.72*I], [7.0 - 4.79*I, 9.3 - 2.31*I, -2.41 - 7.3*I, -7.77 - 6.85*I, -9.32 + 2.71*I]] -> [5.18 + 16.7*I, -24.9 - 2.01*I, -5.59 - 13.8*I, 0.0438 - 10.6*I, -1.26 + 1.82*I]
[[-30.6 - 73.3*I, 1.03 - 15.6*I, -83.4 + 72.5*I, 24.1 + 69.6*I, 52.3 + 2.68*I, 23.8 + 98.0*I, 96.8 + 49.7*I, -26.2 - 5.87*I, -52.4 + 98.2*I, 78.1 + 6.69*I], [-59.7 - 66.9*I, -26.3 + 65.0*I, 5.71 + 4.75*I, 91.9 + 82.5*I, -94.6 + 51.8*I, 61.7 + 82.3*I, 54.8 - 27.8*I, 45.7 + 59.2*I, -28.3 + 78.1*I, -59.9 - 54.5*I], [-36.0 + 22.9*I, -51.7 + 10.8*I, -46.6 - 88.0*I, -52.8 - 32.0*I, -75.7 - 23.4*I, 96.2 - 71.2*I, -15.3 - 32.7*I, 26.9 + 6.31*I, -59.2 + 25.8*I, -0.836 - 98.3*I], [-65.2 - 90.6*I, 65.6 - 24.1*I, 72.5 + 33.9*I, 1.47 - 93.8*I, -0.143 + 39.0*I, -3.71 - 30.1*I, 60.1 - 42.4*I, 55.6 + 5.65*I, 48.2 - 53.0*I, -3.9 - 33.0*I], [7.04 + 0.0326*I, -12.8 - 50.4*I, 70.1 - 30.3*I, 42.7 - 76.3*I, -3.24 - 64.1*I, 97.3 + 66.8*I, -11.0 + 16.5*I, -40.6 - 90.7*I, 71.5 - 26.2*I, 83.1 - 49.4*I], [-59.5 + 8.08*I, 74.6 + 29.1*I, -65.8 + 26.3*I, -76.7 - 83.2*I, 26.2 + 99.0*I, -54.8 + 33.3*I, 2.79 - 16.6*I, -85.2 - 3.64*I, 98.4 - 12.4*I, -27.6 - 62.3*I], [82.6 - 95.3*I, 55.8 - 73.6*I, -49.9 + 42.1*I, 53.4 + 16.5*I, 80.2 - 43.6*I, -43.3 - 3.9*I, -2.26 - 58.3*I, -19.9 + 98.1*I, 47.2 + 62.4*I, -63.3 - 54.0*I], [-88.7 + 57.7*I, 55.6 + 70.9*I, 84.1 - 52.8*I, 71.3 - 29.8*I, -3.74 - 19.6*I, 29.7 + 1.18*I, -70.6 - 10.5*I, 37.6 + 99.9*I, 87.0 + 19.0*I, -26.1 - 82.0*I], [69.5 - 47.1*I, 11.3 - 59.0*I, -84.3 - 35.1*I, -3.61 - 35.7*I, 88.0 + 88.1*I, -47.5 + 0.956*I, 14.1 + 89.8*I, 51.3 + 0.14*I, -78.5 - 66.5*I, 2.12 - 53.2*I], [0.599 - 71.2*I, 21.7 + 10.8*I, 19.9 - 97.1*I, 20.5 + 37.4*I, 24.7 + 40.6*I, -82.7 - 29.1*I, 77.9 + 12.5*I, 94.1 - 87.4*I, 78.6 - 89.6*I, 82.6 - 69.6*I]] -> [262. - 180.*I, 179. + 117.*I, 10.3 + 214.*I, 102. - 145.*I, -36.5 + 97.7*I, -82.2 + 89.8*I, -241. - 104.*I, -119. - 26.0*I, -140. - 218.*I, -56.0 - 160.*I]



관련 ? 아마 관련 ? (접근 방식에 따라 다름)
user202729

답변:


12

하스켈 , 576554532507 바이트

내장 기능이 없습니다!

import Data.Complex
s=sum
l=length
m=magnitude
i=fromIntegral
(&)=zip
t=zipWith
(x!a)b=x*a+b
a#b=[[s$t(*)x y|y<-foldr(t(:))([]<$b)b]|x<-a]
f a|let c=[1..l a];g(u,d)k|m<-[t(+)a b|(a,b)<-a#u&[[s[d|x==y]|y<-c]|x<-c]]=(m,-s[s[b|(n,b)<-c&a,n==m]|(a,m)<-a#m&c]/i k)=snd<$>scanl g(0<$c<$c,1)c
p?x|let f=foldl1(x!);c=l p-1;n=i c;q p=init$t(*)p$i<$>[c,c-1..];o=f(q p)/f p;a|d<-sqrt$(n-1)*(n*(o^2-f(q$q p)/f p)-o^2)=n/last(o-d:[o+d|m(o-d)<m(o+d)])=last$p?(x-a):[x|m a<1e-9]
z[a,b]=[-b/a]
z p=p?0:z(init$scanl1(p?0!)p)

온라인으로 사용해보십시오!

총 -47 바이트에 대해 @ ØrjanJohansen에게 감사드립니다!

설명

먼저 이것은 함수 인 Faddeev–LeVerrier 알고리즘으로 특성 다항식을 계산합니다 f. 그런 다음이 함수 는 루트를 찾기위한 Laguerre의 방법 을 구현 z하는 반복 g을 통해 해당 다항식의 모든 루트를 계산합니다 . 루트가 발견되면 루트가 제거되고 다항식이 차수가 1이 될 때까지 다시 호출됩니다 .gz[a,b]=[-b/a]

언 골프

나는 기능 - 인라인 재 sum, length, magnitude, fromIntegral, zipWith(&)뿐만 아니라 작은 도우미 (!). 함수 faddeevLeVerrier에 대응하는 f, rootszglaguerre각각.

-- Transpose a matrix/list
transpose a = foldr (zipWith(:)) (replicate (length a) []) a

-- Straight forward implementation for matrix-matrix multiplication
(#) :: [[Complex Double]] -> [[Complex Double]] -> [[Complex Double]]
a # b = [[sum $ zipWith (*) x y | y <- transpose b]|x<-a]


-- Faddeev-LeVerrier algorithm
faddeevLeVerrier :: [[Complex Double]] -> [Complex Double]
faddeevLeVerrier a = snd <$> scanl go (zero,1) [1..n]
  where n = length a
        zero = replicate n (replicate n 0)
        trace m = sum [sum [b|(n,b)<-zip [1..n] a,n==m]|(m,a)<-zip [1..n] m]
        diag d = [[sum[d|x==y]|y<-[1..n]]|x<-[1..n]]
        add as bs = [[x+y | (x,y) <- zip a b] | (b,a) <- zip as bs]
        go (u,d) k = (m, -trace (a#m) / fromIntegral k)
          where m = add (diag d) (a#u)


-- Compute roots by succesively removing newly computed roots
roots :: [Complex Double] -> [Complex Double]
roots [a,b] = [-b/a]
roots   p   = root : roots (removeRoot p)
  where root = laguerre p 0
        removeRoot = init . scanl1 (\a b -> root*a + b)

-- Compute a root of a polynomial p with an initial guess x
laguerre :: [Complex Double] -> Complex Double -> Complex Double
laguerre p x = if magnitude a < 1e-9 then x else laguerre p new_x
  where evaluate = foldl1 (\a b -> x*a+b)
        order' = length p - 1
        order  = fromIntegral $ length p - 1
        derivative p = init $ zipWith (*) p $ map fromIntegral [order',order'-1..]
        g  = evaluate (derivative p) / evaluate p
        h  = (g ** 2 - evaluate (derivative (derivative p)) / evaluate p)
        d  = sqrt $ (order-1) * (order*h - g**2)
        ga = g - d
        gb = g + d
        s = if magnitude ga < magnitude gb then gb else ga
        a = order /s
        new_x = x - a

1
빌트인을 사용하지 않는 유일한 제출물로, 가장 투표가 많은 답변이어야합니다.
Esolanging 과일

보다 뭔가 관련 - 투 - 결정 시간을 계산하기위한 하나 n!!
user202729

고마워요! @ user202729 : 처음에는 내가 감독했고 !정말 혼란 스러웠습니다. : D
ბიბო

6

옥타브 , 4 바이트

@eig

온라인으로 사용해보십시오!

MATL 골프 언어에 비해 2 바이트 만 더!

eig내장 함수에 대한 익명 함수 핸들을 정의합니다 . 흥미롭게도 MATLAB 디자인 철학은 사용하려는 많은 고급 언어에 반하는 DescripteFunctionNamesTakingArguments()반면 MATLAB과 결과적으로 Octave는 가능한 가장 짧은 기능 명을 얻는 경향이 있습니다. 예를 들어 고유 값 소 집합 (예 : n절대 크기 가 가장 작은 )을 얻으려면 을 사용 eigs합니다.

보너스로, 여기에 solve내장 기능을 사용하지 않고 대신 고유 값 문제를 해결 det(A-λI)=0하고 변환 하는 함수 (MATLAB에서 작동하고 이론적으로 Octave에서는 작동하지만 실제로는 작업에 달려 있지 않습니다)가 있습니다. 를 사용하여 숫자 형태로vpa

@(A)vpa(solve(det(A-sym('l')*eye(size(A)))))

3

MATL , 2 바이트

Yv

온라인으로 사용해보십시오!

설명

나는 수치 선형 대수에서 일반적인 조언을 따랐습니다. 자신의 함수를 작성하는 대신 수치 불안정성을 피하기 위해 특별히 설계된 내장 기능을 사용하십시오.

또한 짧습니다. ¯ \ _ (ツ) _ / ¯


이것은 질문이 얼마나 오래 걸립 Yv니까?
Sanchises

@Sanchises 확실하지 않습니다. 나는 아마도 ZQ다항식 의 근 ( )을 찾아서 그것에 대해 갈 것입니다 . 그러나 다항식의 계수를 명시 적으로 계산하는 것은 많은 작업이 될 수 있습니다.
Luis Mendo

2

수학, 11 바이트

Eigenvalues

온라인으로 사용해보십시오!


예, "이 질문에 대한 새로운 답변 1 개"를 클릭하기 전에 내장 답변이 필요했습니다. 내장되지 않은 답변을 기다리 자 ... / 기본적으로 Mathematica 솔루션은 종종 <제목의 첫 단어>
user202729

내가 얻은 가장 짧은 비 순수 내장은 First@Eigensystem@#&(20 바이트)
Mr. Xcoder

7
나는 실제로 여기 user202729에 동의합니다. Mathematica가 모든 것을 위해 내장되어 있다는 것은 농담이지만, 챌린지 포스터로서 매우 성가시다. 골프 (IMO)는 상기 알고리즘의 가장 짧은 알고리즘 및 구현을 찾으려고 시도하지만 내장 된 답변은 "스포츠"에서 멀어지게합니다.
caird coinheringaahing

2
@cairdcoinheringaahing xnor의 제안을 실제로 실천 하기 시작해야한다 .
Martin Ender

1

R , 22 바이트

function(m)eigen(m)$va

온라인으로 사용해보십시오!

걸리는 m행렬로. 답답하게 eigenR 의 함수는 , 고유 값과 고유 벡터 eigen라는 두 개의 필드가있는 class의 객체를 반환합니다 .valuesvectors

그러나 더 짜증나게, 선택적 인수 only.values는 고유 값을 포함하는, 및 로 설정된 list두 개의 필드와 함께를 반환 하지만 22 바이트이므로 워시입니다.valuesvectorsNULLeigen(m,,T)



0

파이썬 + numpy, 33 바이트

from numpy.linalg import*
eigvals

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.