-
Notifications
You must be signed in to change notification settings - Fork 4
/
qr.py
68 lines (50 loc) · 1.61 KB
/
qr.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
# qr.py : QR分解法
import numpy as np
import scipy.linalg as sclinalg
# 時間計測
import time
# QR分解法
def qr(mat_a, rtol, atol, max_times):
row_dim, col_dim = mat_a.shape
if row_dim != col_dim:
return 0, 0
dim = row_dim
rq = mat_a
old_diagonal = np.array([mat_a[i, i] for i in range(dim)])
# メインループ
for times in range(max_times):
# QR分解
q, r = sclinalg.qr(rq, pivoting=False)
# RQ生成
rq = r @ q
if times % 10 == 0:
print('times = ', times)
print(rq)
new_diagonal = np.array([rq[i, i] for i in range(dim)])
diff_diagonal = new_diagonal - old_diagonal
# 収束判定
if np.linalg.norm(diff_diagonal) <= (rtol * np.linalg.norm(new_diagonal) + atol):
break
old_diagonal = new_diagonal
return rq, times
# 行列サイズ
str_dim = input('正方行列サイズ dim = ')
dim = int(str_dim) # 文字列→整数
# (1)
mat_a = np.zeros((dim, dim))
for i in range(dim):
for j in range(dim):
mat_a[i, j] = float(dim - max(i, j))
print('mat_a = \n', mat_a)
# QR分解法実行
start_time1 = time.time()
qr, iterative_times = qr(mat_a, 1.0e-15, 0.0, 51)
time1 = time.time() - start_time1
print('QR: iteration, time = ', iterative_times, time1)
print(' i eigenvalues ')
for i in range(dim):
print(f'{i:2d} {qr[i, i]:25.17e}')
# -------------------------------------
# Copyright (c) 2021 Tomonori Kouya
# All rights reserved.
# -------------------------------------