-
Notifications
You must be signed in to change notification settings - Fork 88
/
Copy pathsolve-linear-by-iteration.py
151 lines (134 loc) · 4.04 KB
/
solve-linear-by-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
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
''' mbinary
#########################################################################
# File : solve-linear-by-iteration.py
# Author: mbinary
# Mail: [email protected]
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-10-02 21:14
# Description:
#########################################################################
'''
'''
#########################################################################
# File : solve-linear-by-iteration.py
# Author: mbinary
# Mail: [email protected]
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-05-04 07:42
# Description:
#########################################################################
'''
import numpy as np
from operator import le, lt
def jacob(A, b, x, accuracy=None, times=6):
''' Ax=b, arg x is the init val, times is the time of iterating'''
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
n, m = A.shape
if n != m:
raise Exception("Not square matrix: {A}".format(A=A))
if b.shape != (n, 1):
raise Exception(
'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n))
D = np.diag(np.diag(A))
DI = np.zeros([n, n])
for i in range(n):
DI[i, i] = 1/D[i, i]
R = np.eye(n) - DI * A
g = DI * b
print('R =\n{}'.format(R))
print('g =\n{}'.format(g))
last = -x
if accuracy != None:
ct = 0
while 1:
ct += 1
tmp = x-last
last = x
mx = max(abs(i) for i in tmp)
if mx < accuracy:
return x
x = R*x+g
print('x{ct} =\n{x}'.format(ct=ct, x=x))
else:
for i in range(times):
x = R*x+g
print('x{ct} = \n{x}'.format(ct=i+1, x=x))
print('isLimitd: {}'.format(isLimited(A)))
return x
def gauss_seidel(A, b, x, accuracy=None, times=6):
''' Ax=b, arg x is the init val, times is the time of iterating'''
A, b, x = np.matrix(A), np.matrix(b), np.matrix(x)
n, m = A.shape
if n != m:
raise Exception("Not square matrix: {A}".format(A=A))
if b.shape != (n, 1):
raise Exception(
'Error: {b} must be {n} x1 in dimension'.format(b=b, n=n))
D = np. matrix(np.diag(np.diag(A)))
L = np.tril(A) - D # L = np.triu(D.T) - D
U = np.triu(A) - D
DLI = (D+L).I
S = - (DLI) * U
f = (DLI)*b
print('S =\n{}'.format(S))
print('f =\n{}'.format(f))
last = -x
if accuracy != None:
ct = 0
while 1:
ct += 1
tmp = x-last
last = x
mx = max(abs(i) for i in tmp)
if mx < accuracy:
return x
x = S*x+f
print('x{ct} =\n{x}'.format(ct=ct, x=x))
else:
for i in range(times):
x = S*x+f
print('x{ct} = \n{x}'.format(ct=i+1, x=x))
print('isLimitd: {}'.format(isLimited(A)))
return x
def isLimited(A, strict=False):
'''通过检查A是否是[严格]对角优来判断迭代是否收敛, 即对角线上的值是否都大于对应行(或者列)的值'''
diag = np.diag(A)
op = lt if strict else le
if op(A.max(axis=0), diag).all():
return True
if op(A.max(axis=1), diag).all():
return True
return False
testcase = []
def test():
for func, A, b, x, *args in testcase:
acc = None
times = 6
if args != []:
if isinstance(args[0], int):
times = args[0]
else:
acc = args[0]
return func(A, b, x, acc, times)
if __name__ == '__main__':
A = [[2, -1, -1],
[1, 5, -1],
[1, 1, 10]
]
b = [[-5], [8], [11]]
x = [[1], [1], [1]]
# testcase.append([gauss_seidel,A,b,x])
A = [[2, -1, 1], [3, 3, 9], [3, 3, 5]]
b = [[-1], [0], [4]]
x = [[0], [0], [0]]
# testcase.append([jacob,A,b,x])
A = [[5, -1, -1],
[3, 6, 2],
[1, -1, 2]
]
b = [[16], [11], [-2]]
x = [[1], [1], [-1]]
testcase.append([gauss_seidel, A, b, x, 0.001])
test()