/
tc_eigensystem.rb
85 lines (73 loc) · 2.33 KB
/
tc_eigensystem.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#
# Copyright (c) 2004-2008 by James M. Lawrence
#
# See LICENSE
#
require 'linalg-test'
#
# isomorphism C <--> M2(R)
#
# a + ib <--> [a -b]
# [b a]
#
def isomorphic_complex(a, b = nil)
c = DMatrix.new(2*a.vsize, 2*a.hsize)
a.each_index { |i, j|
c[2*i, 2*j ] = a[i,j]
c[2*i + 1, 2*j + 1] = a[i,j]
if b
c[2*i, 2*j + 1] = -b[i,j]
c[2*i + 1, 2*j ] = b[i,j]
end
}
c
end
class TestEigensystem < Test::Unit::TestCase
def test_raise
($count/6).times {
a = DMatrix.new(n = $dim/2 + rand($dim/2), n + 1 + rand($dim/2 - 1))
assert_raises(DimensionError) { a.eigensystem { } }
a = DMatrix.new(n = $dim + rand($dim), n - 1 - rand($dim/2 - 1))
assert_raises(DimensionError) { a.eigensystem { } }
}
end
def test_eigensystem
($count/4).times {
dim = 1 + rand($dim)
a = DMatrix.rand(dim, dim)
begin
eigs, real, imag = a.eigensystem
a_c = isomorphic_complex(a)
lambda_re = DMatrix.diagonal(dim) { |i| real[i] }
lambda_im = DMatrix.diagonal(dim) { |i| imag[i] }
lambda_c = isomorphic_complex(lambda_re, lambda_im)
eigs_list = []
j = 0
while j < dim
if imag[j] == 0.0
eigs_list.push isomorphic_complex(eigs.column(j))
j += 1
else
assert_equal(real[j], real[j+1])
assert_equal(imag[j], -imag[j+1])
eigs_list.push isomorphic_complex(eigs.column(j),
eigs.column(j+1))
eigs_list.push isomorphic_complex(eigs.column(j),
-eigs.column(j+1))
j += 2
end
end
eigs_c = DMatrix.new(2*dim, 2*dim)
eigs_list.each_with_index { |c, jj|
eigs_c.replace_minor(0, 2*jj, c)
}
assert_close(a_c*eigs_c, eigs_c*lambda_c)
real2, imag2 = a.eigenvalues
assert_close(real, real2)
assert_close(imag, imag2)
rescue Diverged
puts "\nnote: divergent eigensystem:\n#{a.inspect}"
end
}
end
end