-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGaussElimination_v1.0.py
87 lines (79 loc) · 2.76 KB
/
GaussElimination_v1.0.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
#------------------------------------------------#
# Gauss Elimination Linear System Numeric Solver #
# 10/05/21 #
#------------------------------------------------#
#Auxilary
import numpy as np
def rowChange(checkMat, line1, line2):
line1Aux = line1
while (line1Aux < checkMat.shape[0]) and (checkMat[line1Aux, line2]) == 0:
line1Aux += 1
#If entire row is 0s
if line1Aux == checkMat.shape[0]:
return None
#Swap Row
checkMat[[line1, line1Aux]] = checkMat[[line1Aux, line1]]
return checkMat
#Main
def gaussElim(aMat_in, bMat_in):
import numpy as np
i = 0 #RowNum
j = 0 #ColNum
mult = 0 #Multiplier array
pivot = 0 #Line pivot
#Setup
aMat = aMat_in
bMat = bMat_in.reshape(aMat.shape[0],1)
augMat = np.hstack((aMat, bMat))
m = augMat.shape[0]
k = augMat.shape[1]
#Gauss algorithm
while (i < m) and (j < k):
#print("Step n°" + str(i+1) + ":" + "\n" + str(augMat))
#Check consistency
if np.linalg.det(augMat[:, :-1]) == 0:
print("Matrix is not consistent / System is undetermined")
break
#Search for pivot / Swap rows if pivot == 0 / Pivotal condensation
if (augMat[i,j] == 0):
augMat = rowChange(augMat, i, j)
pivot = augMat[i,j]
#Define multiplier
for i_m in range(i+1, m):
mult = augMat[i_m,j]/pivot
for j_m in range(j+1, k):
augMat[i_m,j_m] = augMat[i_m,j_m] - mult*augMat[i,j_m]
#Store multiplier in empty spaces
augMat[i_m,j] = mult
#Iterate
i += 1
j += 1
#Separating augmented matrix for convenience
newBMat = augMat[:, k-1]
newAMat = augMat[:, 0:k-1]
#Find results in triangular Matrix
results = [0]*m
results[m-1] = (newBMat[m-1]/newAMat[m-1, m-1])
for i in reversed(range(0, m-1)):
sumMat = 0
for j in range(i+1, m):
sumMat = sumMat + (newAMat[i,j]*results[j])
results[i] = (newBMat[i] - sumMat)/newAMat[i,i]
return results
#Implementation Example
#Test
aMat_in = np.array([[1,0,0,0],[1,0.5,pow(0.5,2),pow(0.5,3)],[1,0.75,pow(0.75,2),pow(0.75,3)],[1,1,1,1]])
bMat_in = np.array([0,0.479,0.682,0.841])
results = gaussElim(aMat_in,bMat_in)
print(results)
#Refinement step
resultsRef = results
refError = 5
while refError > 1e-5:
rMat = np.longdouble(np.subtract(bMat_in,np.matmul(aMat_in, resultsRef)))
corrMat = gaussElim(aMat_in, rMat)
oldResultsRef = resultsRef
resultsRef = np.add(resultsRef,corrMat)
refError = (abs(np.subtract(oldResultsRef,resultsRef))).max()
finalResult = resultsRef
print(finalResult)