method
diagonalize
v2_4_6 -
Show latest stable
- Class:
Matrix::EigenvalueDecomposition
diagonalize()private
Symmetric tridiagonal QL algorithm.
# File lib/matrix/eigenvalue_decomposition.rb, line 234
def diagonalize
# This is derived from the Algol procedures tql2, by
# Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
# Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
# Fortran subroutine in EISPACK.
1.upto(@size-1) do |i|
@e[i-1] = @e[i]
end
@e[@size-1] = 0.0
f = 0.0
tst1 = 0.0
eps = Float::EPSILON
@size.times do |l|
# Find small subdiagonal element
tst1 = [tst1, @d[l].abs + @e[l].abs].max
m = l
while (m < @size) do
if (@e[m].abs <= eps*tst1)
break
end
m+=1
end
# If m == l, @d[l] is an eigenvalue,
# otherwise, iterate.
if (m > l)
iter = 0
begin
iter = iter + 1 # (Could check iteration count here.)
# Compute implicit shift
g = @d[l]
p = (@d[l+1] - g) / (2.0 * @e[l])
r = Math.hypot(p, 1.0)
if (p < 0)
r = -r
end
@d[l] = @e[l] / (p + r)
@d[l+1] = @e[l] * (p + r)
dl1 = @d[l+1]
h = g - @d[l]
(l+2).upto(@size-1) do |i|
@d[i] -= h
end
f += h
# Implicit QL transformation.
p = @d[m]
c = 1.0
c2 = c
c3 = c
el1 = @e[l+1]
s = 0.0
s2 = 0.0
(m-1).downto(l) do |i|
c3 = c2
c2 = c
s2 = s
g = c * @e[i]
h = c * p
r = Math.hypot(p, @e[i])
@e[i+1] = s * r
s = @e[i] / r
c = p / r
p = c * @d[i] - s * g
@d[i+1] = h + s * (c * g + s * @d[i])
# Accumulate transformation.
@size.times do |k|
h = @v[k][i+1]
@v[k][i+1] = s * @v[k][i] + c * h
@v[k][i] = c * @v[k][i] - s * h
end
end
p = -s * s2 * c3 * el1 * @e[l] / dl1
@e[l] = s * p
@d[l] = c * p
# Check for convergence.
end while (@e[l].abs > eps*tst1)
end
@d[l] = @d[l] + f
@e[l] = 0.0
end
# Sort eigenvalues and corresponding vectors.
0.upto(@size-2) do |i|
k = i
p = @d[i]
(i+1).upto(@size-1) do |j|
if (@d[j] < p)
k = j
p = @d[j]
end
end
if (k != i)
@d[k] = @d[i]
@d[i] = p
@size.times do |j|
p = @v[j][i]
@v[j][i] = @v[j][k]
@v[j][k] = p
end
end
end
end Related methods
- Instance methods
- d
- eigenvalue_matrix
- eigenvalues
- eigenvector_matrix
- eigenvector_matrix_inv
- eigenvectors
- to_a
- to_ary
- v
- v_inv
- Class methods
- new
- Private methods
-
build_eigenvectors -
cdiv -
diagonalize -
hessenberg_to_real_schur -
reduce_to_hessenberg -
tridiagonalize