-
Notifications
You must be signed in to change notification settings - Fork 88
/
Copy pathlinear_equation.py
136 lines (117 loc) · 3.49 KB
/
linear_equation.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
''' mbinary
#########################################################################
# File : linear_equation.py
# Author: mbinary
# Mail: [email protected]
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-10-02 21:14
# Description:
#########################################################################
'''
#coding: utf-8
'''************************************************************************
> File Name: doolittle.py
> Author: mbinary
> Mail: [email protected]
> Blog: https://mbinary.xyz
> Created Time: 2018-04-20 08:32
************************************************************************'''
import numpy as np
def getLU(A):
'''doolittle : A = LU,
L is in down-triangle form,
U is in up-triangle form
'''
m, n = A.shape
if m != n:
raise Exception("this matrix is not inversable")
L = np.zeros([m, m])
U = np.zeros([m, m])
L = np.matrix(L)
U = np. matrix(U)
U[0] = A[0]
L[:, 0] = A[:, 0] / A[0, 0]
for i in range(1, m):
for j in range(i, m):
U[i, j] = A[i, j] - sum(L[i, k]*U[k, j] for k in range(i))
L[j, i] = (A[j, i] - sum(L[j, k]*U[k, i]
for k in range(i)))/U[i, i]
print(L)
print(U)
return L, U
def gauss_prior_elimination(A):
'''using guass elimination,get up_trianglge form of A'''
m, n = A.shape
if m != n:
raise Exception("[Error]: matrix is not inversable")
# necessary,otherwise when the dtype of A is int, then it will be wrong
B = np.matrix(A, dtype=float)
for i in range(m-1):
# note using abs value, return a matrix in (m-i)x1 form
col = abs(B[i:, i])
mx = col.max()
if mx == 0:
raise Exception("[Error]: matrix is not inversable")
pos = i+col.argmax()
if pos != i:
B[[pos, i], :] = B[[i, pos], :] # note how to swap cols/rows
B[i, :] = 1/mx*B[i, :]
for j in range(i+1, m):
# print(B)
B[j, :] -= B[j, i] * B[i, :]
print(B)
return B
def solveDown(A, b):
'''A is a matrix in down-triangle form'''
sol = np.zeros(b.shape)
for i in range(b.shape[0]):
sol[i, 0] = (b[i, 0]-sum(A[i, j]*sol[j, 0] for j in range(i)))/A[i, i]
return sol
def solveUp(A, b):
'''A is a matrix in up-triangle form'''
sol = np.zeros(b.shape)
n = b.shape[0]
for i in range(n-1, -1, -1):
sol[i, 0] = (b[i, 0]-sum(A[i, j]*sol[j, 0]
for j in range(n-1, i, -1)))/A[i, i]
return sol
def doolittle(A, b):
L, U = getLU(A)
y = solveDown(L, b)
x = solveUp(U, y)
print(y)
print(x)
return x
def ldlt(A, b):
L, U = getLU(A)
D = np.diag(np.diag(U))
print(D, "D")
z = np.linalg.solve(L, b)
print(z, "z")
y = np.linalg.solve(D, z)
print(y, "y")
x = np.linalg.solve(L.T, y)
print(x, "x")
return x
if __name__ == '__main__':
A = np.matrix([[10, 5, 0, 0],
[2, 2, 1, 0],
[0, 10, 0, 5],
[0, 0, 2, 1]])
b = np.matrix([[5], [3], [27], [6]])
gauss_prior_elimination(A)
'''ldlt
A = np.matrix([[-6,3,2],
[3,5,1],
[2,1,6]])
b = np.matrix([[-4],[11],[-8]])
ldlt(A,b)
'''
'''
A = np.matrix([[2,1,1],
[1,3,2],
[1,2,2]])
b = np.matrix([[4],[6],[5]])
doolittle(A,b)
'''