This repository has been archived by the owner on Dec 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
70 lines (51 loc) · 1.79 KB
/
main.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
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/python3
import numpy as np
from time import time
EPS = 1e-3
'''
Sequential Implementation of https://doi.org/10.1007/978-3-319-11194-0_18
'''
def compute_next(mat, vec):
sigma = np.diag(vec)
sigma_inv = np.diag(1/vec)
return np.matmul(np.matmul(sigma_inv, mat), sigma)
def sum_across_rows(mat):
n = mat.shape[1]
v = np.array([np.sum(mat[i]) for i in range(n)])
return v
def stop(vec):
return all(map(lambda e: e < EPS, [abs(vec[i] - vec[i-1])
for i in range(1, len(vec))]))
def max_eigen_value_and_vector(mat):
eigen_val = 0
eigen_vec = np.ones(mat.shape[0])
itr = 0
while True:
vec = sum_across_rows(mat)
vec_max = np.max(vec)
eigen_vec = np.array([j * (vec[i]/vec_max)
for i, j in enumerate(eigen_vec)])
if stop(vec):
eigen_val = vec[0]
break
mat = compute_next(mat, vec)
itr += 1
return eigen_val, eigen_vec, itr + 1
if __name__ == '__main__':
# handwritten test begins
mat = np.array([[1, 1, 2], [2, 1, 3], [2, 3, 5]])
val, vec, _ = max_eigen_value_and_vector(mat)
assert abs(val - 7.5311) < EPS
assert abs(vec[0] - 0.3941) < EPS
assert abs(vec[1] - 0.5788) < EPS
assert abs(vec[2] - 0.9975) < EPS
# handwritten test ends
print('Sequential Similarity Transform, for finding maximum eigen value ( with vector )\n')
for dim in range(5, 11):
mat = np.random.random((1 << dim, 1 << dim))
start = time() * 1000
val, _, itr = max_eigen_value_and_vector(mat)
end = time() * 1000
assert val - np.max(np.linalg.eigvals(mat)) < EPS
print(
f'{1 << dim:<4} x {1 << dim:>4}\t\t{end - start:>6.2f} ms\t\t{itr:>8} round(s)')