-
-
Notifications
You must be signed in to change notification settings - Fork 46.6k
/
Copy pathrayleigh_quotient_iteration.py
57 lines (46 loc) · 1.65 KB
/
rayleigh_quotient_iteration.py
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
from typing import Tuple
import numpy as np
def rayleigh_quotient_iteration(
input_matrix: np.array,
vector: np.array,
value: float,
error_tol=1e-12,
max_iterations=100,
) -> Tuple[float, np.array]:
"""
https://en.wikipedia.org/wiki/Rayleigh_quotient_iteration
Rayleigh quotient iteration
Find an approximate eigenvector and eigenvalue of the input matrix. Which
eigenvalue, eigenvector pair is found depends on the vector and value
input. Has very rapid convergence.
>>> import numpy as np
>>> input_matrix = np.array([
... [41, 4, 20],
... [ 4, 26, 30],
... [20, 30, 50]
... ])
>>> vector = np.array([1, 1, 1])
>>> value = 30
>>> rayleigh_quotient_iteration(input_matrix, vector, value)
(33.60344292195729, array([-0.86306005, 0.45012643, 0.22915836]))
>>> value = 1
>>> rayleigh_quotient_iteration(input_matrix, vector, value)
(3.735693290153355, array([-0.23946876, -0.7641015 , 0.59900218]))
"""
N = len(input_matrix)
error = error_tol + 1
prev_eigenvalue = value
iterations = 0
while error > error_tol and iterations < max_iterations:
# Construct the iterating matrix
A = np.linalg.inv(input_matrix - np.eye(N) * value)
# Construct new eigenvector
vector = np.dot(A, vector)
# Normalize new eigenvector
vector = vector / np.linalg.norm(vector)
# Construct better approximation for eigenvalue
value = np.dot(np.conj(vector).T, np.dot(input_matrix, vector))
error = abs(value - prev_eigenvalue)
prev_eigenvalue = value
iterations += 1
return value, vector